Merge branch 'master' into v2

pull/4994/head
Niklas Fiekas 2019-04-18 21:44:03 +02:00
commit c6ebca0a0f
10 changed files with 59 additions and 52 deletions

View File

@ -159,11 +159,7 @@ object User extends LilaController {
def ratingHistory(username: String) = OpenBody { implicit ctx =>
EnabledUser(username) { u =>
negotiate(
html = notFound,
api = _ =>
Env.history.ratingChartApi(u) map { Ok(_) as JSON }
)
Env.history.ratingChartApi(u) map { Ok(_) as JSON }
}
}

View File

@ -119,7 +119,9 @@ object activity {
entryTag(
iconTag(";"),
div(
trans.activity.playedNbMoves.plural(nb, nb, subCount(povs.size)),
trans.activity.playedNbMoves.pluralSame(nb),
" ",
trans.activity.inNbCorrespondenceGames.plural(povs.size, subCount(povs.size)),
subTag(
povs.map { pov =>
frag(

View File

@ -47,7 +47,7 @@ object side {
),
rankMap.fold(rankUnavailable) { ranks =>
ranks.get(perfType.key) map { rank =>
span(cls := "rank", title := trans.rankIsUpdatedEveryXMinutes.txt(15))(trans.rankX(rank.localize))
span(cls := "rank", title := trans.rankIsUpdatedEveryNbMinutes.pluralSameTxt(15))(trans.rankX(rank.localize))
}
}
),

View File

@ -153,7 +153,6 @@ val `passwordReset` = new Translated("passwordReset", Site)
val `forgotPassword` = new Translated("forgotPassword", Site)
val `rank` = new Translated("rank", Site)
val `rankX` = new Translated("rankX", Site)
val `rankIsUpdatedEveryXMinutes` = new Translated("rankIsUpdatedEveryXMinutes", Site)
val `gamesPlayed` = new Translated("gamesPlayed", Site)
val `cancel` = new Translated("cancel", Site)
val `timeOut` = new Translated("timeOut", Site)
@ -523,14 +522,11 @@ val `onlyFriends` = new Translated("onlyFriends", Site)
val `menu` = new Translated("menu", Site)
val `castling` = new Translated("castling", Site)
val `whiteCastlingKingside` = new Translated("whiteCastlingKingside", Site)
val `whiteCastlingQueenside` = new Translated("whiteCastlingQueenside", Site)
val `blackCastlingKingside` = new Translated("blackCastlingKingside", Site)
val `blackCastlingQueenside` = new Translated("blackCastlingQueenside", Site)
val `tpTimeSpentPlaying` = new Translated("tpTimeSpentPlaying", Site)
val `watchGames` = new Translated("watchGames", Site)
val `tpTimeSpentOnTV` = new Translated("tpTimeSpentOnTV", Site)
val `watch` = new Translated("watch", Site)
val `internationalEvents` = new Translated("internationalEvents", Site)
val `videoLibrary` = new Translated("videoLibrary", Site)
val `mobileApp` = new Translated("mobileApp", Site)
val `webmasters` = new Translated("webmasters", Site)
@ -724,6 +720,7 @@ val `nbGames` = new Translated("nbGames", Site)
val `nbBookmarks` = new Translated("nbBookmarks", Site)
val `nbDays` = new Translated("nbDays", Site)
val `nbHours` = new Translated("nbHours", Site)
val `rankIsUpdatedEveryNbMinutes` = new Translated("rankIsUpdatedEveryNbMinutes", Site)
val `nbPuzzles` = new Translated("nbPuzzles", Site)
val `nbGamesWithYou` = new Translated("nbGamesWithYou", Site)
val `nbRated` = new Translated("nbRated", Site)
@ -968,13 +965,14 @@ val `retry` = new Translated("retry", Learn)
object activity {
val `activity` = new Translated("activity", Activity)
val `supportedNbMonths` = new Translated("supportedNbMonths", Activity)
val `signedUp` = new Translated("signedUp", Activity)
val `supportedNbMonths` = new Translated("supportedNbMonths", Activity)
val `practicedNbPositions` = new Translated("practicedNbPositions", Activity)
val `solvedNbPuzzles` = new Translated("solvedNbPuzzles", Activity)
val `playedNbGames` = new Translated("playedNbGames", Activity)
val `postedNbMessages` = new Translated("postedNbMessages", Activity)
val `playedNbMoves` = new Translated("playedNbMoves", Activity)
val `inNbCorrespondenceGames` = new Translated("inNbCorrespondenceGames", Activity)
val `completedNbGames` = new Translated("completedNbGames", Activity)
val `followedNbPlayers` = new Translated("followedNbPlayers", Activity)
val `gainedNbFollowers` = new Translated("gainedNbFollowers", Activity)

View File

@ -73,7 +73,7 @@ private[round] final class Round(
}
case ResignForce(playerId) => handle(playerId) { pov =>
(pov.game.resignable && !pov.game.hasAi && pov.game.hasClock) ?? {
(pov.game.resignable && !pov.game.hasAi && pov.game.hasClock && !pov.isMyTurn) ?? {
pov.forceResignable ?? {
socketMap.ask[Boolean](pov.gameId)(IsGone(!pov.color, _)) flatMap {
case true if !pov.game.variant.insufficientWinningMaterial(pov.game.board, pov.color) => finisher.rageQuit(pov.game, Some(pov.color))

View File

@ -26,7 +26,9 @@ final class PgnDump(
def ofChapter(study: Study, chapter: Chapter) = Pgn(
tags = makeTags(study, chapter),
turns = toTurns(chapter.root),
initial = Initial(chapter.root.comments.list.map(_.text.value))
initial = Initial(
chapter.root.comments.list.map(_.text.value) ::: shapeComment(chapter.root.shapes).toList
)
)
private val fileR = """[\s,]""".r

View File

@ -1,7 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources>
<string name="activity">Activity</string>
<string name="supportedNbMonths">Supported lichess.org for %1$s months as a %2$s</string>
<plurals name="supportedNbMonths">
<item quantity="one">Supported lichess.org for %1$s month as a %2$s</item>
<item quantity="other">Supported lichess.org for %1$s months as a %2$s</item>
</plurals>
<plurals name="practicedNbPositions">
<item quantity="one">Practised %1$s position on %2$s</item>
<item quantity="other">Practised %1$s positions on %2$s</item>
@ -19,8 +22,12 @@
<item quantity="other">Posted %1$s messages in %2$s</item>
</plurals>
<plurals name="playedNbMoves">
<item quantity="one">Played %1$s move in %2$s correspondence game(s)</item>
<item quantity="other">Played %1$s moves in %2$s correspondence game(s)</item>
<item quantity="one">Played %1$s move</item>
<item quantity="other">Played %1$s moves</item>
</plurals>
<plurals name="inNbCorrespondenceGames">
<item quantity="one">in %1$s correspondence game</item>
<item quantity="other">in %1$s correspondence games</item>
</plurals>
<plurals name="completedNbGames">
<item quantity="one">Completed %s correspondence game</item>

View File

@ -173,7 +173,10 @@
<string name="forgotPassword">Forgot password?</string>
<string name="rank">Rank</string>
<string name="rankX">Rank: %s</string>
<string name="rankIsUpdatedEveryXMinutes">Rank is updated every %s minutes</string>
<plurals name="rankIsUpdatedEveryNbMinutes">
<item quantity="one">Rank is updated every minute</item>
<item quantity="other">Rank is updated every %s minutes</item>
</plurals>
<plurals name="nbPuzzles">
<item quantity="one">%s puzzle</item>
<item quantity="other">%s puzzles</item>
@ -587,7 +590,7 @@ computer analysis, game chat and shareable URL.</string>
<string name="starting">Starting:</string>
<string name="allInformationIsPublicAndOptional">All information is public and optional.</string>
<string name="yourCityRegionOrDepartment">Your city, region, or province.</string>
<string name="biographyDescription">Tell about you, what you like in chess, your favourite openings, games, players…</string>
<string name="biographyDescription">Talk about yourself, your interests, what you like in chess, your favorite openings, players, ...</string>
<plurals name="maximumNbCharacters">
<item quantity="one">Maximum: %s character.</item>
<item quantity="other">Maximum: %s characters.</item>
@ -596,7 +599,7 @@ computer analysis, game chat and shareable URL.</string>
<item quantity="one">%s block</item>
<item quantity="other">%s blocks</item>
</plurals>
<string name="listBlockedPlayers">List players that you have blocked</string>
<string name="listBlockedPlayers">List players you have blocked</string>
<string name="human">Human</string>
<string name="computer">Computer</string>
<string name="side">Side</string>
@ -632,9 +635,7 @@ computer analysis, game chat and shareable URL.</string>
<string name="menu">Menu</string>
<string name="castling">Castling</string>
<string name="whiteCastlingKingside">White O-O</string>
<string name="whiteCastlingQueenside">White O-O-O</string>
<string name="blackCastlingKingside">Black O-O</string>
<string name="blackCastlingQueenside">Black O-O-O</string>
<plurals name="nbForumPosts">
<item quantity="one">%s forum post</item>
<item quantity="other">%s forum posts</item>
@ -643,7 +644,6 @@ computer analysis, game chat and shareable URL.</string>
<string name="watchGames">Watch games</string>
<string name="tpTimeSpentOnTV">Time on TV: %s</string>
<string name="watch">Watch</string>
<string name="internationalEvents">International events</string>
<string name="videoLibrary">Video library</string>
<string name="mobileApp">Mobile App</string>
<string name="webmasters">Webmasters</string>
@ -685,7 +685,7 @@ computer analysis, game chat and shareable URL.</string>
<string name="keyShowOrHideComments">show/hide comments</string>
<string name="keyEnterOrExitVariation">enter/exit variation</string>
<string name="newTournament">New tournament</string>
<string name="tournamentHomeTitle">Chess tournament featuring various time controls and variants</string>
<string name="tournamentHomeTitle">Chess tournaments featuring various time controls and variants</string>
<string name="tournamentHomeDescription">Play fast-paced chess tournaments! Join an official scheduled tournament, or create your own. Bullet, Blitz, Classical, Chess960, King of the Hill, Threecheck, and more options available for endless chess fun.</string>
<string name="tournamentNotFound">Tournament not found</string>
<string name="tournamentDoesNotExist">This tournament does not exist.</string>

View File

@ -1,3 +1,4 @@
import { empty } from 'common';
import { h } from 'snabbdom'
import { VNode } from 'snabbdom/vnode'
import { Hooks } from 'snabbdom/hooks'
@ -22,15 +23,15 @@ const baseSpeeds: AutoplaySpeed[] = [{
delay: 5000
}];
const allSpeeds = baseSpeeds.concat({
const realtimeSpeed: AutoplaySpeed = {
name: 'realtimeReplay',
delay: 'realtime'
});
};
const cplSpeeds: AutoplaySpeed[] = [{
const cplSpeed: AutoplaySpeed = {
name: 'byCPL',
delay: 'cpl_slow'
}];
delay: 'cpl'
};
function deleteButton(ctrl: AnalyseCtrl, userId: string | null): VNode | undefined {
const g = ctrl.data.game;
@ -55,8 +56,11 @@ function deleteButton(ctrl: AnalyseCtrl, userId: string | null): VNode | undefin
function autoplayButtons(ctrl: AnalyseCtrl): VNode {
const d = ctrl.data;
let speeds = (d.game.moveCentis && d.game.moveCentis.length) ? allSpeeds : baseSpeeds;
speeds = d.analysis ? speeds.concat(cplSpeeds) : speeds;
const speeds = [
...baseSpeeds,
...(d.game.speed !== 'correspondence' && !empty(d.game.moveCentis) ? [realtimeSpeed] : []),
...(d.analysis ? [cplSpeed] : [])
];
return h('div.autoplay', speeds.map(speed => {
return h('a.button.button-empty', {
hook: bind('click', () => ctrl.togglePlay(speed.delay), ctrl.redraw)

View File

@ -2,7 +2,7 @@ import AnalyseCtrl from './ctrl';
import * as control from './control';
export type AutoplayDelay = number | 'realtime' | 'cpl_fast' | 'cpl_slow' | 'fast' | 'slow';
export type AutoplayDelay = number | 'realtime' | 'cpl';
export class Autoplay {
@ -32,27 +32,25 @@ export class Autoplay {
}
private nextDelay(): number {
if (typeof this.delay === 'string') {
// in a variation
if (!this.ctrl.onMainline) return 1500;
if (this.delay === 'realtime') {
if (this.ctrl.node.ply < 2) return 1000;
const centis = this.ctrl.data.game.moveCentis;
if (!centis) return 1500;
const time = centis[this.ctrl.node.ply - this.ctrl.tree.root.ply];
// estimate 130ms of lag to improve playback.
return time * 10 + 130 || 2000;
} else {
const slowDown = this.delay === 'cpl_fast' ? 10 : 30;
if (this.ctrl.node.ply >= this.ctrl.mainline.length - 1) return 0;
const currPlyCp = this.evalToCp(this.ctrl.node);
const nextPlyCp = this.evalToCp(this.ctrl.node.children[0]);
return Math.max(500,
Math.min(10000,
Math.abs(currPlyCp - nextPlyCp) * slowDown));
}
if (typeof this.delay === 'string' && !this.ctrl.onMainline) return 1500;
else if (this.delay === 'realtime') {
if (this.ctrl.node.ply < 2) return 1000;
const centis = this.ctrl.data.game.moveCentis;
if (!centis) return 1500;
const time = centis[this.ctrl.node.ply - this.ctrl.tree.root.ply];
// estimate 130ms of lag to improve playback.
return time * 10 + 130 || 2000;
}
return this.delay!;
else if (this.delay === 'cpl') {
const slowDown = 30;
if (this.ctrl.node.ply >= this.ctrl.mainline.length - 1) return 0;
const currPlyCp = this.evalToCp(this.ctrl.node);
const nextPlyCp = this.evalToCp(this.ctrl.node.children[0]);
return Math.max(500,
Math.min(10000,
Math.abs(currPlyCp - nextPlyCp) * slowDown));
}
else return this.delay!;
}
private schedule(): void {