fix: overhaul PWA icons with v2 suffix to bust all cache layers
- Redesign favicon SVG with gradient border matching splash screen - Rename all icon files with -v2 suffix to bypass browser/SW/PWA caches - Delete 9 old/duplicate icon files (~13MB removed) - Add nginx cache-control headers for icons and manifest - Rename assets-cache to assets-cache-v2 to orphan stale SW cache - Update all HTML, manifest, and component icon references Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@ -10,7 +10,7 @@ server {
|
|||||||
location /aiui/ {
|
location /aiui/ {
|
||||||
alias /opt/archipelago/web-ui/aiui/;
|
alias /opt/archipelago/web-ui/aiui/;
|
||||||
index index.html;
|
index index.html;
|
||||||
try_files $uri $uri/ =404;
|
try_files $uri $uri/ /aiui/index.html;
|
||||||
}
|
}
|
||||||
|
|
||||||
# AIUI Claude API proxy — routes through claude-proxy service (port 3141)
|
# AIUI Claude API proxy — routes through claude-proxy service (port 3141)
|
||||||
@ -54,6 +54,12 @@ server {
|
|||||||
return 503 '{"error":"SearXNG is not running"}';
|
return 503 '{"error":"SearXNG is not running"}';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Icons, favicon, manifest — always revalidate (no heuristic caching)
|
||||||
|
location ~* ^/(favicon\.ico|manifest\.webmanifest|assets/icon/) {
|
||||||
|
add_header Cache-Control "no-cache, must-revalidate";
|
||||||
|
try_files $uri =404;
|
||||||
|
}
|
||||||
|
|
||||||
# Serve static files (Vue.js SPA)
|
# Serve static files (Vue.js SPA)
|
||||||
location / {
|
location / {
|
||||||
try_files $uri $uri/ /index.html;
|
try_files $uri $uri/ /index.html;
|
||||||
@ -385,17 +391,23 @@ server {
|
|||||||
proxy_send_timeout 120s;
|
proxy_send_timeout 120s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Icons, favicon, manifest — always revalidate (no heuristic caching)
|
||||||
|
location ~* ^/(favicon\.ico|manifest\.webmanifest|assets/icon/) {
|
||||||
|
add_header Cache-Control "no-cache, must-revalidate";
|
||||||
|
try_files $uri =404;
|
||||||
|
}
|
||||||
|
|
||||||
location / {
|
location / {
|
||||||
try_files $uri $uri/ /index.html;
|
try_files $uri $uri/ /index.html;
|
||||||
}
|
}
|
||||||
|
|
||||||
location /archipelago/ {
|
location /archipelago/ {
|
||||||
proxy_pass http://127.0.0.1:5678;
|
proxy_pass http://127.0.0.1:5678;
|
||||||
proxy_http_version 1.1;
|
proxy_http_version 1.1;
|
||||||
proxy_set_header Host $host;
|
proxy_set_header Host $host;
|
||||||
proxy_set_header X-Real-IP $remote_addr;
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
location /rpc/ {
|
location /rpc/ {
|
||||||
proxy_pass http://127.0.0.1:5678;
|
proxy_pass http://127.0.0.1:5678;
|
||||||
proxy_http_version 1.1;
|
proxy_http_version 1.1;
|
||||||
@ -405,7 +417,7 @@ server {
|
|||||||
proxy_send_timeout 600s;
|
proxy_send_timeout 600s;
|
||||||
proxy_read_timeout 600s;
|
proxy_read_timeout 600s;
|
||||||
}
|
}
|
||||||
|
|
||||||
location /app/nextcloud/ {
|
location /app/nextcloud/ {
|
||||||
proxy_pass http://127.0.0.1:8085/;
|
proxy_pass http://127.0.0.1:8085/;
|
||||||
proxy_http_version 1.1;
|
proxy_http_version 1.1;
|
||||||
|
|||||||
@ -82,11 +82,12 @@ define(['./workbox-21a80088'], (function (workbox) { 'use strict';
|
|||||||
"revision": "3ca0b8505b4bec776b69afdba2768812"
|
"revision": "3ca0b8505b4bec776b69afdba2768812"
|
||||||
}, {
|
}, {
|
||||||
"url": "index.html",
|
"url": "index.html",
|
||||||
"revision": "0.0ddc43l70qk"
|
"revision": "0.qqvn6d3mva8"
|
||||||
}], {});
|
}], {});
|
||||||
workbox.cleanupOutdatedCaches();
|
workbox.cleanupOutdatedCaches();
|
||||||
workbox.registerRoute(new workbox.NavigationRoute(workbox.createHandlerBoundToURL("index.html"), {
|
workbox.registerRoute(new workbox.NavigationRoute(workbox.createHandlerBoundToURL("index.html"), {
|
||||||
allowlist: [/^\/$/]
|
allowlist: [/^\/$/],
|
||||||
|
denylist: [/^\/app\//, /^\/rpc\//, /^\/ws/, /^\/aiui\//]
|
||||||
}));
|
}));
|
||||||
workbox.registerRoute(/^https:\/\/fonts\.googleapis\.com\/.*/i, new workbox.CacheFirst({
|
workbox.registerRoute(/^https:\/\/fonts\.googleapis\.com\/.*/i, new workbox.CacheFirst({
|
||||||
"cacheName": "google-fonts-cache",
|
"cacheName": "google-fonts-cache",
|
||||||
|
|||||||
@ -2,15 +2,15 @@
|
|||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
<link rel="icon" href="/favicon.ico" sizes="48x48" />
|
<link rel="icon" type="image/svg+xml" href="/assets/icon/favico-black-v2.svg" />
|
||||||
<link rel="icon" type="image/svg+xml" href="/assets/icon/favico-black.svg" />
|
<link rel="icon" href="/favicon-v2.ico" sizes="48x48" />
|
||||||
<link rel="icon" type="image/png" sizes="64x64" href="/assets/icon/pwa-64x64.png" />
|
<link rel="icon" type="image/png" sizes="64x64" href="/assets/icon/pwa-64x64-v2.png" />
|
||||||
<link rel="icon" type="image/png" sizes="192x192" href="/assets/icon/pwa-192x192.png" />
|
<link rel="icon" type="image/png" sizes="192x192" href="/assets/icon/pwa-192x192-v2.png" />
|
||||||
<link rel="icon" type="image/png" sizes="512x512" href="/assets/icon/pwa-512x512.png" />
|
<link rel="icon" type="image/png" sizes="512x512" href="/assets/icon/pwa-512x512-v2.png" />
|
||||||
<link rel="apple-touch-icon" href="/assets/icon/apple-touch-icon-180x180.png" />
|
<link rel="apple-touch-icon" href="/assets/icon/apple-touch-icon-180x180-v2.png" />
|
||||||
<link rel="apple-touch-icon" sizes="180x180" href="/assets/icon/apple-touch-icon-180x180.png" />
|
<link rel="apple-touch-icon" sizes="180x180" href="/assets/icon/apple-touch-icon-180x180-v2.png" />
|
||||||
<link rel="apple-touch-icon" sizes="192x192" href="/assets/icon/pwa-192x192.png" />
|
<link rel="apple-touch-icon" sizes="192x192" href="/assets/icon/pwa-192x192-v2.png" />
|
||||||
<link rel="apple-touch-icon" sizes="512x512" href="/assets/icon/pwa-512x512.png" />
|
<link rel="apple-touch-icon" sizes="512x512" href="/assets/icon/pwa-512x512-v2.png" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover, interactive-widget=resizes-content" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover, interactive-widget=resizes-content" />
|
||||||
<meta name="description" content="Archipelago - Your sovereign personal server" />
|
<meta name="description" content="Archipelago - Your sovereign personal server" />
|
||||||
<meta name="theme-color" content="#000000" />
|
<meta name="theme-color" content="#000000" />
|
||||||
@ -20,7 +20,7 @@
|
|||||||
<meta name="apple-mobile-web-app-title" content="Archipelago" />
|
<meta name="apple-mobile-web-app-title" content="Archipelago" />
|
||||||
<meta name="application-name" content="Archipelago" />
|
<meta name="application-name" content="Archipelago" />
|
||||||
<meta name="msapplication-TileColor" content="#000000" />
|
<meta name="msapplication-TileColor" content="#000000" />
|
||||||
<meta name="msapplication-TileImage" content="/assets/icon/pwa-192x192.png" />
|
<meta name="msapplication-TileImage" content="/assets/icon/pwa-192x192-v2.png" />
|
||||||
<title>Archipelago OS</title>
|
<title>Archipelago OS</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|||||||
@ -235,7 +235,7 @@ async function getDockerContainers() {
|
|||||||
|
|
||||||
const metadata = appMetadata[appId] || {
|
const metadata = appMetadata[appId] || {
|
||||||
title: appId,
|
title: appId,
|
||||||
icon: '/assets/img/favico.png',
|
icon: '/assets/icon/pwa-192x192-v2.png',
|
||||||
description: `${appId} application`
|
description: `${appId} application`
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -342,15 +342,15 @@ async function installPackage(id, manifestUrl) {
|
|||||||
title: 'Amin',
|
title: 'Amin',
|
||||||
shortDesc: 'Administrative interface for Archipelago',
|
shortDesc: 'Administrative interface for Archipelago',
|
||||||
longDesc: 'Amin provides administrative tools and monitoring.',
|
longDesc: 'Amin provides administrative tools and monitoring.',
|
||||||
icon: '/assets/img/favico.png'
|
icon: '/assets/icon/pwa-192x192-v2.png'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const metadata = packageMetadata[id] || {
|
const metadata = packageMetadata[id] || {
|
||||||
title: id.charAt(0).toUpperCase() + id.slice(1),
|
title: id.charAt(0).toUpperCase() + id.slice(1),
|
||||||
shortDesc: `${id} application`,
|
shortDesc: `${id} application`,
|
||||||
longDesc: `${id} application for Archipelago`,
|
longDesc: `${id} application for Archipelago`,
|
||||||
icon: '/assets/img/favico.png'
|
icon: '/assets/icon/pwa-192x192-v2.png'
|
||||||
}
|
}
|
||||||
|
|
||||||
// Determine port
|
// Determine port
|
||||||
|
|||||||
BIN
neode-ui/public/assets/icon/apple-touch-icon-180x180-v2.png
Normal file
|
After Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 363 B |
31
neode-ui/public/assets/icon/favico-black-v2.svg
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
<svg width="1024" height="1024" viewBox="0 0 1024 1024" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<defs>
|
||||||
|
<radialGradient id="bgGrad" cx="50%" cy="45%" r="55%">
|
||||||
|
<stop offset="0%" stop-color="#1a1a1a"/>
|
||||||
|
<stop offset="100%" stop-color="#050505"/>
|
||||||
|
</radialGradient>
|
||||||
|
<linearGradient id="borderGrad" x1="0" y1="0" x2="1024" y2="1024" gradientUnits="userSpaceOnUse">
|
||||||
|
<stop offset="0%" stop-color="#ffffff" stop-opacity="0.55"/>
|
||||||
|
<stop offset="50%" stop-color="#888888" stop-opacity="0.25"/>
|
||||||
|
<stop offset="100%" stop-color="#000000" stop-opacity="0.7"/>
|
||||||
|
</linearGradient>
|
||||||
|
<radialGradient id="glassGlow" cx="35%" cy="30%" r="50%">
|
||||||
|
<stop offset="0%" stop-color="#ffffff" stop-opacity="0.06"/>
|
||||||
|
<stop offset="100%" stop-color="#000000" stop-opacity="0"/>
|
||||||
|
</radialGradient>
|
||||||
|
</defs>
|
||||||
|
|
||||||
|
<!-- Background circle -->
|
||||||
|
<circle cx="512" cy="512" r="484" fill="url(#bgGrad)"/>
|
||||||
|
|
||||||
|
<!-- Glass glow highlight (top-left) -->
|
||||||
|
<circle cx="512" cy="512" r="460" fill="url(#glassGlow)"/>
|
||||||
|
|
||||||
|
<!-- Gradient border ring (white-to-dark, like logo-gradient-border CSS) -->
|
||||||
|
<circle cx="512" cy="512" r="484" fill="none" stroke="url(#borderGrad)" stroke-width="16"/>
|
||||||
|
|
||||||
|
<!-- The "A" logo — pixel-art style, centered and scaled -->
|
||||||
|
<g transform="translate(160, 168) scale(0.69)">
|
||||||
|
<path d="M357.614 388.936V318H428.621V388.936H357.614ZM436.152 388.936V318H508.234V388.936H436.152ZM515.766 388.936V318H587.848V388.936H515.766ZM595.379 388.936V318H666.386V388.936H595.379ZM595.379 468.471V396.46H666.386V468.471H595.379ZM673.917 468.471V396.46H746V468.471H673.917ZM278 548.006V475.994H350.083V548.006H278ZM357.614 548.006V475.994H428.621V548.006H357.614ZM436.152 548.006V475.994H508.234V548.006H436.152ZM515.766 548.006V475.994H587.848V548.006H515.766ZM595.379 548.006V475.994H666.386V548.006H595.379ZM673.917 548.006V475.994H746V548.006H673.917ZM278 626.465V555.529H350.083V626.465H278ZM357.614 626.465V555.529H428.621V626.465H357.614ZM595.379 626.465V555.529H666.386V626.465H595.379ZM673.917 626.465V555.529H746V626.465H673.917ZM357.614 706V633.989H428.621V706H357.614ZM436.152 706V633.989H508.234V706H436.152ZM515.766 706V633.989H587.848V706H515.766ZM595.379 706V633.989H666.386V706H595.379Z" fill="white"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 2.2 KiB |
@ -1,4 +0,0 @@
|
|||||||
<svg width="1024" height="1024" viewBox="0 0 1024 1024" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<rect width="1024" height="1024" fill="#030202"/>
|
|
||||||
<path d="M357.614 388.936V318H428.621V388.936H357.614ZM436.152 388.936V318H508.234V388.936H436.152ZM515.766 388.936V318H587.848V388.936H515.766ZM595.379 388.936V318H666.386V388.936H595.379ZM595.379 468.471V396.46H666.386V468.471H595.379ZM673.917 468.471V396.46H746V468.471H673.917ZM278 548.006V475.994H350.083V548.006H278ZM357.614 548.006V475.994H428.621V548.006H357.614ZM436.152 548.006V475.994H508.234V548.006H436.152ZM515.766 548.006V475.994H587.848V548.006H515.766ZM595.379 548.006V475.994H666.386V548.006H595.379ZM673.917 548.006V475.994H746V548.006H673.917ZM278 626.465V555.529H350.083V626.465H278ZM357.614 626.465V555.529H428.621V626.465H357.614ZM595.379 626.465V555.529H666.386V626.465H595.379ZM673.917 626.465V555.529H746V626.465H673.917ZM357.614 706V633.989H428.621V706H357.614ZM436.152 706V633.989H508.234V706H436.152ZM515.766 706V633.989H587.848V706H515.766ZM595.379 706V633.989H666.386V706H595.379Z" fill="white"/>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 1.0 MiB |
|
Before Width: | Height: | Size: 5.5 MiB |
|
Before Width: | Height: | Size: 356 B |
BIN
neode-ui/public/assets/icon/maskable-icon-512x512-v2.png
Normal file
|
After Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 1.2 KiB |
BIN
neode-ui/public/assets/icon/pwa-192x192-v2.png
Normal file
|
After Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 417 B |
BIN
neode-ui/public/assets/icon/pwa-512x512-v2.png
Normal file
|
After Width: | Height: | Size: 48 KiB |
|
Before Width: | Height: | Size: 1.2 KiB |
BIN
neode-ui/public/assets/icon/pwa-64x64-v2.png
Normal file
|
After Width: | Height: | Size: 3.6 KiB |
|
Before Width: | Height: | Size: 287 B |
|
Before Width: | Height: | Size: 1.0 MiB |
|
Before Width: | Height: | Size: 5.5 MiB |
|
Before Width: | Height: | Size: 7.0 KiB |
|
Before Width: | Height: | Size: 32 KiB |
|
Before Width: | Height: | Size: 24 KiB |
@ -1,17 +0,0 @@
|
|||||||
<svg width="285" height="273" viewBox="0 0 285 273" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<g filter="url(#filter0_d_145_9)">
|
|
||||||
<path d="M67.6045 215.234H154.772V240.824H28L77.7109 127.559L131.736 76.2861L67.6045 215.234ZM198.893 146.688H256.594L213.508 240.824H171.984V172.604H114.283L156.588 76.7314L177.74 50.3652L198.893 24V146.688ZM198.893 214.361L217.207 172.604H198.893V214.361ZM153.67 146.688H171.984V104.929L153.67 146.688Z" fill="white"/>
|
|
||||||
</g>
|
|
||||||
<defs>
|
|
||||||
<filter id="filter0_d_145_9" x="0" y="0" width="284.594" height="272.824" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
|
||||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
|
||||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
|
||||||
<feOffset dy="4"/>
|
|
||||||
<feGaussianBlur stdDeviation="14"/>
|
|
||||||
<feComposite in2="hardAlpha" operator="out"/>
|
|
||||||
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.25 0"/>
|
|
||||||
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_145_9"/>
|
|
||||||
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_145_9" result="shape"/>
|
|
||||||
</filter>
|
|
||||||
</defs>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 1.1 KiB |
BIN
neode-ui/public/favicon-v2.ico
Normal file
|
After Width: | Height: | Size: 2.6 KiB |
|
Before Width: | Height: | Size: 356 B |
@ -7,7 +7,7 @@
|
|||||||
>
|
>
|
||||||
<div class="glass-card p-4 flex items-center gap-4 shadow-xl">
|
<div class="glass-card p-4 flex items-center gap-4 shadow-xl">
|
||||||
<img
|
<img
|
||||||
src="/assets/icon/pwa-192x192.png"
|
src="/assets/icon/pwa-192x192-v2.png"
|
||||||
alt="Archipelago"
|
alt="Archipelago"
|
||||||
class="w-14 h-14 rounded-xl shrink-0"
|
class="w-14 h-14 rounded-xl shrink-0"
|
||||||
/>
|
/>
|
||||||
|
|||||||
@ -4,7 +4,7 @@
|
|||||||
<div class="text-center mb-8">
|
<div class="text-center mb-8">
|
||||||
<div class="logo-gradient-border inline-block mb-8">
|
<div class="logo-gradient-border inline-block mb-8">
|
||||||
<img
|
<img
|
||||||
src="/assets/img/favico.svg"
|
src="/assets/icon/favico-black-v2.svg"
|
||||||
alt="Archipelago"
|
alt="Archipelago"
|
||||||
class="w-20 h-20"
|
class="w-20 h-20"
|
||||||
/>
|
/>
|
||||||
|
|||||||
@ -9,7 +9,7 @@ export default defineConfig({
|
|||||||
vue(),
|
vue(),
|
||||||
VitePWA({
|
VitePWA({
|
||||||
registerType: 'autoUpdate',
|
registerType: 'autoUpdate',
|
||||||
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'],
|
includeAssets: ['assets/icon/favico-black-v2.svg', 'assets/icon/pwa-64x64-v2.png', 'assets/icon/pwa-192x192-v2.png', 'assets/icon/pwa-512x512-v2.png', 'assets/icon/maskable-icon-512x512-v2.png', 'assets/icon/apple-touch-icon-180x180-v2.png', 'favicon-v2.ico'],
|
||||||
manifest: {
|
manifest: {
|
||||||
name: 'Archipelago',
|
name: 'Archipelago',
|
||||||
short_name: 'Archipelago',
|
short_name: 'Archipelago',
|
||||||
@ -25,15 +25,15 @@ export default defineConfig({
|
|||||||
categories: ['productivity', 'utilities'],
|
categories: ['productivity', 'utilities'],
|
||||||
prefer_related_applications: false,
|
prefer_related_applications: false,
|
||||||
icons: [
|
icons: [
|
||||||
{ src: '/assets/icon/pwa-64x64.png', sizes: '64x64', type: 'image/png', purpose: 'any' },
|
{ src: '/assets/icon/pwa-64x64-v2.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-192x192-v2.png', sizes: '192x192', type: 'image/png', purpose: 'any' },
|
||||||
{ src: '/assets/icon/pwa-512x512.png', sizes: '512x512', type: 'image/png', purpose: 'any' },
|
{ src: '/assets/icon/pwa-512x512-v2.png', sizes: '512x512', type: 'image/png', purpose: 'any' },
|
||||||
{ src: '/assets/icon/maskable-icon-512x512.png', sizes: '512x512', type: 'image/png', purpose: 'maskable' }
|
{ src: '/assets/icon/maskable-icon-512x512-v2.png', sizes: '512x512', type: 'image/png', purpose: 'maskable' }
|
||||||
],
|
],
|
||||||
shortcuts: [
|
shortcuts: [
|
||||||
{ name: 'Dashboard', short_name: 'Dashboard', description: 'Open the dashboard', url: '/dashboard', icons: [{ src: '/assets/icon/pwa-192x192.png', sizes: '192x192' }] },
|
{ name: 'Dashboard', short_name: 'Dashboard', description: 'Open the dashboard', url: '/dashboard', icons: [{ src: '/assets/icon/pwa-192x192-v2.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: 'My Apps', short_name: 'Apps', description: 'Manage your apps', url: '/dashboard/apps', icons: [{ src: '/assets/icon/pwa-192x192-v2.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' }] }
|
{ name: 'App Store', short_name: 'Store', description: 'Browse and install apps', url: '/dashboard/marketplace', icons: [{ src: '/assets/icon/pwa-192x192-v2.png', sizes: '192x192' }] }
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
workbox: {
|
workbox: {
|
||||||
@ -44,8 +44,6 @@ export default defineConfig({
|
|||||||
'**/*-1.47mb.mp4',
|
'**/*-1.47mb.mp4',
|
||||||
'**/bg-*.mp4', // Exclude large background videos from precache
|
'**/bg-*.mp4', // Exclude large background videos from precache
|
||||||
'**/video-intro.mp4', // Exclude video-intro.mp4 from precache (7MB, cached at runtime)
|
'**/video-intro.mp4', // Exclude video-intro.mp4 from precache (7MB, cached at runtime)
|
||||||
'**/favico.svg', // Exclude large SVG (5.73MB) - use PNG instead
|
|
||||||
'**/icon/favico.svg' // Exclude duplicate large SVG
|
|
||||||
],
|
],
|
||||||
maximumFileSizeToCacheInBytes: 5 * 1024 * 1024, // 5MB limit (increased from 2MB)
|
maximumFileSizeToCacheInBytes: 5 * 1024 * 1024, // 5MB limit (increased from 2MB)
|
||||||
skipWaiting: false, // Wait for user to accept update
|
skipWaiting: false, // Wait for user to accept update
|
||||||
@ -95,7 +93,7 @@ export default defineConfig({
|
|||||||
urlPattern: /\/assets\/.*/i,
|
urlPattern: /\/assets\/.*/i,
|
||||||
handler: 'CacheFirst',
|
handler: 'CacheFirst',
|
||||||
options: {
|
options: {
|
||||||
cacheName: 'assets-cache',
|
cacheName: 'assets-cache-v2',
|
||||||
expiration: {
|
expiration: {
|
||||||
maxEntries: 100,
|
maxEntries: 100,
|
||||||
maxAgeSeconds: 60 * 60 * 24 * 30 // 30 days
|
maxAgeSeconds: 60 * 60 * 24 * 30 // 30 days
|
||||||
|
|||||||
@ -153,19 +153,26 @@ if [ "$LIVE" = true ]; then
|
|||||||
sshpass -p "$ARCHIPELAGO_PASSWORD" ssh $SSH_OPTS "$TARGET_HOST" "sudo cp -rf $TARGET_DIR/web/dist/neode-ui/* /opt/archipelago/web-ui/"
|
sshpass -p "$ARCHIPELAGO_PASSWORD" ssh $SSH_OPTS "$TARGET_HOST" "sudo cp -rf $TARGET_DIR/web/dist/neode-ui/* /opt/archipelago/web-ui/"
|
||||||
sshpass -p "$ARCHIPELAGO_PASSWORD" ssh $SSH_OPTS "$TARGET_HOST" "sudo chown -R 1000:1000 /opt/archipelago/web-ui"
|
sshpass -p "$ARCHIPELAGO_PASSWORD" ssh $SSH_OPTS "$TARGET_HOST" "sudo chown -R 1000:1000 /opt/archipelago/web-ui"
|
||||||
|
|
||||||
# Build and deploy AIUI
|
# Build and deploy AIUI (non-fatal — never delete existing AIUI on failure)
|
||||||
AIUI_DIR="$PROJECT_DIR/../AIUI"
|
AIUI_DIR="$PROJECT_DIR/../AIUI"
|
||||||
AIUI_DIST="$AIUI_DIR/packages/app/dist"
|
AIUI_DIST="$AIUI_DIR/packages/app/dist"
|
||||||
if [ -d "$AIUI_DIR/packages/app" ]; then
|
if [ -d "$AIUI_DIR/packages/app" ]; then
|
||||||
echo "$(timestamp) Building AIUI for /aiui/ base path..."
|
echo "$(timestamp) Building AIUI for /aiui/ base path..."
|
||||||
cd "$AIUI_DIR" && VITE_BASE_PATH=/aiui/ pnpm build 2>&1 | tail -5
|
AIUI_BUILD_OK=false
|
||||||
|
if (cd "$AIUI_DIR" && VITE_BASE_PATH=/aiui/ pnpm build 2>&1 | tail -10); then
|
||||||
|
AIUI_BUILD_OK=true
|
||||||
|
fi
|
||||||
cd "$PROJECT_DIR"
|
cd "$PROJECT_DIR"
|
||||||
echo "$(timestamp) Deploying AIUI..."
|
if [ "$AIUI_BUILD_OK" = true ] && [ -d "$AIUI_DIST" ] && [ -f "$AIUI_DIST/index.html" ]; then
|
||||||
sshpass -p "$ARCHIPELAGO_PASSWORD" ssh $SSH_OPTS "$TARGET_HOST" "sudo mkdir -p /opt/archipelago/web-ui/aiui"
|
echo "$(timestamp) Deploying AIUI..."
|
||||||
sshpass -p "$ARCHIPELAGO_PASSWORD" ssh $SSH_OPTS "$TARGET_HOST" "sudo rm -rf /opt/archipelago/web-ui/aiui/*"
|
sshpass -p "$ARCHIPELAGO_PASSWORD" ssh $SSH_OPTS "$TARGET_HOST" "sudo mkdir -p /opt/archipelago/web-ui/aiui"
|
||||||
cd "$AIUI_DIST" && tar cf - . | sshpass -p "$ARCHIPELAGO_PASSWORD" ssh $SSH_OPTS "$TARGET_HOST" "sudo tar xf - -C /opt/archipelago/web-ui/aiui/"
|
sshpass -p "$ARCHIPELAGO_PASSWORD" ssh $SSH_OPTS "$TARGET_HOST" "sudo rm -rf /opt/archipelago/web-ui/aiui/*"
|
||||||
cd "$PROJECT_DIR"
|
cd "$AIUI_DIST" && tar cf - . | sshpass -p "$ARCHIPELAGO_PASSWORD" ssh $SSH_OPTS "$TARGET_HOST" "sudo tar xf - -C /opt/archipelago/web-ui/aiui/"
|
||||||
sshpass -p "$ARCHIPELAGO_PASSWORD" ssh $SSH_OPTS "$TARGET_HOST" "sudo chown -R 1000:1000 /opt/archipelago/web-ui/aiui && sudo chmod 755 /opt/archipelago/web-ui/aiui && sudo find /opt/archipelago/web-ui/aiui -type d -exec chmod 755 {} \;"
|
cd "$PROJECT_DIR"
|
||||||
|
sshpass -p "$ARCHIPELAGO_PASSWORD" ssh $SSH_OPTS "$TARGET_HOST" "sudo chown -R 1000:1000 /opt/archipelago/web-ui/aiui && sudo chmod 755 /opt/archipelago/web-ui/aiui && sudo find /opt/archipelago/web-ui/aiui -type d -exec chmod 755 {} \;"
|
||||||
|
else
|
||||||
|
echo "$(timestamp) ⚠️ AIUI build failed — keeping existing AIUI on server"
|
||||||
|
fi
|
||||||
else
|
else
|
||||||
echo "$(timestamp) ⚠️ AIUI not found at $AIUI_DIR, skipping"
|
echo "$(timestamp) ⚠️ AIUI not found at $AIUI_DIR, skipping"
|
||||||
fi
|
fi
|
||||||
|
|||||||