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
6 changes: 6 additions & 0 deletions modules/coreI18n/src/main/key.scala
Original file line number Diff line number Diff line change
Expand Up @@ -912,6 +912,7 @@ object I18nKey:
val `opponentClock`: I18nKey = "nvui:opponentClock"
val `gameStart`: I18nKey = "nvui:gameStart"
val `boardCommandList`: I18nKey = "nvui:boardCommandList"
val `inputFormCommandList`: I18nKey = "nvui:inputFormCommandList"
val `goToInputForm`: I18nKey = "nvui:goToInputForm"
val `announceCurrentSquare`: I18nKey = "nvui:announceCurrentSquare"
val `announceLastMove`: I18nKey = "nvui:announceLastMove"
Expand All @@ -922,6 +923,11 @@ object I18nKey:
val `moveToPieceByType`: I18nKey = "nvui:moveToPieceByType"
val `moveToRank`: I18nKey = "nvui:moveToRank"
val `moveToFile`: I18nKey = "nvui:moveToFile"
val `announcePieceLocations`: I18nKey = "nvui:announcePieceLocations"
val `announcePiecesOnRankOrFile`: I18nKey = "nvui:announcePiecesOnRankOrFile"
val `goToBoard`: I18nKey = "nvui:goToBoard"
val `movePiece`: I18nKey = "nvui:movePiece"
val `promotion`: I18nKey = "nvui:promotion"

object oauthScope:
val `newAccessToken`: I18nKey = "oauthScope:newAccessToken"
Expand Down
16 changes: 11 additions & 5 deletions translation/source/nvui.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,26 @@
<string name="pieces">Pieces</string>
<string name="gameStatus">Game status</string>
<string name="lastMove">Last move</string>
<string name="inputForm">Move and command input form</string>
<string name="inputForm">Command input form</string>
<string name="actions">Actions</string>
<string name="yourClock">Your clock</string>
<string name="opponentClock">Opponent clock</string>
<string name="gameStart">Game start</string>
<string name="boardCommandList">Command list when the board has focus</string>
<string name="goToInputForm">Go to move and command input form.</string>
<string name="inputFormCommandList">Type these commands in the command input form.</string>
<string name="goToInputForm">Go to the command input form.</string>
<string name="announceCurrentSquare">Announce current square.</string>
<string name="announceLastMove">Announce last move.</string>
<string name="announceLastMoveCapture">Announce piece captured in last move.</string>
<string name="announcePossibleMoves">Announce possible moves for the selected piece.</string>
<string name="announcePossibleCaptures">Announce possible captures with selected piece.</string>
<string name="moveWithArrows">Move to adjacent square left, right, up or down.</string>
<string name="moveToPieceByType">Move to a piece typing its type. Use uppercase to invert order.</string>
<string name="moveToRank">Move to rank 1-8.</string>
<string name="moveToFile">Move to file a-h.</string>
<string name="moveToPieceByType">Move to squares using piece names. For example: repeated k will move to every square where there is a knight. Use uppercase to invert order.</string>
<string name="moveToRank">Move to rank 1 to 8.</string>
<string name="moveToFile">Move to file a to h.</string>
<string name="announcePieceLocations">Announce locations of pieces. Example: p capital N for white knights, p lowercase k for black king.</string>
<string name="announcePiecesOnRankOrFile">Announce pieces on a rank or a file. Example: s a, s 1.</string>
<string name="goToBoard">Go to the board. Default square is e-4. You can specify a square: board a-1 or b a-1 will take you to square a-1.</string>
<string name="movePiece">To move a piece, use standard algebraic notation.</string>
<string name="promotion">To promote to anything else than a queen, use equals. For example a-8-equals-n promotes to a knight.</string>
</resources>
22 changes: 17 additions & 5 deletions ui/@types/lichess/i18n.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1747,6 +1747,10 @@ interface I18n {
announceLastMove: string;
/** Announce piece captured in last move. */
announceLastMoveCapture: string;
/** Announce locations of pieces. Example: p capital N for white knights, p lowercase k for black king. */
announcePieceLocations: string;
/** Announce pieces on a rank or a file. Example: s a, s 1. */
announcePiecesOnRankOrFile: string;
/** Announce possible captures with selected piece. */
announcePossibleCaptures: string;
/** Announce possible moves for the selected piece. */
Expand All @@ -1761,26 +1765,34 @@ interface I18n {
gameStart: string;
/** Game status */
gameStatus: string;
/** Go to move and command input form. */
/** Go to the board. Default square is e-4. You can specify a square: board a-1 or b a-1 will take you to square a-1. */
goToBoard: string;
/** Go to the command input form. */
goToInputForm: string;
/** Move and command input form */
/** Command input form */
inputForm: string;
/** Type these commands in the command input form. */
inputFormCommandList: string;
/** Last move */
lastMove: string;
/** Move list */
moveList: string;
/** Move to file a-h. */
/** To move a piece, use standard algebraic notation. */
movePiece: string;
/** Move to file a to h. */
moveToFile: string;
/** Move to a piece typing its type. Use uppercase to invert order. */
/** Move to squares using piece names. For example: repeated k will move to every square where there is a knight. Use uppercase to invert order. */
moveToPieceByType: string;
/** Move to rank 1-8. */
/** Move to rank 1 to 8. */
moveToRank: string;
/** Move to adjacent square left, right, up or down. */
moveWithArrows: string;
/** Opponent clock */
opponentClock: string;
/** Pieces */
pieces: string;
/** To promote to anything else than a queen, use equals. For example a-8-equals-n promotes to a knight. */
promotion: string;
/** Your clock */
yourClock: string;
};
Expand Down
8 changes: 4 additions & 4 deletions ui/analyse/src/plugins/analyse.nvui.ts
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,7 @@ export function initModule(ctrl: AnalyseController): NvuiPlugin {
`x: ${i18n.site.showThreat}`,
].reduce(addBreaks, []),
),
...boardCommands(),
...boardCommands(i18n),
h('h2', 'Commands'),
h(
'p',
Expand Down Expand Up @@ -363,15 +363,15 @@ function onSubmit(
type Command = 'p' | 's' | 'eval' | 'best' | 'prev' | 'next' | 'prev line' | 'next line' | 'pocket';
type InputCommand = {
cmd: Command;
help: VNode;
help: VNode | string;
cb: (ctrl: AnalyseController, notify: (txt: string) => void, style: MoveStyle, input: string) => void;
invalid?: (ctrl: AnalyseController) => boolean;
};

const inputCommands: InputCommand[] = [
{
cmd: 'p',
help: commands.piece.help,
help: commands.piece.help(i18n),
cb: (ctrl, notify, style, input) =>
notify(
commands.piece.apply(input, ctrl.chessground.state.pieces, style) ||
Expand All @@ -380,7 +380,7 @@ const inputCommands: InputCommand[] = [
},
{
cmd: 's',
help: commands.scan.help,
help: commands.scan.help(i18n),
cb: (ctrl, notify, style, input) =>
notify(
commands.scan.apply(input, ctrl.chessground.state.pieces, style) ||
Expand Down
4 changes: 2 additions & 2 deletions ui/lib/src/nvui/chess.ts
Original file line number Diff line number Diff line change
Expand Up @@ -162,14 +162,14 @@ const keysWithPiece = (pieces: Pieces, role?: Role, color?: Color): Key[] =>
[],
);

export function renderPieceKeys(pieces: Pieces, p: string, style: MoveStyle): string {
export function renderPieceKeys(pieces: Pieces, p: string, style: MoveStyle, i18n: I18n): string {
const color: Color = p === p.toUpperCase() ? 'white' : 'black';
const role = charToRole(p)!;
const keys = keysWithPiece(pieces, role, color);
return `${color} ${role}: ${keys.length ? keys.map(k => renderKey(k, style)).join(', ') : i18n.site.none}`;
}

export function renderPiecesOn(pieces: Pieces, rankOrFile: string, style: MoveStyle): string {
export function renderPiecesOn(pieces: Pieces, rankOrFile: string, style: MoveStyle, i18n: I18n): string {
const renderedKeysWithPiece = Array.from(pieces)
.sort(([key1], [key2]) => key1.localeCompare(key2))
.reduce<string[]>(
Expand Down
19 changes: 10 additions & 9 deletions ui/lib/src/nvui/command.ts
Original file line number Diff line number Diff line change
@@ -1,27 +1,28 @@
import { type VNode, type VNodeChildren, h } from 'snabbdom';
import { renderPieceKeys, renderPiecesOn, type MoveStyle } from './chess';
import type { Pieces } from '@lichess-org/chessground/types';
import { noTrans } from '../snabbdom';

interface Command {
help: VNode;
help(i18n: I18n): VNode | string;
apply(c: string, pieces: Pieces, style: MoveStyle): string | undefined;
}
type Commands = {
[name: string]: Command;
};

const i18n = { site: { none: 'None' } } as I18n;

export const commands: Commands = {
piece: {
help: noTrans('Read locations of a piece type. Example: p N, p k.'),
help: i18n => i18n.nvui.announcePieceLocations,
apply(c: string, pieces: Pieces, style: MoveStyle): string | undefined {
return tryC(c, /^\/?p ([pnbrqk])$/i, p => renderPieceKeys(pieces, p, style));
return tryC(c, /^\/?p ([pnbrqk])$/i, p => renderPieceKeys(pieces, p, style, i18n));
},
},
scan: {
help: noTrans('Read pieces on a rank or file. Example: s a, s 1.'),
help: i18n => i18n.nvui.announcePiecesOnRankOrFile,
apply(c: string, pieces: Pieces, style: MoveStyle): string | undefined {
return tryC(c, /^\/?s ([a-h1-8])$/i, p => renderPiecesOn(pieces, p, style));
return tryC(c, /^\/?s ([a-h1-8])$/i, p => renderPiecesOn(pieces, p, style, i18n));
},
},
};
Expand All @@ -30,7 +31,7 @@ function tryC<A>(c: string, regex: RegExp, f: (arg: string) => A | undefined): A
return c.match(regex) ? f(c.replace(regex, '$1')) : undefined;
}

export const boardCommands = (): VNode[] => [
export const boardCommands = (i18n: I18n): VNode[] => [
h('h2', i18n.nvui.boardCommandList),
h('p', [
`i: ${i18n.nvui.goToInputForm}`,
Expand All @@ -43,8 +44,8 @@ export const boardCommands = (): VNode[] => [
`shift+m: ${i18n.nvui.announcePossibleCaptures}`,
`arrow keys: ${i18n.nvui.moveWithArrows}`,
`k-q-r-b-n-p: ${i18n.nvui.moveToPieceByType}`,
`1-8: ${i18n.nvui.moveToRank}`,
`shift+1-8: ${i18n.nvui.moveToFile}`,
`1 to 8: ${i18n.nvui.moveToRank}`,
`shift+1 to 8: ${i18n.nvui.moveToFile}`,
`shift+a/d: ${i18n.site.keyMoveBackwardOrForward}`,
`alt+shift+a/d: ${i18n.site.cyclePreviousOrNextVariation}`,
].reduce(addBreaks, []),
Expand Down
1 change: 0 additions & 1 deletion ui/lib/tests/command.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ pieces.set('a1', { color: 'white', role: 'king' });
pieces.set('a2', { color: 'white', role: 'queen' });
pieces.set('b1', { color: 'white', role: 'knight' });
pieces.set('b2', { color: 'white', role: 'knight' });
(window.i18n as any) = { site: { none: 'None' } };

test('piece command', () => {
expect(commands.piece.apply('p N', pieces, 'san')).toBe('white knight: b1, b2');
Expand Down
6 changes: 3 additions & 3 deletions ui/puzzle/src/plugins/puzzle.nvui.ts
Original file line number Diff line number Diff line change
Expand Up @@ -171,11 +171,11 @@ export function initModule() {
'Type these commands in the move input.',
`v: ${i18n.site.viewTheSolution}`,
'l: Read last move.',
commands.piece.help,
commands.scan.help,
commands.piece.help(i18n),
commands.scan.help(i18n),
].reduce(addBreaks, []),
),
...boardCommands(),
...boardCommands(i18n),
h('h2', 'Promotion'),
h('p', [
'Standard PGN notation selects the piece to promote to. Example: a8=n promotes to a knight.',
Expand Down
31 changes: 13 additions & 18 deletions ui/round/src/plugins/round.nvui.ts
Original file line number Diff line number Diff line change
Expand Up @@ -208,20 +208,17 @@ export function initModule(): NvuiPlugin {
h('label', [noTrans('Board layout'), renderSetting(boardStyle, ctrl.redraw)]),
h('h2', i18n.keyboardMove.keyboardInputCommands),
h('p', [
noTrans('Type these commands in the move input.'),
i18n.nvui.inputFormCommandList,
h('br'),
i18n.nvui.movePiece,
h('br'),
i18n.nvui.promotion,
h('br'),
...inputCommands
.filter(c => !c.invalid?.(ctrl))
.flatMap(cmd => [`${cmd.cmd}${cmd.alt ? ` / ${cmd.alt}` : ''}: `, cmd.help, h('br')]),
]),
...boardCommands(),
h('h2', noTrans('Promotion')),
h('p', [
noTrans(
'Standard PGN notation selects the piece to promote to. Example: a8=n promotes to a knight.',
),
h('br'),
noTrans('Omission results in promotion to queen'),
]),
...boardCommands(i18n),
]);
},
};
Expand Down Expand Up @@ -294,9 +291,7 @@ type InputCommand = {
const inputCommands: InputCommand[] = [
{
cmd: 'board',
help: noTrans(
'Focus on board. Default square is e4. You can specify a square: board a1 or b a1 will take you to square a1.',
),
help: i18n.nvui.goToBoard,
cb: (_notify, _ctrl, _style, input) => {
const words = input.split(' ');
const file = words[1]?.charAt(0) || 'e';
Expand All @@ -314,7 +309,7 @@ const inputCommands: InputCommand[] = [
},
{
cmd: 'last',
help: noTrans('Read last move.'),
help: i18n.nvui.announceLastMove,
cb: notify => notify($('.lastMove').text()),
alt: 'l',
},
Expand All @@ -332,20 +327,20 @@ const inputCommands: InputCommand[] = [
},
{
cmd: 'p',
help: commands.piece.help,
help: commands.piece.help(i18n),
cb: (notify, ctrl, style, input) =>
notify(
commands.piece.apply(input, ctrl.chessground.state.pieces, style) ??
`Bad input: ${input}. Exptected format: ${commands.piece.help}`,
`Bad input: ${input}. Expected format: ${commands.piece.help}`,
),
},
{
cmd: 's',
help: commands.scan.help,
help: commands.scan.help(i18n),
cb: (notify, ctrl, style, input) =>
notify(
commands.scan.apply(input, ctrl.chessground.state.pieces, style) ??
`Bad input: ${input}. Exptected format: ${commands.scan.help}`,
`Bad input: ${input}. Expected format: ${commands.scan.help}`,
),
},
{
Expand Down
Loading