A Signal's own icon, from all of Font Awesome Free, searchable (#261)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -38,6 +38,23 @@ const hash = s => crypto.createHash('sha256').update(s).digest('hex').slice(0, 1
|
||||
const HLS = fs.readFileSync(path.join(here, '..', 'node_modules', 'hls.js', 'dist', 'hls.light.min.js'), 'utf8');
|
||||
const HLS_URL = `/hls.js?v=${hash(HLS)}`;
|
||||
|
||||
// Font Awesome Free, the set the page's own icons come from, whole, for a Signal's icon (#261):
|
||||
// each icon a file of its own, /icons/<style>/<name>.svg, drawn as a mask so it takes the theme's
|
||||
// colour, and an index of names and search terms the picker fetches when it opens. The page's
|
||||
// script is given the index's address, named by its hash, in place of __ICONS__.
|
||||
const FA = path.join(here, '..', 'node_modules', '@fortawesome', 'fontawesome-free');
|
||||
const FA_STYLES = ['solid', 'regular', 'brands'];
|
||||
/// [`style/name`, label, search terms] for every icon, solid first.
|
||||
export function iconIndex() {
|
||||
const meta = JSON.parse(fs.readFileSync(path.join(FA, 'metadata', 'icon-families.json'), 'utf8'));
|
||||
return FA_STYLES.flatMap(style => fs.readdirSync(path.join(FA, 'svgs', style)).sort().map(f => {
|
||||
const name = f.slice(0, -4), m = meta[name] || {};
|
||||
return [`${style}/${name}`, m.label || name, (m.search?.terms || []).join(' ')];
|
||||
}));
|
||||
}
|
||||
const ICONS = JSON.stringify(iconIndex());
|
||||
const ICONS_URL = `/icons/index.json?v=${hash(ICONS)}`;
|
||||
|
||||
/// The shared stylesheet, minified. @swc/html minifies CSS inside a page, so it goes through as
|
||||
/// one; the doctype only keeps it from complaining that a fragment has none.
|
||||
export function buildStyle({ minify = true } = {}) {
|
||||
@@ -61,6 +78,7 @@ export function buildPage(name, { minify = true } = {}) {
|
||||
const { script, src: files } = PAGES[name];
|
||||
const src = files.map(f => fs.readFileSync(path.join(here, 'src', f + '.ts'), 'utf8')).join('\n')
|
||||
.replaceAll('__HLS_JS__', HLS_URL)
|
||||
.replaceAll('__ICONS__', ICONS_URL)
|
||||
.replaceAll('__WEB_VERSION__', WEB_VERSION);
|
||||
const js = swc.transformSync(src, {
|
||||
filename: name + '.ts',
|
||||
@@ -109,6 +127,12 @@ if (process.argv[1] === fileURLToPath(import.meta.url)) {
|
||||
['apple-touch-icon.png', 'apple-touch-icon.png'], ['apple-touch-icon.png', 'apple-touch-icon-precomposed.png'],
|
||||
['ipodderx-icon.png', 'icon.png'], ['boot.js', 'boot.js'], ['InterVariable.woff2', 'inter.woff2'], ['Inter-LICENSE.txt', 'Inter-LICENSE.txt'],
|
||||
]) fs.copyFileSync(path.join(here, from), path.join(out, to));
|
||||
for (const style of FA_STYLES) {
|
||||
fs.mkdirSync(path.join(out, 'icons', style), { recursive: true });
|
||||
for (const f of fs.readdirSync(path.join(FA, 'svgs', style))) fs.copyFileSync(path.join(FA, 'svgs', style, f), path.join(out, 'icons', style, f));
|
||||
}
|
||||
fs.writeFileSync(path.join(out, 'icons', 'index.json'), ICONS);
|
||||
fs.copyFileSync(path.join(FA, 'LICENSE.txt'), path.join(out, 'icons', 'LICENSE.txt'));
|
||||
for (const name of Object.keys(PAGES)) {
|
||||
const { html, js, script } = buildPage(name);
|
||||
fs.writeFileSync(path.join(out, name), html);
|
||||
|
||||
Reference in New Issue
Block a user