'use strict'; // Generate the Android launcher resources from the committed layers, at every // density, with NO inset (our layers already fill the 108 dp canvas) and a // monochrome (themed) layer. Run build-set.mjs first (it writes the layer PNGs). // // npm i opentype.js # (only build-icon/build-set need it; this reads PNGs) // node build-set.mjs && node build-android-res.mjs // // Writes ui/android/app/src/main/res/mipmap-*/ic_launcher{,_round,_foreground, // _background,_monochrome}.png. The two mipmap-anydpi-v26/*.xml are committed by hand. import { readFileSync, writeFileSync } from 'node:fs'; import { fileURLToPath } from 'node:url'; import { dirname, join } from 'node:path'; const DIR = dirname(fileURLToPath(import.meta.url)); const ROOT = join(DIR, '..', '..', '..'); const RES = join(ROOT, 'ui', 'android', 'app', 'src', 'main', 'res'); const uri = p => 'data:image/png;base64,' + readFileSync(p).toString('base64'); const BG = uri(join(ROOT, 'ui', 'assets', 'icon-background.png')); const FG = uri(join(ROOT, 'ui', 'assets', 'icon-foreground.png')); const MONO = uri(join(DIR, 'android-monochrome.png')); // density: [adaptive-layer px (108 dp), legacy launcher px (48 dp)] const D = { ldpi: [81, 36], mdpi: [108, 48], hdpi: [162, 72], xhdpi: [216, 96], xxhdpi: [324, 144], xxxhdpi: [432, 192] }; const pw = await import(join(ROOT, 'ui', 'node_modules', '@playwright', 'test', 'index.js')); const { chromium } = pw.default ?? pw; const browser = await chromium.launch(); const page = await browser.newPage({ deviceScaleFactor: 1 }); const im = (u, s) => ``; async function shot(html, s, transparent) { await page.setViewportSize({ width: s, height: s }); await page.setContent(`
${html}
`, { waitUntil: 'networkidle' }); return page.locator('#r').screenshot({ omitBackground: !!transparent }); } for (const [d, [fg, lg]] of Object.entries(D)) { const dir = join(RES, `mipmap-${d}`); writeFileSync(join(dir, 'ic_launcher_background.png'), await shot(im(BG, fg), fg, false)); writeFileSync(join(dir, 'ic_launcher_foreground.png'), await shot(im(FG, fg), fg, true)); writeFileSync(join(dir, 'ic_launcher_monochrome.png'), await shot(im(MONO, fg), fg, true)); const comp = `
${im(BG, lg)}
${im(FG, lg)}
`; writeFileSync(join(dir, 'ic_launcher.png'), await shot(comp, lg, false)); const round = `
${im(BG, lg)}
${im(FG, lg)}
`; writeFileSync(join(dir, 'ic_launcher_round.png'), await shot(round, lg, true)); console.log('mipmap-' + d, 'ok'); } await browser.close();