72 lines
2.1 KiB
JavaScript
72 lines
2.1 KiB
JavaScript
#!/usr/bin/env node
|
|
/**
|
|
* Generate Tauri app icons from suite mark SVGs.
|
|
* Usage: node mobile/scripts/sync-app-icons.mjs [ultimail|ultidrive|...|all]
|
|
*/
|
|
import { execSync } from "node:child_process"
|
|
import { mkdirSync, readFileSync } from "node:fs"
|
|
import { dirname, join } from "node:path"
|
|
import { fileURLToPath } from "node:url"
|
|
import sharp from "sharp"
|
|
|
|
const __dirname = dirname(fileURLToPath(import.meta.url))
|
|
const root = join(__dirname, "../..")
|
|
|
|
const APPS = {
|
|
ultimail: { mark: "public/ultimail-mark.svg" },
|
|
ultidrive: { mark: "public/ultidrive-mark.svg" },
|
|
ulticalmeet: { mark: "public/agenda-mark.svg" },
|
|
ultiai: { mark: "public/ultiai-mark.svg" },
|
|
contacts: { mark: "public/contacts-mark.svg" },
|
|
}
|
|
|
|
async function sourcePng(appId, markRel) {
|
|
const markPath = join(root, markRel)
|
|
const outDir = join(root, "mobile/.icon-cache")
|
|
mkdirSync(outDir, { recursive: true })
|
|
const outPath = join(outDir, `${appId}-1024.png`)
|
|
// Android adaptive icons mask ~66% of the canvas — keep the mark inside the safe zone.
|
|
const canvas = 1024
|
|
const safe = Math.round(canvas * 0.62)
|
|
const inset = Math.floor((canvas - safe) / 2)
|
|
const mark = await sharp(readFileSync(markPath), { density: 300 })
|
|
.resize(safe, safe, {
|
|
fit: "contain",
|
|
background: { r: 255, g: 255, b: 255, alpha: 0 },
|
|
})
|
|
.png()
|
|
.toBuffer()
|
|
await sharp({
|
|
create: {
|
|
width: canvas,
|
|
height: canvas,
|
|
channels: 4,
|
|
background: { r: 255, g: 255, b: 255, alpha: 0 },
|
|
},
|
|
})
|
|
.composite([{ input: mark, top: inset, left: inset }])
|
|
.png()
|
|
.toFile(outPath)
|
|
return outPath
|
|
}
|
|
|
|
async function syncOne(appId) {
|
|
const spec = APPS[appId]
|
|
if (!spec) throw new Error(`Unknown app: ${appId}`)
|
|
const png = await sourcePng(appId, spec.mark)
|
|
const appDir = join(root, `mobile/apps/${appId}`)
|
|
execSync(`pnpm exec tauri icon "${png}"`, {
|
|
cwd: appDir,
|
|
stdio: "inherit",
|
|
env: { ...process.env, TAURI_CLI_CONFIG_DEPTH: "5" },
|
|
})
|
|
console.log(`Icons synced for ${appId}`)
|
|
}
|
|
|
|
const arg = process.argv[2] ?? "ultimail"
|
|
const targets = arg === "all" ? Object.keys(APPS) : [arg]
|
|
|
|
for (const appId of targets) {
|
|
await syncOne(appId)
|
|
}
|