Versioning and Updating improvements
This commit is contained in:
+1
-1
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "tasgrid",
|
||||
"private": true,
|
||||
"version": "0.0.0",
|
||||
"version": "1.1.0",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite --host 0.0.0.0 --port 4001",
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
import { type Component, createEffect, onCleanup } from 'solid-js';
|
||||
import { useRegisterSW } from 'virtual:pwa-register/solid';
|
||||
import { toast } from 'solid-sonner';
|
||||
|
||||
// We export a function so other parts of the app can manually trigger an update
|
||||
let manualUpdateFn: (() => void) | undefined;
|
||||
let updateAndReloadFn: (() => void) | undefined;
|
||||
|
||||
export const forceServiceWorkerUpdate = () => {
|
||||
if (manualUpdateFn) {
|
||||
@@ -12,6 +14,15 @@ export const forceServiceWorkerUpdate = () => {
|
||||
}
|
||||
};
|
||||
|
||||
export const updateAndReloadApp = () => {
|
||||
if (updateAndReloadFn) {
|
||||
updateAndReloadFn();
|
||||
} else {
|
||||
console.warn("PWA Updater not initialized yet; reloading directly.");
|
||||
window.location.reload();
|
||||
}
|
||||
};
|
||||
|
||||
export const PwaUpdater: Component = () => {
|
||||
let registration: ServiceWorkerRegistration | undefined;
|
||||
|
||||
@@ -47,6 +58,33 @@ export const PwaUpdater: Component = () => {
|
||||
registration.update();
|
||||
}
|
||||
};
|
||||
|
||||
updateAndReloadFn = () => {
|
||||
if (needRefresh()) {
|
||||
console.log('Update ready. Reloading now...');
|
||||
updateServiceWorker(true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (registration) {
|
||||
console.log('Checking for updates before reload...');
|
||||
registration.update();
|
||||
}
|
||||
|
||||
const start = Date.now();
|
||||
const timeoutMs = 5000;
|
||||
const poll = window.setInterval(() => {
|
||||
if (needRefresh()) {
|
||||
console.log('Update found. Reloading with new SW...');
|
||||
window.clearInterval(poll);
|
||||
updateServiceWorker(true);
|
||||
} else if (Date.now() - start > timeoutMs) {
|
||||
console.log('No update detected quickly. Reloading now...');
|
||||
window.clearInterval(poll);
|
||||
toast.info("No update found");
|
||||
}
|
||||
}, 250);
|
||||
};
|
||||
});
|
||||
|
||||
createEffect(() => {
|
||||
|
||||
+44
-14
@@ -1088,20 +1088,50 @@ export const SettingsView: Component<{ setView?: (v: string) => void }> = (props
|
||||
</div>
|
||||
|
||||
<footer class="pt-40 pb-20 flex flex-col items-center gap-4">
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
class="h-8 gap-2 text-[0.625rem] font-bold uppercase tracking-widest text-muted-foreground hover:text-foreground opacity-30 hover:opacity-100 transition-opacity"
|
||||
onClick={async () => {
|
||||
const { forceServiceWorkerUpdate } = await import('@/components/PwaUpdater');
|
||||
forceServiceWorkerUpdate();
|
||||
toast.success("Checking for updates...");
|
||||
}}
|
||||
>
|
||||
<Upload class="rotate-180" size={14} />
|
||||
Check for Updates
|
||||
</Button>
|
||||
<p class="text-[0.5rem] font-mono text-muted-foreground/30 uppercase tracking-[0.2em]">Tasgrid v1.0.1</p> {/* Versioning System: v[breaking update].[user-facing update].[patch/backend updated] */}
|
||||
<div class="flex items-center gap-2">
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
class="h-8 gap-2 text-[0.625rem] font-bold uppercase tracking-widest text-muted-foreground hover:text-foreground opacity-70 hover:opacity-100 transition-opacity"
|
||||
onClick={async () => {
|
||||
const { updateAndReloadApp } = await import('@/components/PwaUpdater');
|
||||
toast.success("Updating app...");
|
||||
updateAndReloadApp();
|
||||
}}
|
||||
>
|
||||
<Upload class="rotate-180" size={14} />
|
||||
Update App
|
||||
</Button>
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
class="h-8 gap-2 text-[0.625rem] font-bold uppercase tracking-widest text-muted-foreground hover:text-foreground opacity-70 hover:opacity-100 transition-opacity"
|
||||
onClick={async () => {
|
||||
if (!confirm("Reset PWA? This will clear offline data and reload.")) return;
|
||||
try {
|
||||
const registrations = await navigator.serviceWorker?.getRegistrations?.();
|
||||
if (registrations) {
|
||||
await Promise.all(registrations.map(r => r.unregister()));
|
||||
}
|
||||
if ('caches' in window) {
|
||||
const keys = await caches.keys();
|
||||
await Promise.all(keys.map(k => caches.delete(k)));
|
||||
}
|
||||
toast.success("PWA reset. Reloading...");
|
||||
window.location.reload();
|
||||
} catch (err) {
|
||||
console.error("Failed to reset PWA", err);
|
||||
toast.error("Failed to reset PWA");
|
||||
}
|
||||
}}
|
||||
>
|
||||
<Trash2 size={14} />
|
||||
Reset PWA
|
||||
</Button>
|
||||
</div>
|
||||
<p class="text-[0.5rem] font-mono text-muted-foreground/60 uppercase tracking-[0.2em]">
|
||||
Tasgrid v{__APP_VERSION__}
|
||||
</p> {/* Versioning System: v[breaking update].[user-facing update].[patch/backend updated] */}
|
||||
</footer>
|
||||
</div>
|
||||
);
|
||||
|
||||
Vendored
+3
@@ -0,0 +1,3 @@
|
||||
/// <reference types="vite/client" />
|
||||
|
||||
declare const __APP_VERSION__: string;
|
||||
+9
-1
@@ -3,8 +3,16 @@ import solid from 'vite-plugin-solid'
|
||||
import { VitePWA } from 'vite-plugin-pwa'
|
||||
import tailwindcss from '@tailwindcss/vite'
|
||||
import path from 'path'
|
||||
import { readFileSync } from 'fs'
|
||||
|
||||
const packageJson = JSON.parse(
|
||||
readFileSync(new URL('./package.json', import.meta.url), 'utf-8')
|
||||
);
|
||||
|
||||
export default defineConfig({
|
||||
define: {
|
||||
__APP_VERSION__: JSON.stringify(packageJson.version),
|
||||
},
|
||||
plugins: [
|
||||
solid(),
|
||||
tailwindcss(),
|
||||
@@ -76,4 +84,4 @@ export default defineConfig({
|
||||
"@": path.resolve(__dirname, "./src")
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user