Files
lucianoandClaude Opus 4.8 c0230ee1d6 Mobile remote: per-track trim (in/out) + waveform + times + scrub/seek + gap
- Queue cards expand to a detail panel with the waveform, elapsed/total/remaining
  times, draggable in/out handles, scrub-to-seek and a 'pausa dopo' gap.
- /api/peaks now also returns exact duration (samples/8000) so non-playing tracks
  have correct times/trim without relying on the output media probe.
- Service worker switched to network-first (+v2) so UI updates aren't masked by
  a stale cache; output.js probeDurations hardened (load()+timeout fallback).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-29 14:37:43 +02:00

27 lines
1.2 KiB
JavaScript

// App-shell caching for installability/offline. The server is local and fast,
// so we use NETWORK-FIRST for the shell (always get the latest UI after a
// redeploy) and fall back to cache only when offline. API/media never cached.
const CACHE = 'djv-shell-v2';
const SHELL = [
'./', 'index.html', 'css/mobile.css',
'js/net.js', 'js/control.js', 'js/engine/shaders.js', 'js/engine/effects.js',
'manifest.webmanifest', 'icons/icon-192.png', 'icons/icon-512.png'
];
self.addEventListener('install', (e) => {
e.waitUntil(caches.open(CACHE).then((c) => c.addAll(SHELL)).then(() => self.skipWaiting()));
});
self.addEventListener('activate', (e) => {
e.waitUntil(caches.keys().then((ks) => Promise.all(ks.filter((k) => k !== CACHE).map((k) => caches.delete(k)))).then(() => self.clients.claim()));
});
self.addEventListener('fetch', (e) => {
const url = new URL(e.request.url);
if (e.request.method !== 'GET' || url.pathname.startsWith('/api') || url.pathname.startsWith('/media')) return;
e.respondWith(
fetch(e.request).then((res) => {
const copy = res.clone();
caches.open(CACHE).then((c) => c.put(e.request, copy)).catch(() => {});
return res;
}).catch(() => caches.match(e.request))
);
});