Update PWA assets and enhance UI components for improved user experience

- Replaced outdated favicon and app icons with new PNG assets for better scalability and visual quality.
- Updated index.html and manifest.json to reflect new icon paths and improve PWA support.
- Added a script in package.json to generate PWA icons automatically.
- Enhanced AppLauncherOverlay.vue with a refresh button for better user interaction.
- Improved SplashScreen.vue with new transition effects for a more engaging user experience.
This commit is contained in:
Dorian 2026-02-18 10:10:12 +00:00
parent d6ecf5ea2f
commit e6fb1d20be
17 changed files with 790 additions and 145 deletions

Binary file not shown.

View File

@ -82,7 +82,7 @@ define(['./workbox-21a80088'], (function (workbox) { 'use strict';
"revision": "3ca0b8505b4bec776b69afdba2768812"
}, {
"url": "index.html",
"revision": "0.lheu907255"
"revision": "0.b6sm1j93jm8"
}], {});
workbox.cleanupOutdatedCaches();
workbox.registerRoute(new workbox.NavigationRoute(workbox.createHandlerBoundToURL("index.html"), {

View File

@ -2,16 +2,15 @@
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" href="/favicon.ico" sizes="48x48" />
<link rel="icon" type="image/svg+xml" href="/assets/icon/favico-black.svg" />
<link rel="apple-touch-icon" href="/assets/icon/favico-black.svg" />
<link rel="apple-touch-icon" sizes="72x72" href="/assets/icon/favico-black.svg" />
<link rel="apple-touch-icon" sizes="96x96" href="/assets/icon/favico-black.svg" />
<link rel="apple-touch-icon" sizes="128x128" href="/assets/icon/favico-black.svg" />
<link rel="apple-touch-icon" sizes="144x144" href="/assets/icon/favico-black.svg" />
<link rel="apple-touch-icon" sizes="152x152" href="/assets/icon/favico-black.svg" />
<link rel="apple-touch-icon" sizes="180x180" href="/assets/icon/favico-black.svg" />
<link rel="apple-touch-icon" sizes="192x192" href="/assets/icon/favico-black.svg" />
<link rel="apple-touch-icon" sizes="512x512" href="/assets/icon/favico-black.svg" />
<link rel="icon" type="image/png" sizes="64x64" href="/assets/icon/pwa-64x64.png" />
<link rel="icon" type="image/png" sizes="192x192" href="/assets/icon/pwa-192x192.png" />
<link rel="icon" type="image/png" sizes="512x512" href="/assets/icon/pwa-512x512.png" />
<link rel="apple-touch-icon" href="/assets/icon/apple-touch-icon-180x180.png" />
<link rel="apple-touch-icon" sizes="180x180" href="/assets/icon/apple-touch-icon-180x180.png" />
<link rel="apple-touch-icon" sizes="192x192" href="/assets/icon/pwa-192x192.png" />
<link rel="apple-touch-icon" sizes="512x512" href="/assets/icon/pwa-512x512.png" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover" />
<meta name="description" content="Archipelago - Your sovereign personal server" />
<meta name="theme-color" content="#000000" />
@ -21,7 +20,7 @@
<meta name="apple-mobile-web-app-title" content="Archipelago" />
<meta name="application-name" content="Archipelago" />
<meta name="msapplication-TileColor" content="#000000" />
<meta name="msapplication-TileImage" content="/assets/icon/favico-black.svg" />
<meta name="msapplication-TileImage" content="/assets/icon/pwa-192x192.png" />
<link rel="manifest" href="/manifest.webmanifest" />
<title>Archipelago OS</title>
</head>

View File

@ -17,6 +17,7 @@
},
"devDependencies": {
"@types/node": "^24.10.0",
"@vite-pwa/assets-generator": "^1.0.2",
"@vitejs/plugin-vue": "^6.0.1",
"@vue/tsconfig": "^0.8.1",
"autoprefixer": "^10.4.22",
@ -1666,6 +1667,24 @@
"integrity": "sha512-wMue2Sy4GAVTk6Ic4tJVcnfdau+gx2EnG7S+uAEe+TWJFqE4YoWN4/H8MSLj4eYJKxGg26lZwboEniNiNwZQ6Q==",
"license": "Apache-2.0"
},
"node_modules/@canvas/image-data": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/@canvas/image-data/-/image-data-1.1.0.tgz",
"integrity": "sha512-QdObRRjRbcXGmM1tmJ+MrHcaz1MftF2+W7YI+MsphnsCrmtyfS0d5qJbk0MeSbUeyM/jCb0hmnkXPsy026L7dA==",
"dev": true,
"license": "MIT"
},
"node_modules/@emnapi/runtime": {
"version": "1.8.1",
"resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.8.1.tgz",
"integrity": "sha512-mehfKSMWjjNol8659Z8KxEMrdSJDDot5SXMq00dM8BN4o+CLNXQ0xH2V7EchNHV4RmbZLmmPdEaXZc5H2FXmDg==",
"dev": true,
"license": "MIT",
"optional": true,
"dependencies": {
"tslib": "^2.4.0"
}
},
"node_modules/@esbuild/aix-ppc64": {
"version": "0.27.2",
"resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.2.tgz",
@ -2157,6 +2176,386 @@
"node": ">=6"
}
},
"node_modules/@img/sharp-darwin-arm64": {
"version": "0.33.5",
"resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.33.5.tgz",
"integrity": "sha512-UT4p+iz/2H4twwAoLCqfA9UH5pI6DggwKEGuaPy7nCVQ8ZsiY5PIcrRvD1DzuY3qYL07NtIQcWnBSY/heikIFQ==",
"cpu": [
"arm64"
],
"dev": true,
"license": "Apache-2.0",
"optional": true,
"os": [
"darwin"
],
"engines": {
"node": "^18.17.0 || ^20.3.0 || >=21.0.0"
},
"funding": {
"url": "https://opencollective.com/libvips"
},
"optionalDependencies": {
"@img/sharp-libvips-darwin-arm64": "1.0.4"
}
},
"node_modules/@img/sharp-darwin-x64": {
"version": "0.33.5",
"resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.33.5.tgz",
"integrity": "sha512-fyHac4jIc1ANYGRDxtiqelIbdWkIuQaI84Mv45KvGRRxSAa7o7d1ZKAOBaYbnepLC1WqxfpimdeWfvqqSGwR2Q==",
"cpu": [
"x64"
],
"dev": true,
"license": "Apache-2.0",
"optional": true,
"os": [
"darwin"
],
"engines": {
"node": "^18.17.0 || ^20.3.0 || >=21.0.0"
},
"funding": {
"url": "https://opencollective.com/libvips"
},
"optionalDependencies": {
"@img/sharp-libvips-darwin-x64": "1.0.4"
}
},
"node_modules/@img/sharp-libvips-darwin-arm64": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.0.4.tgz",
"integrity": "sha512-XblONe153h0O2zuFfTAbQYAX2JhYmDHeWikp1LM9Hul9gVPjFY427k6dFEcOL72O01QxQsWi761svJ/ev9xEDg==",
"cpu": [
"arm64"
],
"dev": true,
"license": "LGPL-3.0-or-later",
"optional": true,
"os": [
"darwin"
],
"funding": {
"url": "https://opencollective.com/libvips"
}
},
"node_modules/@img/sharp-libvips-darwin-x64": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.0.4.tgz",
"integrity": "sha512-xnGR8YuZYfJGmWPvmlunFaWJsb9T/AO2ykoP3Fz/0X5XV2aoYBPkX6xqCQvUTKKiLddarLaxpzNe+b1hjeWHAQ==",
"cpu": [
"x64"
],
"dev": true,
"license": "LGPL-3.0-or-later",
"optional": true,
"os": [
"darwin"
],
"funding": {
"url": "https://opencollective.com/libvips"
}
},
"node_modules/@img/sharp-libvips-linux-arm": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.0.5.tgz",
"integrity": "sha512-gvcC4ACAOPRNATg/ov8/MnbxFDJqf/pDePbBnuBDcjsI8PssmjoKMAz4LtLaVi+OnSb5FK/yIOamqDwGmXW32g==",
"cpu": [
"arm"
],
"dev": true,
"license": "LGPL-3.0-or-later",
"optional": true,
"os": [
"linux"
],
"funding": {
"url": "https://opencollective.com/libvips"
}
},
"node_modules/@img/sharp-libvips-linux-arm64": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.0.4.tgz",
"integrity": "sha512-9B+taZ8DlyyqzZQnoeIvDVR/2F4EbMepXMc/NdVbkzsJbzkUjhXv/70GQJ7tdLA4YJgNP25zukcxpX2/SueNrA==",
"cpu": [
"arm64"
],
"dev": true,
"license": "LGPL-3.0-or-later",
"optional": true,
"os": [
"linux"
],
"funding": {
"url": "https://opencollective.com/libvips"
}
},
"node_modules/@img/sharp-libvips-linux-s390x": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.0.4.tgz",
"integrity": "sha512-u7Wz6ntiSSgGSGcjZ55im6uvTrOxSIS8/dgoVMoiGE9I6JAfU50yH5BoDlYA1tcuGS7g/QNtetJnxA6QEsCVTA==",
"cpu": [
"s390x"
],
"dev": true,
"license": "LGPL-3.0-or-later",
"optional": true,
"os": [
"linux"
],
"funding": {
"url": "https://opencollective.com/libvips"
}
},
"node_modules/@img/sharp-libvips-linux-x64": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.0.4.tgz",
"integrity": "sha512-MmWmQ3iPFZr0Iev+BAgVMb3ZyC4KeFc3jFxnNbEPas60e1cIfevbtuyf9nDGIzOaW9PdnDciJm+wFFaTlj5xYw==",
"cpu": [
"x64"
],
"dev": true,
"license": "LGPL-3.0-or-later",
"optional": true,
"os": [
"linux"
],
"funding": {
"url": "https://opencollective.com/libvips"
}
},
"node_modules/@img/sharp-libvips-linuxmusl-arm64": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.0.4.tgz",
"integrity": "sha512-9Ti+BbTYDcsbp4wfYib8Ctm1ilkugkA/uscUn6UXK1ldpC1JjiXbLfFZtRlBhjPZ5o1NCLiDbg8fhUPKStHoTA==",
"cpu": [
"arm64"
],
"dev": true,
"license": "LGPL-3.0-or-later",
"optional": true,
"os": [
"linux"
],
"funding": {
"url": "https://opencollective.com/libvips"
}
},
"node_modules/@img/sharp-libvips-linuxmusl-x64": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.0.4.tgz",
"integrity": "sha512-viYN1KX9m+/hGkJtvYYp+CCLgnJXwiQB39damAO7WMdKWlIhmYTfHjwSbQeUK/20vY154mwezd9HflVFM1wVSw==",
"cpu": [
"x64"
],
"dev": true,
"license": "LGPL-3.0-or-later",
"optional": true,
"os": [
"linux"
],
"funding": {
"url": "https://opencollective.com/libvips"
}
},
"node_modules/@img/sharp-linux-arm": {
"version": "0.33.5",
"resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.33.5.tgz",
"integrity": "sha512-JTS1eldqZbJxjvKaAkxhZmBqPRGmxgu+qFKSInv8moZ2AmT5Yib3EQ1c6gp493HvrvV8QgdOXdyaIBrhvFhBMQ==",
"cpu": [
"arm"
],
"dev": true,
"license": "Apache-2.0",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": "^18.17.0 || ^20.3.0 || >=21.0.0"
},
"funding": {
"url": "https://opencollective.com/libvips"
},
"optionalDependencies": {
"@img/sharp-libvips-linux-arm": "1.0.5"
}
},
"node_modules/@img/sharp-linux-arm64": {
"version": "0.33.5",
"resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.33.5.tgz",
"integrity": "sha512-JMVv+AMRyGOHtO1RFBiJy/MBsgz0x4AWrT6QoEVVTyh1E39TrCUpTRI7mx9VksGX4awWASxqCYLCV4wBZHAYxA==",
"cpu": [
"arm64"
],
"dev": true,
"license": "Apache-2.0",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": "^18.17.0 || ^20.3.0 || >=21.0.0"
},
"funding": {
"url": "https://opencollective.com/libvips"
},
"optionalDependencies": {
"@img/sharp-libvips-linux-arm64": "1.0.4"
}
},
"node_modules/@img/sharp-linux-s390x": {
"version": "0.33.5",
"resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.33.5.tgz",
"integrity": "sha512-y/5PCd+mP4CA/sPDKl2961b+C9d+vPAveS33s6Z3zfASk2j5upL6fXVPZi7ztePZ5CuH+1kW8JtvxgbuXHRa4Q==",
"cpu": [
"s390x"
],
"dev": true,
"license": "Apache-2.0",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": "^18.17.0 || ^20.3.0 || >=21.0.0"
},
"funding": {
"url": "https://opencollective.com/libvips"
},
"optionalDependencies": {
"@img/sharp-libvips-linux-s390x": "1.0.4"
}
},
"node_modules/@img/sharp-linux-x64": {
"version": "0.33.5",
"resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.33.5.tgz",
"integrity": "sha512-opC+Ok5pRNAzuvq1AG0ar+1owsu842/Ab+4qvU879ippJBHvyY5n2mxF1izXqkPYlGuP/M556uh53jRLJmzTWA==",
"cpu": [
"x64"
],
"dev": true,
"license": "Apache-2.0",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": "^18.17.0 || ^20.3.0 || >=21.0.0"
},
"funding": {
"url": "https://opencollective.com/libvips"
},
"optionalDependencies": {
"@img/sharp-libvips-linux-x64": "1.0.4"
}
},
"node_modules/@img/sharp-linuxmusl-arm64": {
"version": "0.33.5",
"resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.33.5.tgz",
"integrity": "sha512-XrHMZwGQGvJg2V/oRSUfSAfjfPxO+4DkiRh6p2AFjLQztWUuY/o8Mq0eMQVIY7HJ1CDQUJlxGGZRw1a5bqmd1g==",
"cpu": [
"arm64"
],
"dev": true,
"license": "Apache-2.0",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": "^18.17.0 || ^20.3.0 || >=21.0.0"
},
"funding": {
"url": "https://opencollective.com/libvips"
},
"optionalDependencies": {
"@img/sharp-libvips-linuxmusl-arm64": "1.0.4"
}
},
"node_modules/@img/sharp-linuxmusl-x64": {
"version": "0.33.5",
"resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.33.5.tgz",
"integrity": "sha512-WT+d/cgqKkkKySYmqoZ8y3pxx7lx9vVejxW/W4DOFMYVSkErR+w7mf2u8m/y4+xHe7yY9DAXQMWQhpnMuFfScw==",
"cpu": [
"x64"
],
"dev": true,
"license": "Apache-2.0",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": "^18.17.0 || ^20.3.0 || >=21.0.0"
},
"funding": {
"url": "https://opencollective.com/libvips"
},
"optionalDependencies": {
"@img/sharp-libvips-linuxmusl-x64": "1.0.4"
}
},
"node_modules/@img/sharp-wasm32": {
"version": "0.33.5",
"resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.33.5.tgz",
"integrity": "sha512-ykUW4LVGaMcU9lu9thv85CbRMAwfeadCJHRsg2GmeRa/cJxsVY9Rbd57JcMxBkKHag5U/x7TSBpScF4U8ElVzg==",
"cpu": [
"wasm32"
],
"dev": true,
"license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT",
"optional": true,
"dependencies": {
"@emnapi/runtime": "^1.2.0"
},
"engines": {
"node": "^18.17.0 || ^20.3.0 || >=21.0.0"
},
"funding": {
"url": "https://opencollective.com/libvips"
}
},
"node_modules/@img/sharp-win32-ia32": {
"version": "0.33.5",
"resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.33.5.tgz",
"integrity": "sha512-T36PblLaTwuVJ/zw/LaH0PdZkRz5rd3SmMHX8GSmR7vtNSP5Z6bQkExdSK7xGWyxLw4sUknBuugTelgw2faBbQ==",
"cpu": [
"ia32"
],
"dev": true,
"license": "Apache-2.0 AND LGPL-3.0-or-later",
"optional": true,
"os": [
"win32"
],
"engines": {
"node": "^18.17.0 || ^20.3.0 || >=21.0.0"
},
"funding": {
"url": "https://opencollective.com/libvips"
}
},
"node_modules/@img/sharp-win32-x64": {
"version": "0.33.5",
"resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.33.5.tgz",
"integrity": "sha512-MpY/o8/8kj+EcnxwvrP4aTJSWw/aZ7JIGR4aBeZkZw5B7/Jn+tY9/VNwtcoGmdT7GfggGIU4kygOMSbYnOrAbg==",
"cpu": [
"x64"
],
"dev": true,
"license": "Apache-2.0 AND LGPL-3.0-or-later",
"optional": true,
"os": [
"win32"
],
"engines": {
"node": "^18.17.0 || ^20.3.0 || >=21.0.0"
},
"funding": {
"url": "https://opencollective.com/libvips"
}
},
"node_modules/@isaacs/balanced-match": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/@isaacs/balanced-match/-/balanced-match-4.0.1.tgz",
@ -2370,6 +2769,19 @@
"integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==",
"license": "BSD-3-Clause"
},
"node_modules/@quansync/fs": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@quansync/fs/-/fs-1.0.0.tgz",
"integrity": "sha512-4TJ3DFtlf1L5LDMaM6CanJ/0lckGNtJcMjQ1NAV6zDmA0tEHKZtxNKin8EgPaVX1YzljbxckyT2tJrpQKAtngQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"quansync": "^1.0.0"
},
"funding": {
"url": "https://github.com/sponsors/sxzz"
}
},
"node_modules/@rolldown/pluginutils": {
"version": "1.0.0-beta.53",
"resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.53.tgz",
@ -2864,6 +3276,31 @@
"dev": true,
"license": "MIT"
},
"node_modules/@vite-pwa/assets-generator": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/@vite-pwa/assets-generator/-/assets-generator-1.0.2.tgz",
"integrity": "sha512-MCbrb508JZHqe7bUibmZj/lyojdhLRnfkmyXnkrCM2zVrjTgL89U8UEfInpKTvPeTnxsw2hmyZxnhsdNR6yhwg==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"cac": "^6.7.14",
"colorette": "^2.0.20",
"consola": "^3.4.2",
"sharp": "^0.33.5",
"sharp-ico": "^0.1.5",
"unconfig": "^7.3.1"
},
"bin": {
"pwa-assets-generator": "bin/pwa-assets-generator.mjs"
},
"engines": {
"node": ">=16.14.0"
},
"funding": {
"url": "https://github.com/sponsors/antfu"
}
},
"node_modules/@vitejs/plugin-vue": {
"version": "6.0.3",
"resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-6.0.3.tgz",
@ -3588,6 +4025,16 @@
"node": ">= 0.8"
}
},
"node_modules/cac": {
"version": "6.7.14",
"resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz",
"integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=8"
}
},
"node_modules/call-bind": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz",
@ -3815,6 +4262,20 @@
"url": "https://github.com/chalk/wrap-ansi?sponsor=1"
}
},
"node_modules/color": {
"version": "4.2.3",
"resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz",
"integrity": "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==",
"dev": true,
"license": "MIT",
"dependencies": {
"color-convert": "^2.0.1",
"color-string": "^1.9.0"
},
"engines": {
"node": ">=12.5.0"
}
},
"node_modules/color-convert": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
@ -3833,6 +4294,24 @@
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
"license": "MIT"
},
"node_modules/color-string": {
"version": "1.9.1",
"resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz",
"integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==",
"dev": true,
"license": "MIT",
"dependencies": {
"color-name": "^1.0.0",
"simple-swizzle": "^0.2.2"
}
},
"node_modules/colorette": {
"version": "2.0.20",
"resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz",
"integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==",
"dev": true,
"license": "MIT"
},
"node_modules/commander": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz",
@ -3878,6 +4357,16 @@
"url": "https://github.com/open-cli-tools/concurrently?sponsor=1"
}
},
"node_modules/consola": {
"version": "3.4.2",
"resolved": "https://registry.npmjs.org/consola/-/consola-3.4.2.tgz",
"integrity": "sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==",
"dev": true,
"license": "MIT",
"engines": {
"node": "^14.18.0 || >=16.10.0"
}
},
"node_modules/content-disposition": {
"version": "0.5.4",
"resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz",
@ -4108,6 +4597,35 @@
"ms": "2.0.0"
}
},
"node_modules/decode-bmp": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/decode-bmp/-/decode-bmp-0.2.1.tgz",
"integrity": "sha512-NiOaGe+GN0KJqi2STf24hfMkFitDUaIoUU3eKvP/wAbLe8o6FuW5n/x7MHPR0HKvBokp6MQY/j7w8lewEeVCIA==",
"dev": true,
"license": "MIT",
"dependencies": {
"@canvas/image-data": "^1.0.0",
"to-data-view": "^1.1.0"
},
"engines": {
"node": ">=8.6.0"
}
},
"node_modules/decode-ico": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/decode-ico/-/decode-ico-0.4.1.tgz",
"integrity": "sha512-69NZfbKIzux1vBOd31al3XnMnH+2mqDhEgLdpygErm4d60N+UwA5Sq5WFjmEDQzumgB9fElojGwWG0vybVfFmA==",
"dev": true,
"license": "MIT",
"dependencies": {
"@canvas/image-data": "^1.0.0",
"decode-bmp": "^0.2.0",
"to-data-view": "^1.1.0"
},
"engines": {
"node": ">=8.6"
}
},
"node_modules/deepmerge": {
"version": "4.3.1",
"resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz",
@ -4154,6 +4672,13 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/defu": {
"version": "6.1.4",
"resolved": "https://registry.npmjs.org/defu/-/defu-6.1.4.tgz",
"integrity": "sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==",
"dev": true,
"license": "MIT"
},
"node_modules/depd": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
@ -4175,6 +4700,16 @@
"npm": "1.2.8000 || >= 1.4.16"
}
},
"node_modules/detect-libc": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz",
"integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==",
"dev": true,
"license": "Apache-2.0",
"engines": {
"node": ">=8"
}
},
"node_modules/didyoumean": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz",
@ -5176,6 +5711,13 @@
"url": "https://opencollective.com/express"
}
},
"node_modules/ico-endec": {
"version": "0.1.6",
"resolved": "https://registry.npmjs.org/ico-endec/-/ico-endec-0.1.6.tgz",
"integrity": "sha512-ZdLU38ZoED3g1j3iEyzcQj+wAkY2xfWNkymszfJPoxucIUhK7NayQ+/C4Kv0nDFMIsbtbEHldv3V8PU494/ueQ==",
"dev": true,
"license": "MPL-2.0"
},
"node_modules/iconv-lite": {
"version": "0.4.24",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
@ -5265,6 +5807,13 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/is-arrayish": {
"version": "0.3.4",
"resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.4.tgz",
"integrity": "sha512-m6UrgzFVUYawGBh1dUsWR5M2Clqic9RVXC/9f8ceNlv2IcO9j9J/z8UoCLPqtsPBFNzEpfR3xftohbfqDx8EQA==",
"dev": true,
"license": "MIT"
},
"node_modules/is-async-function": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.1.1.tgz",
@ -6645,6 +7194,23 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/quansync": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/quansync/-/quansync-1.0.0.tgz",
"integrity": "sha512-5xZacEEufv3HSTPQuchrvV6soaiACMFnq1H8wkVioctoH3TRha9Sz66lOxRwPK/qZj7HPiSveih9yAyh98gvqA==",
"dev": true,
"funding": [
{
"type": "individual",
"url": "https://github.com/sponsors/antfu"
},
{
"type": "individual",
"url": "https://github.com/sponsors/sxzz"
}
],
"license": "MIT"
},
"node_modules/queue-microtask": {
"version": "1.2.3",
"resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
@ -7182,6 +7748,71 @@
"dev": true,
"license": "ISC"
},
"node_modules/sharp": {
"version": "0.33.5",
"resolved": "https://registry.npmjs.org/sharp/-/sharp-0.33.5.tgz",
"integrity": "sha512-haPVm1EkS9pgvHrQ/F3Xy+hgcuMV0Wm9vfIBSiwZ05k+xgb0PkBQpGsAA/oWdDobNaZTH5ppvHtzCFbnSEwHVw==",
"dev": true,
"hasInstallScript": true,
"license": "Apache-2.0",
"dependencies": {
"color": "^4.2.3",
"detect-libc": "^2.0.3",
"semver": "^7.6.3"
},
"engines": {
"node": "^18.17.0 || ^20.3.0 || >=21.0.0"
},
"funding": {
"url": "https://opencollective.com/libvips"
},
"optionalDependencies": {
"@img/sharp-darwin-arm64": "0.33.5",
"@img/sharp-darwin-x64": "0.33.5",
"@img/sharp-libvips-darwin-arm64": "1.0.4",
"@img/sharp-libvips-darwin-x64": "1.0.4",
"@img/sharp-libvips-linux-arm": "1.0.5",
"@img/sharp-libvips-linux-arm64": "1.0.4",
"@img/sharp-libvips-linux-s390x": "1.0.4",
"@img/sharp-libvips-linux-x64": "1.0.4",
"@img/sharp-libvips-linuxmusl-arm64": "1.0.4",
"@img/sharp-libvips-linuxmusl-x64": "1.0.4",
"@img/sharp-linux-arm": "0.33.5",
"@img/sharp-linux-arm64": "0.33.5",
"@img/sharp-linux-s390x": "0.33.5",
"@img/sharp-linux-x64": "0.33.5",
"@img/sharp-linuxmusl-arm64": "0.33.5",
"@img/sharp-linuxmusl-x64": "0.33.5",
"@img/sharp-wasm32": "0.33.5",
"@img/sharp-win32-ia32": "0.33.5",
"@img/sharp-win32-x64": "0.33.5"
}
},
"node_modules/sharp-ico": {
"version": "0.1.5",
"resolved": "https://registry.npmjs.org/sharp-ico/-/sharp-ico-0.1.5.tgz",
"integrity": "sha512-a3jODQl82NPp1d5OYb0wY+oFaPk7AvyxipIowCHk7pBsZCWgbe0yAkU2OOXdoH0ENyANhyOQbs9xkAiRHcF02Q==",
"dev": true,
"license": "MIT",
"dependencies": {
"decode-ico": "*",
"ico-endec": "*",
"sharp": "*"
}
},
"node_modules/sharp/node_modules/semver": {
"version": "7.7.4",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz",
"integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==",
"dev": true,
"license": "ISC",
"bin": {
"semver": "bin/semver.js"
},
"engines": {
"node": ">=10"
}
},
"node_modules/shebang-command": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
@ -7307,6 +7938,16 @@
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/simple-swizzle": {
"version": "0.2.4",
"resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.4.tgz",
"integrity": "sha512-nAu1WFPQSMNr2Zn9PGSZK9AGn4t/y97lEm+MXTtUDwfP0ksAIX4nO+6ruD9Jwut4C49SB1Ws+fbXsm/yScWOHw==",
"dev": true,
"license": "MIT",
"dependencies": {
"is-arrayish": "^0.3.1"
}
},
"node_modules/smob": {
"version": "1.5.0",
"resolved": "https://registry.npmjs.org/smob/-/smob-1.5.0.tgz",
@ -7905,6 +8546,13 @@
"url": "https://github.com/sponsors/jonschlinkert"
}
},
"node_modules/to-data-view": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/to-data-view/-/to-data-view-1.1.0.tgz",
"integrity": "sha512-1eAdufMg6mwgmlojAx3QeMnzB/BTVp7Tbndi3U7ftcT2zCZadjxkkmLmd97zmaxWi+sgGcgWrokmpEoy0Dn0vQ==",
"dev": true,
"license": "MIT"
},
"node_modules/to-regex-range": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
@ -8107,6 +8755,47 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/unconfig": {
"version": "7.5.0",
"resolved": "https://registry.npmjs.org/unconfig/-/unconfig-7.5.0.tgz",
"integrity": "sha512-oi8Qy2JV4D3UQ0PsopR28CzdQ3S/5A1zwsUwp/rosSbfhJ5z7b90bIyTwi/F7hCLD4SGcZVjDzd4XoUQcEanvA==",
"dev": true,
"license": "MIT",
"dependencies": {
"@quansync/fs": "^1.0.0",
"defu": "^6.1.4",
"jiti": "^2.6.1",
"quansync": "^1.0.0",
"unconfig-core": "7.5.0"
},
"funding": {
"url": "https://github.com/sponsors/antfu"
}
},
"node_modules/unconfig-core": {
"version": "7.5.0",
"resolved": "https://registry.npmjs.org/unconfig-core/-/unconfig-core-7.5.0.tgz",
"integrity": "sha512-Su3FauozOGP44ZmKdHy2oE6LPjk51M/TRRjHv2HNCWiDvfvCoxC2lno6jevMA91MYAdCdwP05QnWdWpSbncX/w==",
"dev": true,
"license": "MIT",
"dependencies": {
"@quansync/fs": "^1.0.0",
"quansync": "^1.0.0"
},
"funding": {
"url": "https://github.com/sponsors/antfu"
}
},
"node_modules/unconfig/node_modules/jiti": {
"version": "2.6.1",
"resolved": "https://registry.npmjs.org/jiti/-/jiti-2.6.1.tgz",
"integrity": "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==",
"dev": true,
"license": "MIT",
"bin": {
"jiti": "lib/jiti-cli.mjs"
}
},
"node_modules/undici-types": {
"version": "7.16.0",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz",

View File

@ -17,6 +17,7 @@
"preview": "vite preview",
"type-check": "vue-tsc --noEmit",
"prebuild": "cp ../../loop-start.mp3 public/assets/audio/ 2>/dev/null || true",
"generate-pwa-icons": "pwa-assets-generator --preset minimal-2023 public/assets/icon/favico-black.svg && cp public/assets/icon/favicon.ico public/favicon.ico",
"generate-welcome-speech": "node scripts/generate-welcome-speech.js"
},
"dependencies": {
@ -29,6 +30,7 @@
},
"devDependencies": {
"@types/node": "^24.10.0",
"@vite-pwa/assets-generator": "^1.0.2",
"@vitejs/plugin-vue": "^6.0.1",
"@vue/tsconfig": "^0.8.1",
"autoprefixer": "^10.4.22",

Binary file not shown.

After

Width:  |  Height:  |  Size: 363 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 356 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 417 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 287 B

BIN
neode-ui/public/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 356 B

View File

@ -1,43 +1 @@
{
"name": "Archipelago",
"short_name": "Archipelago",
"description": "Your sovereign personal server",
"theme_color": "#000000",
"background_color": "#000000",
"display": "standalone",
"orientation": "any",
"scope": "/",
"start_url": "/",
"id": "/",
"icons": [
{
"src": "/assets/img/favico.png",
"sizes": "192x192",
"type": "image/png",
"purpose": "any maskable"
},
{
"src": "/assets/img/favico.png",
"sizes": "512x512",
"type": "image/png",
"purpose": "any maskable"
}
],
"categories": ["utilities", "productivity"],
"screenshots": [],
"shortcuts": [
{
"name": "Dashboard",
"short_name": "Dashboard",
"description": "Open the dashboard",
"url": "/dashboard",
"icons": [
{
"src": "/assets/img/favico.png",
"sizes": "192x192"
}
]
}
]
}
{"name":"Archipelago","short_name":"Archipelago","description":"Your sovereign personal server","theme_color":"#000000","background_color":"#000000","display":"standalone","orientation":"any","scope":"/","start_url":"/","id":"/","icons":[{"src":"/assets/icon/pwa-192x192.png","sizes":"192x192","type":"image/png","purpose":"any"},{"src":"/assets/icon/pwa-512x512.png","sizes":"512x512","type":"image/png","purpose":"any"},{"src":"/assets/icon/maskable-icon-512x512.png","sizes":"512x512","type":"image/png","purpose":"maskable"}],"categories":["utilities","productivity"],"screenshots":[],"shortcuts":[{"name":"Dashboard","short_name":"Dashboard","description":"Open the dashboard","url":"/dashboard","icons":[{"src":"/assets/icon/pwa-192x192.png","sizes":"192x192"}]}]}

View File

@ -22,6 +22,23 @@
</svg>
</div>
<span class="flex-1 truncate text-sm font-medium text-white/90">{{ store.title || 'App' }}</span>
<button
type="button"
class="flex items-center justify-center w-9 h-9 rounded-lg hover:bg-white/15 text-white/70 hover:text-white transition-colors disabled:opacity-70"
aria-label="Refresh"
:disabled="isRefreshing"
@click="refreshIframe"
>
<svg
class="w-5 h-5 transition-transform duration-300"
:class="{ 'animate-spin': isRefreshing }"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
>
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15" />
</svg>
</button>
<button
ref="closeBtnRef"
type="button"
@ -41,10 +58,11 @@
<iframe
ref="iframeRef"
v-if="store.url"
:key="iframeRefreshKey"
:src="store.url"
class="absolute inset-0 w-full h-full border-0 iframe-scrollbar-hide"
title="App content"
@load="injectScrollbarHideIfSameOrigin"
@load="onIframeLoad"
/>
</div>
</div>
@ -60,6 +78,18 @@ import { useAppLauncherStore } from '@/stores/appLauncher'
const store = useAppLauncherStore()
const closeBtnRef = ref<HTMLButtonElement | null>(null)
const iframeRef = ref<HTMLIFrameElement | null>(null)
const iframeRefreshKey = ref(0)
const isRefreshing = ref(false)
function refreshIframe() {
isRefreshing.value = true
iframeRefreshKey.value++
}
function onIframeLoad() {
injectScrollbarHideIfSameOrigin()
isRefreshing.value = false
}
function injectScrollbarHideIfSameOrigin() {
try {
@ -95,6 +125,8 @@ watch(
(open) => {
if (open) {
closeBtnRef.value?.focus()
} else {
isRefreshing.value = false
}
}
)

View File

@ -99,14 +99,21 @@
<!-- Tap to start - logo + "Enter the Exit" behind (like screensaver) -->
<div
v-if="showTapToStart"
class="absolute inset-0 z-[100] flex items-center justify-center bg-black/40 cursor-pointer"
class="absolute inset-0 z-[100] flex items-center justify-center cursor-pointer overflow-hidden"
:class="tapStartTransitioning ? 'tap-overlay-zoom-out' : 'bg-black/40'"
@click="handleTapToStart"
>
<div class="tap-to-start-content relative flex items-center justify-center">
<span class="tap-to-start-text font-archipelago font-extrabold text-[rgba(0,0,0,0.35)] text-6xl sm:text-7xl md:text-8xl lg:text-9xl tracking-widest uppercase whitespace-nowrap select-none">
<div class="tap-to-start-content relative flex items-center justify-center perspective-1000">
<span
class="tap-to-start-text font-archipelago font-extrabold text-[rgba(0,0,0,0.35)] text-6xl sm:text-7xl md:text-8xl lg:text-9xl tracking-widest uppercase whitespace-nowrap select-none transition-opacity duration-300"
:class="{ 'opacity-0': tapStartTransitioning }"
>
Enter the Exit
</span>
<div class="tap-to-start-logo absolute">
<div
class="tap-to-start-logo absolute"
:class="{ 'tap-logo-launch': tapStartTransitioning }"
>
<ScreensaverLogo />
</div>
</div>
@ -144,6 +151,7 @@ const BLINK_AFTER_TYPING = 1500
const showSplash = ref(true)
const showTapToStart = ref(true)
const tapStartTransitioning = ref(false)
const backgroundOpacity = ref(0)
const alienIntroComplete = ref(false)
const fadeAlienIntro = ref(false)
@ -232,10 +240,15 @@ watch([showWelcome, showLogo], ([welcome, logo]) => {
const seenIntro = localStorage.getItem('neode_intro_seen') === '1'
function handleTapToStart() {
if (!showTapToStart.value) return
if (!showTapToStart.value || tapStartTransitioning.value) return
resumeAudioContext()
showTapToStart.value = false
startAlienIntro()
tapStartTransitioning.value = true
// Logo: grow (150ms) then zoom out to background (850ms). Total 1s.
setTimeout(() => {
showTapToStart.value = false
tapStartTransitioning.value = false
startAlienIntro()
}, 1000)
}
function handleSkipClick() {
@ -573,6 +586,32 @@ onBeforeUnmount(() => {
transform: scale(1.15);
}
/* Tap to start - logo grow then zoom out to background */
.tap-overlay-zoom-out {
background-color: rgba(0, 0, 0, 0.4);
transition: background-color 0.6s cubic-bezier(0.4, 0, 0.2, 1);
animation: tap-overlay-fade 1s ease-out forwards;
}
@keyframes tap-overlay-fade {
0% { background-color: rgba(0, 0, 0, 0.4); }
30% { background-color: rgba(0, 0, 0, 0.35); }
100% { background-color: rgba(0, 0, 0, 0); }
}
.perspective-1000 {
perspective: 1000px;
}
.tap-logo-launch {
animation: tap-logo-launch 1s cubic-bezier(0.22, 1, 0.36, 1) forwards;
transform-origin: center center;
will-change: transform, opacity;
}
@keyframes tap-logo-launch {
0% { transform: scale(1); opacity: 1; }
15% { transform: scale(1.2); opacity: 1; }
25% { transform: scale(1.15); opacity: 1; }
100% { transform: scale(0); opacity: 0; }
}
/* Tap to start - "Enter the Exit" big behind logo */
.tap-to-start-content {
min-height: 12rem;

View File

@ -9,7 +9,7 @@ export default defineConfig({
vue(),
VitePWA({
registerType: 'autoUpdate',
includeAssets: ['assets/icon/favico-black.svg', 'favico.svg', 'favicon.ico'],
includeAssets: ['assets/icon/favico-black.svg', 'assets/icon/pwa-192x192.png', 'assets/icon/pwa-512x512.png', 'assets/icon/apple-touch-icon-180x180.png', 'favicon.ico'],
manifest: {
name: 'Archipelago',
short_name: 'Archipelago',
@ -23,89 +23,15 @@ export default defineConfig({
categories: ['productivity', 'utilities'],
prefer_related_applications: false,
icons: [
{
src: '/assets/icon/favico-black.svg',
sizes: '72x72',
type: 'image/svg+xml',
purpose: 'any'
},
{
src: '/assets/icon/favico-black.svg',
sizes: '96x96',
type: 'image/svg+xml',
purpose: 'any'
},
{
src: '/assets/icon/favico-black.svg',
sizes: '128x128',
type: 'image/svg+xml',
purpose: 'any'
},
{
src: '/assets/icon/favico-black.svg',
sizes: '144x144',
type: 'image/svg+xml',
purpose: 'any'
},
{
src: '/assets/icon/favico-black.svg',
sizes: '152x152',
type: 'image/svg+xml',
purpose: 'any'
},
{
src: '/assets/icon/favico-black.svg',
sizes: '192x192',
type: 'image/svg+xml',
purpose: 'any'
},
{
src: '/assets/icon/favico-black.svg',
sizes: '384x384',
type: 'image/svg+xml',
purpose: 'any'
},
{
src: '/assets/icon/favico-black.svg',
sizes: '512x512',
type: 'image/svg+xml',
purpose: 'any'
},
{
src: '/assets/icon/favico-black.svg',
sizes: '192x192',
type: 'image/svg+xml',
purpose: 'maskable'
},
{
src: '/assets/icon/favico-black.svg',
sizes: '512x512',
type: 'image/svg+xml',
purpose: 'maskable'
}
{ src: '/assets/icon/pwa-64x64.png', sizes: '64x64', type: 'image/png', purpose: 'any' },
{ src: '/assets/icon/pwa-192x192.png', sizes: '192x192', type: 'image/png', purpose: 'any' },
{ src: '/assets/icon/pwa-512x512.png', sizes: '512x512', type: 'image/png', purpose: 'any' },
{ src: '/assets/icon/maskable-icon-512x512.png', sizes: '512x512', type: 'image/png', purpose: 'maskable' }
],
shortcuts: [
{
name: 'Dashboard',
short_name: 'Dashboard',
description: 'Open the dashboard',
url: '/dashboard',
icons: [{ src: '/assets/icon/favico-black.svg', sizes: '192x192' }]
},
{
name: 'My Apps',
short_name: 'Apps',
description: 'Manage your apps',
url: '/apps',
icons: [{ src: '/assets/icon/favico-black.svg', sizes: '192x192' }]
},
{
name: 'App Store',
short_name: 'Store',
description: 'Browse and install apps',
url: '/marketplace',
icons: [{ src: '/assets/icon/favico-black.svg', sizes: '192x192' }]
}
{ name: 'Dashboard', short_name: 'Dashboard', description: 'Open the dashboard', url: '/dashboard', icons: [{ src: '/assets/icon/pwa-192x192.png', sizes: '192x192' }] },
{ name: 'My Apps', short_name: 'Apps', description: 'Manage your apps', url: '/dashboard/apps', icons: [{ src: '/assets/icon/pwa-192x192.png', sizes: '192x192' }] },
{ name: 'App Store', short_name: 'Store', description: 'Browse and install apps', url: '/dashboard/marketplace', icons: [{ src: '/assets/icon/pwa-192x192.png', sizes: '192x192' }] }
]
},
workbox: {