extract speech plugin, enable speech in analysis
parent
6b3cd629ed
commit
50b874bfb3
|
@ -37,6 +37,7 @@
|
|||
"ui/editor",
|
||||
"ui/game",
|
||||
"ui/nvui",
|
||||
"ui/speech",
|
||||
"ui/insight",
|
||||
"ui/learn",
|
||||
"ui/lobby",
|
||||
|
|
|
@ -13,10 +13,10 @@ interface Lichess {
|
|||
compiledScript(path: string): string
|
||||
keyboardMove: any
|
||||
slider(): any
|
||||
raf(f: () => void): void
|
||||
requestIdleCallback(f: () => void): void
|
||||
loadCss(path: string): void
|
||||
loadCssPath(path: string): void
|
||||
raf(f: () => void): void;
|
||||
requestIdleCallback(f: () => void): void;
|
||||
loadCss(path: string): void;
|
||||
loadCssPath(path: string): void;
|
||||
loadedCss: {
|
||||
[key: string]: boolean;
|
||||
}
|
||||
|
@ -54,16 +54,18 @@ interface Lichess {
|
|||
render(ctrl: any): any;
|
||||
}
|
||||
playMusic(): any;
|
||||
Speech?: {
|
||||
say(t: string, cut: boolean): void;
|
||||
step(s: { san?: San }, cut: boolean): void;
|
||||
};
|
||||
LichessSpeech?: LichessSpeech;
|
||||
spinnerHtml: string;
|
||||
movetimeChart: any;
|
||||
hasTouchEvents: boolean;
|
||||
mousedownEvent: 'mousedown' | 'touchstart';
|
||||
}
|
||||
|
||||
interface LichessSpeech {
|
||||
say(t: string, cut: boolean): void;
|
||||
step(s: { san?: San }, cut: boolean): void;
|
||||
}
|
||||
|
||||
interface Cookie {
|
||||
name: string;
|
||||
value: string;
|
||||
|
@ -88,9 +90,9 @@ interface Trans {
|
|||
type PubsubCallback = (...data: any[]) => void;
|
||||
|
||||
interface Pubsub {
|
||||
on(msg: string, f: PubsubCallback): void
|
||||
off(msg: string, f: PubsubCallback): void
|
||||
emit(msg: string): (...args: any[]) => void
|
||||
on(msg: string, f: PubsubCallback): void;
|
||||
off(msg: string, f: PubsubCallback): void;
|
||||
emit(msg: string): (...args: any[]) => void;
|
||||
}
|
||||
|
||||
interface LichessStorageHelper {
|
||||
|
|
|
@ -29,6 +29,7 @@ import { make as makePractice, PracticeCtrl } from './practice/practiceCtrl';
|
|||
import { make as makeEvalCache, EvalCache } from './evalCache';
|
||||
import { compute as computeAutoShapes } from './autoShape';
|
||||
import { nextGlyphSymbol } from './nodeFinder';
|
||||
import * as speech from './speech';
|
||||
import { AnalyseOpts, AnalyseData, ServerEvalData, Key, CgDests, JustCaptured, NvuiPlugin, Redraw } from './interfaces';
|
||||
import GamebookPlayCtrl from './study/gamebook/gamebookPlayCtrl';
|
||||
import { ctrl as treeViewCtrl, TreeView } from './treeView/treeView';
|
||||
|
@ -168,6 +169,8 @@ export default class AnalyseCtrl {
|
|||
this.jumpToIndex(index);
|
||||
this.redraw()
|
||||
});
|
||||
|
||||
speech.setup();
|
||||
}
|
||||
|
||||
initialize(data: AnalyseData, merge: boolean): void {
|
||||
|
@ -339,6 +342,7 @@ export default class AnalyseCtrl {
|
|||
this.threatMode(false);
|
||||
this.ceval.stop();
|
||||
this.startCeval();
|
||||
speech.node(this.node);
|
||||
}
|
||||
this.justPlayed = this.justDropped = this.justCaptured = undefined;
|
||||
this.explorer.setNode();
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
export function setup() {
|
||||
window.lichess.pubsub.on('speech.enabled', onSpeechChange);
|
||||
onSpeechChange(window.lichess.sound.speech());
|
||||
}
|
||||
|
||||
function onSpeechChange(enabled: boolean) {
|
||||
if (!window.LichessSpeech && enabled)
|
||||
window.lichess.loadScript(window.lichess.compiledScript('speech'));
|
||||
else if (window.LichessSpeech && !enabled) window.LichessSpeech = undefined;
|
||||
}
|
||||
|
||||
export function node(n: Tree.Node) {
|
||||
withSpeech(s => s.step(n, true));
|
||||
}
|
||||
|
||||
export function withSpeech(f: (speech: LichessSpeech) => void) {
|
||||
if (window.LichessSpeech) f(window.LichessSpeech);
|
||||
}
|
|
@ -10,11 +10,6 @@ lilaGulpPlugins([
|
|||
entries: ['src/plugins/keyboardMove.ts'],
|
||||
target: 'lichess.round.keyboardMove.min.js'
|
||||
},
|
||||
{
|
||||
standalone: 'Speech',
|
||||
entries: ['src/plugins/speech.ts'],
|
||||
target: 'lichess.round.speech.min.js'
|
||||
},
|
||||
{
|
||||
standalone: 'NVUI',
|
||||
entries: ['src/plugins/nvui.ts'],
|
||||
|
|
|
@ -710,8 +710,7 @@ export default class RoundController {
|
|||
|
||||
if (!this.nvui) keyboard.init(this);
|
||||
|
||||
li.pubsub.on('speech.enabled', speech.onSpeechChange(this));
|
||||
speech.onSpeechChange(this)(li.sound.speech());
|
||||
speech.setup(this);
|
||||
|
||||
this.onChange();
|
||||
});
|
||||
|
|
|
@ -2,29 +2,40 @@ import RoundController from './ctrl';
|
|||
import { Step } from './interfaces';
|
||||
import viewStatus from 'game/view/status';
|
||||
|
||||
export function onSpeechChange(ctrl: RoundController) {
|
||||
export function setup(ctrl: RoundController) {
|
||||
window.lichess.pubsub.on('speech.enabled', onSpeechChange(ctrl));
|
||||
onSpeechChange(ctrl)(window.lichess.sound.speech());
|
||||
}
|
||||
|
||||
function onSpeechChange(ctrl: RoundController) {
|
||||
return function(enabled: boolean) {
|
||||
if (!window.Speech && enabled)
|
||||
window.lichess.loadScript('compiled/lichess.round.speech.min.js').then(() => status(ctrl));
|
||||
else if (window.Speech && !enabled) window.Speech = undefined;
|
||||
if (!window.LichessSpeech && enabled)
|
||||
window.lichess.loadScript(
|
||||
window.lichess.compiledScript('speech')
|
||||
).then(() => status(ctrl));
|
||||
else if (window.LichessSpeech && !enabled) window.LichessSpeech = undefined;
|
||||
};
|
||||
}
|
||||
|
||||
export function status(ctrl: RoundController) {
|
||||
const s = viewStatus(ctrl);
|
||||
if (s == 'playingRightNow') window.Speech!.step(ctrl.stepAt(ctrl.ply), false);
|
||||
if (s == 'playingRightNow') window.LichessSpeech!.step(ctrl.stepAt(ctrl.ply), false);
|
||||
else {
|
||||
window.Speech!.say(s);
|
||||
withSpeech(speech => speech.say(s, false));
|
||||
const w = ctrl.data.game.winner;
|
||||
if (w) window.Speech!.say(ctrl.trans.noarg(w + 'IsVictorious'), false)
|
||||
if (w) withSpeech(speech => speech.say(ctrl.trans.noarg(w + 'IsVictorious'), false));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export function userJump(ctrl: RoundController, ply: Ply) {
|
||||
if (window.Speech) window.Speech.step(ctrl.stepAt(ply), true);
|
||||
withSpeech(s => s.step(ctrl.stepAt(ply), true));
|
||||
}
|
||||
|
||||
export function step(step: Step) {
|
||||
if (window.Speech) window.Speech.step(step, false);
|
||||
withSpeech(s => s.step(step, false));
|
||||
}
|
||||
|
||||
export function withSpeech(f: (speech: LichessSpeech) => void) {
|
||||
if (window.LichessSpeech) f(window.LichessSpeech);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
const lilaGulp = require('../gulp/tsProject.js');
|
||||
|
||||
lilaGulp('LichessSpeech', 'lichess.speech', __dirname);
|
|
@ -0,0 +1,33 @@
|
|||
{
|
||||
"name": "speech",
|
||||
"version": "1.0.0",
|
||||
"description": "lichess.org speech synthesis",
|
||||
"main": "dist/main.js",
|
||||
"types": "dist/main",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/ornicar/lila"
|
||||
},
|
||||
"keywords": [
|
||||
"chess",
|
||||
"lichess",
|
||||
"non-visual",
|
||||
"speech synthesis",
|
||||
"accessibility"
|
||||
],
|
||||
"author": "Thibault Duplessis",
|
||||
"license": "AGPL-3.0",
|
||||
"bugs": {
|
||||
"url": "https://github.com/ornicar/lila/issues"
|
||||
},
|
||||
"homepage": "https://github.com/ornicar/lila",
|
||||
"scripts": {
|
||||
"compile": "tsc"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/lichess": "1.0.0",
|
||||
"typescript": "^3"
|
||||
},
|
||||
"dependencies": {
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"noImplicitAny": true,
|
||||
"strictNullChecks": true,
|
||||
"noUnusedLocals": true,
|
||||
"noUnusedParameters": true,
|
||||
"noEmitOnError": false,
|
||||
"alwaysStrict": true,
|
||||
"noImplicitReturns": true,
|
||||
"noImplicitThis": true,
|
||||
"moduleResolution": "node",
|
||||
"target": "ES5",
|
||||
"lib": ["DOM", "ES5", "es2015.core", "es2015.Promise"]
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue