diff --git a/ui/.build/src/build.ts b/ui/.build/src/build.ts index 75373bf48f4a..23aeeb81ffb0 100644 --- a/ui/.build/src/build.ts +++ b/ui/.build/src/build.ts @@ -7,7 +7,7 @@ import { sass, stopSass } from './sass'; import { esbuild, stopEsbuild } from './esbuild'; import { copies, stopCopies } from './copies'; import { startMonitor, stopMonitor } from './monitor'; -import { initManifest } from './manifest'; +import { initManifest, writeManifest } from './manifest'; import { clean } from './clean'; import { LichessModule, env, errorMark, colors as c } from './main'; @@ -50,6 +50,7 @@ export async function stop() { } export function postBuild() { + writeManifest(); for (const mod of env.building) { mod.post.forEach((args: string[]) => { env.log(`[${c.grey(mod.name)}] exec - ${c.cyanBold(args.join(' '))}`); diff --git a/ui/.build/src/esbuild.ts b/ui/.build/src/esbuild.ts index b8be7a30a719..43b74b4c37d2 100644 --- a/ui/.build/src/esbuild.ts +++ b/ui/.build/src/esbuild.ts @@ -58,12 +58,11 @@ export async function esbuild(tsc?: Promise): Promise { const onEndPlugin = { name: 'onEnd', setup(build: es.PluginBuild) { - build.onEnd((result: es.BuildResult) => { + build.onEnd(async (result: es.BuildResult) => { for (const err of result.errors) esbuildMessage(err, true); for (const warn of result.warnings) esbuildMessage(warn); + if (result.errors.length === 0) await jsManifest(result.metafile!); env.done(result.errors.length, 'esbuild'); - if (result.errors.length) return; - jsManifest(result.metafile!); }); }, }; diff --git a/ui/.build/src/manifest.ts b/ui/.build/src/manifest.ts index 074fa5dcd289..10978532e868 100644 --- a/ui/.build/src/manifest.ts +++ b/ui/.build/src/manifest.ts @@ -9,12 +9,12 @@ import { allSources } from './sass'; type Manifest = { [key: string]: { hash?: string; imports?: string[] } }; -const current: { js: Manifest; css: Manifest } = { js: {}, css: {} }; +const current: { js: Manifest; css: Manifest; dirty: boolean } = { js: {}, css: {}, dirty: false }; let writeTimer: NodeJS.Timeout; export async function initManifest() { if (env.building.length === env.modules.size) return; - // we're building a subset of modules. if possible reuse the previously built full manifest to give us + // we're building a subset of modules. reuse the previousl full manifest for // a shot at changes viewable in the browser, otherwise punt. if (!fs.existsSync(env.manifestFile)) return; if (Object.keys(current.js).length && Object.keys(current.css).length) return; @@ -24,15 +24,20 @@ export async function initManifest() { current.css = manifest.css; } +export async function writeManifest() { + if (!current.dirty) return; + clearTimeout(writeTimer); + writeTimer = setTimeout(write, 500); +} + export async function css() { const files = await globArray(path.join(env.cssTempDir, '*.css'), { abs: true }); const css: { name: string; hash: string }[] = await Promise.all(files.map(hashMove)); const newCssManifest: Manifest = {}; for (const { name, hash } of css) newCssManifest[name] = { hash }; - if (enumerableEquivalence(newCssManifest, current.css)) return; + if (isEquivalent(newCssManifest, current.css)) return; current.css = shallowSort({ ...current.css, ...newCssManifest }); - clearTimeout(writeTimer); - writeTimer = setTimeout(write, 500); + current.dirty = true; } export async function js(meta: es.Metafile) { @@ -53,10 +58,9 @@ export async function js(meta: es.Metafile) { } newJsManifest[out.name].imports = imports; } - if (enumerableEquivalence(newJsManifest, current.js) && fs.existsSync(env.manifestFile)) return; + if (isEquivalent(newJsManifest, current.js) && fs.existsSync(env.manifestFile)) return; current.js = shallowSort({ ...current.js, ...newJsManifest }); - clearTimeout(writeTimer); - writeTimer = setTimeout(write, 500); + current.dirty = true; } async function write() { @@ -98,6 +102,7 @@ async function write() { JSON.stringify(serverManifest, null, env.prod ? undefined : 2), ), ]); + current.dirty = false; env.log(`Manifest hash ${c.green(hash)}`); } @@ -142,20 +147,16 @@ function parsePath(path: string) { return match ? { name: match[1], hash: match[2] } : undefined; } -function enumerableEquivalence(a: any, b: any): boolean { +function isEquivalent(a: any, b: any): boolean { if (a === b) return true; if (typeof a !== typeof b) return false; if (Array.isArray(a)) - return ( - Array.isArray(b) && - a.length === b.length && - a.every(x => b.find((y: any) => enumerableEquivalence(x, y))) - ); + return Array.isArray(b) && a.length === b.length && a.every(x => b.find((y: any) => isEquivalent(x, y))); if (typeof a !== 'object') return false; const [aKeys, bKeys] = [Object.keys(a), Object.keys(b)]; if (aKeys.length !== bKeys.length) return false; for (const key of aKeys) { - if (!bKeys.includes(key) || !enumerableEquivalence(a[key], b[key])) return false; + if (!bKeys.includes(key) || !isEquivalent(a[key], b[key])) return false; } return true; } diff --git a/ui/common/css/component/_lichess-pgn-viewer.scss b/ui/common/css/component/_lichess-pgn-viewer.scss index 30f918240add..008be59453e1 100644 --- a/ui/common/css/component/_lichess-pgn-viewer.scss +++ b/ui/common/css/component/_lichess-pgn-viewer.scss @@ -10,6 +10,9 @@ --c-lpv-bg-pane: #{$m-bg-zebra2--fade-1}; --c-lpv-pgn-text: #{$c-bg-zebra2}; --c-lpv-font: #{$c-font}; + // TODO: erase or replace with `--c-lpv-past-moves` when lpv-pgn-viewer > 2.1.0 is out + --c-lpv-font-accent: #{$c-font}; + --c-lpv-font-shy: #{$c-font-dim}; --c-lpv-accent-over: #{$c-over}; --c-lpv-fbt-hover: #{$m-primary_bg--mix-75};