extract manifest out of build script and have both (non)-maskable icons

also make PWA standalone instead of fullscreen as that doesn't seem
to play well with the onscreen keyboard on mobile
This commit is contained in:
Bruno Windels 2020-09-24 11:15:15 +02:00
parent 4a0173e90f
commit ae2f9c6332
6 changed files with 34 additions and 31 deletions

View file

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

View file

Before

Width:  |  Height:  |  Size: 1 KiB

After

Width:  |  Height:  |  Size: 1 KiB

BIN
assets/icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

4
assets/icon.svg Normal file
View file

@ -0,0 +1,4 @@
<svg width="384" height="384" viewBox="0 0 384 384" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M64.1212 192C64.1212 121.375 121.375 64.1212 192 64.1212C219.695 64.1212 245.333 72.9249 266.269 87.8864C264.331 92.1063 263.25 96.8018 263.25 101.75C263.25 120.113 278.136 135 296.5 135C299.74 135 302.871 134.536 305.832 133.672C314.811 151.161 319.879 170.989 319.879 192C319.879 262.626 262.626 319.879 192 319.879C121.375 319.879 64.1212 262.626 64.1212 192ZM320.589 124.669C331.148 144.792 337.121 167.698 337.121 192C337.121 272.148 272.148 337.121 192 337.121C111.852 337.121 46.8792 272.148 46.8792 192C46.8792 111.852 111.852 46.8792 192 46.8792C223.884 46.8792 253.367 57.1615 277.313 74.5912C282.733 70.7544 289.353 68.4998 296.5 68.4998C314.863 68.4998 329.75 83.3863 329.75 101.75C329.75 110.634 326.266 118.704 320.589 124.669Z" fill="#0DBD8B"/>
<circle cx="192" cy="192" r="85.5" fill="#0DBD8B"/>
</svg>

After

Width:  |  Height:  |  Size: 968 B

12
assets/manifest.json Normal file
View file

@ -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"
}

View file

@ -93,16 +93,9 @@ async function build() {
const cssBundlePaths = await buildCssBundles(legacy ? buildCssLegacy : buildCss, themes, themeAssets); const cssBundlePaths = await buildCssBundles(legacy ? buildCssLegacy : buildCss, themes, themeAssets);
let manifestPath; 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, const assetPaths = createAssetPaths(jsBundlePath, jsLegacyBundlePath, jsWorkerPath,
iconPngPath, iconSvgPath, cssBundlePaths, themeAssets); cssBundlePaths, themeAssets);
if (offline) { if (offline) {
manifestPath = await buildOffline(version, assetPaths); manifestPath = await buildOffline(version, assetPaths);
@ -112,13 +105,14 @@ async function build() {
console.log(`built ${PROJECT_ID} ${version} successfully`); console.log(`built ${PROJECT_ID} ${version} successfully`);
} }
function createAssetPaths(jsBundlePath, jsLegacyBundlePath, jsWorkerPath, iconPngPath, iconSvgPath, cssBundlePaths, themeAssets) { function trim(path) {
function trim(path) {
if (!path.startsWith(targetDir)) { if (!path.startsWith(targetDir)) {
throw new Error("invalid target path: " + targetDir); throw new Error("invalid target path: " + targetDir);
} }
return path.substr(targetDir.length); return path.substr(targetDir.length);
} }
function createAssetPaths(jsBundlePath, jsLegacyBundlePath, jsWorkerPath, cssBundlePaths, themeAssets) {
return { return {
jsBundle: () => trim(jsBundlePath), jsBundle: () => trim(jsBundlePath),
jsLegacyBundle: () => trim(jsLegacyBundlePath), jsLegacyBundle: () => trim(jsLegacyBundlePath),
@ -127,8 +121,6 @@ function createAssetPaths(jsBundlePath, jsLegacyBundlePath, jsWorkerPath, iconPn
cssThemeBundle: themeName => trim(cssBundlePaths.themes[themeName]), cssThemeBundle: themeName => trim(cssBundlePaths.themes[themeName]),
cssThemeBundles: () => Object.values(cssBundlePaths.themes).map(a => trim(a)), cssThemeBundles: () => Object.values(cssBundlePaths.themes).map(a => trim(a)),
otherAssets: () => Object.values(themeAssets).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) { 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 // write offline availability
const offlineFiles = [ const offlineFiles = [
assetPaths.cssMainBundle(), assetPaths.cssMainBundle(),
"index.html", "index.html",
assetPaths.iconPngPath(), ].concat(assetPaths.cssThemeBundles())
assetPaths.iconSvgPath(), .concat(webManifest.icons.map(i => i.src));
].concat(assetPaths.cssThemeBundles());
// write appcache manifest // write appcache manifest
const appCacheLines = [ const appCacheLines = [
@ -289,18 +288,6 @@ async function buildOffline(version, assetPaths) {
swSource = swSource.replace(`"%%OFFLINE_FILES%%"`, JSON.stringify(swOfflineFiles)); swSource = swSource.replace(`"%%OFFLINE_FILES%%"`, JSON.stringify(swOfflineFiles));
swSource = swSource.replace(`"%%CACHE_FILES%%"`, JSON.stringify(assetPaths.otherAssets())); swSource = swSource.replace(`"%%CACHE_FILES%%"`, JSON.stringify(assetPaths.otherAssets()));
await fs.writeFile(path.join(targetDir, "sw.js"), swSource, "utf8"); 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 manifestJson = JSON.stringify(webManifest);
const manifestPath = resource("manifest.json", manifestJson); const manifestPath = resource("manifest.json", manifestJson);
await fs.writeFile(manifestPath, manifestJson, "utf8"); await fs.writeFile(manifestPath, manifestJson, "utf8");