Automatically generate cordova icons from singe app icon image

This commit is contained in:
Martin Kleinschrodt 2021-10-12 17:31:12 +02:00
parent 07bc7cfe9c
commit bde6ef77d9
10 changed files with 14688 additions and 14026 deletions

BIN
assets/app-icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 105 KiB

View File

@ -30,59 +30,37 @@
<preference name="android-minSdkVersion" value="22" />
<preference name="android-targetSdkVersion" value="30" />
<preference name="StatusBarStyle" value="lightcontent" />
<icon density="ldpi" src="res/android/icon/app-icon-ldpi.png" />
<icon density="mdpi" src="res/android/icon/app-icon-mdpi.png" />
<icon density="hdpi" src="res/android/icon/app-icon-hdpi.png" />
<icon density="xhdpi" src="res/android/icon/app-icon-xhdpi.png" />
<icon density="xxhdpi" src="res/android/icon/app-icon-xxhdpi.png" />
<icon density="xxxhdpi" src="res/android/icon/app-icon-xxxhdpi.png" />
<splash density="land-ldpi" src="res/android/splash/splash-ldpi.png" />
<splash density="land-mdpi" src="res/android/splash/splash-mdpi.png" />
<splash density="land-hdpi" src="res/android/splash/splash-hdpi.png" />
<splash density="land-xhdpi" src="res/android/splash/splash-xhdpi.png" />
<splash density="land-xxhdpi" src="res/android/splash/splash-xxhdpi.png" />
<splash density="land-xxxhdpi" src="res/android/splash/splash-xxxhdpi.png" />
<splash density="port-ldpi" src="res/android/splash/splash-ldpi.png" />
<splash density="port-mdpi" src="res/android/splash/splash-mdpi.png" />
<splash density="port-hdpi" src="res/android/splash/splash-hdpi.png" />
<splash density="port-xhdpi" src="res/android/splash/splash-xhdpi.png" />
<splash density="port-xxhdpi" src="res/android/splash/splash-xxhdpi.png" />
<splash density="port-xxxhdpi" src="res/android/splash/splash-xxxhdpi.png" />
<resource-file src="www/res/icons/android/colors.xml" target="/app/src/main/res/values/colors.xml" />
<icon density="ldpi" foreground="www/res/icons/android/app-icon-36.png" background="@color/background" />
<icon density="mdpi" foreground="www/res/icons/android/app-icon-48.png" background="@color/background" />
<icon density="hdpi" foreground="www/res/icons/android/app-icon-72.png" background="@color/background" />
<icon density="xhdpi" foreground="www/res/icons/android/app-icon-96.png" background="@color/background" />
<icon density="xxhdpi" foreground="www/res/icons/android/app-icon-144.png" background="@color/background" />
<icon density="xxxhdpi" foreground="www/res/icons/android/app-icon-192.png" background="@color/background" />
</platform>
<platform name="ios">
<preference name="Fullscreen" value="true" />
<preference name="deployment-target" value="11.0" />
<preference name="StatusBarStyle" value="default" />
<icon height="20" src="res/ios/icon/app-icon-20.png" width="20" />
<icon height="29" src="res/ios/icon/app-icon-29.png" width="29" />
<icon height="40" src="res/ios/icon/app-icon-40.png" width="40" />
<icon height="50" src="res/ios/icon/app-icon-50.png" width="50" />
<icon height="57" src="res/ios/icon/app-icon-57.png" width="57" />
<icon height="58" src="res/ios/icon/app-icon-58.png" width="58" />
<icon height="60" src="res/ios/icon/app-icon-60.png" width="60" />
<icon height="72" src="res/ios/icon/app-icon-72.png" width="72" />
<icon height="76" src="res/ios/icon/app-icon-76.png" width="76" />
<icon height="80" src="res/ios/icon/app-icon-80.png" width="80" />
<icon height="87" src="res/ios/icon/app-icon-87.png" width="87" />
<icon height="100" src="res/ios/icon/app-icon-100.png" width="100" />
<icon height="114" src="res/ios/icon/app-icon-114.png" width="114" />
<icon height="120" src="res/ios/icon/app-icon-120.png" width="120" />
<icon height="144" src="res/ios/icon/app-icon-144.png" width="144" />
<icon height="152" src="res/ios/icon/app-icon-152.png" width="152" />
<icon height="167" src="res/ios/icon/app-icon-167.png" width="167" />
<icon height="180" src="res/ios/icon/app-icon-180.png" width="180" />
<icon height="1024" src="res/ios/icon/app-icon-1024.jpg" width="1024" />
<splash src="res/ios/splash/Default@2x~universal~anyany.png" />
<splash height="480" src="res/ios/splash/splash-320x480.png" width="320" />
<splash height="960" src="res/ios/splash/splash-640x960.png" width="640" />
<splash height="1024" src="res/ios/splash/splash-768x1024.png" width="768" />
<splash height="2048" src="res/ios/splash/splash-1536x2048.png" width="1536" />
<splash height="768" src="res/ios/splash/splash-1024x768.png" width="1024" />
<splash height="1536" src="res/ios/splash/splash-2048x1536.png" width="2048" />
<splash height="1136" src="res/ios/splash/splash-640x1136.png" width="640" />
<splash height="1334" src="res/ios/splash/splash-750x1334.png" width="750" />
<splash height="2208" src="res/ios/splash/splash-1242x2208.png" width="1242" />
<splash height="1242" src="res/ios/splash/splash-2208x1242.png" width="2208" />
<icon height="20" src="www/res/icons/ios/app-icon-20.png" width="20" />
<icon height="29" src="www/res/icons/ios/app-icon-29.png" width="29" />
<icon height="40" src="www/res/icons/ios/app-icon-40.png" width="40" />
<icon height="50" src="www/res/icons/ios/app-icon-50.png" width="50" />
<icon height="57" src="www/res/icons/ios/app-icon-57.png" width="57" />
<icon height="58" src="www/res/icons/ios/app-icon-58.png" width="58" />
<icon height="60" src="www/res/icons/ios/app-icon-60.png" width="60" />
<icon height="72" src="www/res/icons/ios/app-icon-72.png" width="72" />
<icon height="76" src="www/res/icons/ios/app-icon-76.png" width="76" />
<icon height="80" src="www/res/icons/ios/app-icon-80.png" width="80" />
<icon height="87" src="www/res/icons/ios/app-icon-87.png" width="87" />
<icon height="100" src="www/res/icons/ios/app-icon-100.png" width="100" />
<icon height="114" src="www/res/icons/ios/app-icon-114.png" width="114" />
<icon height="120" src="www/res/icons/ios/app-icon-120.png" width="120" />
<icon height="144" src="www/res/icons/ios/app-icon-144.png" width="144" />
<icon height="152" src="www/res/icons/ios/app-icon-152.png" width="152" />
<icon height="167" src="www/res/icons/ios/app-icon-167.png" width="167" />
<icon height="180" src="www/res/icons/ios/app-icon-180.png" width="180" />
<icon height="1024" src="www/res/icons/ios/app-icon-1024.jpg" width="1024" />
<config-file parent="UIStatusBarHidden" platform="ios" target="*-Info.plist">
<false />
</config-file>

File diff suppressed because it is too large Load Diff

View File

@ -49,16 +49,17 @@
"cordova-plugin-splashscreen": "6.0.0",
"cordova-plugin-statusbar": "2.4.3",
"cordova-plugin-x-socialsharing": "6.0.3",
"cordova-plugin-androidx-adapter": "^1.1.3",
"cordova-plugin-fingerprint-aio": "^4.0.2",
"es6-promise-plugin": "4.2.2",
"ionic-plugin-keyboard": "~2.2.1"
"ionic-plugin-keyboard": "~2.2.1",
"typescript": "^4.4.3"
},
"devDependencies": {
"@types/cordova-plugin-qrscanner": "^1.0.31",
"clean-webpack-plugin": "^3.0.0",
"cordova": "^10.0.0",
"cordova-android": "^10.1.0",
"cordova-plugin-androidx-adapter": "^1.1.3",
"cordova-plugin-fingerprint-aio": "^4.0.2",
"css-loader": "^5.2.6",
"file-loader": "^6.2.0",
"html-webpack-plugin": "^5.3.1",
@ -66,7 +67,8 @@
"ts-loader": "^9.2.2",
"ts-node": "^10.0.0",
"webpack": "^5.38.1",
"webpack-cli": "^4.7.0"
"webpack-cli": "^4.7.0",
"sharp": "^0.29.1"
},
"scripts": {
"build": "webpack",

View File

@ -11,12 +11,12 @@
<style>
html,
body {
background: linear-gradient(rgb(89, 198, 255), rgb(7, 124, 185));
background: var(--app-backdrop-background);
color: var(--app-backdrop-color);
width: 100%;
height: 100%;
margin: 0;
overscroll-behavior: none;
color: #fff;
position: fixed;
}
@ -59,7 +59,6 @@
rotate linear 1.2s infinite;
}
</style>
</head>
<body>
<svg viewBox="0 0 100 100" class="spinner">

View File

@ -15,6 +15,10 @@ declare var device: any;
declare var plugins: any;
export class CordovaPlatform extends WebPlatform implements Platform {
get supportedAuthTypes() {
return [AuthType.Email, AuthType.Totp, AuthType.PublicKey];
}
async scanQR() {
await cordovaReady;
return new Promise<string>((resolve, reject) => {

View File

@ -3,6 +3,9 @@ const { EnvironmentPlugin, optimize } = require("webpack");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
const { version } = require("./package.json");
const sharp = require("sharp");
const assetsDir = process.env.PL_ASSETS_DIR || "../../assets";
module.exports = {
entry: path.resolve(__dirname, "src/index.ts"),
@ -15,7 +18,10 @@ module.exports = {
devtool: "source-map",
stats: "minimal",
resolve: {
extensions: [".ts", ".js"],
extensions: [".ts", ".js", ".css", ".svg", ".png", ".jpg"],
alias: {
assets: path.resolve(__dirname, assetsDir),
},
},
module: {
rules: [
@ -55,16 +61,121 @@ module.exports = {
meta: {
"Content-Security-Policy": {
"http-equiv": "Content-Security-Policy",
content: `default-src 'self' ${process.env.PL_SERVER_URL} ${
process.env.PL_BILLING_ENABLED ? "https://*.stripe.com" : ""
}; style-src 'self' 'unsafe-inline'; object-src 'self' blob:; frame-src 'self' blob: ${
process.env.PL_BILLING_ENABLED ? "https://*.stripe.com" : ""
}; img-src 'self' blob:`,
content: `default-src 'self' ${process.env.PL_SERVER_URL}; style-src 'self' 'unsafe-inline'; object-src 'self' blob:; frame-src 'self' blob:; img-src 'self' blob:`,
},
},
}),
new optimize.LimitChunkCountPlugin({
maxChunks: 1,
}),
{
apply(compiler) {
compiler.hooks.emit.tapPromise("Prepare App Icons", async (compilation) => {
const background = process.env.PL_ICON_BACKGROUND;
const iconPath = path.resolve(__dirname, assetsDir, "app-icon.png");
const { width } = await sharp(iconPath).metadata();
const iosPadding = Math.floor(width / 10);
const androidPadding = Math.floor(width * 0.7);
const iosIcon = await sharp(iconPath)
.flatten({ background })
.extend({
top: iosPadding,
right: iosPadding,
bottom: iosPadding,
left: iosPadding,
background,
})
.toBuffer();
const androidIcon = await sharp(iconPath)
.extend({
top: androidPadding,
right: androidPadding,
bottom: androidPadding,
left: androidPadding,
background,
})
.toBuffer();
const iosIconSizes = [
20,
29,
40,
50,
57,
58,
60,
72,
76,
80,
87,
100,
114,
120,
144,
152,
167,
180,
];
const androidIconSizes = [36, 48, 72, 96, 144, 192];
await Promise.all([
...iosIconSizes.map(async (size) => {
const icon = await sharp(iosIcon)
.resize({
width: size,
height: size,
})
.png({ quality: 100 })
.toBuffer();
compilation.assets[`res/icons/ios/app-icon-${size}.png`] = {
source: () => icon,
size: () => Buffer.byteLength(icon),
};
}),
...androidIconSizes.map(async (size) => {
const icon = await sharp(androidIcon)
.resize({
width: size,
height: size,
})
.png({ quality: 100 })
.toBuffer();
compilation.assets[`res/icons/android/app-icon-${size}.png`] = {
source: () => icon,
size: () => Buffer.byteLength(icon),
};
}),
]);
const storeIcon = await sharp(iosIcon)
.resize({
width: 1024,
height: 1024,
})
.jpeg({ quality: 100 })
.toBuffer();
compilation.assets[`res/icons/ios/app-icon-1024.jpg`] = {
source: () => storeIcon,
size: () => Buffer.byteLength(storeIcon),
};
const colors = `<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="background">${background}</color>
</resources>`;
compilation.assets["res/icons/android/colors.xml"] = {
source: () => colors,
size: () => colors.length,
};
return true;
});
},
},
],
};

View File

@ -4,7 +4,6 @@ const HtmlWebpackPlugin = require("html-webpack-plugin");
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
const { version } = require("./package.json");
const manifest = require("./src/manifest.json");
const fs = require("fs");
const sharp = require("sharp");
const serverUrl = process.env.PL_SERVER_URL || `http://0.0.0.0:${process.env.PL_SERVER_PORT || 3000}`;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 73 KiB

View File

@ -74,7 +74,7 @@ module.exports = {
theme: "#59c6ff",
icons: [
{
src: path.resolve(__dirname, "assets/icon-512.png"),
src: path.resolve(__dirname, assetsDir, "app-icon.png"),
sizes: [96, 128, 192, 256, 384, 512],
},
],