diff --git a/icon.png b/assets/icon-maskable.png similarity index 100% rename from icon.png rename to assets/icon-maskable.png diff --git a/icon.svg b/assets/icon-maskable.svg similarity index 100% rename from icon.svg rename to assets/icon-maskable.svg diff --git a/assets/icon.png b/assets/icon.png new file mode 100644 index 00000000..b6c70c00 Binary files /dev/null and b/assets/icon.png differ diff --git a/assets/icon.svg b/assets/icon.svg new file mode 100644 index 00000000..134a3f7e --- /dev/null +++ b/assets/icon.svg @@ -0,0 +1,4 @@ + + + + diff --git a/assets/manifest.json b/assets/manifest.json new file mode 100644 index 00000000..01728ff9 --- /dev/null +++ b/assets/manifest.json @@ -0,0 +1,12 @@ +{ + "name": "Hydrogen", + "short_name": "Hydrogen", + "display": "standalone", + "description": "Lightweight matrix client with legacy and mobile browser support", + "start_url": "index.html", + "icons": [ + {"src": "assets/icon.png", "sizes": "384x384", "type": "image/png"}, + {"src": "assets/icon-maskable.png", "sizes": "384x384", "type": "image/png", "purpose": "maskable"} + ], + "theme_color": "#0DBD8B" +} diff --git a/scripts/build.mjs b/scripts/build.mjs index c2909283..e3006349 100644 --- a/scripts/build.mjs +++ b/scripts/build.mjs @@ -93,16 +93,9 @@ async function build() { const cssBundlePaths = await buildCssBundles(legacy ? buildCssLegacy : buildCss, themes, themeAssets); let manifestPath; - // copy icons - let iconPng = await fs.readFile(path.join(projectDir, "icon.png")); - let iconPngPath = resource("icon.png", iconPng); - await fs.writeFile(iconPngPath, iconPng); - let iconSvg = await fs.readFile(path.join(projectDir, "icon.svg")); - let iconSvgPath = resource("icon.svg", iconSvg); - await fs.writeFile(iconSvgPath, iconSvg); const assetPaths = createAssetPaths(jsBundlePath, jsLegacyBundlePath, jsWorkerPath, - iconPngPath, iconSvgPath, cssBundlePaths, themeAssets); + cssBundlePaths, themeAssets); if (offline) { manifestPath = await buildOffline(version, assetPaths); @@ -112,13 +105,14 @@ async function build() { console.log(`built ${PROJECT_ID} ${version} successfully`); } -function createAssetPaths(jsBundlePath, jsLegacyBundlePath, jsWorkerPath, iconPngPath, iconSvgPath, cssBundlePaths, themeAssets) { - function trim(path) { - if (!path.startsWith(targetDir)) { - throw new Error("invalid target path: " + targetDir); - } - return path.substr(targetDir.length); +function trim(path) { + if (!path.startsWith(targetDir)) { + throw new Error("invalid target path: " + targetDir); } + return path.substr(targetDir.length); +} + +function createAssetPaths(jsBundlePath, jsLegacyBundlePath, jsWorkerPath, cssBundlePaths, themeAssets) { return { jsBundle: () => trim(jsBundlePath), jsLegacyBundle: () => trim(jsLegacyBundlePath), @@ -127,8 +121,6 @@ function createAssetPaths(jsBundlePath, jsLegacyBundlePath, jsWorkerPath, iconPn cssThemeBundle: themeName => trim(cssBundlePaths.themes[themeName]), cssThemeBundles: () => Object.values(cssBundlePaths.themes).map(a => trim(a)), otherAssets: () => Object.values(themeAssets).map(a => trim(a)), - iconSvgPath: () => trim(iconSvgPath), - iconPngPath: () => trim(iconPngPath), }; } @@ -263,13 +255,20 @@ function buildWorkerJsLegacy(inputFile, outputName) { } async function buildOffline(version, assetPaths) { + // write web manifest + const webManifest = JSON.parse(await fs.readFile(path.join(projectDir, "assets/manifest.json"), "utf8")); + for (const icon of webManifest.icons) { + let iconData = await fs.readFile(path.join(projectDir, icon.src)); + let iconPath = resource(path.basename(icon.src), iconData); + await fs.writeFile(iconPath, iconData); + icon.src = trim(iconPath); + } // write offline availability const offlineFiles = [ assetPaths.cssMainBundle(), "index.html", - assetPaths.iconPngPath(), - assetPaths.iconSvgPath(), - ].concat(assetPaths.cssThemeBundles()); + ].concat(assetPaths.cssThemeBundles()) + .concat(webManifest.icons.map(i => i.src)); // write appcache manifest const appCacheLines = [ @@ -289,18 +288,6 @@ async function buildOffline(version, assetPaths) { swSource = swSource.replace(`"%%OFFLINE_FILES%%"`, JSON.stringify(swOfflineFiles)); swSource = swSource.replace(`"%%CACHE_FILES%%"`, JSON.stringify(assetPaths.otherAssets())); await fs.writeFile(path.join(targetDir, "sw.js"), swSource, "utf8"); - // write web manifest - const webManifest = { - name:PROJECT_NAME, - short_name: PROJECT_SHORT_NAME, - display: "fullscreen", - start_url: "index.html", - icons: [ - {"src": assetPaths.iconPngPath(), "sizes": "384x384", "type": "image/png"}, - {"src": assetPaths.iconSvgPath(), "type": "image/svg+xml"}, - ], - theme_color: "#0DBD8B" - }; const manifestJson = JSON.stringify(webManifest); const manifestPath = resource("manifest.json", manifestJson); await fs.writeFile(manifestPath, manifestJson, "utf8");