refactor explorer config into a class

openingexplorer3
Thibault Duplessis 2021-10-19 16:26:04 +02:00
parent d064b7d237
commit 25689adf53
5 changed files with 93 additions and 125 deletions

View File

@ -44,10 +44,9 @@
text-overflow: ellipsis;
user-select: text;
}
.player-loading {
.player-indexing {
// text-align: right;
background: $c-bg-zebra !important;
border-bottom: $border;
line-height: 1.9em;
padding-left: 7px;
}

View File

@ -1,79 +1,96 @@
import { h, VNode } from 'snabbdom';
import { prop } from 'common';
import { Prop, prop } from 'common';
import { bind, dataIcon, onInsert } from 'common/snabbdom';
import { storedProp, storedJsonProp, StoredJsonProp } from 'common/storage';
import { storedProp, storedJsonProp, StoredJsonProp, StoredProp } from 'common/storage';
import { Game } from '../interfaces';
import { ExplorerDb, ExplorerSpeed, ExplorerConfigData, ExplorerConfigCtrl, ExplorerMode } from './interfaces';
import { ExplorerDb, ExplorerSpeed, ExplorerMode } from './interfaces';
import { snabModal } from 'common/modal';
const allSpeeds: ExplorerSpeed[] = ['bullet', 'blitz', 'rapid', 'classical'];
const allModes: ExplorerMode[] = ['casual', 'rated'];
const allRatings = [1600, 1800, 2000, 2200, 2500];
export function controller(game: Game, onClose: () => void, trans: Trans, redraw: () => void): ExplorerConfigCtrl {
const variant = game.variant.key === 'fromPosition' ? 'standard' : game.variant.key;
const available: ExplorerDb[] = ['lichess', 'player'];
if (variant === 'standard') available.unshift('masters');
const data: ExplorerConfigData = {
open: prop(true),
db: {
available,
selected: available.length > 1 ? storedProp('explorer.db.' + variant, available[0]) : () => available[0],
},
rating: {
available: allRatings,
selected: storedJsonProp('explorer.rating', () => allRatings),
},
speed: {
available: allSpeeds,
selected: storedJsonProp<ExplorerSpeed[]>('explorer.speed', () => allSpeeds),
},
mode: {
available: allModes,
selected: storedJsonProp<ExplorerMode[]>('explorer.mode', () => allModes),
},
playerName: {
open: prop(false),
value: storedProp<string>('explorer.player.name', document.body.dataset['user'] || ''),
previous: storedJsonProp<string[]>('explorer.player.name.previous', () => []),
},
export interface ExplorerConfigData {
open: Prop<boolean>;
db: {
available: ExplorerDb[];
selected: StoredProp<ExplorerDb>;
};
rating: {
available: number[];
selected: StoredJsonProp<number[]>;
};
speed: {
available: ExplorerSpeed[];
selected: StoredJsonProp<ExplorerSpeed[]>;
};
mode: {
available: ExplorerMode[];
selected: StoredJsonProp<ExplorerMode[]>;
};
playerName: {
open: Prop<boolean>;
value: StoredProp<string>;
previous: StoredJsonProp<string[]>;
};
}
const toggleMany = function <T>(c: StoredJsonProp<T[]>, value: T) {
export class ExplorerConfigCtrl {
data: ExplorerConfigData;
constructor(
readonly game: Game,
readonly variant: VariantKey,
readonly onClose: () => void,
readonly trans: Trans,
readonly redraw: () => void
) {
const available: ExplorerDb[] = ['lichess', 'player'];
if (variant === 'standard') available.unshift('masters');
this.data = {
open: prop(true),
db: {
available,
selected: available.length > 1 ? storedProp('explorer.db.' + variant, available[0]) : () => available[0],
},
rating: {
available: allRatings,
selected: storedJsonProp('explorer.rating', () => allRatings),
},
speed: {
available: allSpeeds,
selected: storedJsonProp<ExplorerSpeed[]>('explorer.speed', () => allSpeeds),
},
mode: {
available: allModes,
selected: storedJsonProp<ExplorerMode[]>('explorer.mode', () => allModes),
},
playerName: {
open: prop(false),
value: storedProp<string>('explorer.player.name', document.body.dataset['user'] || ''),
previous: storedJsonProp<string[]>('explorer.player.name.previous', () => []),
},
};
}
db = () => this.data.db.selected();
toggleMany = <T>(c: StoredJsonProp<T[]>, value: T) => {
if (!c().includes(value)) c(c().concat([value]));
else if (c().length > 1) c(c().filter(v => v !== value));
};
return {
trans,
redraw,
data,
toggleOpen() {
data.open(!data.open());
if (!data.open()) onClose();
},
toggleDb(db) {
data.db.selected(db);
},
toggleRating(v) {
toggleMany(data.rating.selected, v);
},
toggleSpeed(v) {
toggleMany(data.speed.selected, v);
},
toggleMode(v) {
toggleMany(data.mode.selected, v);
},
fullHouse() {
return (
data.db.selected() === 'masters' ||
(data.rating.selected().length === data.rating.available.length &&
data.speed.selected().length === data.speed.available.length)
);
},
toggleOpen = () => {
this.data.open(!this.data.open());
if (!this.data.open()) this.onClose();
};
toggleRating = (v: number) => this.toggleMany(this.data.rating.selected, v);
toggleSpeed = (v: ExplorerSpeed) => this.toggleMany(this.data.speed.selected, v);
toggleMode = (v: ExplorerMode) => this.toggleMany(this.data.mode.selected, v);
fullHouse = () =>
this.db() === 'masters' ||
(this.data.rating.selected().length === this.data.rating.available.length &&
this.data.speed.selected().length === this.data.speed.available.length);
}
export function view(ctrl: ExplorerConfigCtrl): VNode[] {
@ -87,20 +104,16 @@ export function view(ctrl: ExplorerConfigCtrl): VNode[] {
'button',
{
attrs: {
'aria-pressed': `${ctrl.data.db.selected() === s}`,
'aria-pressed': `${ctrl.db() === s}`,
},
hook: bind('click', _ => ctrl.toggleDb(s), ctrl.redraw),
hook: bind('click', _ => ctrl.data.db.selected(s), ctrl.redraw),
},
s
)
)
),
]),
ctrl.data.db.selected() === 'masters'
? masterDb(ctrl)
: ctrl.data.db.selected() === 'lichess'
? lichessDb(ctrl)
: playerDb(ctrl),
ctrl.db() === 'masters' ? masterDb(ctrl) : ctrl.db() === 'lichess' ? lichessDb(ctrl) : playerDb(ctrl),
h(
'section.save',
h(

View File

@ -3,21 +3,13 @@ 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';
import { winnerOf, colorOf } from './explorerUtil';
import * as gameUtil from 'game';
import AnalyseCtrl from '../ctrl';
import {
Hovering,
ExplorerData,
ExplorerDb,
OpeningData,
SimpleTablebaseHit,
ExplorerOpts,
ExplorerConfigCtrl,
} from './interfaces';
import { Hovering, ExplorerData, ExplorerDb, OpeningData, SimpleTablebaseHit, ExplorerOpts } from './interfaces';
import { CancellableStream } from 'common/ndjson';
import { ExplorerConfigCtrl } from './explorerConfig';
function pieceCount(fen: Fen) {
const parts = fen.split(/\s/);
@ -38,8 +30,7 @@ function tablebasePieces(variant: VariantKey) {
}
}
export const tablebaseGuaranteed = (variant: VariantKey, fen: Fen) =>
pieceCount(fen) <= tablebasePieces(variant);
export const tablebaseGuaranteed = (variant: VariantKey, fen: Fen) => pieceCount(fen) <= tablebasePieces(variant);
export default class ExplorerCtrl {
allowed: Prop<boolean>;
@ -61,7 +52,13 @@ export default class ExplorerCtrl {
this.enabled = root.embed ? prop(false) : storedProp('explorer.enabled', false);
this.withGames = root.synthetic || gameUtil.replayable(root.data) || !!root.data.opponent.ai;
this.effectiveVariant = root.data.game.variant.key === 'fromPosition' ? 'standard' : root.data.game.variant.key;
this.config = configCtrl(root.data.game, this.onConfigClose, root.trans, root.redraw);
this.config = new ExplorerConfigCtrl(
root.data.game,
this.effectiveVariant,
this.onConfigClose,
root.trans,
root.redraw
);
window.addEventListener('hashchange', this.checkHash, false);
this.checkHash();
}
@ -161,8 +158,7 @@ export default class ExplorerCtrl {
}
};
db = () => this.config.data.db.selected();
db = () => this.config.db();
current = () => this.cache[this.root.node.fen];
toggle = () => {
this.movesAway(0);

View File

@ -393,7 +393,7 @@ function show(ctrl: AnalyseCtrl): MaybeVNode {
const playerIndexing = (explorer: ExplorerCtrl) =>
explorer.db() == 'player' && explorer.isIndexing()
? h('div.player-loading', [
? h('div.player-indexing', [
'Indexing ',
h('strong', explorer.config.data.playerName.value()),
' games',

View File

@ -1,6 +1,3 @@
import { Prop } from 'common';
import { StoredProp, StoredJsonProp } from 'common/storage';
export interface Hovering {
fen: Fen;
uci: Uci;
@ -21,43 +18,6 @@ export interface ExplorerOpts {
tablebaseEndpoint: string;
}
export interface ExplorerConfigData {
open: Prop<boolean>;
db: {
available: ExplorerDb[];
selected: StoredProp<ExplorerDb>;
};
rating: {
available: number[];
selected: StoredJsonProp<number[]>;
};
speed: {
available: ExplorerSpeed[];
selected: StoredJsonProp<ExplorerSpeed[]>;
};
mode: {
available: ExplorerMode[];
selected: StoredJsonProp<ExplorerMode[]>;
};
playerName: {
open: Prop<boolean>;
value: StoredProp<string>;
previous: StoredJsonProp<string[]>;
};
}
export interface ExplorerConfigCtrl {
trans: Trans;
redraw(): void;
data: ExplorerConfigData;
toggleOpen(): void;
toggleDb(db: ExplorerDb): void;
toggleRating(rating: number): void;
toggleSpeed(speed: string): void;
toggleMode(mode: string): void;
fullHouse(): boolean;
}
export interface ExplorerData {
fen: Fen;
moves: MoveStats[];