Merge branch 'master' into ScalaEvaluator
* master: (23 commits) add missing font realtime replay autoplay fast and slow analysis autoplay analysis action menu fix analysis board from FEN fix swiss tournament UI upgrade chess module lv "latviešu valoda" translation #12512. Author: krauzand. fixed translation errors send a reload message on failed force resign link to actual game initial position show previous moves in correspondence analysis screen - resolves #274 fix integer overflow in correspondence games - fixes #278 don't cancel draw offer on move - resolves #277 don't batch single messages cancel premove on takeback - fixes #276 he "עִבְרִית" translation #12508. Author: _PurelySmart. lv "latviešu valoda" translation #12507. Author: krauzand. hu "Magyar" translation #12506. Author: WMage. fa "فارسی" translation #12502. Author: gambi. ...
This commit is contained in:
commit
4819f24869
|
@ -8,10 +8,10 @@ import play.api.mvc._
|
||||||
import play.twirl.api.Html
|
import play.twirl.api.Html
|
||||||
|
|
||||||
import lila.analyse.{ Analysis, TimeChart, AdvantageChart, Accuracy }
|
import lila.analyse.{ Analysis, TimeChart, AdvantageChart, Accuracy }
|
||||||
import lila.evaluation.GameResults
|
|
||||||
import lila.api.Context
|
import lila.api.Context
|
||||||
import lila.app._
|
import lila.app._
|
||||||
import lila.common.HTTPRequest
|
import lila.common.HTTPRequest
|
||||||
|
import lila.evaluation.GameResults
|
||||||
import lila.game.{ Pov, Game => GameModel, GameRepo, PgnDump }
|
import lila.game.{ Pov, Game => GameModel, GameRepo, PgnDump }
|
||||||
import lila.hub.actorApi.map.Tell
|
import lila.hub.actorApi.map.Tell
|
||||||
import lila.round.actorApi.AnalysisAvailable
|
import lila.round.actorApi.AnalysisAvailable
|
||||||
|
@ -60,17 +60,21 @@ object Analyse extends LilaController {
|
||||||
GameRepo initialFen pov.game.id flatMap { initialFen =>
|
GameRepo initialFen pov.game.id flatMap { initialFen =>
|
||||||
(env.analyser get pov.game.id) zip
|
(env.analyser get pov.game.id) zip
|
||||||
(pov.game.tournamentId ?? lila.tournament.TournamentRepo.byId) zip
|
(pov.game.tournamentId ?? lila.tournament.TournamentRepo.byId) zip
|
||||||
Env.game.crosstableApi(pov.game) flatMap {
|
Env.game.crosstableApi(pov.game) flatMap {
|
||||||
case ((analysis, tour), crosstable) =>
|
case ((analysis, tour), crosstable) =>
|
||||||
val division =
|
val division =
|
||||||
if (HTTPRequest.isBot(ctx.req)) divider.empty
|
if (HTTPRequest.isBot(ctx.req)) divider.empty
|
||||||
else divider(pov.game, initialFen)
|
else divider(pov.game, initialFen)
|
||||||
val pgn = Env.game.pgnDump(pov.game, initialFen)
|
val pgn = Env.game.pgnDump(pov.game, initialFen)
|
||||||
val assessResults = if (isGranted(_.MarkEngine)) Env.mod.assessApi.getResultsByGameId(pov.game.id)
|
val assessResults = if (isGranted(_.MarkEngine)) Env.mod.assessApi.getResultsByGameId(pov.game.id)
|
||||||
else fuccess(GameResults(None, None))
|
else fuccess(GameResults(None, None))
|
||||||
assessResults flatMap {
|
assessResults flatMap {
|
||||||
results =>
|
results =>
|
||||||
Env.api.roundApi.watcher(pov, lila.api.Mobile.Api.currentVersion, tv = none, analysis.map(pgn -> _), initialFen = initialFen.some) map { data => {
|
Env.api.roundApi.watcher(pov, lila.api.Mobile.Api.currentVersion,
|
||||||
|
tv = none,
|
||||||
|
analysis.map(pgn -> _),
|
||||||
|
initialFen = initialFen.some,
|
||||||
|
withMoveTimes = true) map { data =>
|
||||||
Ok(html.analyse.replay(
|
Ok(html.analyse.replay(
|
||||||
pov,
|
pov,
|
||||||
data,
|
data,
|
||||||
|
@ -83,8 +87,8 @@ object Analyse extends LilaController {
|
||||||
userTv,
|
userTv,
|
||||||
division,
|
division,
|
||||||
results))
|
results))
|
||||||
} }
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,9 +18,9 @@ object UserAnalysis extends LilaController with BaseGame {
|
||||||
val decodedFen = fenStr.map { java.net.URLDecoder.decode(_, "UTF-8").trim }.filter(_.nonEmpty)
|
val decodedFen = fenStr.map { java.net.URLDecoder.decode(_, "UTF-8").trim }.filter(_.nonEmpty)
|
||||||
val situation = (decodedFen flatMap Forsyth.<<<) | SituationPlus(Situation(chess.variant.Standard), 1)
|
val situation = (decodedFen flatMap Forsyth.<<<) | SituationPlus(Situation(chess.variant.Standard), 1)
|
||||||
val pov = makePov(situation)
|
val pov = makePov(situation)
|
||||||
val data = Env.round.jsonView.userAnalysisJson(pov, ctx.pref)
|
Env.round.jsonView.userAnalysisJson(pov, ctx.pref) zip makeListMenu map {
|
||||||
makeListMenu map { listMenu =>
|
case (data, listMenu) =>
|
||||||
Ok(html.board.userAnalysis(listMenu, data, none))
|
Ok(html.board.userAnalysis(listMenu, data, none))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,9 +42,9 @@ object UserAnalysis extends LilaController with BaseGame {
|
||||||
def game(id: String, color: String) = Open { implicit ctx =>
|
def game(id: String, color: String) = Open { implicit ctx =>
|
||||||
OptionFuOk(GameRepo game id) { game =>
|
OptionFuOk(GameRepo game id) { game =>
|
||||||
val pov = Pov(game, chess.Color(color == "white"))
|
val pov = Pov(game, chess.Color(color == "white"))
|
||||||
val data = Env.round.jsonView.userAnalysisJson(pov, ctx.pref)
|
Env.round.jsonView.userAnalysisJson(pov, ctx.pref) zip makeListMenu map {
|
||||||
makeListMenu map { listMenu =>
|
case (data, listMenu) =>
|
||||||
html.board.userAnalysis(listMenu, data, pov.some)
|
html.board.userAnalysis(listMenu, data, pov.some)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,10 @@ data: @Html(play.api.libs.json.Json.stringify(data)),
|
||||||
routes: roundRoutes.controllers,
|
routes: roundRoutes.controllers,
|
||||||
i18n: @round.jsI18n()
|
i18n: @round.jsI18n()
|
||||||
};
|
};
|
||||||
lichess.user_analysis.data.inGame = @pov.isDefined;
|
@pov.map { p =>
|
||||||
|
lichess.user_analysis.data.inGame = true;
|
||||||
|
lichess.user_analysis.data.path = "@p.game.turns";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
}
|
}
|
||||||
} •
|
} •
|
||||||
@if(game.variant.exotic) {
|
@if(game.variant.exotic) {
|
||||||
@variantLink(game.variant, (if (game.variant == chess.variant.KingOfTheHill) game.variant.shortName else game.variant.name).toUpperCase, cssClass = "hint--top")
|
@variantLink(game.variant, (if (game.variant == chess.variant.KingOfTheHill) game.variant.shortName else game.variant.name).toUpperCase, cssClass = "hint--top", initialFen = initialFen)
|
||||||
} else {
|
} else {
|
||||||
@game.perfType.map { pt =>
|
@game.perfType.map { pt =>
|
||||||
<span class="hint--top" data-hint="@pt.title">@pt.name.toUpperCase</span>
|
<span class="hint--top" data-hint="@pt.title">@pt.name.toUpperCase</span>
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
@(variant: chess.variant.Variant, name: String, hintAsTitle: Boolean = false, cssClass: String = "hint--bottom")
|
@(variant: chess.variant.Variant, name: String, hintAsTitle: Boolean = false, cssClass: String = "hint--bottom", initialFen: Option[String] = None)
|
||||||
@url = {
|
@url = {
|
||||||
@variant match {
|
@variant match {
|
||||||
case chess.variant.Standard => {https://en.wikipedia.org/wiki/Chess}
|
case chess.variant.Standard => {https://en.wikipedia.org/wiki/Chess}
|
||||||
|
@ -6,7 +6,7 @@ case chess.variant.Chess960 => {https://en.wikipedia.org/wiki/Chess960}
|
||||||
case chess.variant.KingOfTheHill => {@routes.Page.kingOfTheHill}
|
case chess.variant.KingOfTheHill => {@routes.Page.kingOfTheHill}
|
||||||
case chess.variant.ThreeCheck => {http://en.wikipedia.org/wiki/Three-check_chess}
|
case chess.variant.ThreeCheck => {http://en.wikipedia.org/wiki/Three-check_chess}
|
||||||
case chess.variant.Antichess => {http://en.wikipedia.org/wiki/Losing_chess}
|
case chess.variant.Antichess => {http://en.wikipedia.org/wiki/Losing_chess}
|
||||||
case chess.variant.FromPosition => {@routes.Editor.index}
|
case chess.variant.FromPosition => {@routes.Editor.index?fen=@initialFen}
|
||||||
case chess.variant.Atomic => {http://www.freechess.org/Help/HelpFiles/atomic.html}
|
case chess.variant.Atomic => {http://www.freechess.org/Help/HelpFiles/atomic.html}
|
||||||
case _ => {}
|
case _ => {}
|
||||||
}
|
}
|
||||||
|
|
|
@ -382,7 +382,7 @@ gameBehavior=Chování hry
|
||||||
premovesPlayingDuringOpponentTurn=Předtahy (hraní během protivníkova tahu)
|
premovesPlayingDuringOpponentTurn=Předtahy (hraní během protivníkova tahu)
|
||||||
takebacksWithOpponentApproval=Vrácení tahu (s protivníkovým souhlasem)
|
takebacksWithOpponentApproval=Vrácení tahu (s protivníkovým souhlasem)
|
||||||
promoteToQueenAutomatically=Povýšit na královnu automaticky
|
promoteToQueenAutomatically=Povýšit na královnu automaticky
|
||||||
claimDrawOnThreefoldRepetitionAutomatically=Vyžádat remízu při %trojím opakování pozic%s automaticky
|
claimDrawOnThreefoldRepetitionAutomatically=Vyžádat remízu při %strojím opakování pozic%s automaticky
|
||||||
privacy=Soukromí
|
privacy=Soukromí
|
||||||
letOtherPlayersFollowYou=Umožnit ostatním hráčům následovat Tě
|
letOtherPlayersFollowYou=Umožnit ostatním hráčům následovat Tě
|
||||||
letOtherPlayersChallengeYou=Umožnit ostatním hráčům vyzvat Tě
|
letOtherPlayersChallengeYou=Umožnit ostatním hráčům vyzvat Tě
|
||||||
|
|
|
@ -347,3 +347,23 @@ blog=Blog
|
||||||
questionsAndAnswers=Spørgsmål & svar
|
questionsAndAnswers=Spørgsmål & svar
|
||||||
notes=Noter
|
notes=Noter
|
||||||
materialDifference=Materialeforskel
|
materialDifference=Materialeforskel
|
||||||
|
chessClock=Ur
|
||||||
|
tenthsOfSeconds=Tiendedele sekunder
|
||||||
|
never=Aldrig
|
||||||
|
soundWhenTimeGetsCritical=Lyd, når tiden bliver kritisk
|
||||||
|
gameBehavior=Spil adfærd
|
||||||
|
letOtherPlayersFollowYou=Lad andre spillere følge dig
|
||||||
|
letOtherPlayersChallengeYou=Lad andre spillere udfordre dig
|
||||||
|
sound=Lys
|
||||||
|
yourPreferencesHaveBeenSaved=Dine præferencer er blevet gemt.
|
||||||
|
none=Ingen
|
||||||
|
fast=Hurtigt
|
||||||
|
normal=Normalt
|
||||||
|
slow=Langsomt
|
||||||
|
insideTheBoard=På brættet
|
||||||
|
outsideTheBoard=Udenfor brættet
|
||||||
|
always=Altid
|
||||||
|
difficultyEasy=Nemt
|
||||||
|
difficultyNormal=Normalt
|
||||||
|
difficultyHard=Svært
|
||||||
|
timeline=Tidslinje
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
playWithAFriend=بازی دوستانه
|
playWithAFriend=بازی دوستانه
|
||||||
playWithTheMachine=بازی با رایانه
|
playWithTheMachine=بازی با رایانه
|
||||||
toInviteSomeoneToPlayGiveThisUrl=فراخواندن برای بازی با استفاده از این لینک
|
toInviteSomeoneToPlayGiveThisUrl=%برای دعوت کردن حریف این پیوند را برای او بفرستید%
|
||||||
gameOver=بازنده شدید
|
gameOver=%پایان بازی%
|
||||||
waitingForOpponent=منتظر حریف
|
waitingForOpponent=منتظر حریف
|
||||||
waiting=انتظار
|
waiting=انتظار
|
||||||
yourTurn=نوبت شماست
|
yourTurn=نوبت شماست
|
||||||
|
@ -361,6 +361,7 @@ materialDifference=تفاوت ماده
|
||||||
closeAccount=بستن اکانت
|
closeAccount=بستن اکانت
|
||||||
closeYourAccount=بستن اکانت شما
|
closeYourAccount=بستن اکانت شما
|
||||||
changedMindDoNotCloseAccount=نظرم را عوض کردم اکانتم را نمی بندم
|
changedMindDoNotCloseAccount=نظرم را عوض کردم اکانتم را نمی بندم
|
||||||
|
closeAccountExplanation=در صورت بستن حساب کاربری دیگر قادر نخواهید بود آنرا بازگزدانید. و صفحه کاربری از دسترس خارج خواهد شد . آیا اطمینان دارید ؟؟
|
||||||
thisAccountIsClosed=این اکانت بسته شده است
|
thisAccountIsClosed=این اکانت بسته شده است
|
||||||
invalidUsernameOrPassword=نام کاربری و رمز عبور نادرست است
|
invalidUsernameOrPassword=نام کاربری و رمز عبور نادرست است
|
||||||
emailMeALink=یک لینک به من ایمیل کنید
|
emailMeALink=یک لینک به من ایمیل کنید
|
||||||
|
@ -385,6 +386,7 @@ privacy=خلوت
|
||||||
letOtherPlayersFollowYou=بقیه بازیکنان شما را دنبال کنند
|
letOtherPlayersFollowYou=بقیه بازیکنان شما را دنبال کنند
|
||||||
letOtherPlayersChallengeYou=بقیه بازیکنان با شما بازی کنند
|
letOtherPlayersChallengeYou=بقیه بازیکنان با شما بازی کنند
|
||||||
sound=صدا
|
sound=صدا
|
||||||
|
soundControlInTheTopBarOfEveryPage=%کنترل صدا در همه صفحات بالا سمت راست قرار دارد%
|
||||||
yourPreferencesHaveBeenSaved=تغییرات شما ذخیره شده است
|
yourPreferencesHaveBeenSaved=تغییرات شما ذخیره شده است
|
||||||
none=هیچ کدام
|
none=هیچ کدام
|
||||||
fast=سریع
|
fast=سریع
|
||||||
|
|
|
@ -310,20 +310,38 @@ nbGamesInPlay=%s משחקים בתהליך
|
||||||
automaticallyProceedToNextGameAfterMoving=המשך אוטומטית למשחק הבא אחרי מהלך
|
automaticallyProceedToNextGameAfterMoving=המשך אוטומטית למשחק הבא אחרי מהלך
|
||||||
autoSwitch=החלפה אוטומטית
|
autoSwitch=החלפה אוטומטית
|
||||||
openingId=פתיחה%s
|
openingId=פתיחה%s
|
||||||
|
findNbStrongMoves=מצא %s מהלכים חזקים
|
||||||
thisMoveGivesYourOpponentTheAdvantage=מהלך זה נותן ליריבך את היתרון
|
thisMoveGivesYourOpponentTheAdvantage=מהלך זה נותן ליריבך את היתרון
|
||||||
openingFailed=פתיחה נכשלה
|
openingFailed=פתיחה נכשלה
|
||||||
openingSolved=פתיחה נפתרה
|
openingSolved=פתיחה נפתרה
|
||||||
recentlyPlayedOpenings=פתיחות אחרונות ששוחקו
|
recentlyPlayedOpenings=פתיחות אחרונות ששוחקו
|
||||||
puzzles=פאזלים
|
puzzles=פאזלים
|
||||||
|
coordinates=קואורדינטות
|
||||||
openings=פתיחות
|
openings=פתיחות
|
||||||
|
latestUpdates=עדכונים אחרונים
|
||||||
|
tournamentWinners=מנצחי הטורנירים
|
||||||
name=שם
|
name=שם
|
||||||
|
description=תיאור
|
||||||
no=לא
|
no=לא
|
||||||
yes=כן
|
yes=כן
|
||||||
help=:עזרה
|
help=:עזרה
|
||||||
createANewTopic=צור נושא חדש
|
createANewTopic=צור נושא חדש
|
||||||
topics=נושאים
|
topics=נושאים
|
||||||
|
posts=אשכולות
|
||||||
|
lastPost=אשכול אחרון
|
||||||
views=צפיות
|
views=צפיות
|
||||||
replies=תגובות
|
replies=תגובות
|
||||||
|
replyToThisTopic=הגב לאשכול זה
|
||||||
|
reply=הגב
|
||||||
|
message=הודעה
|
||||||
|
createTheTopic=צור אשכול
|
||||||
|
reportAUser=דווח על משתמש
|
||||||
|
user=משתמש
|
||||||
|
reason=סיבה
|
||||||
|
whatIsIheMatter=מה הבעיה?
|
||||||
|
cheat=רמאות
|
||||||
|
insult=העלבה
|
||||||
|
troll=טרול
|
||||||
other=אחר
|
other=אחר
|
||||||
donate=תרום
|
donate=תרום
|
||||||
blog=בלוג
|
blog=בלוג
|
||||||
|
|
|
@ -338,18 +338,20 @@ message=Üzenet
|
||||||
createTheTopic=Topik létrehozása
|
createTheTopic=Topik létrehozása
|
||||||
reportAUser=Jelenteni egy felhasználót
|
reportAUser=Jelenteni egy felhasználót
|
||||||
user=Felhasználó
|
user=Felhasználó
|
||||||
reason=Indoklás
|
reason=Ok
|
||||||
whatIsIheMatter=Mi újság
|
whatIsIheMatter=Probléma meghatározása
|
||||||
cheat=Csevegő
|
cheat=Csalás
|
||||||
insult=Sértegetés
|
insult=Sértegetés
|
||||||
troll=Trollkodás
|
troll=Trollkodás
|
||||||
other=Más
|
other=Egyéb
|
||||||
|
reportDescriptionHelp=Játék(ok) linkje és a játékos viselkedésében tapasztalt probléma kifejtése
|
||||||
by=%s által
|
by=%s által
|
||||||
thisTopicIsNowClosed=Ez a téma jelenleg lezárt
|
thisTopicIsNowClosed=Ez a téma jelenleg lezárt
|
||||||
theming=Kinézet
|
theming=Kinézet
|
||||||
donate=Támogatás
|
donate=Támogatás
|
||||||
blog=Blog
|
blog=Blog
|
||||||
map=Térkép
|
map=Térkép
|
||||||
|
realTimeWorldMapOfChessMoves=Valós idejő földtérkép a sakk-lépésekről
|
||||||
questionsAndAnswers=Kérdések & Válaszok
|
questionsAndAnswers=Kérdések & Válaszok
|
||||||
notes=Jegyzetek
|
notes=Jegyzetek
|
||||||
typePrivateNotesHere=Ide írd a saját jegyzeteidet
|
typePrivateNotesHere=Ide írd a saját jegyzeteidet
|
||||||
|
@ -359,6 +361,7 @@ materialDifference=Különböző anyagok
|
||||||
closeAccount=Fiók zárolása
|
closeAccount=Fiók zárolása
|
||||||
closeYourAccount=Fiók zárolása
|
closeYourAccount=Fiók zárolása
|
||||||
changedMindDoNotCloseAccount=Meggondoltam magam, mégsem zárolom a fiókomat
|
changedMindDoNotCloseAccount=Meggondoltam magam, mégsem zárolom a fiókomat
|
||||||
|
closeAccountExplanation=Biztos hogy zárolod a fiókodat? A zárolás végleges. Nem leszel képes bejelentkezni, és a profilod sem lesz elérhető.
|
||||||
thisAccountIsClosed=Ez a fiók zárolva van
|
thisAccountIsClosed=Ez a fiók zárolva van
|
||||||
invalidUsernameOrPassword=Érvénytelen felhasználónév vagy jelszó
|
invalidUsernameOrPassword=Érvénytelen felhasználónév vagy jelszó
|
||||||
emailMeALink=Link küldése E-mailban
|
emailMeALink=Link küldése E-mailban
|
||||||
|
@ -373,9 +376,12 @@ tenthsOfSeconds=Tizedmásodpercek
|
||||||
never=Soha
|
never=Soha
|
||||||
whenTimeRemainingLessThanTenSeconds=Amikor a hátralevő idő < 10 másodperc
|
whenTimeRemainingLessThanTenSeconds=Amikor a hátralevő idő < 10 másodperc
|
||||||
horizontalGreenProgressBars=Vízszintes zöld folyamatjelző
|
horizontalGreenProgressBars=Vízszintes zöld folyamatjelző
|
||||||
|
soundWhenTimeGetsCritical=Figyelmeztető hang, mikor a hátralevő idő kritikus alá csökken
|
||||||
|
gameBehavior=Játék működése
|
||||||
premovesPlayingDuringOpponentTurn=Előre meghatározott lépések (Lépés meghatározása, míg az ellenfél van soron)
|
premovesPlayingDuringOpponentTurn=Előre meghatározott lépések (Lépés meghatározása, míg az ellenfél van soron)
|
||||||
takebacksWithOpponentApproval=Visszalépés (Ellenfél beleegyezésével)
|
takebacksWithOpponentApproval=Visszalépés (Ellenfél beleegyezésével)
|
||||||
promoteToQueenAutomatically=Bejutott paraszt automatikus királynőre cseréje
|
promoteToQueenAutomatically=Bejutott paraszt automatikus királynőre cseréje
|
||||||
|
privacy=Személyes
|
||||||
letOtherPlayersFollowYou=Követésed engedélyezése a többi játékosnak
|
letOtherPlayersFollowYou=Követésed engedélyezése a többi játékosnak
|
||||||
letOtherPlayersChallengeYou=Kihívásod engedélyezése a többi játékosnak
|
letOtherPlayersChallengeYou=Kihívásod engedélyezése a többi játékosnak
|
||||||
sound=Hangok
|
sound=Hangok
|
||||||
|
|
|
@ -233,7 +233,7 @@ xToYMinutes=%s līdz %s minūtes
|
||||||
textIsTooShort=Teksts ir par īsu.
|
textIsTooShort=Teksts ir par īsu.
|
||||||
textIsTooLong=Teksts ir par garu.
|
textIsTooLong=Teksts ir par garu.
|
||||||
required=Obligāts.
|
required=Obligāts.
|
||||||
openTournaments=Atvērt turnīrus
|
openTournaments=Atvērtie turnīri
|
||||||
duration=Ilgums
|
duration=Ilgums
|
||||||
winner=Uzvarētājs
|
winner=Uzvarētājs
|
||||||
standing=Pozīcija
|
standing=Pozīcija
|
||||||
|
@ -339,23 +339,23 @@ createTheTopic=Izveidot jaunu tematu
|
||||||
reportAUser=Ziņot lietotājam
|
reportAUser=Ziņot lietotājam
|
||||||
user=Lietotājs
|
user=Lietotājs
|
||||||
reason=Cēlonis
|
reason=Cēlonis
|
||||||
whatIsIheMatter=Kāds ir Jūsu jautājums?
|
whatIsIheMatter=Kas par lietu?
|
||||||
cheat=Apkrāpšana
|
cheat=Krāpšanās
|
||||||
insult=Aizvainišana
|
insult=Apvainošana
|
||||||
troll=Trollis
|
troll=Troļļošana
|
||||||
other=Cits
|
other=Cits
|
||||||
reportDescriptionHelp=Ielikt atsauci spēlē un izskaidrot kas nav kārtībā lietotāja uzvedībā.
|
reportDescriptionHelp=Iekopē saiti uz spēli un paskaidro, kas nav kārtībā ar lietotāja uzvedību.
|
||||||
by=No %s
|
by=No %s
|
||||||
thisTopicIsNowClosed=Šis temats tagad ir slēgts!
|
thisTopicIsNowClosed=Šis temats tagad ir slēgts.
|
||||||
theming=Tēmas
|
theming=Tēmas
|
||||||
donate=Ziedot
|
donate=Ziedot
|
||||||
blog=Blogs
|
blog=Blogs
|
||||||
map=Karte
|
map=Karte
|
||||||
realTimeWorldMapOfChessMoves=Šahveida gaitu karte reālā laikā
|
realTimeWorldMapOfChessMoves=Šaha gājienu reāllaika pasaules karte
|
||||||
questionsAndAnswers=Jautājumi un Atbildes
|
questionsAndAnswers=Jautājumi un Atbildes
|
||||||
notes=Piezīmes
|
notes=Piezīmes
|
||||||
typePrivateNotesHere=Uzrakstīt privāto piezīmi šeit
|
typePrivateNotesHere=Šeit vari rakstīt savas slepenās piezīmes
|
||||||
gameDisplay=Spēļu displejs
|
gameDisplay=Spēļu ekrāns
|
||||||
pieceAnimation=Figūru animācija
|
pieceAnimation=Figūru animācija
|
||||||
materialDifference=Materiāla starpība
|
materialDifference=Materiāla starpība
|
||||||
closeAccount=Slēgt kontu
|
closeAccount=Slēgt kontu
|
||||||
|
@ -415,3 +415,5 @@ allInformationIsPublicAndOptional=Visa informācija ir publiska un nav obligāta
|
||||||
yourCityRegionOrDepartment=Tava pilsēta, novads vai nodaļa.
|
yourCityRegionOrDepartment=Tava pilsēta, novads vai nodaļa.
|
||||||
biographyDescription=Pastāsti par sevi, kāpēc tev patīk šahs, savas mīļākās atklātes, spēles, šahistus ...
|
biographyDescription=Pastāsti par sevi, kāpēc tev patīk šahs, savas mīļākās atklātes, spēles, šahistus ...
|
||||||
maximumNbCharacters=Maksimums: %s simboli.
|
maximumNbCharacters=Maksimums: %s simboli.
|
||||||
|
blocks=%s bloķētie
|
||||||
|
listBlockedPlayers=Parādīt bloķēto spēlētāju sarakstu
|
||||||
|
|
|
@ -31,9 +31,12 @@ private[api] final class RoundApi(
|
||||||
|
|
||||||
def watcher(pov: Pov, apiVersion: Int, tv: Option[Boolean],
|
def watcher(pov: Pov, apiVersion: Int, tv: Option[Boolean],
|
||||||
analysis: Option[(Pgn, Analysis)] = None,
|
analysis: Option[(Pgn, Analysis)] = None,
|
||||||
initialFen: Option[Option[String]] = None)(implicit ctx: Context): Fu[JsObject] =
|
initialFen: Option[Option[String]] = None,
|
||||||
|
withMoveTimes: Boolean = false)(implicit ctx: Context): Fu[JsObject] =
|
||||||
jsonView.watcherJson(pov, ctx.pref, apiVersion, ctx.me, tv,
|
jsonView.watcherJson(pov, ctx.pref, apiVersion, ctx.me, tv,
|
||||||
withBlurs = ctx.me ?? Granter(_.ViewBlurs), initialFen = initialFen) zip
|
withBlurs = ctx.me ?? Granter(_.ViewBlurs),
|
||||||
|
initialFen = initialFen,
|
||||||
|
withMoveTimes = withMoveTimes) zip
|
||||||
(pov.game.tournamentId ?? TournamentRepo.byId) zip
|
(pov.game.tournamentId ?? TournamentRepo.byId) zip
|
||||||
(ctx.me ?? (me => noteApi.get(pov.gameId, me.id))) map {
|
(ctx.me ?? (me => noteApi.get(pov.gameId, me.id))) map {
|
||||||
case ((json, tourOption), note) => (
|
case ((json, tourOption), note) => (
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit acbe2c7a81c82ef078566eddb6782fc4cdfce738
|
Subproject commit a4c01151936ffdd12faeccfd259f03bdc8cafcc6
|
|
@ -90,7 +90,7 @@ case class Game(
|
||||||
} orElse updatedAt.map(_.getMillis / 100)
|
} orElse updatedAt.map(_.getMillis / 100)
|
||||||
|
|
||||||
private def lastMoveTimeDate: Option[DateTime] = castleLastMoveTime.lastMoveTime map { lmt =>
|
private def lastMoveTimeDate: Option[DateTime] = castleLastMoveTime.lastMoveTime map { lmt =>
|
||||||
createdAt plusMillis (lmt * 100)
|
createdAt plus (lmt * 100l)
|
||||||
} orElse updatedAt
|
} orElse updatedAt
|
||||||
|
|
||||||
def updatedAtOrCreatedAt = updatedAt | createdAt
|
def updatedAtOrCreatedAt = updatedAt | createdAt
|
||||||
|
|
|
@ -138,7 +138,8 @@ final class JsonView(
|
||||||
user: Option[User],
|
user: Option[User],
|
||||||
tv: Option[Boolean],
|
tv: Option[Boolean],
|
||||||
withBlurs: Boolean,
|
withBlurs: Boolean,
|
||||||
initialFen: Option[Option[String]] = None) =
|
initialFen: Option[Option[String]] = None,
|
||||||
|
withMoveTimes: Boolean) =
|
||||||
initialFen.fold(GameRepo initialFen pov.game)(fuccess) zip
|
initialFen.fold(GameRepo initialFen pov.game)(fuccess) zip
|
||||||
getSocketStatus(pov.game.id) zip
|
getSocketStatus(pov.game.id) zip
|
||||||
getWatcherChat(pov.game, user) zip
|
getWatcherChat(pov.game, user) zip
|
||||||
|
@ -163,6 +164,7 @@ final class JsonView(
|
||||||
"rematch" -> game.next,
|
"rematch" -> game.next,
|
||||||
"source" -> game.source.map(sourceJson),
|
"source" -> game.source.map(sourceJson),
|
||||||
"moves" -> game.pgnMoves.mkString(" "),
|
"moves" -> game.pgnMoves.mkString(" "),
|
||||||
|
"moveTimes" -> withMoveTimes.option(game.moveTimes),
|
||||||
"opening" -> game.opening.map { o =>
|
"opening" -> game.opening.map { o =>
|
||||||
Json.obj(
|
Json.obj(
|
||||||
"code" -> o.code,
|
"code" -> o.code,
|
||||||
|
@ -224,31 +226,37 @@ final class JsonView(
|
||||||
).noNull
|
).noNull
|
||||||
}
|
}
|
||||||
|
|
||||||
def userAnalysisJson(pov: Pov, pref: Pref) = {
|
def userAnalysisJson(pov: Pov, pref: Pref) =
|
||||||
import pov._
|
(pov.game.pgnMoves.nonEmpty ?? GameRepo.initialFen(pov.game)) map { initialFen =>
|
||||||
val fen = Forsyth >> game.toChess
|
import pov._
|
||||||
Json.obj(
|
val fen = Forsyth >> game.toChess
|
||||||
"game" -> Json.obj(
|
Json.obj(
|
||||||
"id" -> gameId,
|
"game" -> Json.obj(
|
||||||
"variant" -> variantJson(game.variant),
|
"id" -> gameId,
|
||||||
"initialFen" -> fen,
|
"variant" -> variantJson(game.variant),
|
||||||
"fen" -> fen,
|
"initialFen" -> {
|
||||||
"player" -> game.turnColor.name,
|
if (pov.game.pgnMoves.isEmpty) fen
|
||||||
"status" -> statusJson(game.status)),
|
else (initialFen | chess.format.Forsyth.initial)
|
||||||
"player" -> Json.obj(
|
},
|
||||||
"color" -> color.name
|
"fen" -> fen,
|
||||||
),
|
"moves" -> game.pgnMoves.mkString(" "),
|
||||||
"opponent" -> Json.obj(
|
"turns" -> game.turns,
|
||||||
"color" -> opponent.color.name
|
"player" -> game.turnColor.name,
|
||||||
),
|
"status" -> statusJson(game.status)),
|
||||||
"pref" -> Json.obj(
|
"player" -> Json.obj(
|
||||||
"animationDuration" -> animationDuration(pov, pref),
|
"color" -> color.name
|
||||||
"highlight" -> pref.highlight,
|
),
|
||||||
"destination" -> pref.destination,
|
"opponent" -> Json.obj(
|
||||||
"coords" -> pref.coords
|
"color" -> opponent.color.name
|
||||||
),
|
),
|
||||||
"userAnalysis" -> true)
|
"pref" -> Json.obj(
|
||||||
}
|
"animationDuration" -> animationDuration(pov, pref),
|
||||||
|
"highlight" -> pref.highlight,
|
||||||
|
"destination" -> pref.destination,
|
||||||
|
"coords" -> pref.coords
|
||||||
|
),
|
||||||
|
"userAnalysis" -> true)
|
||||||
|
}
|
||||||
|
|
||||||
private def blurs(game: Game, player: lila.game.Player) = {
|
private def blurs(game: Game, player: lila.game.Player) = {
|
||||||
val percent = game.playerBlurPercent(player.color)
|
val percent = game.playerBlurPercent(player.color)
|
||||||
|
|
|
@ -38,8 +38,8 @@ private[round] final class Player(
|
||||||
case Some(color) => round ! Cheat(color)
|
case Some(color) => round ! Cheat(color)
|
||||||
case None =>
|
case None =>
|
||||||
if (progress.game.playableByAi) round ! AiPlay
|
if (progress.game.playableByAi) round ! AiPlay
|
||||||
if (game.player.isOfferingDraw) round ! DrawNo(game.player.id)
|
if (pov.opponent.isOfferingDraw) round ! DrawNo(pov.player.id)
|
||||||
if (game.player.isProposingTakeback) round ! TakebackNo(game.player.id)
|
if (pov.player.isProposingTakeback) round ! TakebackNo(pov.player.id)
|
||||||
} inject progress.events
|
} inject progress.events
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -75,7 +75,7 @@ private[round] final class Round(
|
||||||
(pov.game.resignable && !pov.game.hasAi && pov.game.hasClock) ?? {
|
(pov.game.resignable && !pov.game.hasAi && pov.game.hasClock) ?? {
|
||||||
socketHub ? Ask(pov.gameId, IsGone(!pov.color)) flatMap {
|
socketHub ? Ask(pov.gameId, IsGone(!pov.color)) flatMap {
|
||||||
case true => finisher(pov.game, _.Timeout, Some(pov.color))
|
case true => finisher(pov.game, _.Timeout, Some(pov.color))
|
||||||
case _ => fufail("[round] cannot force resign of " + pov)
|
case _ => fuccess(List(Event.Reload))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -88,7 +88,7 @@ private[round] final class Round(
|
||||||
(pov.game.drawable && !pov.game.hasAi && pov.game.hasClock) ?? {
|
(pov.game.drawable && !pov.game.hasAi && pov.game.hasClock) ?? {
|
||||||
socketHub ? Ask(pov.gameId, IsGone(!pov.color)) flatMap {
|
socketHub ? Ask(pov.gameId, IsGone(!pov.color)) flatMap {
|
||||||
case true => finisher(pov.game, _.Timeout, None)
|
case true => finisher(pov.game, _.Timeout, None)
|
||||||
case _ => fufail("[round] cannot force draw of " + pov)
|
case _ => fuccess(List(Event.Reload))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -188,8 +188,10 @@ private[round] final class Socket(
|
||||||
}
|
}
|
||||||
|
|
||||||
def batch(member: Member, vevents: List[VersionedEvent]) {
|
def batch(member: Member, vevents: List[VersionedEvent]) {
|
||||||
if (vevents.nonEmpty) {
|
vevents match {
|
||||||
member push makeMessage("b", vevents map (_ jsFor member))
|
case Nil =>
|
||||||
|
case List(one) => member push one.jsFor(member)
|
||||||
|
case many => member push makeMessage("b", many map (_ jsFor member))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Binary file not shown.
Binary file not shown.
|
@ -98,4 +98,5 @@
|
||||||
<glyph unicode="`" d="M228 359c5 0 9 1 14 2 2 0 4 1 5 3 1 2 2 4 2 6l-24 135c-1 5-5 8-10 7-42-7-70-47-62-89 6-37 38-64 75-64z m-18 134l20-116-2-1c-29 0-53 21-58 50-6 29 12 58 40 67z m154-132c5-1 9-2 14-2 37 0 69 27 75 64 8 42-20 82-62 89-2 0-4 0-6-2-2-1-3-3-4-5l-23-135c-1-4 2-9 6-9z m32 132c28-9 46-38 41-67-6-29-31-51-61-49z m99-374l-94 0 6 33c5-3 10-6 16-7 19-4 37 9 40 28l14 90c3 15-1 31-10 44-9 13-23 22-38 25l-67 12c-3 0-5 0-7-2-2-1-3-3-3-5l-31-177c-1-4 2-9 6-9 5-1 8-6 7-10l-3-22-57 0-2 22c-1 4 2 9 7 10 2 0 4 1 5 3 2 2 2 4 2 6l-31 177c-1 5-6 8-10 7l-68-12c-32-6-54-37-48-69l15-89c2-9 7-17 14-22 8-6 17-8 26-6 6 1 11 4 15 7l6-34-43 0 0 9c0 5-4 9-8 9-5 0-9-4-9-9l0-9-128 0c-13 0-15-18-15-34 0-15 2-34 15-34l128 0 0-25c0-5 4-9 9-9 4 0 8 4 8 9l0 25 56 0 4-23c3-17 18-28 34-28 2 0 4 0 6 0 18 4 31 21 28 40l-2 11 31 0-2-11c-2-9 0-18 5-26 5-7 13-12 22-14 2 0 4 0 6 0 17 0 31 12 34 28l4 23 73 0c25 0 43 39 43 60 0 5-4 8-9 8z m-284 65l0 1-10 58c-1 5-5 8-10 7-4 0-8-5-7-9l10-58 0 0 0-1c2-9-4-18-13-19-5-1-9 0-13 3-4 2-6 6-7 11l-15 89c-4 23 11 45 34 49l59 11 29-162c-10-5-15-15-13-26l2-19-35 0z m-117-82l17 0 0-34-17 0z m-17-34l-17 0 0 34 17 0z m-57 34l23 0 0-34-23 0c-2 7-2 27 0 34z m108-34l0 34 17 0 0-34z m145-31c1-9-5-18-14-20-9-2-18 5-20 14l-3 20 34 0z m-111 31l0 34 166 0-6-34z m205-37c-2-9-10-16-20-14-4 1-8 3-11 7-2 4-3 8-3 13l18 101c2 11-3 21-12 26l28 162 59-11c11-2 21-8 27-17 7-10 9-21 7-32l-14-91c-2-9-10-15-20-13-4 0-8 3-11 7-2 3-3 8-3 12l0 1 11 59c0 4-3 9-7 10-5 1-9-3-10-7l-11-61 0-1z m94 37l-70 0 7 34 87 0c-3-14-14-34-24-34z"/>
|
<glyph unicode="`" d="M228 359c5 0 9 1 14 2 2 0 4 1 5 3 1 2 2 4 2 6l-24 135c-1 5-5 8-10 7-42-7-70-47-62-89 6-37 38-64 75-64z m-18 134l20-116-2-1c-29 0-53 21-58 50-6 29 12 58 40 67z m154-132c5-1 9-2 14-2 37 0 69 27 75 64 8 42-20 82-62 89-2 0-4 0-6-2-2-1-3-3-4-5l-23-135c-1-4 2-9 6-9z m32 132c28-9 46-38 41-67-6-29-31-51-61-49z m99-374l-94 0 6 33c5-3 10-6 16-7 19-4 37 9 40 28l14 90c3 15-1 31-10 44-9 13-23 22-38 25l-67 12c-3 0-5 0-7-2-2-1-3-3-3-5l-31-177c-1-4 2-9 6-9 5-1 8-6 7-10l-3-22-57 0-2 22c-1 4 2 9 7 10 2 0 4 1 5 3 2 2 2 4 2 6l-31 177c-1 5-6 8-10 7l-68-12c-32-6-54-37-48-69l15-89c2-9 7-17 14-22 8-6 17-8 26-6 6 1 11 4 15 7l6-34-43 0 0 9c0 5-4 9-8 9-5 0-9-4-9-9l0-9-128 0c-13 0-15-18-15-34 0-15 2-34 15-34l128 0 0-25c0-5 4-9 9-9 4 0 8 4 8 9l0 25 56 0 4-23c3-17 18-28 34-28 2 0 4 0 6 0 18 4 31 21 28 40l-2 11 31 0-2-11c-2-9 0-18 5-26 5-7 13-12 22-14 2 0 4 0 6 0 17 0 31 12 34 28l4 23 73 0c25 0 43 39 43 60 0 5-4 8-9 8z m-284 65l0 1-10 58c-1 5-5 8-10 7-4 0-8-5-7-9l10-58 0 0 0-1c2-9-4-18-13-19-5-1-9 0-13 3-4 2-6 6-7 11l-15 89c-4 23 11 45 34 49l59 11 29-162c-10-5-15-15-13-26l2-19-35 0z m-117-82l17 0 0-34-17 0z m-17-34l-17 0 0 34 17 0z m-57 34l23 0 0-34-23 0c-2 7-2 27 0 34z m108-34l0 34 17 0 0-34z m145-31c1-9-5-18-14-20-9-2-18 5-20 14l-3 20 34 0z m-111 31l0 34 166 0-6-34z m205-37c-2-9-10-16-20-14-4 1-8 3-11 7-2 4-3 8-3 13l18 101c2 11-3 21-12 26l28 162 59-11c11-2 21-8 27-17 7-10 9-21 7-32l-14-91c-2-9-10-15-20-13-4 0-8 3-11 7-2 3-3 8-3 12l0 1 11 59c0 4-3 9-7 10-5 1-9-3-10-7l-11-61 0-1z m94 37l-70 0 7 34 87 0c-3-14-14-34-24-34z"/>
|
||||||
<glyph unicode="@" d="M223 464c-63-3-97-16-105-38-1-3-2-7-2-17-1-20-3-35-7-51-6-22-10-31-39-72-15-22-22-42-22-59 0-21 7-40 22-55 12-12 29-21 46-25 10-1 26-1 35 1 16 3 31 10 45 21 3 1 5 3 5 3 0 0 0-4 0-8 0-16 2-28 7-37 2-4 4-7 10-13 4-4 10-9 14-12l6-4 0-9 0-8-14-8-13-9-1-12 0-13 13 0 13 0 4-12 4-13 23 0 5 13 4 12 13 0 12 0 0 13 0 12-14 9-13 8 0 8 0 9 5 4c8 6 21 18 24 23 4 7 8 23 8 37 1 9 1 11 2 9 1-1 14-10 21-13 15-8 28-12 45-12 20 0 36 5 50 15 7 4 19 17 23 24 13 20 16 44 8 66-5 14-12 27-27 48-13 18-14 20-19 29-11 22-16 46-18 80-1 19-2 22-9 29-8 9-20 15-40 19-27 7-79 10-124 8z m-9-56l42-4 42 4c40 3 46 3 52 2 8-2 10-10 3-15-11-8-49-12-105-11-46 1-77 4-89 11-4 2-5 4-5 7 1 5 4 7 11 8 4 1 6 1 49-2z m-20-78c12-1 40-5 53-8l8-1 13 2c27 5 50 7 68 8 14 1 28-1 37-5 6-3 24-21 36-36 10-15 21-35 26-47 2-8 2-8 2-18 0-11-1-19-6-27-9-18-28-27-53-28-4 0-10 1-13 1-19 4-38 15-57 34-10 10-16 18-22 30-8 16-12 36-12 55 0 10-4 13-13 15-8 1-17-1-21-4-2-3-3-5-3-12 0-23-8-49-20-68-14-20-37-39-59-47-14-5-36-5-50 0-12 4-22 12-28 23-3 7-5 11-6 22-1 11-1 16 3 26 7 20 26 48 47 70 10 9 13 12 23 14 10 3 26 3 47 1z m-37-18c-8-1-10-2-20-10-14-10-32-32-41-50-5-10-6-15-7-24 0-12 2-20 10-28 5-5 11-8 21-11 8-2 23-2 31 0 15 5 27 12 40 25 17 19 27 42 29 73 1 10 1 11 0 14-3 5-9 9-20 11-7 1-32 1-43 0z m156 0c-13-2-19-6-22-12-1-3-1-4-1-12 2-21 6-34 13-49 5-10 11-18 21-27 12-12 23-19 36-23 5-1 7-1 16-1 13 0 18 1 27 5 5 3 12 9 14 14 3 5 5 16 5 22 0 19-17 46-46 70-12 10-15 12-24 13-10 1-32 1-39 0z"/>
|
<glyph unicode="@" d="M223 464c-63-3-97-16-105-38-1-3-2-7-2-17-1-20-3-35-7-51-6-22-10-31-39-72-15-22-22-42-22-59 0-21 7-40 22-55 12-12 29-21 46-25 10-1 26-1 35 1 16 3 31 10 45 21 3 1 5 3 5 3 0 0 0-4 0-8 0-16 2-28 7-37 2-4 4-7 10-13 4-4 10-9 14-12l6-4 0-9 0-8-14-8-13-9-1-12 0-13 13 0 13 0 4-12 4-13 23 0 5 13 4 12 13 0 12 0 0 13 0 12-14 9-13 8 0 8 0 9 5 4c8 6 21 18 24 23 4 7 8 23 8 37 1 9 1 11 2 9 1-1 14-10 21-13 15-8 28-12 45-12 20 0 36 5 50 15 7 4 19 17 23 24 13 20 16 44 8 66-5 14-12 27-27 48-13 18-14 20-19 29-11 22-16 46-18 80-1 19-2 22-9 29-8 9-20 15-40 19-27 7-79 10-124 8z m-9-56l42-4 42 4c40 3 46 3 52 2 8-2 10-10 3-15-11-8-49-12-105-11-46 1-77 4-89 11-4 2-5 4-5 7 1 5 4 7 11 8 4 1 6 1 49-2z m-20-78c12-1 40-5 53-8l8-1 13 2c27 5 50 7 68 8 14 1 28-1 37-5 6-3 24-21 36-36 10-15 21-35 26-47 2-8 2-8 2-18 0-11-1-19-6-27-9-18-28-27-53-28-4 0-10 1-13 1-19 4-38 15-57 34-10 10-16 18-22 30-8 16-12 36-12 55 0 10-4 13-13 15-8 1-17-1-21-4-2-3-3-5-3-12 0-23-8-49-20-68-14-20-37-39-59-47-14-5-36-5-50 0-12 4-22 12-28 23-3 7-5 11-6 22-1 11-1 16 3 26 7 20 26 48 47 70 10 9 13 12 23 14 10 3 26 3 47 1z m-37-18c-8-1-10-2-20-10-14-10-32-32-41-50-5-10-6-15-7-24 0-12 2-20 10-28 5-5 11-8 21-11 8-2 23-2 31 0 15 5 27 12 40 25 17 19 27 42 29 73 1 10 1 11 0 14-3 5-9 9-20 11-7 1-32 1-43 0z m156 0c-13-2-19-6-22-12-1-3-1-4-1-12 2-21 6-34 13-49 5-10 11-18 21-27 12-12 23-19 36-23 5-1 7-1 16-1 13 0 18 1 27 5 5 3 12 9 14 14 3 5 5 16 5 22 0 19-17 46-46 70-12 10-15 12-24 13-10 1-32 1-39 0z"/>
|
||||||
<glyph unicode="^" d="M256 480c-141 0-256-115-256-256 0 0 0-96 0-128 0-32 32-64 64-64 32 0 352 0 384 0 32 0 64 32 64 64 0 32 0 128 0 128 0 141-114 256-256 256z m48-384l-96 0c-9 0-16 7-16 16 0 9 7 16 16 16l96 0c9 0 16-7 16-16 0-9-7-16-16-16z m144 64c0-16-16-32-32-32-16 0-64 0-64 0 0 16-16 32-32 32-16 0-112 0-128 0-16 0-32-16-32-32 0 0-48 0-64 0-16 0-32 16-32 32 0 16 0 180 0 180 39 64 110 108 192 108 82 0 153-44 192-108 0 0 0-164 0-180z m-64 192c-16 0-240 0-256 0-16 0-32-16-32-32 0-16 0-48 0-64 0-16 16-32 32-32 16 0 240 0 256 0 16 0 32 16 32 32 0 16 0 48 0 64 0 16-16 32-32 32z m0-64l-32-32-64 0-32 32-32-32-64 0-32 32 0 32 32 0 32-32 32 32 64 0 32-32 32 32 32 0z"/>
|
<glyph unicode="^" d="M256 480c-141 0-256-115-256-256 0 0 0-96 0-128 0-32 32-64 64-64 32 0 352 0 384 0 32 0 64 32 64 64 0 32 0 128 0 128 0 141-114 256-256 256z m48-384l-96 0c-9 0-16 7-16 16 0 9 7 16 16 16l96 0c9 0 16-7 16-16 0-9-7-16-16-16z m144 64c0-16-16-32-32-32-16 0-64 0-64 0 0 16-16 32-32 32-16 0-112 0-128 0-16 0-32-16-32-32 0 0-48 0-64 0-16 0-32 16-32 32 0 16 0 180 0 180 39 64 110 108 192 108 82 0 153-44 192-108 0 0 0-164 0-180z m-64 192c-16 0-240 0-256 0-16 0-32-16-32-32 0-16 0-48 0-64 0-16 16-32 32-32 16 0 240 0 256 0 16 0 32 16 32 32 0 16 0 48 0 64 0 16-16 32-32 32z m0-64l-32-32-64 0-32 32-32-32-64 0-32 32 0 32 32 0 32-32 32 32 64 0 32-32 32 32 32 0z"/>
|
||||||
|
<glyph unicode="[" d="M484 396c0-19-16-35-36-35l-384 0c-20 0-36 16-36 35 0 19 16 35 36 35l384 0c20 0 36-16 36-35z m0-140c0-19-16-35-36-35l-384 0c-20 0-36 16-36 35 0 19 16 35 36 35l384 0c20 0 36-16 36-35z m0-140c0-19-16-35-36-35l-384 0c-20 0-36 16-36 35 0 19 16 35 36 35l384 0c20 0 36-16 36-35z"/>
|
||||||
</font></defs></svg>
|
</font></defs></svg>
|
Before Width: | Height: | Size: 48 KiB After Width: | Height: | Size: 48 KiB |
Binary file not shown.
BIN
public/font32/fonts/lichess.woff
Normal file
BIN
public/font32/fonts/lichess.woff
Normal file
Binary file not shown.
|
@ -409,6 +409,10 @@ h2{font-size:18px;padding:0 0 21px 5px;margin:45px 0 0 0;text-transform:uppercas
|
||||||
<div class="icon icon-hubot"></div>
|
<div class="icon icon-hubot"></div>
|
||||||
<input type="text" readonly="readonly" value="hubot">
|
<input type="text" readonly="readonly" value="hubot">
|
||||||
</li>
|
</li>
|
||||||
|
<li>
|
||||||
|
<div class="icon icon-reorder"></div>
|
||||||
|
<input type="text" readonly="readonly" value="reorder">
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<h2>Character mapping</h2>
|
<h2>Character mapping</h2>
|
||||||
<ul class="glyphs character-mapping">
|
<ul class="glyphs character-mapping">
|
||||||
|
@ -776,6 +780,10 @@ h2{font-size:18px;padding:0 0 21px 5px;margin:45px 0 0 0;text-transform:uppercas
|
||||||
<div data-icon="^" class="icon"></div>
|
<div data-icon="^" class="icon"></div>
|
||||||
<input type="text" readonly="readonly" value="^">
|
<input type="text" readonly="readonly" value="^">
|
||||||
</li>
|
</li>
|
||||||
|
<li>
|
||||||
|
<div data-icon="[" class="icon"></div>
|
||||||
|
<input type="text" readonly="readonly" value="[">
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div><script type="text/javascript">
|
</div><script type="text/javascript">
|
||||||
(function() {
|
(function() {
|
|
@ -311,3 +311,6 @@
|
||||||
.icon-hubot:before {
|
.icon-hubot:before {
|
||||||
content: "^";
|
content: "^";
|
||||||
}
|
}
|
||||||
|
.icon-reorder:before {
|
||||||
|
content: "[";
|
||||||
|
}
|
|
@ -50,7 +50,7 @@ lichess.StrongSocket.defaults = {
|
||||||
pingDelay: 1000, // time between pong and ping
|
pingDelay: 1000, // time between pong and ping
|
||||||
autoReconnectDelay: 1000,
|
autoReconnectDelay: 1000,
|
||||||
lagTag: false, // jQuery object showing ping lag
|
lagTag: false, // jQuery object showing ping lag
|
||||||
ignoreUnknownMessages: false,
|
ignoreUnknownMessages: true,
|
||||||
baseUrls: ['socket.' + document.domain].concat(
|
baseUrls: ['socket.' + document.domain].concat(
|
||||||
($('body').data('ports') + '').split(',').map(function(port) {
|
($('body').data('ports') + '').split(',').map(function(port) {
|
||||||
return 'socket.' + document.domain + ':' + port;
|
return 'socket.' + document.domain + ':' + port;
|
||||||
|
|
|
@ -100,12 +100,13 @@ div.fen_pgn input.fen {
|
||||||
div.game_control {
|
div.game_control {
|
||||||
margin-top: 10px;
|
margin-top: 10px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
white-space: nowrap
|
width: 244px;
|
||||||
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
div.game_control a {
|
div.game_control a {
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
|
width: 25px;
|
||||||
height: 17px;
|
height: 17px;
|
||||||
width: 12px;
|
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
-webkit-user-select: none;
|
-webkit-user-select: none;
|
||||||
-moz-user-select: none;
|
-moz-user-select: none;
|
||||||
|
@ -113,14 +114,32 @@ div.game_control a {
|
||||||
margin: 0 -1px;
|
margin: 0 -1px;
|
||||||
}
|
}
|
||||||
div.game_control .jumps {
|
div.game_control .jumps {
|
||||||
|
display: inline-block;
|
||||||
margin-right: 10px;
|
margin-right: 10px;
|
||||||
}
|
}
|
||||||
.lichess_ground .replay {
|
.lichess_ground .replay,
|
||||||
|
.lichess_ground .action_menu {
|
||||||
height: calc(100% - 40px);
|
height: calc(100% - 40px);
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
overflow-x: hidden;
|
overflow-x: hidden;
|
||||||
border: 1px solid #ccc;
|
border: 1px solid #ccc;
|
||||||
}
|
}
|
||||||
|
.lichess_ground .action_menu {
|
||||||
|
border-color: transparent;
|
||||||
|
}
|
||||||
|
.lichess_ground .action_menu .inner {
|
||||||
|
position: relative;
|
||||||
|
top: 50%;
|
||||||
|
transform: translateY(-50%);
|
||||||
|
}
|
||||||
|
.lichess_ground .action_menu .button {
|
||||||
|
display: block;
|
||||||
|
margin: 15px 0;
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
.lichess_ground .action_menu .button::before {
|
||||||
|
font-size: 2em;
|
||||||
|
}
|
||||||
.lichess_ground .replay .turn > .index {
|
.lichess_ground .replay .turn > .index {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
width: 26px;
|
width: 26px;
|
||||||
|
|
|
@ -70,8 +70,8 @@ time {
|
||||||
}
|
}
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: "lichess";
|
font-family: "lichess";
|
||||||
src: url("../font31/fonts/lichess.eot");
|
src: url("../font32/fonts/lichess.eot");
|
||||||
src: url("../font31/fonts/lichess.eot?#iefix") format("embedded-opentype"), url("../font31/fonts/lichess.woff") format("woff"), url("../font31/fonts/lichess.ttf") format("truetype"), url("../font31/fonts/lichess.svg#lichess") format("svg");
|
src: url("../font32/fonts/lichess.eot?#iefix") format("embedded-opentype"), url("../font32/fonts/lichess.woff") format("woff"), url("../font32/fonts/lichess.ttf") format("truetype"), url("../font32/fonts/lichess.svg#lichess") format("svg");
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
}
|
}
|
||||||
|
|
57
ui/analyse/src/actionMenu.js
Normal file
57
ui/analyse/src/actionMenu.js
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
var partial = require('chessground').util.partial;
|
||||||
|
var m = require('mithril');
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
controller: function() {
|
||||||
|
|
||||||
|
this.open = false;
|
||||||
|
|
||||||
|
this.toggle = function() {
|
||||||
|
this.open = !this.open
|
||||||
|
}.bind(this);
|
||||||
|
},
|
||||||
|
view: function(ctrl) {
|
||||||
|
var flipAttrs = {};
|
||||||
|
if (ctrl.data.userAnalysis) flipAttrs.onclick = ctrl.flip;
|
||||||
|
else flipAttrs.href = ctrl.router.Round.watcher(ctrl.data.game.id, ctrl.data.opponent.color).url;
|
||||||
|
|
||||||
|
return m('div.action_menu',
|
||||||
|
m('div.inner', [
|
||||||
|
m('a.button.text[data-icon=B]', flipAttrs, ctrl.trans('flipBoard')),
|
||||||
|
m('a.button.text[data-icon=m]', {
|
||||||
|
href: ctrl.data.userAnalysis ? '/editor?fen=' + ctrl.vm.situation.fen : '/' + ctrl.data.game.id + '/edit?fen=' + ctrl.vm.situation.fen,
|
||||||
|
rel: 'nofollow'
|
||||||
|
}, ctrl.trans('boardEditor')),
|
||||||
|
m('a.button.text[data-icon=U]', {
|
||||||
|
onclick: function() {
|
||||||
|
$.modal($('.continue_with.' + ctrl.data.game.id));
|
||||||
|
}
|
||||||
|
}, ctrl.trans('continueFromHere')), [{
|
||||||
|
name: 'fast',
|
||||||
|
delay: 1000
|
||||||
|
}, {
|
||||||
|
name: 'slow',
|
||||||
|
delay: 5000
|
||||||
|
}, {
|
||||||
|
name: 'realtime',
|
||||||
|
delay: true
|
||||||
|
}].map(function(speed) {
|
||||||
|
return m('a.button[data-icon=G]', {
|
||||||
|
class: 'text' + (ctrl.autoplay.active(speed.delay) ? ' active' : ''),
|
||||||
|
onclick: partial(ctrl.togglePlay, speed.delay)
|
||||||
|
}, 'Auto play ' + speed.name);
|
||||||
|
}),
|
||||||
|
m('div.continue_with.' + ctrl.data.game.id, [
|
||||||
|
m('a.button', {
|
||||||
|
href: ctrl.data.userAnalysis ? '/?fen=' + ctrl.vm.situation.fen + '#ai' : ctrl.router.Round.continue(ctrl.data.game.id, 'ai').url + '?fen=' + ctrl.vm.situation.fen,
|
||||||
|
rel: 'nofollow'
|
||||||
|
}, ctrl.trans('playWithTheMachine')),
|
||||||
|
m('br'),
|
||||||
|
m('a.button', {
|
||||||
|
href: ctrl.data.userAnalysis ? '/?fen=' + ctrl.vm.situation.fen + '#friend' : ctrl.router.Round.continue(ctrl.data.game.id, 'friend').url + '?fen=' + ctrl.vm.situation.fen,
|
||||||
|
rel: 'nofollow'
|
||||||
|
}, ctrl.trans('playWithAFriend'))
|
||||||
|
])
|
||||||
|
]));
|
||||||
|
}
|
||||||
|
};
|
63
ui/analyse/src/autoplay.js
Normal file
63
ui/analyse/src/autoplay.js
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
var control = require('./control');
|
||||||
|
var partial = require('chessground').util.partial;
|
||||||
|
var m = require('mithril');
|
||||||
|
|
||||||
|
module.exports = function(ctrl) {
|
||||||
|
|
||||||
|
var timeout;
|
||||||
|
|
||||||
|
this.delay = null;
|
||||||
|
|
||||||
|
var move = function() {
|
||||||
|
if (control.canGoForward(ctrl)) {
|
||||||
|
var p = ctrl.vm.path;
|
||||||
|
p[p.length - 1].ply++;
|
||||||
|
ctrl.jump(p);
|
||||||
|
m.redraw();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
this.stop();
|
||||||
|
m.redraw();
|
||||||
|
return false;
|
||||||
|
}.bind(this);
|
||||||
|
|
||||||
|
var nextDelay = function() {
|
||||||
|
if (this.delay === true) {
|
||||||
|
// in a variation
|
||||||
|
if (ctrl.vm.path.length > 1) return 2000;
|
||||||
|
return (ctrl.data.game.moveTimes[ctrl.vm.path[0].ply] * 100) || 2000;
|
||||||
|
}
|
||||||
|
return this.delay;
|
||||||
|
}.bind(this);
|
||||||
|
|
||||||
|
var schedule = function() {
|
||||||
|
timeout = setTimeout(function() {
|
||||||
|
if (move()) schedule();
|
||||||
|
}, nextDelay());
|
||||||
|
}.bind(this);
|
||||||
|
|
||||||
|
var start = function(delay) {
|
||||||
|
this.delay = delay;
|
||||||
|
this.stop();
|
||||||
|
schedule();
|
||||||
|
}.bind(this);
|
||||||
|
|
||||||
|
this.stop = function() {
|
||||||
|
if (timeout) {
|
||||||
|
clearTimeout(timeout);
|
||||||
|
timeout = null;
|
||||||
|
}
|
||||||
|
}.bind(this);
|
||||||
|
|
||||||
|
this.toggle = function(delay) {
|
||||||
|
if (this.active(delay)) this.stop();
|
||||||
|
else {
|
||||||
|
if (!this.active()) move();
|
||||||
|
start(delay);
|
||||||
|
}
|
||||||
|
}.bind(this);
|
||||||
|
|
||||||
|
this.active = function(delay) {
|
||||||
|
return (!delay || delay === this.delay) && !!timeout;
|
||||||
|
}.bind(this);
|
||||||
|
};
|
|
@ -15,11 +15,13 @@ function canGoForward(ctrl) {
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
|
|
||||||
|
canGoForward: canGoForward,
|
||||||
|
|
||||||
next: function(ctrl) {
|
next: function(ctrl) {
|
||||||
if (!canGoForward(ctrl)) return;
|
if (!canGoForward(ctrl)) return;
|
||||||
var p = ctrl.vm.path;
|
var p = ctrl.vm.path;
|
||||||
p[p.length - 1].ply++;
|
p[p.length - 1].ply++;
|
||||||
ctrl.jump(p);
|
ctrl.userJump(p);
|
||||||
},
|
},
|
||||||
|
|
||||||
prev: function(ctrl) {
|
prev: function(ctrl) {
|
||||||
|
@ -36,18 +38,18 @@ module.exports = {
|
||||||
if (p[len - 2].ply > 1) p[len - 2].ply--;
|
if (p[len - 2].ply > 1) p[len - 2].ply--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ctrl.jump(p);
|
ctrl.userJump(p);
|
||||||
},
|
},
|
||||||
|
|
||||||
last: function(ctrl) {
|
last: function(ctrl) {
|
||||||
ctrl.jump([{
|
ctrl.userJump([{
|
||||||
ply: ctrl.analyse.tree[ctrl.analyse.tree.length - 1].ply,
|
ply: ctrl.analyse.tree[ctrl.analyse.tree.length - 1].ply,
|
||||||
variation: null
|
variation: null
|
||||||
}]);
|
}]);
|
||||||
},
|
},
|
||||||
|
|
||||||
first: function(ctrl) {
|
first: function(ctrl) {
|
||||||
ctrl.jump([{
|
ctrl.userJump([{
|
||||||
ply: 0,
|
ply: 0,
|
||||||
variation: null
|
variation: null
|
||||||
}]);
|
}]);
|
||||||
|
|
|
@ -5,12 +5,17 @@ var analyse = require('./analyse');
|
||||||
var ground = require('./ground');
|
var ground = require('./ground');
|
||||||
var keyboard = require('./keyboard');
|
var keyboard = require('./keyboard');
|
||||||
var treePath = require('./path');
|
var treePath = require('./path');
|
||||||
|
var actionMenu = require('./actionMenu').controller;
|
||||||
|
var autoplay = require('./autoplay');
|
||||||
|
var control = require('./control');
|
||||||
var m = require('mithril');
|
var m = require('mithril');
|
||||||
|
|
||||||
module.exports = function(cfg, router, i18n, onChange) {
|
module.exports = function(cfg, router, i18n, onChange) {
|
||||||
|
|
||||||
this.data = data({}, cfg);
|
this.data = data({}, cfg);
|
||||||
this.analyse = new analyse(this.data.game, this.data.analysis);
|
this.analyse = new analyse(this.data.game, this.data.analysis);
|
||||||
|
this.actionMenu = new actionMenu();
|
||||||
|
this.autoplay = new autoplay(this);
|
||||||
|
|
||||||
var initialPath = cfg.path ? treePath.read(cfg.path) : treePath.default();
|
var initialPath = cfg.path ? treePath.read(cfg.path) : treePath.default();
|
||||||
|
|
||||||
|
@ -29,6 +34,11 @@ module.exports = function(cfg, router, i18n, onChange) {
|
||||||
});
|
});
|
||||||
}.bind(this);
|
}.bind(this);
|
||||||
|
|
||||||
|
this.togglePlay = function(delay) {
|
||||||
|
this.autoplay.toggle(delay);
|
||||||
|
this.actionMenu.open = false;
|
||||||
|
}.bind(this);
|
||||||
|
|
||||||
var gameVariantChessId = function() {
|
var gameVariantChessId = function() {
|
||||||
switch (this.data.game.variant.key) {
|
switch (this.data.game.variant.key) {
|
||||||
case 'chess960':
|
case 'chess960':
|
||||||
|
@ -132,8 +142,13 @@ module.exports = function(cfg, router, i18n, onChange) {
|
||||||
showGround();
|
showGround();
|
||||||
}.bind(this);
|
}.bind(this);
|
||||||
|
|
||||||
|
this.userJump = function(path) {
|
||||||
|
this.autoplay.stop();
|
||||||
|
this.jump(path);
|
||||||
|
}.bind(this);
|
||||||
|
|
||||||
this.jumpToMain = function(ply) {
|
this.jumpToMain = function(ply) {
|
||||||
this.jump([{
|
this.userJump([{
|
||||||
ply: ply,
|
ply: ply,
|
||||||
variation: null
|
variation: null
|
||||||
}]);
|
}]);
|
||||||
|
@ -148,7 +163,7 @@ module.exports = function(cfg, router, i18n, onChange) {
|
||||||
to: dest,
|
to: dest,
|
||||||
promotion: (dest[1] == 1 || dest[1] == 8) ? 'q' : null
|
promotion: (dest[1] == 1 || dest[1] == 8) ? 'q' : null
|
||||||
});
|
});
|
||||||
if (move) this.jump(this.analyse.explore(this.vm.path, move.san));
|
if (move) this.userJump(this.analyse.explore(this.vm.path, move.san));
|
||||||
else this.chessground.set(this.vm.situation);
|
else this.chessground.set(this.vm.situation);
|
||||||
m.redraw();
|
m.redraw();
|
||||||
}.bind(this);
|
}.bind(this);
|
||||||
|
|
|
@ -36,7 +36,7 @@ module.exports = function(ctrl) {
|
||||||
if (!ctrl.vm.comments && ctrl.vm.path.length > 1) {
|
if (!ctrl.vm.comments && ctrl.vm.path.length > 1) {
|
||||||
path = [ctrl.vm.path[0]];
|
path = [ctrl.vm.path[0]];
|
||||||
path[0].variation = null;
|
path[0].variation = null;
|
||||||
ctrl.jump(path);
|
ctrl.userJump(path);
|
||||||
}
|
}
|
||||||
m.redraw();
|
m.redraw();
|
||||||
}));
|
}));
|
||||||
|
|
|
@ -7,6 +7,7 @@ var renderStatus = require('game').view.status;
|
||||||
var mod = require('game').view.mod;
|
var mod = require('game').view.mod;
|
||||||
var treePath = require('./path');
|
var treePath = require('./path');
|
||||||
var control = require('./control');
|
var control = require('./control');
|
||||||
|
var actionMenu = require('./actionMenu').view;
|
||||||
|
|
||||||
function renderEval(e) {
|
function renderEval(e) {
|
||||||
e = Math.round(e / 10) / 10;
|
e = Math.round(e / 10) / 10;
|
||||||
|
@ -224,7 +225,7 @@ function renderAnalyse(ctrl) {
|
||||||
var path = e.target.getAttribute('data-path') || e.target.parentNode.getAttribute('data-path');
|
var path = e.target.getAttribute('data-path') || e.target.parentNode.getAttribute('data-path');
|
||||||
if (path) {
|
if (path) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
ctrl.jump(treePath.read(path));
|
ctrl.userJump(treePath.read(path));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onclick: function(e) {
|
onclick: function(e) {
|
||||||
|
@ -266,17 +267,9 @@ function blindBoard(ctrl) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function buttons(ctrl) {
|
function buttons(ctrl) {
|
||||||
var nbMoves = ctrl.data.game.moves.length;
|
|
||||||
var flipAttrs = {
|
|
||||||
'data-hint': ctrl.trans('flipBoard'),
|
|
||||||
};
|
|
||||||
if (ctrl.data.userAnalysis) flipAttrs.onclick = ctrl.flip;
|
|
||||||
else flipAttrs.href = ctrl.router.Round.watcher(ctrl.data.game.id, ctrl.data.opponent.color).url;
|
|
||||||
return [
|
return [
|
||||||
m('div.game_control', [
|
m('div.game_control', [
|
||||||
m('div.jumps.hint--bottom', {
|
m('div.jumps.hint--bottom', [
|
||||||
'data-hint': 'Tip: use your keyboard arrow keys!'
|
|
||||||
}, [
|
|
||||||
['first', 'W', control.first, ],
|
['first', 'W', control.first, ],
|
||||||
['prev', 'Y', control.prev],
|
['prev', 'Y', control.prev],
|
||||||
['next', 'X', control.next],
|
['next', 'X', control.next],
|
||||||
|
@ -294,29 +287,12 @@ function buttons(ctrl) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
})),
|
})),
|
||||||
m('a.button.hint--bottom', flipAttrs, m('span[data-icon=B]')),
|
ctrl.data.inGame ? null : m('a.button', {
|
||||||
ctrl.data.inGame ? null : m('a.button.hint--bottom', {
|
onclick: ctrl.actionMenu.toggle,
|
||||||
'data-hint': ctrl.trans('boardEditor'),
|
class: ctrl.actionMenu.open ? 'active' : ''
|
||||||
href: ctrl.data.userAnalysis ? '/editor?fen=' + ctrl.vm.situation.fen : '/' + ctrl.data.game.id + '/edit?fen=' + ctrl.vm.situation.fen,
|
}, m('span', {
|
||||||
rel: 'nofollow'
|
'data-icon': '['
|
||||||
}, m('span[data-icon=m]')),
|
}))
|
||||||
ctrl.data.inGame ? null : m('a.button.hint--bottom', {
|
|
||||||
'data-hint': ctrl.trans('continueFromHere'),
|
|
||||||
onclick: function() {
|
|
||||||
$.modal($('.continue_with.' + ctrl.data.game.id));
|
|
||||||
}
|
|
||||||
}, m('span[data-icon=U]'))
|
|
||||||
]),
|
|
||||||
m('div.continue_with.' + ctrl.data.game.id, [
|
|
||||||
m('a.button', {
|
|
||||||
href: ctrl.data.userAnalysis ? '/?fen=' + ctrl.vm.situation.fen + '#ai' : ctrl.router.Round.continue(ctrl.data.game.id, 'ai').url + '?fen=' + ctrl.vm.situation.fen,
|
|
||||||
rel: 'nofollow'
|
|
||||||
}, ctrl.trans('playWithTheMachine')),
|
|
||||||
m('br'),
|
|
||||||
m('a.button', {
|
|
||||||
href: ctrl.data.userAnalysis ? '/?fen=' + ctrl.vm.situation.fen + '#friend' : ctrl.router.Round.continue(ctrl.data.game.id, 'friend').url + '?fen=' + ctrl.vm.situation.fen,
|
|
||||||
rel: 'nofollow'
|
|
||||||
}, ctrl.trans('playWithAFriend'))
|
|
||||||
])
|
])
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
@ -332,7 +308,7 @@ module.exports = function(ctrl) {
|
||||||
}, [
|
}, [
|
||||||
ctrl.data.blind ? blindBoard(ctrl) : visualBoard(ctrl),
|
ctrl.data.blind ? blindBoard(ctrl) : visualBoard(ctrl),
|
||||||
m('div.lichess_ground',
|
m('div.lichess_ground',
|
||||||
m('div.replay', {
|
ctrl.actionMenu.open ? actionMenu(ctrl) : m('div.replay', {
|
||||||
config: function(el, isUpdate) {
|
config: function(el, isUpdate) {
|
||||||
autoScroll(el);
|
autoScroll(el);
|
||||||
if (!isUpdate) setTimeout(partial(autoScroll, el), 100);
|
if (!isUpdate) setTimeout(partial(autoScroll, el), 100);
|
||||||
|
|
|
@ -128,6 +128,11 @@ module.exports = function(opts) {
|
||||||
}.bind(this);
|
}.bind(this);
|
||||||
setQuietMode();
|
setQuietMode();
|
||||||
|
|
||||||
|
this.takebackYes = function() {
|
||||||
|
this.socket.send('takeback-yes');
|
||||||
|
this.chessground.cancelPremove();
|
||||||
|
}.bind(this);
|
||||||
|
|
||||||
this.moveOn = new moveOn(this, 'lichess.move_on');
|
this.moveOn = new moveOn(this, 'lichess.move_on');
|
||||||
|
|
||||||
this.replay = new replayCtrl(this);
|
this.replay = new replayCtrl(this);
|
||||||
|
|
|
@ -8,7 +8,7 @@ var m = require('mithril');
|
||||||
module.exports = {
|
module.exports = {
|
||||||
standard: function(ctrl, condition, icon, hint, socketMsg) {
|
standard: function(ctrl, condition, icon, hint, socketMsg) {
|
||||||
return condition(ctrl.data) ? m('button', {
|
return condition(ctrl.data) ? m('button', {
|
||||||
class: 'button hint--bottom',
|
class: 'button hint--bottom ' + socketMsg,
|
||||||
'data-hint': ctrl.trans(hint),
|
'data-hint': ctrl.trans(hint),
|
||||||
onclick: partial(ctrl.socket.send, socketMsg, null)
|
onclick: partial(ctrl.socket.send, socketMsg, null)
|
||||||
}, m('span', {
|
}, m('span', {
|
||||||
|
@ -71,7 +71,7 @@ module.exports = {
|
||||||
ctrl.trans('yourOpponentProposesATakeback'),
|
ctrl.trans('yourOpponentProposesATakeback'),
|
||||||
m('br'),
|
m('br'),
|
||||||
m('a.button.text[data-icon=E]', {
|
m('a.button.text[data-icon=E]', {
|
||||||
onclick: partial(ctrl.socket.send, 'takeback-yes', null)
|
onclick: partial(ctrl.takebackYes),
|
||||||
}, ctrl.trans('accept')),
|
}, ctrl.trans('accept')),
|
||||||
m.trust(' '),
|
m.trust(' '),
|
||||||
m('a.button.text[data-icon=L]', {
|
m('a.button.text[data-icon=L]', {
|
||||||
|
|
|
@ -85,7 +85,11 @@ function renderTablePlay(ctrl) {
|
||||||
renderReplay(ctrl.replay),
|
renderReplay(ctrl.replay),
|
||||||
m('div.control.icons', [
|
m('div.control.icons', [
|
||||||
button.standard(ctrl, game.abortable, 'L', 'abortGame', 'abort'),
|
button.standard(ctrl, game.abortable, 'L', 'abortGame', 'abort'),
|
||||||
button.standard(ctrl, game.takebackable, 'i', 'proposeATakeback', 'takeback-yes'),
|
game.takebackable ? m('button', {
|
||||||
|
class: 'button hint--bottom takeback-yes',
|
||||||
|
'data-hint': ctrl.trans('proposeATakeback'),
|
||||||
|
onclick: partial(ctrl.takebackYes)
|
||||||
|
}, m('span[data-icon=i]')) : null,
|
||||||
button.standard(ctrl, game.drawable, '2', 'offerDraw', 'draw-yes'),
|
button.standard(ctrl, game.drawable, '2', 'offerDraw', 'draw-yes'),
|
||||||
button.standard(ctrl, game.resignable, 'b', 'resign', 'resign')
|
button.standard(ctrl, game.resignable, 'b', 'resign', 'resign')
|
||||||
]),
|
]),
|
||||||
|
|
|
@ -2,6 +2,7 @@ var m = require('mithril');
|
||||||
var partial = require('chessground').util.partial;
|
var partial = require('chessground').util.partial;
|
||||||
var tournament = require('../tournament');
|
var tournament = require('../tournament');
|
||||||
var util = require('./util');
|
var util = require('./util');
|
||||||
|
var button = require('./button');
|
||||||
|
|
||||||
var legend = m('th.legend', [
|
var legend = m('th.legend', [
|
||||||
m('span.streakstarter', 'Streak starter'),
|
m('span.streakstarter', 'Streak starter'),
|
||||||
|
@ -45,6 +46,9 @@ function playerTrs(ctrl, maxScore, player) {
|
||||||
]
|
]
|
||||||
}, {
|
}, {
|
||||||
tag: 'tr',
|
tag: 'tr',
|
||||||
|
attrs: {
|
||||||
|
key: player.id + '.bar'
|
||||||
|
},
|
||||||
children: [
|
children: [
|
||||||
m('td', {
|
m('td', {
|
||||||
class: 'around-bar',
|
class: 'around-bar',
|
||||||
|
|
Loading…
Reference in a new issue