From 0a8e0afb5d4fc144751a6620f4266f7c2f54978f Mon Sep 17 00:00:00 2001 From: Thibault Duplessis Date: Thu, 31 Oct 2024 12:38:46 +0100 Subject: [PATCH] tweak, type and use window.lichess --- ui/@types/lichess/index.d.ts | 5 +++ ui/bits/src/bits.challengePage.ts | 3 +- ui/bits/src/bits.infiniteScroll.ts | 3 +- ui/bits/src/bits.tvGames.ts | 2 +- ui/bits/src/bits.user.ts | 3 +- ui/chat/src/moderation.ts | 2 +- ui/common/src/socket.ts | 2 +- ui/lobby/src/lobby.ts | 4 +- ui/mod/src/mod.user.ts | 3 +- ui/notify/src/view.ts | 3 +- ui/round/src/round.ts | 2 +- ui/simul/src/simul.home.ts | 2 +- ui/site/src/announce.ts | 3 +- ui/site/src/api.ts | 70 ++++++++++++++---------------- ui/site/src/powertip.ts | 3 +- ui/site/src/site.ts | 2 +- 16 files changed, 53 insertions(+), 59 deletions(-) diff --git a/ui/@types/lichess/index.d.ts b/ui/@types/lichess/index.d.ts index 7fd6721f6b38..69b61ab48853 100644 --- a/ui/@types/lichess/index.d.ts +++ b/ui/@types/lichess/index.d.ts @@ -161,8 +161,13 @@ interface Fipr { x64hash128(input: string, seed: number): string; } +interface Api { + initializeDom: (root?: HTMLElement) => void; +} + interface Window { site: Site; + lichess: Api; fipr: Fipr; i18n: I18n; $as(cash: Cash): T; diff --git a/ui/bits/src/bits.challengePage.ts b/ui/bits/src/bits.challengePage.ts index 8cfb0f1a550c..4b448ab8d214 100644 --- a/ui/bits/src/bits.challengePage.ts +++ b/ui/bits/src/bits.challengePage.ts @@ -1,7 +1,6 @@ import * as xhr from 'common/xhr'; import StrongSocket from 'common/socket'; import { userComplete } from 'common/userComplete'; -import { pubsub } from 'common/pubsub'; interface ChallengeOpts { xhrUrl: string; @@ -19,7 +18,7 @@ export function initModule(opts: ChallengeOpts): void { xhr.text(opts.xhrUrl).then(html => { $(selector).replaceWith($(html).find(selector)); init(); - pubsub.emit('content-loaded', $(selector)[0]); + window.lichess.initializeDom($(selector)[0]); }); }, }, diff --git a/ui/bits/src/bits.infiniteScroll.ts b/ui/bits/src/bits.infiniteScroll.ts index 86dc9f38071e..1e0e9613f51b 100644 --- a/ui/bits/src/bits.infiniteScroll.ts +++ b/ui/bits/src/bits.infiniteScroll.ts @@ -1,6 +1,5 @@ import * as xhr from 'common/xhr'; import { spinnerHtml } from 'common/spinner'; -import { pubsub } from 'common/pubsub'; export function initModule(selector: string = '.infinite-scroll'): void { $(selector).each(function (this: HTMLElement) { @@ -37,7 +36,7 @@ function register(el: HTMLElement, selector: string, backoff = 500) { nav.remove(); $(el).append(($(html).is(selector) ? $(html) : $(html).find(selector)).html()); dedupEntries(el); - pubsub.emit('content-loaded', el); + window.lichess.initializeDom(el); setTimeout(() => register(el, selector, backoff * 1.05), backoff); // recursion with backoff }, e => { diff --git a/ui/bits/src/bits.tvGames.ts b/ui/bits/src/bits.tvGames.ts index 6c57e55955c1..71a8efda6a93 100644 --- a/ui/bits/src/bits.tvGames.ts +++ b/ui/bits/src/bits.tvGames.ts @@ -29,7 +29,7 @@ const requestReplacementGame = () => { .then((data: ReplacementResponse) => { main.find(`.mini-game[href^="/${oldId}"]`).replaceWith(data.html); if (data.html.includes('mini-game__result')) onFinish(data.id); - pubsub.emit('content-loaded'); + window.lichess.initializeDom(); }) .then(done, done); }); diff --git a/ui/bits/src/bits.user.ts b/ui/bits/src/bits.user.ts index 23eb48225cd2..31d5d7494679 100644 --- a/ui/bits/src/bits.user.ts +++ b/ui/bits/src/bits.user.ts @@ -1,6 +1,5 @@ import * as xhr from 'common/xhr'; import { makeLinkPopups } from 'common/linkPopup'; -import { pubsub } from 'common/pubsub'; import { alert } from 'common/dialog'; export function initModule(): void { @@ -48,7 +47,7 @@ export function initModule(): void { browseTo = (path: string) => xhr.text(path).then(html => { $content.html(html); - pubsub.emit('content-loaded', $content[0]); + window.lichess.initializeDom($content[0]); history.replaceState({}, '', path); site.asset.loadEsm('bits.infiniteScroll'); }); diff --git a/ui/chat/src/moderation.ts b/ui/chat/src/moderation.ts index 4d90bf72fc6d..c55e98a66080 100644 --- a/ui/chat/src/moderation.ts +++ b/ui/chat/src/moderation.ts @@ -158,7 +158,7 @@ export function moderationView(ctrl?: ModerationCtrl): VNode[] | undefined { { hook: { insert() { - pubsub.emit('content-loaded'); + window.lichess.initializeDom(); }, }, }, diff --git a/ui/common/src/socket.ts b/ui/common/src/socket.ts index f17163036b0c..0516bd0042a7 100644 --- a/ui/common/src/socket.ts +++ b/ui/common/src/socket.ts @@ -237,7 +237,7 @@ export default class StrongSocket implements SocketI { const mix = this.pongCount > 4 ? 0.1 : 1 / this.pongCount; this.averageLag += mix * (currentLag - this.averageLag); - pubsub.emit('socket.in.pong', this.averageLag); + pubsub.emit('socket.lag', this.averageLag); this.updateStats(currentLag); }; diff --git a/ui/lobby/src/lobby.ts b/ui/lobby/src/lobby.ts index 2f064ae7d2ad..31e78653eb10 100644 --- a/ui/lobby/src/lobby.ts +++ b/ui/lobby/src/lobby.ts @@ -35,12 +35,12 @@ export function initModule(opts: LobbyOpts) { reload_timeline() { xhr.text('/timeline').then(html => { $('.timeline').html(html); - pubsub.emit('content-loaded'); + window.lichess.initializeDom(); }); }, featured(o: { html: string }) { $('.lobby__tv').html(o.html); - pubsub.emit('content-loaded'); + window.lichess.initializeDom(); }, redirect(e: RedirectTo) { lobbyCtrl.setRedirecting(); diff --git a/ui/mod/src/mod.user.ts b/ui/mod/src/mod.user.ts index b34df805f0e3..1d4020076f8b 100644 --- a/ui/mod/src/mod.user.ts +++ b/ui/mod/src/mod.user.ts @@ -5,7 +5,6 @@ import extendTablesortNumber from 'common/tablesortNumber'; import tablesort from 'tablesort'; import { expandCheckboxZone, shiftClickCheckboxRange, selector } from './checkBoxes'; import { spinnerHtml } from 'common/spinner'; -import { pubsub } from 'common/pubsub'; import { confirm } from 'common/dialog'; site.load.then(() => { @@ -64,7 +63,7 @@ site.load.then(() => { const getLocationHash = (a: HTMLAnchorElement) => a.href.replace(/.+(#\w+)$/, '$1'); function userMod($inZone: Cash) { - pubsub.emit('content-loaded', $inZone[0]); + window.lichess.initializeDom($inZone[0]); const makeReady = (selector: string, f: (el: HTMLElement, i: number) => void, cls = 'ready') => { $inZone.find(selector + `:not(.${cls})`).each(function (this: HTMLElement, i: number) { diff --git a/ui/notify/src/view.ts b/ui/notify/src/view.ts index 88c39348cef2..e12cf7807b11 100644 --- a/ui/notify/src/view.ts +++ b/ui/notify/src/view.ts @@ -3,7 +3,6 @@ import { h, VNode } from 'snabbdom'; import * as licon from 'common/licon'; import { spinnerVdom as spinner } from 'common/spinner'; import makeRenderers from './renderers'; -import { pubsub } from 'common/pubsub'; const renderers = makeRenderers(); @@ -74,7 +73,7 @@ function clickHook(f: () => void) { }; } -const contentLoaded = (vnode: VNode) => pubsub.emit('content-loaded', vnode.elm); +const contentLoaded = (vnode: VNode) => window.lichess.initializeDom(vnode.elm as HTMLElement); function recentNotifications(d: NotifyData, scrolling: boolean): VNode { return h( diff --git a/ui/round/src/round.ts b/ui/round/src/round.ts index 6ac24885fc69..a7de88ddf383 100644 --- a/ui/round/src/round.ts +++ b/ui/round/src/round.ts @@ -74,7 +74,7 @@ async function boot( $meta.length && $('.game__meta').replaceWith($meta); $('.crosstable').replaceWith($html.find('.crosstable')); startTournamentClock(); - pubsub.emit('content-loaded'); + window.lichess.initializeDom(); }); }, tourStanding(s: TourPlayer[]) { diff --git a/ui/simul/src/simul.home.ts b/ui/simul/src/simul.home.ts index 047e485e069c..e29a15a0a91d 100644 --- a/ui/simul/src/simul.home.ts +++ b/ui/simul/src/simul.home.ts @@ -7,6 +7,6 @@ site.load.then(() => { const rsp = await fetch('/simul/reload'); const html = await rsp.text(); $('.simul-list__content').html(html); - pubsub.emit('content-loaded'); + window.lichess.initializeDom(); }); }); diff --git a/ui/site/src/announce.ts b/ui/site/src/announce.ts index 4fc477f6f368..7866c06219bd 100644 --- a/ui/site/src/announce.ts +++ b/ui/site/src/announce.ts @@ -1,5 +1,4 @@ import { escapeHtml } from 'common'; -import { pubsub } from 'common/pubsub'; let timeout: Timeout | undefined; @@ -25,7 +24,7 @@ const announce = (d: LichessAnnouncement) => { const millis = d.date ? new Date(d.date).getTime() - Date.now() : 5000; if (millis > 0) timeout = setTimeout(kill, millis); else kill(); - if (d.date) pubsub.emit('content-loaded'); + if (d.date) window.lichess.initializeDom(); } }; diff --git a/ui/site/src/api.ts b/ui/site/src/api.ts index dcb4c96fb2e0..57c1700e5c87 100644 --- a/ui/site/src/api.ts +++ b/ui/site/src/api.ts @@ -2,51 +2,47 @@ import { Pubsub, PubsubCallback, PubsubEvent } from 'common/pubsub'; // #TODO document these somewhere const publicEvents = ['ply', 'analysis.change', 'chat.resize', 'analysis.chart.click', 'analysis.closeAll']; +const socketEvents = ['lag', 'close']; +const socketInEvents = ['mlat', 'fen', 'notifications', 'endData']; +const friendsEvents = ['playing', 'stopped_playing', 'onlines', 'enters', 'leaves']; -export const api = (ps: Pubsub) => ({ - initializeDom: (root?: HTMLElement) => ps.emit('content-loaded', root), +export const api = (pubsub: Pubsub) => ({ + initializeDom: (root?: HTMLElement) => pubsub.emit('content-loaded', root), events: { on(name: PubsubEvent, cb: PubsubCallback): void { if (!publicEvents.includes(name)) throw 'This event is not part of the public API'; - ps.on(name, cb); + pubsub.on(name, cb); }, off(name: PubsubEvent, cb: PubsubCallback): void { - ps.off(name, cb); + pubsub.off(name, cb); }, }, - socket: (() => { - const inKeys = ['mlat', 'fen', 'notifications', 'endData']; - const keys = ['lag', 'close']; - return { - subscribeToMoveLatency: () => ps.emit('socket.send', 'moveLat', true), - events: { - on(key: string, cb: PubsubCallback): void { - if (inKeys.includes(key)) ps.on(`socket.in.${key}` as PubsubEvent, cb); - else if (keys.includes(key)) ps.on(`socket.${key}` as PubsubEvent, cb); - else throw 'This event is not part of the public API'; - }, - off(key: string, cb: PubsubCallback): void { - const ev = inKeys.includes(key) - ? (`socket.in.${key}` as PubsubEvent) - : (`socket.${key}` as PubsubEvent); - ps.off(ev, cb); - }, + socket: { + subscribeToMoveLatency: () => pubsub.emit('socket.send', 'moveLat', true), + events: { + on(key: string, cb: PubsubCallback): void { + if (socketInEvents.includes(key)) pubsub.on(`socket.in.${key}` as PubsubEvent, cb); + else if (socketEvents.includes(key)) pubsub.on(`socket.${key}` as PubsubEvent, cb); + else throw 'This event is not part of the public API'; }, - }; - })(), - onlineFriends: (() => { - const keys = ['playing', 'stopped_playing', 'onlines', 'enters', 'leaves']; - return { - request: () => ps.emit('socket.send', 'following_onlines'), - events: { - on(key: string, cb: PubsubCallback): void { - if (!keys.includes(key)) throw 'This event is not part of the public API'; - ps.on(`socket.in.following_${key}` as PubsubEvent, cb); - }, - off(key: string, cb: PubsubCallback): void { - ps.off(`socket.in.following_${key}` as PubsubEvent, cb); - }, + off(key: string, cb: PubsubCallback): void { + const ev = socketInEvents.includes(key) + ? (`socket.in.${key}` as PubsubEvent) + : (`socket.${key}` as PubsubEvent); + pubsub.off(ev, cb); }, - }; - })(), + }, + }, + onlineFriends: { + request: () => pubsub.emit('socket.send', 'following_onlines'), + events: { + on(key: string, cb: PubsubCallback): void { + if (!friendsEvents.includes(key)) throw 'This event is not part of the public API'; + pubsub.on(`socket.in.following_${key}` as PubsubEvent, cb); + }, + off(key: string, cb: PubsubCallback): void { + pubsub.off(`socket.in.following_${key}` as PubsubEvent, cb); + }, + }, + }, }); diff --git a/ui/site/src/powertip.ts b/ui/site/src/powertip.ts index fe5c6fadc89f..074d75c4b600 100644 --- a/ui/site/src/powertip.ts +++ b/ui/site/src/powertip.ts @@ -2,7 +2,6 @@ import * as licon from 'common/licon'; import * as xhr from 'common/xhr'; import { requestIdleCallback, $as } from 'common'; import { spinnerHtml } from 'common/spinner'; -import { pubsub } from 'common/pubsub'; // Thanks Steven Benner! - adapted from https://github.com/stevenbenner/jquery-powertip @@ -14,7 +13,7 @@ const onPowertipPreRender = (id: string, preload?: (url: string) => void) => (el xhr.text(url + '/mini').then(html => { const el = document.getElementById(id) as HTMLElement; el.innerHTML = html; - pubsub.emit('content-loaded', el); + window.lichess.initializeDom(el); }); }; diff --git a/ui/site/src/site.ts b/ui/site/src/site.ts index 1652bd0e01e1..59c8da0cb8da 100644 --- a/ui/site/src/site.ts +++ b/ui/site/src/site.ts @@ -29,4 +29,4 @@ site.sound = sound; site.load.then(boot); // public API -(window as any).lichess = api(pubsub); +window.lichess = api(pubsub);