Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions modules/coreI18n/src/main/key.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1223,10 +1223,8 @@ object I18nKey:
val `newStreak`: I18nKey = "puzzle:newStreak"
val `fromMyGames`: I18nKey = "puzzle:fromMyGames"
val `lookupOfPlayer`: I18nKey = "puzzle:lookupOfPlayer"
val `fromXGames`: I18nKey = "puzzle:fromXGames"
val `searchPuzzles`: I18nKey = "puzzle:searchPuzzles"
val `fromMyGamesNone`: I18nKey = "puzzle:fromMyGamesNone"
val `fromXGamesFound`: I18nKey = "puzzle:fromXGamesFound"
val `puzzleDashboardDescription`: I18nKey = "puzzle:puzzleDashboardDescription"
val `percentSolved`: I18nKey = "puzzle:percentSolved"
val `noPuzzlesToShow`: I18nKey = "puzzle:noPuzzlesToShow"
Expand All @@ -1235,6 +1233,7 @@ object I18nKey:
val `playedXTimes`: I18nKey = "puzzle:playedXTimes"
val `nbPointsBelowYourPuzzleRating`: I18nKey = "puzzle:nbPointsBelowYourPuzzleRating"
val `nbPointsAboveYourPuzzleRating`: I18nKey = "puzzle:nbPointsAboveYourPuzzleRating"
val `puzzlesFoundInUserGames`: I18nKey = "puzzle:puzzlesFoundInUserGames"
val `nbPlayed`: I18nKey = "puzzle:nbPlayed"
val `nbToReplay`: I18nKey = "puzzle:nbToReplay"

Expand Down Expand Up @@ -1539,6 +1538,7 @@ object I18nKey:
val `drawByMutualAgreement`: I18nKey = "drawByMutualAgreement"
val `fiftyMovesWithoutProgress`: I18nKey = "fiftyMovesWithoutProgress"
val `currentGames`: I18nKey = "currentGames"
val `joinedX`: I18nKey = "joinedX"
val `viewInFullSize`: I18nKey = "viewInFullSize"
val `logOut`: I18nKey = "logOut"
val `signIn`: I18nKey = "signIn"
Expand Down
64 changes: 35 additions & 29 deletions modules/puzzle/src/main/ui/PuzzleUi.scala
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,11 @@ final class PuzzleUi(helpers: Helpers, val bits: PuzzleBits)(
)

def ofPlayer(query: String, user: Option[User], puzzles: Option[Paginator[Puzzle]])(using ctx: Context) =
Page(user.fold(trans.puzzle.lookupOfPlayer.txt())(u => trans.puzzle.fromXGames.txt(u.username)))
val title: String = (user, puzzles).tupled match
case Some(u, pager) =>
trans.puzzle.puzzlesFoundInUserGames.pluralTxt(pager.nbResults, pager.nbResults.localize, u.username)
case _ => trans.puzzle.lookupOfPlayer.txt()
Page(title)
.css("puzzle.page")
.js(infiniteScrollEsmInit):
main(cls := "page-menu")(
Expand All @@ -239,37 +243,39 @@ final class PuzzleUi(helpers: Helpers, val bits: PuzzleBits)(
),
submitButton(cls := "button")(trans.puzzle.searchPuzzles.txt())
),
div(cls := "puzzle-of-player__results")(
(user, puzzles) match
case (Some(u), Some(pager)) =>
if pager.nbResults == 0 && ctx.is(u) then p(trans.puzzle.fromMyGamesNone())
else
frag(
p(strong(trans.puzzle.fromXGamesFound((pager.nbResults), userLink(u)))),
div(cls := "puzzle-of-player__pager infinite-scroll")(
pager.currentPageResults.map { puzzle =>
div(cls := "puzzle-of-player__puzzle")(
chessgroundMini(
fen = puzzle.fenAfterInitialMove.board,
color = puzzle.color,
lastMove = puzzle.line.head.some
)(
a(
cls := s"puzzle-of-player__puzzle__board",
href := routes.Puzzle.show(puzzle.id.value)
)
),
span(cls := "puzzle-of-player__puzzle__meta")(
span(cls := "puzzle-of-player__puzzle__id", s"#${puzzle.id}"),
span(cls := "puzzle-of-player__puzzle__rating", puzzle.glicko.intRating)
div(cls := "puzzle-of-player__results"):
(user, puzzles).tupled.map: (u, pager) =>
if pager.nbResults == 0 && ctx.is(u) then p(trans.puzzle.fromMyGamesNone())
else
frag(
p(
strong(
trans.puzzle.puzzlesFoundInUserGames
.plural(pager.nbResults, pager.nbResults.localize, userLink(u))
)
),
div(cls := "puzzle-of-player__pager infinite-scroll")(
pager.currentPageResults.map { puzzle =>
div(cls := "puzzle-of-player__puzzle")(
chessgroundMini(
fen = puzzle.fenAfterInitialMove.board,
color = puzzle.color,
lastMove = puzzle.line.head.some
)(
a(
cls := s"puzzle-of-player__puzzle__board",
href := routes.Puzzle.show(puzzle.id.value)
)
),
span(cls := "puzzle-of-player__puzzle__meta")(
span(cls := "puzzle-of-player__puzzle__id", s"#${puzzle.id}"),
span(cls := "puzzle-of-player__puzzle__rating", puzzle.glicko.intRating)
)
},
pagerNext(pager, np => s"${routes.Puzzle.ofPlayer(u.username.some, np).url}")
)
)
},
pagerNext(pager, np => s"${routes.Puzzle.ofPlayer(u.username.some, np).url}")
)
case (_, _) => emptyFrag
)
)
)
)

Expand Down
16 changes: 8 additions & 8 deletions modules/ui/src/main/helper/DateHelper.scala
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import play.api.i18n.Lang
import java.time.format.{ DateTimeFormatter, FormatStyle, TextStyle }
import java.time.{ Duration, LocalDate, Month, YearMonth }

import lila.core.i18n.{ maxLangs, Translate }
import lila.core.i18n.{ maxLangs, Translate, I18nKey }
import lila.ui.ScalatagsTemplate.*
import scalalib.model.Seconds

Expand Down Expand Up @@ -78,14 +78,14 @@ trait DateHelper:
absClientInstantEmpty(instant)(nbsp)
else timeTag(cls := s"timeago${once.so(" once")}", datetimeAttr := isoDateTime(instant))(nbsp)

def momentFromNowWithPreload(instant: Instant): Frag =
def momentFromNowWithPreload(instant: Instant)(using Translate): Frag =
momentFromNowWithPreload(instant, false, false)

def momentFromNowWithPreload(
instant: Instant,
alwaysRelative: Boolean = false,
once: Boolean = false
): Frag =
)(using Translate): Frag =
momentFromNow(instant, alwaysRelative, once)(momentFromNowServerText(instant))

def absClientInstant(instant: Instant)(using Translate): Tag =
Expand All @@ -102,7 +102,7 @@ trait DateHelper:
def momentFromNowServer(instant: Instant)(using Translate): Frag =
timeTag(title := s"${showInstant(instant)} UTC")(momentFromNowServerText(instant))

def momentFromNowServerText(instant: Instant): String =
def momentFromNowServerText(instant: Instant)(using Translate): String =
val inFuture = false
val (dateSec, nowSec) = (instant.toMillis / 1000, nowSeconds)
val seconds = (if inFuture then dateSec - nowSec else nowSec - dateSec).toInt.atLeast(0)
Expand All @@ -113,18 +113,18 @@ trait DateHelper:
lazy val months = days / 30
lazy val years = days / 365
val preposition = if inFuture then " from now" else " ago"
if minutes == 0 then "right now"
if minutes == 0 then I18nKey.timeago.rightNow.txt()
else if hours == 0 then s"${pluralize("minute", minutes)}$preposition"
else if days < 2 then s"${pluralize("hour", hours)}$preposition"
else if weeks == 0 then s"${pluralize("day", days)}$preposition"
else if months == 0 then s"${pluralize("week", weeks)}$preposition"
else if years == 0 then s"${pluralize("month", months)}$preposition"
else s"${pluralize("year", years)}$preposition"

def daysFromNow(date: LocalDate): String =
def daysFromNow(date: LocalDate)(using Translate): String =
val today = nowInstant.date
if date == today then "Today"
else if date == today.minusDays(1) then "Yesterday"
if date == today then I18nKey.site.today.txt()
else if date == today.minusDays(1) then I18nKey.site.yesterday.txt()
else momentFromNowServerText(date.atStartOfDay.instant)

def timeRemaining(instant: Instant): Tag =
Expand Down
2 changes: 1 addition & 1 deletion modules/user/src/main/ui/UserShow.scala
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ final class UserShow(helpers: Helpers, bits: UserBits):
),
div(cls := "upt__details")(
span(trans.site.nbGames.plural(u.count.game, u.count.game.localize)),
span("joined ", momentFromNowServerText(u.createdAt)),
span(trans.site.joinedX(momentFromNowServerText(u.createdAt))),
(Granter.opt(_.UserModView) && (u.lameOrTroll || u.enabled.no || u.marks.rankban))
.option(span(cls := "upt__details__marks")(userMarks))
),
Expand Down
6 changes: 4 additions & 2 deletions translation/source/puzzle.xml
Original file line number Diff line number Diff line change
Expand Up @@ -75,12 +75,14 @@
<string name="newStreak">New streak</string>
<string name="fromMyGames">From my games</string>
<string name="lookupOfPlayer">Lookup puzzles from a player's games</string>
<string name="fromXGames">Puzzles from %s' games</string>
<string name="searchPuzzles">Search puzzles</string>
<string name="fromMyGamesNone">You have no puzzles in the database, but Lichess still loves you very much.

Play rapid and classical games to increase your chances of having a puzzle of yours added!</string>
<string name="fromXGamesFound">%1$s puzzles found in %2$s games</string>
<plurals name="puzzlesFoundInUserGames">
<item quantity="one">One puzzle found in games by %2$s</item>
<item quantity="other">%1$s puzzles found in games by %2$s</item>
</plurals>
<string name="puzzleDashboardDescription">Train, analyse, improve</string>
<plurals name="nbPlayed">
<item quantity="other">%s played</item>
Expand Down
1 change: 1 addition & 0 deletions translation/source/site.xml
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,7 @@
<string name="drawByMutualAgreement">Draw by mutual agreement</string>
<string name="fiftyMovesWithoutProgress">Fifty moves without progress</string>
<string name="currentGames">Current games</string>
<string name="joinedX">Joined %s</string>
<plurals name="nbGames">
<item quantity="one">%s game</item>
<item quantity="other">%s games</item>
Expand Down
10 changes: 6 additions & 4 deletions ui/@types/lichess/i18n.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2289,10 +2289,6 @@ interface I18n {
fromMyGames: string;
/** You have no puzzles in the database, but Lichess still loves you very much. */
fromMyGamesNone: string;
/** Puzzles from %s' games */
fromXGames: I18nFormat;
/** %1$s puzzles found in %2$s games */
fromXGamesFound: I18nFormat;
/** Goals */
goals: string;
/** Good move */
Expand Down Expand Up @@ -2363,6 +2359,8 @@ interface I18n {
puzzles: string;
/** Puzzles by openings */
puzzlesByOpenings: string;
/** %1$s puzzles found in games by %2$s */
puzzlesFoundInUserGames: I18nPlural;
/** Success! */
puzzleSuccess: string;
/** Puzzle Themes */
Expand Down Expand Up @@ -3389,6 +3387,8 @@ interface I18n {
itsYourTurn: string;
/** Join */
join: string;
/** Joined %s */
joinedX: I18nFormat;
/** Join the game */
joinTheGame: string;
/** Join the %1$s, to post in this forum */
Expand Down Expand Up @@ -3951,6 +3951,8 @@ interface I18n {
reviewWhiteMistakes: string;
/** revoke all sessions */
revokeAllSessions: string;
/** right now */
rightNow: string;
/** Pick a very safe name for the tournament. */
safeTournamentName: string;
/** Save */
Expand Down
Loading