Merge branch 'master' into reportWeight
* master: upgrade chessground to 7.2.10 restore `ui/build dev upgrade` tweak deploy script also tweak light theme clock sep opacity provide types for Trans Clock tweaks Update StringUtils.java
This commit is contained in:
commit
1d29391e7a
|
@ -27,4 +27,4 @@ rsync --archive --no-o --no-g --progress public $REMOTE:$REMOTE_DIR
|
|||
|
||||
lilalog "Deploy complete"
|
||||
|
||||
xdg-open https://lichess.org/dev/asset-version
|
||||
xdg-open https://lichess.org/dev/settings
|
||||
|
|
|
@ -77,7 +77,7 @@ public class StringUtils {
|
|||
* between two strings is no greater than the sum Levenshtein distances from
|
||||
* a third string).
|
||||
*
|
||||
* Implementation uses dynamic programming (Wagner–Fischer algorithm), with
|
||||
* Implementation uses dynamic programming (Wagner-Fischer algorithm), with
|
||||
* only 2 rows of data. The space requirement is thus O(m) and the algorithm
|
||||
* runs in O(mn).
|
||||
*
|
||||
|
|
2
public/javascripts/vendor/chessground.min.js
vendored
2
public/javascripts/vendor/chessground.min.js
vendored
File diff suppressed because one or more lines are too long
|
@ -642,7 +642,7 @@ div.table_wrap .clock huns {
|
|||
font-size: 80%;
|
||||
}
|
||||
div.table_wrap .clock sep {
|
||||
opacity: 0.6;
|
||||
opacity: 0.5;
|
||||
}
|
||||
div.table_wrap .clock sep.low {
|
||||
opacity: 0.15;
|
||||
|
|
8
ui/@types/lichess/index.d.ts
vendored
8
ui/@types/lichess/index.d.ts
vendored
|
@ -1,6 +1,6 @@
|
|||
interface Lichess {
|
||||
pubsub: Pubsub
|
||||
trans: Trans
|
||||
trans(i18n: { [key: string]: string | undefined }): Trans
|
||||
numberFormat(n: number): string
|
||||
once(key: string): boolean
|
||||
quietMode: boolean
|
||||
|
@ -55,7 +55,11 @@ interface AssetUrlOpts {
|
|||
|
||||
declare type SocketSend = (type: string, data?: any, opts?: any, noRetry?: boolean) => void;
|
||||
|
||||
declare type Trans = any; // todo
|
||||
interface Trans {
|
||||
(key: string, ...args: Array<string | number>): string;
|
||||
noarg(key: string): string;
|
||||
plural(key: string, count: number, ...args: Array<string | number>): string;
|
||||
}
|
||||
|
||||
interface Pubsub {
|
||||
on(msg: string, f: (data: any) => void): void
|
||||
|
|
|
@ -33,7 +33,7 @@ export default function(root: AnalyseCtrl, opts, allow: boolean): ExplorerCtrl {
|
|||
cache = {};
|
||||
setNode();
|
||||
}
|
||||
const withGames = synthetic(root.data) || gameUtil.replayable(root.data) || root.data.opponent.ai;
|
||||
const withGames = synthetic(root.data) || gameUtil.replayable(root.data) || !!root.data.opponent.ai;
|
||||
const effectiveVariant = root.data.game.variant.key === 'fromPosition' ? 'standard' : root.data.game.variant.key;
|
||||
|
||||
const config = configCtrl(root.data.game, onConfigClose, root.trans, root.redraw);
|
||||
|
|
|
@ -176,9 +176,9 @@ function showTablebase(ctrl: AnalyseCtrl, title: string, moves: TablebaseMoveSta
|
|||
}
|
||||
|
||||
function winner(stm: string, move: TablebaseMoveStats): Color | undefined {
|
||||
if ((stm[0] == 'w' && move.wdl < 0) || (stm[0] == 'b' && move.wdl > 0))
|
||||
if ((stm[0] == 'w' && move.wdl! < 0) || (stm[0] == 'b' && move.wdl! > 0))
|
||||
return 'white';
|
||||
if ((stm[0] == 'b' && move.wdl < 0) || (stm[0] == 'w' && move.wdl > 0))
|
||||
if ((stm[0] == 'b' && move.wdl! < 0) || (stm[0] == 'w' && move.wdl! > 0))
|
||||
return 'black';
|
||||
}
|
||||
|
||||
|
@ -251,15 +251,16 @@ function show(ctrl: AnalyseCtrl) {
|
|||
else lastShow = showEmpty(ctrl);
|
||||
} else if (data && isTablebase(data)) {
|
||||
const moves = data.moves;
|
||||
if (moves.length) lastShow = h('div.data', [
|
||||
if (moves.length) lastShow = h('div.data', ([
|
||||
[trans('winning'), m => m.wdl === -2],
|
||||
[trans('unknown'), m => m.wdl === null],
|
||||
[trans('winPreventedBy50MoveRule'), m => m.wdl === -1],
|
||||
[trans('drawn'), m => m.wdl === 0],
|
||||
[trans('lossSavedBy50MoveRule'), m => m.wdl === 1],
|
||||
[trans('losing'), m => m.wdl === 2],
|
||||
].map(a => showTablebase(ctrl, a[0] as string, moves.filter(a[1]), data.fen))
|
||||
.reduce(function(a, b) { return a.concat(b); }, []))
|
||||
] as [string, (move: TablebaseMoveStats) => boolean][])
|
||||
.map(a => showTablebase(ctrl, a[0] as string, moves.filter(a[1]), data.fen))
|
||||
.reduce(function(a, b) { return a.concat(b); }, []));
|
||||
else if (data.checkmate) lastShow = showGameEnd(ctrl, trans('checkmate'))
|
||||
else if (data.stalemate) lastShow = showGameEnd(ctrl, trans('stalemate'))
|
||||
else if (data.variant_win || data.variant_loss) lastShow = showGameEnd(ctrl, trans('variantEnding'));
|
||||
|
|
|
@ -82,15 +82,15 @@ export interface OpeningMoveStats extends MoveStats {
|
|||
averageRating: number;
|
||||
}
|
||||
export interface TablebaseMoveStats extends MoveStats {
|
||||
dtm: number;
|
||||
dtz: number;
|
||||
wdl: number | null;
|
||||
dtz: number | null;
|
||||
dtm: number | undefined;
|
||||
checkmate: boolean;
|
||||
stalemate: boolean;
|
||||
variant_win: boolean;
|
||||
variant_loss: boolean;
|
||||
insufficient_material: boolean;
|
||||
zeroing: boolean;
|
||||
wdl: number;
|
||||
}
|
||||
|
||||
export function isOpening(m: ExplorerData): m is OpeningData {
|
||||
|
|
|
@ -53,9 +53,9 @@ function renderEnd(root: AnalyseCtrl, end: string): VNode {
|
|||
color ? h('div.no-square', h('piece.king.' + color)) : h('div.icon.off', '!'),
|
||||
h('div.instruction', [
|
||||
h('strong', root.trans.noarg(end)),
|
||||
h('em', isMate ?
|
||||
h('color', root.trans.noarg(color === 'white' ? 'whiteWinsGame' : 'blackWinsGame')) :
|
||||
root.trans.noarg('theGameIsADraw'))
|
||||
isMate ?
|
||||
h('em', h('color', root.trans.noarg(color === 'white' ? 'whiteWinsGame' : 'blackWinsGame'))) :
|
||||
h('em', root.trans.noarg('theGameIsADraw'))
|
||||
])
|
||||
]);
|
||||
}
|
||||
|
|
9
ui/build
9
ui/build
|
@ -1,7 +1,8 @@
|
|||
#!/bin/bash -ea
|
||||
target=${1-dev}
|
||||
mode=${2-build} # use "upgrade" to upgrade all deps
|
||||
|
||||
echo "building ui modules with target=$target"
|
||||
echo "building ui modules with target=$target and mode=$mode"
|
||||
|
||||
cd "$(git rev-parse --show-toplevel)"
|
||||
|
||||
|
@ -11,7 +12,11 @@ ts_apps1="common chess"
|
|||
ts_apps2="ceval game tree chat"
|
||||
apps="site chat cli challenge notify learn insight editor puzzle round analyse lobby tournament tournamentSchedule simul perfStat dasher"
|
||||
|
||||
yarn install --non-interactive
|
||||
if [ $mode == "upgrade" ]; then
|
||||
yarn upgrade --non-interactive
|
||||
else
|
||||
yarn install --non-interactive
|
||||
fi
|
||||
|
||||
build_ts() {
|
||||
echo "build_ts" "$@"
|
||||
|
|
|
@ -3,12 +3,12 @@ import { Ctrl, ChallengeOpts, ChallengeData, ChallengeUser } from './interfaces'
|
|||
|
||||
export default function(opts: ChallengeOpts, data: ChallengeData, redraw: () => void): Ctrl {
|
||||
|
||||
let trans: Trans = (key: string) => key;
|
||||
let trans = (key: string) => key;
|
||||
let redirecting = false;
|
||||
|
||||
function update(d: ChallengeData) {
|
||||
data = d;
|
||||
if (d.i18n) trans = window.lichess.trans(d.i18n);
|
||||
if (d.i18n) trans = window.lichess.trans(d.i18n).noarg;
|
||||
opts.setCount(countActiveIn());
|
||||
notifyNew();
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@ export interface ChallengeOpts {
|
|||
export interface Ctrl {
|
||||
update(data: ChallengeData): void
|
||||
data(): ChallengeData
|
||||
trans(): Trans
|
||||
trans(): (key: string) => string
|
||||
decline(id: string): void
|
||||
cancel(id: string): void
|
||||
onRedirect(): void
|
||||
|
|
|
@ -10,7 +10,7 @@ export interface ChatOpts {
|
|||
public: boolean
|
||||
permissions: Permissions
|
||||
timeoutReasons?: ModerationReason[]
|
||||
i18n: Object
|
||||
i18n: { [key: string]: string | undefined }
|
||||
preset?: string
|
||||
noteId?: string
|
||||
loadCss: (url: string) => void
|
||||
|
|
|
@ -49,6 +49,7 @@ function tabName(ctrl: Ctrl, tab: Tab) {
|
|||
})
|
||||
})
|
||||
];
|
||||
if (tab === 'note') return ctrl.trans.noarg('notes');
|
||||
if (ctrl.plugin && tab === ctrl.plugin.tab.key) return ctrl.plugin.tab.name;
|
||||
if (tab === 'note') return [ctrl.trans.noarg('notes')];
|
||||
if (ctrl.plugin && tab === ctrl.plugin.tab.key) return [ctrl.plugin.tab.name];
|
||||
return [];
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { h } from 'snabbdom'
|
||||
import { VNode } from 'snabbdom/vnode'
|
||||
|
||||
import { Redraw, Prop, defined } from './util'
|
||||
import { Redraw, defined } from './util'
|
||||
|
||||
export interface PingData {
|
||||
ping: number | undefined
|
||||
|
@ -13,7 +13,7 @@ export interface PingCtrl {
|
|||
trans: Trans
|
||||
}
|
||||
|
||||
export function ctrl(trans: Prop<Trans>, redraw: Redraw): PingCtrl {
|
||||
export function ctrl(trans: Trans, redraw: Redraw): PingCtrl {
|
||||
|
||||
const data: PingData = {
|
||||
ping: undefined,
|
||||
|
|
|
@ -84,7 +84,7 @@ export function getPlayer(data: GameData, color?: Color): Player | null {
|
|||
}
|
||||
|
||||
export function hasAi(data: GameData): boolean {
|
||||
return data.player.ai || data.opponent.ai;
|
||||
return !!(data.player.ai || data.opponent.ai);
|
||||
}
|
||||
|
||||
export function userAnalysable(data: GameData): boolean {
|
||||
|
@ -97,7 +97,7 @@ export function isCorrespondence(data: GameData): boolean {
|
|||
|
||||
export function setOnGame(data: GameData, color: Color, onGame: boolean): void {
|
||||
var player = getPlayer(data, color);
|
||||
onGame = onGame || player.ai;
|
||||
onGame = onGame || !!player.ai;
|
||||
player.onGame = onGame;
|
||||
if (onGame) setIsGone(data, color, false);
|
||||
}
|
||||
|
|
|
@ -50,7 +50,7 @@ export interface Player {
|
|||
proposingTakeback?: boolean;
|
||||
offeringRematch?: boolean;
|
||||
offeringDraw?: boolean;
|
||||
ai: boolean;
|
||||
ai: number | null;
|
||||
onGame: boolean;
|
||||
isGone: boolean;
|
||||
blurs?: Blurs;
|
||||
|
|
|
@ -43,7 +43,7 @@ export default function(ctrl: LobbyController) {
|
|||
pov.opponent.ai ? ctrl.trans('aiNameLevelAiLevel', 'Stockfish', pov.opponent.ai) : pov.opponent.username,
|
||||
h('span.indicator',
|
||||
pov.isMyTurn ?
|
||||
(pov.secondsLeft ? timer(pov) : ctrl.trans('yourTurn')) :
|
||||
(pov.secondsLeft ? timer(pov) : [ctrl.trans.noarg('yourTurn')]) :
|
||||
h('span', {
|
||||
hook: {
|
||||
insert(vnode) {
|
||||
|
|
|
@ -19,9 +19,9 @@ export default function(ctrl: LobbyController) {
|
|||
}).length;
|
||||
const active = ctrl.tab;
|
||||
return [
|
||||
tab(ctrl, 'pools', active, ctrl.trans.noarg('quickPairing')),
|
||||
tab(ctrl, 'real_time', active, ctrl.trans.noarg('lobby')),
|
||||
tab(ctrl, 'seeks', active, ctrl.trans.noarg('correspondence')),
|
||||
tab(ctrl, 'pools', active, [ctrl.trans.noarg('quickPairing')]),
|
||||
tab(ctrl, 'real_time', active, [ctrl.trans.noarg('lobby')]),
|
||||
tab(ctrl, 'seeks', active, [ctrl.trans.noarg('correspondence')]),
|
||||
(active === 'now_playing' || ctrl.data.nbNowPlaying > 0) ? tab(ctrl, 'now_playing', active, [
|
||||
ctrl.trans.plural('nbGamesInPlay', ctrl.data.nbNowPlaying),
|
||||
myTurnPovsNb > 0 ? h('span.unread', myTurnPovsNb) : null
|
||||
|
|
|
@ -128,6 +128,8 @@ export class ClockController {
|
|||
}
|
||||
}
|
||||
|
||||
hardStopClock = (): void => this.times.activeColor = undefined;
|
||||
|
||||
scheduleTick = (time: Millis, extraDelay: Millis) => {
|
||||
if (this.tickCallback !== undefined) clearTimeout(this.tickCallback);
|
||||
this.tickCallback = setTimeout(
|
||||
|
|
|
@ -234,10 +234,12 @@ export default class RoundController {
|
|||
};
|
||||
if (this.clock) {
|
||||
socketOpts.withLag = !this.shouldSendMoveTime || !this.clock.isRunning;
|
||||
const moveMillis = this.clock.stopClock();
|
||||
if (this.shouldSendMoveTime) {
|
||||
if (meta.premove) socketOpts.millis = 0;
|
||||
else if (moveMillis !== undefined) {
|
||||
if (meta.premove && this.shouldSendMoveTime) {
|
||||
this.clock.hardStopClock();
|
||||
socketOpts.millis = 0;
|
||||
} else {
|
||||
const moveMillis = this.clock.stopClock();
|
||||
if (moveMillis !== undefined && this.shouldSendMoveTime) {
|
||||
socketOpts.millis = moveMillis;
|
||||
if (socketOpts.millis < 3) {
|
||||
// instant move, no premove? might be fishy
|
||||
|
|
|
@ -25,7 +25,7 @@ function bottomPlayer(ctrl: RoundController) {
|
|||
function renderPlayer(ctrl: RoundController, player: Player) {
|
||||
return player.ai ? h('div.username.user_link.online', [
|
||||
h('i.line'),
|
||||
h('name', renderUser.aiName(ctrl, player))
|
||||
h('name', renderUser.aiName(ctrl, player.ai))
|
||||
]) :
|
||||
renderUser.userHtml(ctrl, player);
|
||||
}
|
||||
|
|
|
@ -10,8 +10,8 @@ function ratingDiff(player: Player): VNode | undefined {
|
|||
return;
|
||||
}
|
||||
|
||||
export function aiName(ctrl: RoundController, player: Player) {
|
||||
return ctrl.trans('aiNameLevelAiLevel', 'Stockfish', player.ai);
|
||||
export function aiName(ctrl: RoundController, level: number) {
|
||||
return ctrl.trans('aiNameLevelAiLevel', 'Stockfish', level);
|
||||
}
|
||||
|
||||
export function userHtml(ctrl: RoundController, player: Player) {
|
||||
|
@ -71,6 +71,6 @@ export function userHtml(ctrl: RoundController, player: Player) {
|
|||
export function userTxt(ctrl: RoundController, player: Player) {
|
||||
if (player.user) {
|
||||
return (player.user.title ? player.user.title + ' ' : '') + player.user.username;
|
||||
} else if (player.ai) return aiName(ctrl, player)
|
||||
} else if (player.ai) return aiName(ctrl, player.ai)
|
||||
else return 'Anonymous';
|
||||
}
|
||||
|
|
|
@ -22,10 +22,5 @@ lichess.trans = function(i18n) {
|
|||
// optimisation for translations without arguments
|
||||
return i18n[key] || key;
|
||||
};
|
||||
trans.merge = function(more) {
|
||||
Object.keys(more).forEach(function(k) {
|
||||
i18n[k] = more[k];
|
||||
});
|
||||
};
|
||||
return trans;
|
||||
};
|
||||
|
|
22
yarn.lock
22
yarn.lock
|
@ -64,8 +64,8 @@ ajv@^4.9.1:
|
|||
json-stable-stringify "^1.0.1"
|
||||
|
||||
ajv@^5.1.0:
|
||||
version "5.5.0"
|
||||
resolved "https://registry.yarnpkg.com/ajv/-/ajv-5.5.0.tgz#eb2840746e9dc48bd5e063a36e3fd400c5eab5a9"
|
||||
version "5.5.1"
|
||||
resolved "https://registry.yarnpkg.com/ajv/-/ajv-5.5.1.tgz#b38bb8876d9e86bee994956a04e721e88b248eb2"
|
||||
dependencies:
|
||||
co "^4.6.0"
|
||||
fast-deep-equal "^1.0.0"
|
||||
|
@ -583,8 +583,8 @@ chalk@^1.0.0, chalk@^1.1.1, chalk@^1.1.3:
|
|||
resolved "https://codeload.github.com/ornicar/chess.js/tar.gz/ad0709c0b07773d9d0da8e4605a9a2a28f00d249"
|
||||
|
||||
chessground@^7.2:
|
||||
version "7.2.9"
|
||||
resolved "https://registry.yarnpkg.com/chessground/-/chessground-7.2.9.tgz#3f030f7290037024457e00cbde64a5e163083892"
|
||||
version "7.2.10"
|
||||
resolved "https://registry.yarnpkg.com/chessground/-/chessground-7.2.10.tgz#8b8f920db8ef85b6e7e37e7ec5769e8ea1523058"
|
||||
|
||||
"chessground@github:ornicar/chessground#v4.4.0":
|
||||
version "4.4.0"
|
||||
|
@ -983,8 +983,8 @@ detect-newline@2.X:
|
|||
resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-2.1.0.tgz#f41f1c10be4b00e87b5f13da680759f2c5bfd3e2"
|
||||
|
||||
detective@^4.0.0:
|
||||
version "4.6.0"
|
||||
resolved "https://registry.yarnpkg.com/detective/-/detective-4.6.0.tgz#d1a793ad0bcc829fa225465061096b7bca040527"
|
||||
version "4.7.0"
|
||||
resolved "https://registry.yarnpkg.com/detective/-/detective-4.7.0.tgz#6276e150f9e50829ad1f90ace4d9a2304188afcf"
|
||||
dependencies:
|
||||
acorn "^5.2.1"
|
||||
defined "^1.0.0"
|
||||
|
@ -1187,10 +1187,14 @@ extglob@^0.3.1:
|
|||
dependencies:
|
||||
is-extglob "^1.0.0"
|
||||
|
||||
extsprintf@1.3.0, extsprintf@^1.2.0:
|
||||
extsprintf@1.3.0:
|
||||
version "1.3.0"
|
||||
resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05"
|
||||
|
||||
extsprintf@^1.2.0:
|
||||
version "1.4.0"
|
||||
resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f"
|
||||
|
||||
fancy-log@^1.1.0:
|
||||
version "1.3.0"
|
||||
resolved "https://registry.yarnpkg.com/fancy-log/-/fancy-log-1.3.0.tgz#45be17d02bb9917d60ccffd4995c999e6c8c9948"
|
||||
|
@ -3886,8 +3890,8 @@ uglify-js@^2, uglify-js@^2.6:
|
|||
uglify-to-browserify "~1.0.0"
|
||||
|
||||
uglify-js@^3.0.5:
|
||||
version "3.2.0"
|
||||
resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.2.0.tgz#cb411ee4ca0e0cadbfe3a4e1a1da97e6fa0d19c1"
|
||||
version "3.2.1"
|
||||
resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.2.1.tgz#d6427fd45a25fefc5d196689c0c772a6915e10fe"
|
||||
dependencies:
|
||||
commander "~2.12.1"
|
||||
source-map "~0.6.1"
|
||||
|
|
Loading…
Reference in a new issue