personal opening explorer: show indexing status
parent
8139647bdc
commit
2f2807d185
|
@ -44,6 +44,11 @@
|
|||
text-overflow: ellipsis;
|
||||
user-select: text;
|
||||
}
|
||||
.player-loading {
|
||||
text-align: right;
|
||||
background: $c-bg-zebra !important;
|
||||
border-bottom: $border;
|
||||
}
|
||||
|
||||
.empty {
|
||||
display: flex;
|
||||
|
|
|
@ -155,7 +155,6 @@ const playerModal = (ctrl: ExplorerConfigCtrl) => {
|
|||
input,
|
||||
tag: 'span',
|
||||
onSelect(v) {
|
||||
// input.value = v.name;
|
||||
ctrl.data.playerName.value(v.name);
|
||||
ctrl.data.playerName.open(false);
|
||||
ctrl.redraw();
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import { prop } from 'common';
|
||||
import { storedProp } from 'common/storage';
|
||||
import debounce from 'common/debounce';
|
||||
import { sync, Sync } from 'common/sync';
|
||||
import { opposite } from 'chessground/util';
|
||||
import { controller as configCtrl } from './explorerConfig';
|
||||
import * as xhr from './explorerXhr';
|
||||
|
@ -50,7 +51,7 @@ export default function (root: AnalyseCtrl, opts: ExplorerOpts, allow: boolean):
|
|||
hovering = prop<Hovering | null>(null),
|
||||
movesAway = prop(0),
|
||||
gameMenu = prop<string | null>(null),
|
||||
lastStream = prop<Promise<CancellableStream> | null>(null);
|
||||
lastStream = prop<Sync<CancellableStream> | null>(null);
|
||||
|
||||
const checkHash = (e?: HashChangeEvent) => {
|
||||
if ((location.hash === '#explorer' || location.hash === '#opening') && !root.embed) {
|
||||
|
@ -88,29 +89,36 @@ export default function (root: AnalyseCtrl, opts: ExplorerOpts, allow: boolean):
|
|||
root.redraw();
|
||||
};
|
||||
const prev = lastStream();
|
||||
if (prev) prev.then(stream => stream.cancel());
|
||||
if (prev) prev.promise.then(stream => stream.cancel());
|
||||
if (withGames && tablebaseRelevant(effectiveVariant, fen))
|
||||
xhr.tablebase(opts.tablebaseEndpoint, effectiveVariant, fen).then(processData, onError);
|
||||
else
|
||||
lastStream(
|
||||
xhr.opening(
|
||||
{
|
||||
endpoint: opts.endpoint,
|
||||
endpoint3: opts.endpoint3,
|
||||
db: config.data.db.selected() as ExplorerDb,
|
||||
personal: {
|
||||
player: config.data.playerName.value(),
|
||||
color: root.getOrientation(),
|
||||
},
|
||||
variant: effectiveVariant,
|
||||
rootFen: root.nodeList[0].fen,
|
||||
play: root.nodeList.slice(1).map(s => s.uci!),
|
||||
fen,
|
||||
speeds: config.data.speed.selected(),
|
||||
ratings: config.data.rating.selected(),
|
||||
withGames,
|
||||
},
|
||||
processData
|
||||
sync(
|
||||
xhr
|
||||
.opening(
|
||||
{
|
||||
endpoint: opts.endpoint,
|
||||
endpoint3: opts.endpoint3,
|
||||
db: config.data.db.selected() as ExplorerDb,
|
||||
personal: {
|
||||
player: config.data.playerName.value(),
|
||||
color: root.getOrientation(),
|
||||
},
|
||||
variant: effectiveVariant,
|
||||
rootFen: root.nodeList[0].fen,
|
||||
play: root.nodeList.slice(1).map(s => s.uci!),
|
||||
fen,
|
||||
speeds: config.data.speed.selected(),
|
||||
ratings: config.data.rating.selected(),
|
||||
withGames,
|
||||
},
|
||||
processData
|
||||
)
|
||||
.then(stream => {
|
||||
stream.end.promise.then(root.redraw);
|
||||
return stream;
|
||||
})
|
||||
)
|
||||
);
|
||||
},
|
||||
|
@ -182,6 +190,10 @@ export default function (root: AnalyseCtrl, opts: ExplorerOpts, allow: boolean):
|
|||
setNode();
|
||||
}
|
||||
},
|
||||
isIndexing: () => {
|
||||
const stream = lastStream();
|
||||
return !!stream && (!stream.sync || !stream.sync.end.sync);
|
||||
},
|
||||
fetchMasterOpening: (() => {
|
||||
const masterCache: Dictionary<OpeningData> = {};
|
||||
return (fen: Fen): Promise<OpeningData> => {
|
||||
|
|
|
@ -14,6 +14,7 @@ import {
|
|||
OpeningMoveStats,
|
||||
OpeningGame,
|
||||
Opening,
|
||||
ExplorerCtrl,
|
||||
} from './interfaces';
|
||||
|
||||
function resultBar(move: OpeningMoveStats): VNode {
|
||||
|
@ -79,6 +80,7 @@ function showMoveTable(ctrl: AnalyseCtrl, data: OpeningData): VNode | null {
|
|||
return h('table.moves', [
|
||||
h('thead', [
|
||||
h('tr', [h('th.title', trans('move')), h('th.title', trans('games')), h('th.title', trans('whiteDrawBlack'))]),
|
||||
playerLoading(ctrl.explorer),
|
||||
]),
|
||||
h(
|
||||
'tbody',
|
||||
|
@ -388,6 +390,19 @@ function show(ctrl: AnalyseCtrl): MaybeVNode {
|
|||
return lastShow;
|
||||
}
|
||||
|
||||
const playerLoading = (explorer: ExplorerCtrl) =>
|
||||
explorer.config.data.db.selected() == 'player' && explorer.isIndexing()
|
||||
? h(
|
||||
'tr',
|
||||
h('th.title.player-loading', { attrs: { colspan: 3 } }, [
|
||||
'Indexing ',
|
||||
h('strong', explorer.config.data.playerName.value()),
|
||||
' games',
|
||||
h('i.ddloader'),
|
||||
])
|
||||
)
|
||||
: undefined;
|
||||
|
||||
function showTitle(ctrl: AnalyseCtrl, variant: Variant) {
|
||||
if (variant.key === 'standard' || variant.key === 'fromPosition') return ctrl.trans.noarg('openingExplorer');
|
||||
return ctrl.trans('xOpeningExplorer', variant.name);
|
||||
|
|
|
@ -157,6 +157,7 @@ export interface ExplorerCtrl {
|
|||
disable(): void;
|
||||
setHovering(fen: Fen, uci: Uci | null): void;
|
||||
onFlip(): void;
|
||||
isIndexing: () => boolean;
|
||||
fetchMasterOpening(fen: Fen): Promise<OpeningData>;
|
||||
fetchTablebaseHit(fen: Fen): Promise<SimpleTablebaseHit>;
|
||||
}
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
import { sync, Sync } from './sync';
|
||||
|
||||
export type ProcessLine = (line: any) => void;
|
||||
|
||||
export interface CancellableStream {
|
||||
cancel(): void;
|
||||
end: Promise<void>;
|
||||
end: Sync<boolean>;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -19,11 +21,11 @@ export const readNdJson =
|
|||
const decoder = new TextDecoder();
|
||||
let buf = '';
|
||||
|
||||
const loop = (): Promise<void> =>
|
||||
const loop = (): Promise<boolean> =>
|
||||
stream.read().then(({ done, value }) => {
|
||||
if (done) {
|
||||
if (buf.length > 0) processLine(JSON.parse(buf));
|
||||
return Promise.resolve();
|
||||
return Promise.resolve(true);
|
||||
} else {
|
||||
const chunk = decoder.decode(value, { stream: true });
|
||||
buf += chunk;
|
||||
|
@ -36,6 +38,6 @@ export const readNdJson =
|
|||
|
||||
return {
|
||||
cancel: () => stream.cancel(),
|
||||
end: loop(),
|
||||
end: sync(loop()),
|
||||
};
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue