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
2 changes: 1 addition & 1 deletion bin/trans-dump
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ const path = require('path');
const lilaDir = path.resolve(__dirname, '..');
const baseDir = path.resolve(lilaDir, 'translation/source');
const dbs =
'site arena emails learn activity coordinates study clas contact appeal patron coach broadcast streamer tfa settings preferences team perfStat search tourname faq lag swiss puzzle puzzleTheme challenge storm ublog insight keyboardMove timeago oauthScope dgt voiceCommands onboarding'.split(
'site arena emails learn activity coordinates study clas contact appeal patron coach broadcast streamer tfa settings preferences team perfStat search tourname faq lag swiss puzzle puzzleTheme challenge storm ublog insight keyboardMove timeago oauthScope dgt voiceCommands onboarding features'.split(
' ',
);

Expand Down
2 changes: 1 addition & 1 deletion build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ lazy val i18n = module("i18n",
I18n.serialize(
sourceDir = new File("translation/source"),
destDir = new File("translation/dest"),
dbs = "site arena emails learn activity coordinates study class contact appeal patron coach broadcast streamer tfa settings preferences team perfStat search tourname faq lag swiss puzzle puzzleTheme challenge storm ublog insight keyboardMove timeago oauthScope dgt voiceCommands onboarding".split(' ').toList,
dbs = "site arena emails learn activity coordinates study class contact appeal patron coach broadcast streamer tfa settings preferences team perfStat search tourname faq lag swiss puzzle puzzleTheme challenge storm ublog insight keyboardMove timeago oauthScope dgt voiceCommands onboarding features".split(' ').toList,
outputFile
)
}.taskValue
Expand Down
37 changes: 34 additions & 3 deletions modules/coreI18n/src/main/key.scala
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,7 @@ object I18nKey:
val `latestForumPosts`: I18nKey = "latestForumPosts"
val `players`: I18nKey = "players"
val `friends`: I18nKey = "friends"
val `otherPlayers`: I18nKey = "otherPlayers"
val `discussions`: I18nKey = "discussions"
val `today`: I18nKey = "today"
val `yesterday`: I18nKey = "yesterday"
Expand Down Expand Up @@ -421,6 +422,8 @@ object I18nKey:
val `descPrivateHelp`: I18nKey = "descPrivateHelp"
val `no`: I18nKey = "no"
val `yes`: I18nKey = "yes"
val `website`: I18nKey = "website"
val `mobile`: I18nKey = "mobile"
val `help`: I18nKey = "help"
val `createANewTopic`: I18nKey = "createANewTopic"
val `topics`: I18nKey = "topics"
Expand All @@ -438,7 +441,6 @@ object I18nKey:
val `whatIsIheMatter`: I18nKey = "whatIsIheMatter"
val `cheat`: I18nKey = "cheat"
val `troll`: I18nKey = "troll"
val `ratingManipulation`: I18nKey = "ratingManipulation"
val `other`: I18nKey = "other"
val `reportDescriptionHelp`: I18nKey = "reportDescriptionHelp"
val `error.provideOneCheatedGameLink`: I18nKey = "error.provideOneCheatedGameLink"
Expand Down Expand Up @@ -1497,9 +1499,7 @@ object I18nKey:
val `botRatingAbuse`: I18nKey = "contact:botRatingAbuse"
val `errorPage`: I18nKey = "contact:errorPage"
val `reportErrorPage`: I18nKey = "contact:reportErrorPage"
val `wantBroadcastTournament`: I18nKey = "contact:wantBroadcastTournament"
val `learnHowToMakeBroadcasts`: I18nKey = "contact:learnHowToMakeBroadcasts"
val `contactAboutOfficialBroadcasts`: I18nKey = "contact:contactAboutOfficialBroadcasts"
val `banAppeal`: I18nKey = "contact:banAppeal"
val `engineAppeal`: I18nKey = "contact:engineAppeal"
val `sendAppealTo`: I18nKey = "contact:sendAppealTo"
Expand Down Expand Up @@ -2736,3 +2736,34 @@ object I18nKey:
val `configureLichess`: I18nKey = "onboarding:configureLichess"
val `exploreTheSiteAndHaveFun`: I18nKey = "onboarding:exploreTheSiteAndHaveFun"

object features:
val `zeroAdsAndNoTracking`: I18nKey = "features:zeroAdsAndNoTracking"
val `correspondenceWithConditionalPremoves`: I18nKey = "features:correspondenceWithConditionalPremoves"
val `standardChessAndX`: I18nKey = "features:standardChessAndX"
val `deepXServerAnalysis`: I18nKey = "features:deepXServerAnalysis"
val `boardEditorAndAnalysisBoardWithEngine`: I18nKey = "features:boardEditorAndAnalysisBoardWithEngine"
val `cloudEngineAnalysis`: I18nKey = "features:cloudEngineAnalysis"
val `studies`: I18nKey = "features:studies"
val `chessInsights`: I18nKey = "features:chessInsights"
val `allChessBasicsLessons`: I18nKey = "features:allChessBasicsLessons"
val `tacticalPuzzlesFromUserGames`: I18nKey = "features:tacticalPuzzlesFromUserGames"
val `personalOpeningExplorerX`: I18nKey = "features:personalOpeningExplorerX"
val `personalOpeningExplorer`: I18nKey = "features:personalOpeningExplorer"
val `endgameTablebase`: I18nKey = "features:endgameTablebase"
val `downloadOrUploadAnyGameAsPgn`: I18nKey = "features:downloadOrUploadAnyGameAsPgn"
val `xThroughLichessBillionGames`: I18nKey = "features:xThroughLichessBillionGames"
val `tvForumBlogTeamsMessagingFriendsChallenges`: I18nKey = "features:tvForumBlogTeamsMessagingFriendsChallenges"
val `lightOrDarkThemeCustomBoardsPiecesAndBackground`: I18nKey = "features:lightOrDarkThemeCustomBoardsPiecesAndBackground"
val `allFeaturesToCome`: I18nKey = "features:allFeaturesToCome"
val `landscapeSupportOnApp`: I18nKey = "features:landscapeSupportOnApp"
val `supportLichess`: I18nKey = "features:supportLichess"
val `contributeToLichessAndGetIcon`: I18nKey = "features:contributeToLichessAndGetIcon"
val `ifYouLoveLichess`: I18nKey = "features:ifYouLoveLichess"
val `supportUsWithAPatronAccount`: I18nKey = "features:supportUsWithAPatronAccount"
val `allFeaturesAreFreeForEverybody`: I18nKey = "features:allFeaturesAreFreeForEverybody"
val `weBelieveEveryChessPlayerDeservesTheBest`: I18nKey = "features:weBelieveEveryChessPlayerDeservesTheBest"
val `ultraBulletBulletBlitzRapidClassicalAndCorrespondenceChess`: I18nKey = "features:ultraBulletBulletBlitzRapidClassicalAndCorrespondenceChess"
val `everybodyGetsAllFeaturesForFree`: I18nKey = "features:everybodyGetsAllFeaturesForFree"
val `gamesPerDay`: I18nKey = "features:gamesPerDay"
val `globalOpeningExplorerInNbGames`: I18nKey = "features:globalOpeningExplorerInNbGames"

127 changes: 56 additions & 71 deletions modules/plan/src/main/ui/PlanPages.scala
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,12 @@ final class PlanPages(helpers: Helpers)(fishnetPerDay: Int):

def features(using Context) =
def header(name: Frag)(using Translate) = thead(
st.tr(th(name), th(trans.patron.freeAccount()), th(trans.patron.lichessPatron()))
st.tr(th(name), th(trp.freeAccount()), th(trp.lichessPatron()))
)
val unlimited = span(dataIcon := Icon.Checkmark, cls := "is is-green text unlimited")("Unlimited")
val check = span(dataIcon := Icon.Checkmark, cls := "is is-green text check")("Yes")
def custom(str: String) = span(dataIcon := Icon.Checkmark, cls := "is is-green text check")(str)
val unlimited =
span(dataIcon := Icon.Checkmark, cls := "is is-green text unlimited")(trans.site.unlimited())
val custom = span(dataIcon := Icon.Checkmark, cls := "is is-green text check")
val check = custom(trans.site.yes())
def all(content: Frag) = frag(td(content), td(content))
def tr(value: Frag)(text: Frag*) = st.tr(th(text), all(value))
val title = "Lichess features"
Expand All @@ -27,62 +28,57 @@ final class PlanPages(helpers: Helpers)(fishnetPerDay: Int):
):
main(cls := "box box-pad features")(
table(
header(h1(dataIcon := Icon.ScreenDesktop)("Website")),
header(h1(dataIcon := Icon.ScreenDesktop)(trans.site.website())),
tbody(
tr(check)(
strong("Zero ads")
strong(trans.features.zeroAdsAndNoTracking())
),
tr(check)(
strong("No tracking")
tr(unlimited)(
a(href := routes.Tournament.home)(trans.arena.arenaTournaments())
),
tr(unlimited)(
"Play and create ",
a(href := routes.Tournament.home)("tournaments")
a(href := routes.Swiss.home)(trans.swiss.swissTournaments())
),
tr(unlimited)(
"Play and create ",
a(href := routes.Simul.home)("simultaneous exhibitions")
a(href := routes.Simul.home)(trans.site.simultaneousExhibitions())
),
tr(unlimited)(
"Correspondence chess with conditional premoves"
trans.features.correspondenceWithConditionalPremoves()
),
tr(check)(
"Standard chess and ",
a(href := routes.Cms.variantHome)("8 chess variants (Crazyhouse, Chess960, Horde, ...)")
trans.features.standardChessAndX(a(href := routes.Cms.variantHome)(trans.faq.eightVariants()))
),
tr(custom(s"$fishnetPerDay per day"))(
"Deep ",
lila.ui.bits.engineFullName,
" server analysis"
tr(custom(trans.features.gamesPerDay.pluralSame(fishnetPerDay)))(
trans.features.deepXServerAnalysis(lila.ui.bits.engineFullName)
),
tr(unlimited)(
"Instant local Stockfish 14+ analysis (depth 99)"
trans.features.boardEditorAndAnalysisBoardWithEngine("Stockfish 16+ NNUE")
),
tr(unlimited)(
a(href := "https://lichess.org/blog/WN-gLzAAAKlI89Xn/thousands-of-stockfish-analysers")(
"Cloud engine analysis"
trans.features.cloudEngineAnalysis()
)
),
tr(unlimited)(
a(href := "https://lichess.org/blog/WFvLpiQAACMA8e9D/learn-from-your-mistakes")(
"Learn from your mistakes"
trans.site.learnFromYourMistakes()
)
),
tr(unlimited)(
a(href := "https://lichess.org/blog/V0KrLSkAAMo3hsi4/study-chess-the-lichess-way")(
"Studies (shared and persistent analysis)"
trans.features.studies()
)
),
tr(unlimited)(
a(href := "https://lichess.org/blog/VmZbaigAABACtXQC/chess-insights")(
"Chess insights (detailed analysis of your play)"
trans.features.chessInsights()
)
),
tr(check)(
a(href := routes.Learn.index)("All chess basics lessons")
a(href := routes.Learn.index)(trans.features.allChessBasicsLessons())
),
tr(unlimited)(
a(href := routes.Puzzle.home)("Tactical puzzles from user games")
a(href := routes.Puzzle.home)(trans.features.tacticalPuzzlesFromUserGames())
),
tr(unlimited)(
a(href := routes.Puzzle.streak)("Puzzle Streak"),
Expand All @@ -92,87 +88,78 @@ final class PlanPages(helpers: Helpers)(fishnetPerDay: Int):
a(href := routes.Racer.home)("Puzzle Racer")
),
tr(check)(
a(href := s"${routes.UserAnalysis.index}#explorer")("Global opening explorer"),
" (430 million games!)"
a(href := s"${routes.UserAnalysis.index}#explorer")(
trans.features.globalOpeningExplorerInNbGames(6_000_000_000L.localize)
)
),
tr(check)(
a(href := s"${routes.UserAnalysis.index}#explorer/me")("Personal opening explorer"),
" (also works on ",
a(href := s"${routes.UserAnalysis.index}#explorer/DrNykterstein")("other players"),
")"
trans.features.personalOpeningExplorerX(
a(href := s"${routes.UserAnalysis.index}#explorer/me")(
trans.features.personalOpeningExplorer()
),
a(href := s"${routes.UserAnalysis.index}#explorer/DrNykterstein")(trans.site.otherPlayers())
)
),
tr(unlimited)(
a(href := s"${routes.UserAnalysis.parseArg("QN4n1/6r1/3k4/8/b2K4/8/8/8_b_-_-")}#explorer")(
"7-piece endgame tablebase"
trans.features.endgameTablebase()
)
),
tr(check)(
"Download/Upload any game as PGN"
),
tr(unlimited)(
a(href := routes.Search.index(1))("Advanced search"),
" through Lichess 4 billion games"
),
tr(unlimited)(
a(href := routes.Video.index)("Chess video library")
trans.features.downloadOrUploadAnyGameAsPgn()
),
tr(check)(
"Forum, teams, messaging, friends, challenges"
trans.features.tvForumBlogTeamsMessagingFriendsChallenges()
),
tr(check)(
"Available in ",
a(href := "https://crowdin.com/project/lichess")("80+ languages")
trans.site.availableInNbLanguages(a(href := "https://crowdin.com/project/lichess")("140+"))
),
tr(check)(
"Light/dark theme, custom boards, pieces and background"
trans.features.lightOrDarkThemeCustomBoardsPiecesAndBackground()
),
tr(check)(
strong("All features to come, forever")
strong(trans.features.allFeaturesToCome())
)
),
header(h1(dataIcon := Icon.PhoneMobile)("Mobile")),
header(h1(dataIcon := Icon.PhoneMobile)(trans.site.mobile())),
tbody(
tr(check)(
strong("Zero ads, no tracking")
strong(trans.features.zeroAdsAndNoTracking())
),
tr(unlimited)(
"Online and offline games, with 8 variants"
trans.site.onlineAndOfflinePlay()
),
tr(unlimited)(
"Bullet, Blitz, Rapid, Classical and Correspondence chess"
trans.features.ultraBulletBulletBlitzRapidClassicalAndCorrespondenceChess()
),
tr(unlimited)(
a(href := routes.Tournament.home)("Arena tournaments")
a(href := routes.Tournament.home)(trans.arena.arenaTournaments())
),
tr(check)(
"Board editor and analysis board with Stockfish 14+"
trans.features.boardEditorAndAnalysisBoardWithEngine("Stockfish 14+")
),
tr(unlimited)(
a(href := routes.Puzzle.home)("Tactics puzzles")
a(href := routes.Puzzle.home)(trans.features.tacticalPuzzlesFromUserGames())
),
tr(check)(
"Available in 80+ languages"
trans.site.availableInNbLanguages(a(href := "https://crowdin.com/project/lichess")("100+"))
),
tr(check)(
"Light and dark theme, custom boards and pieces"
trans.features.lightOrDarkThemeCustomBoardsPiecesAndBackground()
),
tr(check)(
"iPhone & Android phones and tablets, landscape support"
trans.features.landscapeSupportOnApp()
),
tr(check)(
strong("All features to come, forever")
strong(trans.features.allFeaturesToCome())
)
),
header(h1("Support Lichess")),
header(h1(trans.features.supportLichess())),
tbody(cls := "support")(
st.tr(
th(
"Contribute to Lichess and",
br,
"get a cool looking Patron icon"
),
th(trans.features.contributeToLichessAndGetIcon()),
td("-"),
td(span(dataIcon := patronIconChar, cls := "is is-green text check")("Yes"))
td(span(dataIcon := patronIconChar, cls := "is is-green text check")(trans.site.yes()))
),
st.tr(cls := "price")(
th,
Expand All @@ -182,17 +169,15 @@ final class PlanPages(helpers: Helpers)(fishnetPerDay: Int):
)
),
p(cls := "explanation")(
strong("Yes, both accounts have the same features!"),
br,
"That is because Lichess is built for the love of chess.",
strong(trans.features.everybodyGetsAllFeaturesForFree()),
br,
"We believe every chess player deserves the best, and so:",
trans.features.weBelieveEveryChessPlayerDeservesTheBest(),
br,
br,
strong("all features are free for everybody, forever!"),
strong(trans.features.allFeaturesAreFreeForEverybody()),
br,
"If you love Lichess, ",
a(cls := "button", href := routes.Plan.index)("Support us with a Patron account!")
trans.features.ifYouLoveLichess(),
a(cls := "button", href := routes.Plan.index)(trans.features.supportUsWithAPatronAccount())
)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the text of this box no longer makes sense.

)

Expand Down
34 changes: 34 additions & 0 deletions translation/source/features.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="zeroAdsAndNoTracking">Zero advertisement, no tracking</string>
<string name="correspondenceWithConditionalPremoves">Correspondence chess with conditional premoves</string>
<string name="standardChessAndX" comment="%s is 8 variants">Standard chess and %s</string>
<string name="deepXServerAnalysis" comment="%s is the engine name">Deep %s server analysis</string>
<plurals name="gamesPerDay">
<item quantity="one">%s game per day</item>
<item quantity="other">%s games per day</item>
</plurals>
<string name="boardEditorAndAnalysisBoardWithEngine" comment="%s is the engine name (Stockfish, Fairy-Stockfish)">Board editor and analysis board with %s</string>
<string name="cloudEngineAnalysis">Cloud engine analysis</string>
<string name="studies">Studies (shared and persistent analysis)</string>
<string name="chessInsights">Chess insights (detailed analysis of your play)</string>
<string name="allChessBasicsLessons">All chess basics lessons</string>
<string name="tacticalPuzzlesFromUserGames">Tactical puzzles from user games</string>
<string name="personalOpeningExplorerX">%1$s (also works on %2$s)</string>
<string name="personalOpeningExplorer">Personal opening explorer</string>
<string name="globalOpeningExplorerInNbGames">Global opening explorer (%s games!)</string>
<string name="endgameTablebase">7-piece endgame tablebase</string>
<string name="downloadOrUploadAnyGameAsPgn">Download/Upload any game as PGN</string>
<string name="tvForumBlogTeamsMessagingFriendsChallenges">Blog, forum, teams, TV, messaging, friends, challenges</string>
<string name="lightOrDarkThemeCustomBoardsPiecesAndBackground">Light/Dark theme, custom boards, pieces and background</string>
<string name="ultraBulletBulletBlitzRapidClassicalAndCorrespondenceChess">UltraBullet, Bullet, Blitz, Rapid, Classical, Correspondence Chess</string>
<string name="allFeaturesToCome">All features to come, forever!</string>
<string name="landscapeSupportOnApp">iPhone &amp; Android phones and tablets, landscape support</string>
<string name="supportLichess">Support Lichess</string>
<string name="contributeToLichessAndGetIcon">Contribute to Lichess and get a cool looking Patron icon</string>
<string name="everybodyGetsAllFeaturesForFree">Yes, both accounts have the same features!</string>
<string name="weBelieveEveryChessPlayerDeservesTheBest">We believe every chess player deserves the best, and so:</string>
<string name="allFeaturesAreFreeForEverybody">All features are free for everybody, forever!</string>
<string name="ifYouLoveLichess">If you love Lichess,</string>
<string name="supportUsWithAPatronAccount">Support us with a Patron account!</string>
</resources>
Loading