# Plan: Filme-Tab + Web-Sync-Reparatur + Navigations-Bug Drei unabhängige Fixes, alle ohne Datenbank-Migration (Room `fallbackToDestructiveMigration` ist aktiv, Schema bleibt v1, nur neue Queries). --- ## Fix 1: Filme als eigener Tab in der Bottom-Navi Aktuell ist das Dashboard "Filme"-Zählen kaputt (`itemCount - topShows.episodeCount` mit `LIMIT 20`) und Filme tauchen im Serien-Ranking auf. **1a. Neue DAO-Queries** (`ViewingDao.kt`) — Room speichert `contentType` als TEXT (`'MOVIE'`/`'SERIES'`), daher String-Filter: - `getTopMovies(limit)` → `SELECT ... WHERE contentType = 'MOVIE' GROUP BY showTitle ORDER BY totalMinutes DESC` - `getTopShows(limit)` → ergänze `WHERE contentType != 'MOVIE'` damit Filme aus dem Serien-Ranking verschwinden - `getMoviesCount()` → `SELECT COUNT(*) ... WHERE contentType = 'MOVIE'` - `getSeriesEpisodesCount()` → `SELECT COUNT(*) ... WHERE contentType != 'MOVIE'` **1b. `WatchStats` korrekt befüllen** (`StatsRepository.kt`) — `combine` von 7 Flows (Vararg-Variante wie bereits vorhanden), echte Counts statt Heuristik. `moviesCount` und `seriesEpisodesCount` direkt aus der DB. **1c. Neue Datenmodelle** (`WatchStats.kt`) — `MovieSummary` (analog `ShowSummary`) + `topMovies: List`-Feld in `WatchStats`. **1d. Neuer Screen `MoviesScreen.kt`** — Clone von `SeriesStatsScreen.kt` mit `MovieRankItem` (zeigt Dauer statt Folgenanzahl, Movie-Icon statt "X Folgen"). Wiederverwendet `ProviderBadge`. **1e. Bottom-Navi erweitern** (`MainActivity.kt`) — Neuer `Screen.Movies("movies", "Filme", Icons.Default.Movie)` zwischen Series und Analytics. `NavHost` erhält die neue Route. --- ## Fix 2: Web-Sync JS-Extraktion reparieren Root Cause: Der Button nimmt die **komplette HTML-Seite** (`document.documentElement.outerHTML`) und füttert sie dem CSV-Parser → 1 Müll-Eintrag mit ``-Tag-Text. Recherche zeigt: DOM-Klassen sind bei Netflix gehasht (brittel). Der robuste Weg ist die **Netflix Shakti-API** aus dem WebView heraus, da die Session-Cookies (`NetflixId`) automatisch vorliegen. **2a. Provider-spezifische JS-Extraktion** (`ProviderSyncScreen.kt` → `WebViewSyncSection`): - **Netflix**: Injiziere JS, das `window.netflix.reactContext.models.serverDefs.data.BUILD_IDENTIFIER` + `authURL` liest, dann `fetch('/api/shakti/'+buildId+'/viewingactivity?pg='+n)` paginiert (Schleife bis `vhSize` erreicht) und ein sauberes JSON-Array von `{title, seriesTitle, episodeTitle, date, duration}` zurückgibt. - **Prime Video**: Parse inline-JSON aus `script[type="text/template"]` (`props`→widgets→`content.content.titles[]`), fallback auf `[data-automation-id^="wh-date"]`. - **Andere (Disney+/Apple)**: Greaceful-Degradation-Meldung "Web-Sync noch nicht unterstützt, bitte CSV verwenden". **2b. Toast-Feedback statt HTML-String**: Der Button zeigt Fortschritt ("Lade Seite N…"). Die extrahierten JSON-Daten gehen an `viewModel.importScrapedWebHistory(json, provider)` — bereits vorhanden, leitet an `NetflixParser.parseJsonApiPayload` weiter. **2c. `parseJsonApiPayload` robuster machen** (`NetflixParser.kt`): Akzeptiert jetzt sowohl das Netflix-`viewedItems`-Array **als auch** ein flaches Array (für den Prime-Fall). Field-Reading defensiv (`seriesTitle` für Episoden, `title` für Filme → korrekter `contentType`). Dauer aus dem `duration`-Feld (ms → Minuten) falls vorhanden, sonst Default. --- ## Fix 3: Navigations-Bug (hängt nach "Verlauf Auslesen" fest) Symptom: Nach dem Sync-Screen kommt man nicht mehr aufs Dashboard. Ursachen: WebView wird nicht disposed, `update`-Lambda erzwingt Reloads, und das alte Parsing der kompletten HTML lief auf dem Main-Thread. **3a. WebView sauber lifecycle-gebunden** (`WebViewSyncSection`): - `DisposableEffect` / `remember { ...; onDispose { webView.destroy() } }` statt freischwebendem Ref — verhindert, dass der WebView den Screen blockiert. - Reload-Schleife in `update`-Lambda entfernen (vergleicht nur noch, ob sich der Provider geändert hat, nicht jeden Frame). **3b. Parsing off-main**: Die extrahierten JSON-Daten werden ohnehin über `viewModelScope.launch(Dispatchers.IO)` verarbeitet (bereits in `importScrapedWebHistory`), aber das JS-`evaluateJavascript`-Ergebnis wird vor dem Parsen als String geprüft — keine riesige HTML-Seite mehr, die den Main-Thread blockiert. **3c. Navi-Zurück-Verhalten**: `BackHandler` im Sync-Screen, der bei geladenem WebView zuerst `webView.goBack()` macht (falls History vorhanden) und erst dann `navController.popBackStack()`. So kommt man sicher vom Sync-Screen weg. --- ## Validierung - `./gradlew assembleDebug` (Java 21) baut fehlerfrei. - `adb install -r` auf das S24 Ultra. - Manueller Smoke-Test: Sample-Daten → Filme-Tab zeigt Filme, Serien-Tab nur Serien, Dashboard zählt korrekt. Navi nach Sync funktioniert. Alle drei Fixes sind voneinander unabhängig und werden in einem Build-Zyklus umgesetzt. Keine DB-Schema-Änderung (nur neue Queries auf bestehenden Spalten).