TV-App (/tv/): - Login mit bcrypt-Passwort-Hashing und DB-Sessions (30 Tage) - Home (Weiterschauen, Serien, Filme), Serien-Detail mit Staffeln - Film-Uebersicht und Detail, Fullscreen Video-Player - Suche mit Live-Ergebnissen, Watch-Progress (alle 10s gespeichert) - D-Pad/Fernbedienung-Navigation (FocusManager, Samsung Tizen Keys) - PWA: manifest.json, Service Worker, Icons fuer Handy/Tablet - Pro-User Berechtigungen (Serien, Filme, Admin, erlaubte Pfade) Admin-Erweiterungen: - QR-Code fuer TV-App URL - User-Verwaltung (CRUD) mit Rechte-Konfiguration - Log-API: GET /api/log?lines=100&level=INFO Tizen-App (tizen-app/): - Wrapper-App fuer Samsung Smart TVs (.wgt Paket) - Einmalige Server-IP Eingabe, danach automatische Verbindung - Installationsanleitung (INSTALL.md) Bug-Fixes: - executeImport: Job-ID vor resetImport() gesichert - cursor(aiomysql.DictCursor) statt cursor(dict) - DB-Spalten width/height statt video_width/video_height Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
68 lines
2 KiB
JavaScript
68 lines
2 KiB
JavaScript
/**
|
|
* VideoKonverter TV - Service Worker (minimal)
|
|
* Ermoeglicht PWA-Installation auf Handys und Tablets
|
|
* Kein Offline-Caching noetig (Streaming braucht Netzwerk)
|
|
*/
|
|
|
|
const CACHE_NAME = "vk-tv-v1";
|
|
const STATIC_ASSETS = [
|
|
"/static/tv/css/tv.css",
|
|
"/static/tv/js/tv.js",
|
|
"/static/tv/js/player.js",
|
|
"/static/tv/icons/icon-192.png",
|
|
];
|
|
|
|
// Installation: Statische Assets cachen
|
|
self.addEventListener("install", (event) => {
|
|
event.waitUntil(
|
|
caches.open(CACHE_NAME)
|
|
.then(cache => cache.addAll(STATIC_ASSETS))
|
|
.then(() => self.skipWaiting())
|
|
);
|
|
});
|
|
|
|
// Aktivierung: Alte Caches aufraemen
|
|
self.addEventListener("activate", (event) => {
|
|
event.waitUntil(
|
|
caches.keys()
|
|
.then(keys => Promise.all(
|
|
keys.filter(k => k !== CACHE_NAME)
|
|
.map(k => caches.delete(k))
|
|
))
|
|
.then(() => self.clients.claim())
|
|
);
|
|
});
|
|
|
|
// Fetch: Network-First Strategie (Streaming braucht immer Netzwerk)
|
|
self.addEventListener("fetch", (event) => {
|
|
// Nur GET-Requests cachen
|
|
if (event.request.method !== "GET") return;
|
|
|
|
// Streaming/API nie cachen
|
|
const url = new URL(event.request.url);
|
|
if (url.pathname.startsWith("/api/") || url.pathname.includes("/stream")) {
|
|
return;
|
|
}
|
|
|
|
// Statische Assets: Cache-First
|
|
if (url.pathname.startsWith("/static/tv/")) {
|
|
event.respondWith(
|
|
caches.match(event.request)
|
|
.then(cached => cached || fetch(event.request)
|
|
.then(response => {
|
|
const clone = response.clone();
|
|
caches.open(CACHE_NAME)
|
|
.then(cache => cache.put(event.request, clone));
|
|
return response;
|
|
})
|
|
)
|
|
);
|
|
return;
|
|
}
|
|
|
|
// Alles andere: Network-First
|
|
event.respondWith(
|
|
fetch(event.request)
|
|
.catch(() => caches.match(event.request))
|
|
);
|
|
});
|