diff --git a/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/android/app/src/main/res/mipmap-hdpi/ic_launcher.png index 770a8bf8..8a4d533d 100644 Binary files a/android/app/src/main/res/mipmap-hdpi/ic_launcher.png and b/android/app/src/main/res/mipmap-hdpi/ic_launcher.png differ diff --git a/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png b/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png index 43ac7116..422266c5 100644 Binary files a/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png and b/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png differ diff --git a/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png b/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png index 770a8bf8..8a4d533d 100644 Binary files a/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png and b/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png differ diff --git a/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/android/app/src/main/res/mipmap-mdpi/ic_launcher.png index e56881b7..a2fa5e19 100644 Binary files a/android/app/src/main/res/mipmap-mdpi/ic_launcher.png and b/android/app/src/main/res/mipmap-mdpi/ic_launcher.png differ diff --git a/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png b/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png index cf7273b7..8f3af791 100644 Binary files a/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png and b/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png differ diff --git a/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png b/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png index e56881b7..a2fa5e19 100644 Binary files a/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png and b/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png differ diff --git a/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png index 5a214a1c..fa49e2ef 100644 Binary files a/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png and b/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png b/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png index 96fecb98..945f8e9f 100644 Binary files a/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png and b/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png differ diff --git a/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png b/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png index 5a214a1c..fa49e2ef 100644 Binary files a/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png and b/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png differ diff --git a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png index d1e3d747..dc4e7c23 100644 Binary files a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png and b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png index 219efbd4..bbc67178 100644 Binary files a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png and b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png differ diff --git a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png index d1e3d747..dc4e7c23 100644 Binary files a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png and b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png differ diff --git a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png index 62e071c1..c2fb74a5 100644 Binary files a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png and b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png index 9cec02fa..96b0222f 100644 Binary files a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png and b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png differ diff --git a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png index 62e071c1..c2fb74a5 100644 Binary files a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png and b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png differ diff --git a/fastlane/screenshots/da-DK/ipad-13-01-dashboard.jpg b/fastlane/screenshots/da-DK/ipad-13-01-dashboard.jpg new file mode 100644 index 00000000..b89831da Binary files /dev/null and b/fastlane/screenshots/da-DK/ipad-13-01-dashboard.jpg differ diff --git a/fastlane/screenshots/da-DK/ipad-13-02-wash-setup.jpg b/fastlane/screenshots/da-DK/ipad-13-02-wash-setup.jpg new file mode 100644 index 00000000..fa31e503 Binary files /dev/null and b/fastlane/screenshots/da-DK/ipad-13-02-wash-setup.jpg differ diff --git a/fastlane/screenshots/da-DK/ipad-13-03-wash-lane.jpg b/fastlane/screenshots/da-DK/ipad-13-03-wash-lane.jpg new file mode 100644 index 00000000..db1a451b Binary files /dev/null and b/fastlane/screenshots/da-DK/ipad-13-03-wash-lane.jpg differ diff --git a/fastlane/screenshots/da-DK/ipad-13-04-booking.jpg b/fastlane/screenshots/da-DK/ipad-13-04-booking.jpg new file mode 100644 index 00000000..97f4945d Binary files /dev/null and b/fastlane/screenshots/da-DK/ipad-13-04-booking.jpg differ diff --git a/fastlane/screenshots/da-DK/ipad-13-05-vehicles.jpg b/fastlane/screenshots/da-DK/ipad-13-05-vehicles.jpg new file mode 100644 index 00000000..c7431cf6 Binary files /dev/null and b/fastlane/screenshots/da-DK/ipad-13-05-vehicles.jpg differ diff --git a/fastlane/screenshots/da-DK/ipad-13-06-wash-history.jpg b/fastlane/screenshots/da-DK/ipad-13-06-wash-history.jpg new file mode 100644 index 00000000..578acf0c Binary files /dev/null and b/fastlane/screenshots/da-DK/ipad-13-06-wash-history.jpg differ diff --git a/fastlane/screenshots/da-DK/iphone-6.9-01-dashboard.jpg b/fastlane/screenshots/da-DK/iphone-6.9-01-dashboard.jpg new file mode 100644 index 00000000..a9960171 Binary files /dev/null and b/fastlane/screenshots/da-DK/iphone-6.9-01-dashboard.jpg differ diff --git a/fastlane/screenshots/da-DK/iphone-6.9-02-wash-setup.jpg b/fastlane/screenshots/da-DK/iphone-6.9-02-wash-setup.jpg new file mode 100644 index 00000000..446efc66 Binary files /dev/null and b/fastlane/screenshots/da-DK/iphone-6.9-02-wash-setup.jpg differ diff --git a/fastlane/screenshots/da-DK/iphone-6.9-03-wash-lane.jpg b/fastlane/screenshots/da-DK/iphone-6.9-03-wash-lane.jpg new file mode 100644 index 00000000..72507138 Binary files /dev/null and b/fastlane/screenshots/da-DK/iphone-6.9-03-wash-lane.jpg differ diff --git a/fastlane/screenshots/da-DK/iphone-6.9-04-booking.jpg b/fastlane/screenshots/da-DK/iphone-6.9-04-booking.jpg new file mode 100644 index 00000000..1c7701d5 Binary files /dev/null and b/fastlane/screenshots/da-DK/iphone-6.9-04-booking.jpg differ diff --git a/fastlane/screenshots/da-DK/iphone-6.9-05-vehicles.jpg b/fastlane/screenshots/da-DK/iphone-6.9-05-vehicles.jpg new file mode 100644 index 00000000..81e1da27 Binary files /dev/null and b/fastlane/screenshots/da-DK/iphone-6.9-05-vehicles.jpg differ diff --git a/fastlane/screenshots/da-DK/iphone-6.9-06-wash-history.jpg b/fastlane/screenshots/da-DK/iphone-6.9-06-wash-history.jpg new file mode 100644 index 00000000..362c161c Binary files /dev/null and b/fastlane/screenshots/da-DK/iphone-6.9-06-wash-history.jpg differ diff --git a/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-1024.png b/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-1024.png index 274837b9..ef23fcac 100644 Binary files a/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-1024.png and b/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-1024.png differ diff --git a/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-20-ipad@2x.png b/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-20-ipad@2x.png index a4a1894f..857f05b5 100644 Binary files a/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-20-ipad@2x.png and b/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-20-ipad@2x.png differ diff --git a/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-20@1x.png b/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-20@1x.png index 4f3cc636..ccf06ab4 100644 Binary files a/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-20@1x.png and b/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-20@1x.png differ diff --git a/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-20@2x.png b/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-20@2x.png index a4a1894f..857f05b5 100644 Binary files a/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-20@2x.png and b/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-20@2x.png differ diff --git a/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-20@3x.png b/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-20@3x.png index bc01add0..240a8b65 100644 Binary files a/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-20@3x.png and b/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-20@3x.png differ diff --git a/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-29-ipad@2x.png b/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-29-ipad@2x.png index fbaadf07..9cd49d9e 100644 Binary files a/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-29-ipad@2x.png and b/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-29-ipad@2x.png differ diff --git a/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-29@1x.png b/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-29@1x.png index 59305ffc..b4abc1a7 100644 Binary files a/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-29@1x.png and b/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-29@1x.png differ diff --git a/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-29@2x.png b/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-29@2x.png index fbaadf07..9cd49d9e 100644 Binary files a/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-29@2x.png and b/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-29@2x.png differ diff --git a/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-29@3x.png b/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-29@3x.png index 5efd6b90..458e1145 100644 Binary files a/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-29@3x.png and b/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-29@3x.png differ diff --git a/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-40-ipad@2x.png b/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-40-ipad@2x.png index cb8f7ee7..41ae3917 100644 Binary files a/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-40-ipad@2x.png and b/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-40-ipad@2x.png differ diff --git a/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-40@1x.png b/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-40@1x.png index a4a1894f..857f05b5 100644 Binary files a/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-40@1x.png and b/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-40@1x.png differ diff --git a/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-40@2x.png b/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-40@2x.png index cb8f7ee7..41ae3917 100644 Binary files a/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-40@2x.png and b/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-40@2x.png differ diff --git a/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-40@3x.png b/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-40@3x.png index bba56cd1..b409bcbd 100644 Binary files a/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-40@3x.png and b/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-40@3x.png differ diff --git a/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-512@2x.png b/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-512@2x.png index 9579236b..ef23fcac 100644 Binary files a/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-512@2x.png and b/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-512@2x.png differ diff --git a/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-60@2x.png b/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-60@2x.png index bba56cd1..b409bcbd 100644 Binary files a/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-60@2x.png and b/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-60@2x.png differ diff --git a/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-60@3x.png b/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-60@3x.png index 8fdfa2ba..37b624b9 100644 Binary files a/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-60@3x.png and b/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-60@3x.png differ diff --git a/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-76@1x.png b/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-76@1x.png index e931a6b4..97eda231 100644 Binary files a/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-76@1x.png and b/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-76@1x.png differ diff --git a/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-76@2x.png b/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-76@2x.png index 51fc48c4..6ccaaa01 100644 Binary files a/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-76@2x.png and b/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-76@2x.png differ diff --git a/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-83.5@2x.png b/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-83.5@2x.png index ea766332..4ce76407 100644 Binary files a/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-83.5@2x.png and b/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-83.5@2x.png differ diff --git a/package.json b/package.json index 6c1f1eb2..a004381d 100644 --- a/package.json +++ b/package.json @@ -74,6 +74,7 @@ "mobile:android:play-upload": "node scripts/mobile/upload-google-play.mjs", "mobile:ios:sync": "npm run mobile:sync && npm run mobile:permissions:check", "mobile:ios:device": "node scripts/mobile/ios-device.mjs", + "mobile:ios:screenshots": "node scripts/playstore/generate-graphics.mjs --app-store-screenshots", "mobile:ios:storefront:check": "node scripts/mobile/validate-app-store.mjs", "mobile:ios:storefront:check-strict": "node scripts/mobile/validate-app-store.mjs --strict", "playstore:graphics": "node scripts/playstore/generate-graphics.mjs" diff --git a/public/icons/icon-192x192.png b/public/icons/icon-192x192.png index 62e071c1..c2fb74a5 100644 Binary files a/public/icons/icon-192x192.png and b/public/icons/icon-192x192.png differ diff --git a/public/icons/icon-512x512.png b/public/icons/icon-512x512.png index 915fe0eb..53d893ff 100644 Binary files a/public/icons/icon-512x512.png and b/public/icons/icon-512x512.png differ diff --git a/scripts/mobile/generate-android-icons.mjs b/scripts/mobile/generate-android-icons.mjs index 9f750e11..f68401bf 100644 --- a/scripts/mobile/generate-android-icons.mjs +++ b/scripts/mobile/generate-android-icons.mjs @@ -5,10 +5,9 @@ import { fileURLToPath } from "node:url"; import Jimp from "jimp"; const projectRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "../.."); -const sourcePath = path.join( - projectRoot, - "ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-1024.png", -); +const sourcePath = path.join(projectRoot, "public/favicons/web-app-manifest-512x512.png"); +const iosIconDirectory = path.join(projectRoot, "ios/App/App/Assets.xcassets/AppIcon.appiconset"); +const iosContentsPath = path.join(iosIconDirectory, "Contents.json"); const checkOnly = process.argv.includes("--check"); const launcherBackground = "#FFFFFF"; @@ -41,6 +40,7 @@ for (const [density, scale] of Object.entries(densityScale)) { { relativePath: `android/app/src/main/res/mipmap-${density}/ic_launcher_foreground.png`, size: foregroundSize, + safeZone: true, }, ); } @@ -84,8 +84,19 @@ async function writeIfChanged(relativePath, content) { return true; } -async function renderPng(sourceImage, size) { - const image = sourceImage.clone().resize(size, size, Jimp.RESIZE_BICUBIC); +async function renderPng(sourceImage, size, safeZone = false) { + const image = new Jimp(size, size, launcherBackground); + const artworkSize = safeZone ? Math.round(size * 0.72) : size; + const artwork = sourceImage.clone(); + if (artwork.bitmap.width !== artworkSize || artwork.bitmap.height !== artworkSize) { + artwork.resize(artworkSize, artworkSize, Jimp.RESIZE_BICUBIC); + } + const offset = Math.round((size - artworkSize) / 2); + image.composite(artwork, offset, offset); + image.scan(0, 0, size, size, (_x, _y, index) => { + image.bitmap.data[index + 3] = 255; + }); + image.colorType(2); return image.getBufferAsync(Jimp.MIME_PNG); } @@ -93,14 +104,24 @@ async function main() { const sourceBuffer = await fs.readFile(sourcePath); const sourceImage = await Jimp.read(sourceBuffer); - if (sourceImage.bitmap.width !== 1024 || sourceImage.bitmap.height !== 1024) { - throw new Error(`Expected ${path.relative(projectRoot, sourcePath)} to be a 1024x1024 PNG.`); + if (sourceImage.bitmap.width !== 512 || sourceImage.bitmap.height !== 512) { + throw new Error(`Expected ${path.relative(projectRoot, sourcePath)} to be a 512x512 PNG.`); } + const iosContents = JSON.parse(await fs.readFile(iosContentsPath, "utf8")); + const iosTargets = iosContents.images.map(({ filename, scale, size }) => ({ + relativePath: path.relative(projectRoot, path.join(iosIconDirectory, filename)), + size: Math.round(Number.parseFloat(size) * Number.parseFloat(scale)), + })); + iosTargets.push({ + relativePath: path.relative(projectRoot, path.join(iosIconDirectory, "AppIcon-512@2x.png")), + size: 1024, + }); + const imageTargets = [...targets, ...iosTargets]; const changed = []; - for (const target of targets) { - const buffer = await renderPng(sourceImage, target.size); + for (const target of imageTargets) { + const buffer = await renderPng(sourceImage, target.size, target.safeZone); if (await writeIfChanged(target.relativePath, buffer)) { changed.push(target.relativePath); } @@ -113,12 +134,12 @@ async function main() { } if (changed.length === 0) { - console.log(`Android icon assets are current (${targets.length + xmlTargets.length} files).`); + console.log(`Mobile icon assets are current (${imageTargets.length + xmlTargets.length} files).`); return; } if (checkOnly) { - console.error("Android icon assets are out of date:"); + console.error("Mobile icon assets are out of date:"); for (const relativePath of changed) { console.error(`- ${relativePath}`); } @@ -127,7 +148,7 @@ async function main() { return; } - console.log(`Updated ${changed.length} Android icon asset${changed.length === 1 ? "" : "s"}.`); + console.log(`Updated ${changed.length} mobile icon asset${changed.length === 1 ? "" : "s"}.`); } main().catch((error) => { diff --git a/scripts/playstore/generate-graphics.mjs b/scripts/playstore/generate-graphics.mjs index a3d047bf..d974a976 100644 --- a/scripts/playstore/generate-graphics.mjs +++ b/scripts/playstore/generate-graphics.mjs @@ -15,10 +15,12 @@ const workspaceRoot = fsSync.existsSync("/home/jeppe/pleno-workspace/frontend/pa ? "/home/jeppe/pleno-workspace" : path.resolve(projectRoot, ".."); const outputRoot = path.join(workspaceRoot, "playstoregraphics"); +const appStoreScreenshotRoot = path.join(projectRoot, "fastlane/screenshots/da-DK"); const baseUrl = process.env.PLAYSTORE_GRAPHICS_BASE_URL || "http://127.0.0.1:5179"; const devPort = new URL(baseUrl).port || "5179"; const devHost = new URL(baseUrl).hostname || "127.0.0.1"; const generatedAt = new Date().toISOString(); +const appStoreScreenshotsOnly = process.argv.includes("--app-store-screenshots"); const disallowedRoutePatterns = [ /^\/admin(?:\/|$)/i, @@ -81,6 +83,29 @@ const deviceProfiles = [ }, ]; +const appStoreDeviceProfiles = [ + { + key: "iphone-6.9", + outputRoot: appStoreScreenshotRoot, + fileNamePrefix: "iphone-6.9-", + viewport: { width: 440, height: 956 }, + deviceScaleFactor: 3, + isMobile: true, + hasTouch: true, + expected: { width: 1320, height: 2868 }, + }, + { + key: "ipad-13", + outputRoot: appStoreScreenshotRoot, + fileNamePrefix: "ipad-13-", + viewport: { width: 768, height: 1024 }, + deviceScaleFactor: 2.6875, + isMobile: true, + hasTouch: true, + expected: { width: 2064, height: 2752 }, + }, +]; + const screenshotScenes = [ { key: "dashboard", @@ -197,7 +222,7 @@ const screenshotScenes = [ timeout: 20_000, }); - if (device?.key === "phone") { + if (device?.key === "phone" || device?.key === "iphone-6.9") { await page.waitForFunction( () => { const nextButton = document.querySelector('[data-testid="booking-mobile-next"]'); @@ -362,7 +387,7 @@ const products = [ const demoPosFixture = createPosFixture({ departments: [ { id: 1, name: "Roskilde", exclude_from_invoicing: false }, - { id: 12, name: "Taastrup", exclude_from_invoicing: false }, + { id: 12, name: "Taastrup", exclude_from_invoicing: false, bookingsystem_time_based_enabled: true }, ], products, departmentCategories: [ @@ -726,7 +751,10 @@ const demoSelfServe = { }; async function ensureDirectories() { - await Promise.all(requiredDirectories.map((directory) => fs.mkdir(path.join(outputRoot, directory), { recursive: true }))); + await Promise.all([ + ...requiredDirectories.map((directory) => fs.mkdir(path.join(outputRoot, directory), { recursive: true })), + fs.mkdir(appStoreScreenshotRoot, { recursive: true }), + ]); } function isDisallowedRoute(routePath) { @@ -857,7 +885,7 @@ async function installCommonPageState(context, page) { async function setupMockApi(page, mode) { const baseOptions = { authenticated: true, - permissions: ["user"], + permissions: ["user", "add_own_department_selfserve_vehicle_conditions"], sessionData: demoSession, edgeGateways: false, workerVersion: "playstore-graphics", @@ -977,7 +1005,12 @@ async function captureScene(browser, device, scene) { await page.evaluate(() => window.scrollTo(0, 0)); await page.waitForTimeout(350); - const outputPath = path.join(outputRoot, device.screenshotDir, scene.fileName); + const captureRoot = device.outputRoot || outputRoot; + const outputPath = path.join( + captureRoot, + device.screenshotDir || "", + `${device.fileNamePrefix || ""}${scene.fileName}`, + ); await page.screenshot({ path: outputPath, type: "jpeg", @@ -993,7 +1026,8 @@ async function captureScene(browser, device, scene) { type: "screenshot", scene: scene.key, route: currentPath, - path: path.relative(outputRoot, outputPath), + path: path.relative(captureRoot, outputPath), + ...(device.outputRoot ? { absolutePath: outputPath } : {}), altText: scene.altText, expected: device.expected, }; @@ -1400,7 +1434,7 @@ async function createFeatureGraphicVariants(browser) { } async function validateAsset(entry) { - const absolutePath = path.join(outputRoot, entry.path); + const absolutePath = entry.absolutePath || path.join(outputRoot, entry.path); const metadata = await readImageMetadata(absolutePath); if (metadata.width !== entry.expected.width || metadata.height !== entry.expected.height) { throw new Error( @@ -1472,17 +1506,23 @@ async function run() { const entries = []; try { - entries.push(await copyAndValidateIcon()); - - for (const device of deviceProfiles) { + const captureDevices = appStoreScreenshotsOnly ? appStoreDeviceProfiles : deviceProfiles; + for (const device of captureDevices) { for (const scene of screenshotScenes) { entries.push(await captureScene(browser, device, scene)); } } - entries.push(await createFeatureGraphic(browser)); - entries.push(...(await createFeatureGraphicVariants(browser))); - await writeMetadata(entries); + if (appStoreScreenshotsOnly) { + for (const entry of entries) { + await validateAsset(entry); + } + } else { + entries.unshift(await copyAndValidateIcon()); + entries.push(await createFeatureGraphic(browser)); + entries.push(...(await createFeatureGraphicVariants(browser))); + await writeMetadata(entries); + } } finally { await browser.close(); if (server) { @@ -1494,7 +1534,11 @@ async function run() { } } - console.log(`Generated ${entries.length} Play Store graphics in ${outputRoot}`); + if (appStoreScreenshotsOnly) { + console.log(`Generated ${entries.length} App Store screenshots in ${appStoreScreenshotRoot}`); + } else { + console.log(`Generated ${entries.length} Play Store graphics in ${outputRoot}`); + } } run().catch((error) => { diff --git a/store_icon.png b/store_icon.png index 915fe0eb..53d893ff 100644 Binary files a/store_icon.png and b/store_icon.png differ