Commit Graph

207 Commits

Author SHA1 Message Date
Sucukdeluxe
ce3d7bb728 Account-Liste: kein irrefuehrendes gruenes "Konfiguriert" mehr bei nicht-pruefbaren Anbietern
Single-Token-Anbieter (Real-Debrid, AllDebrid, 1Fichier, DDownload, LinkSnappy,
BestDebrid) haben keine Status-Pruefung. Bisher stand bei ihnen ein gruenes
"Konfiguriert"-Badge in der Status-Spalte, das wie "geprueft & ok" aussah, obwohl
nichts geprueft wurde. Jetzt zeigen sie dort ein dezentes graues "—" (Tooltip:
"Fuer diesen Anbieter gibt es keine Status-Pruefung"). Gruen/gelb/rot bleibt den
tatsaechlich geprueften Mega-Debrid-/Debrid-Link-Accounts vorbehalten.

Reine Renderer-Aenderung. tsc=6, build ok.
2026-06-15 02:02:07 +02:00
Sucukdeluxe
32e43d1a62 Account-Liste: einklappbare Anbieter-Gruppen (z.B. "Mega-Debrid · 4 Accounts")
User-Idee: Anbieter mit mehreren Accounts zusammenfassbar machen, platzsparend.

- Anbieter mit >= 2 Accounts (Mega-Debrid, Debrid-Link) bekommen einen klickbaren
  Gruppen-Kopf "<Anbieter> · N Accounts" mit Chevron zum Ein-/Ausklappen; Einzel-
  account-Anbieter bleiben normale flache Zeilen.
- Gruppen-Kopf zeigt eine Mini-Status-Zusammenfassung als Badges: "X OK" (gruen),
  "Y Problem" (rot, ungueltige Logins), "Z aus" (deaktiviert).
- Standard ausgeklappt (Status bleibt auf einen Blick sichtbar); Klapp-Zustand wird
  pro Anbieter in localStorage gemerkt (rd-account-collapsed-groups-v1).
- Mitglied-Zeilen leicht eingerueckt mit Akzent-Leiste. Zebra-Streifen entfernt
  (mit Gruppen-Koepfen unruhig).
- Zeilen-Rendering in renderAccountRow ausgelagert (fuer flache + Gruppen-Mitglieder
  wiederverwendet); neues groupedAccountRows-useMemo gruppiert accountRows nach Service.

Reine Renderer-Aenderung. 810 Tests gruen, tsc=6, build ok.
2026-06-15 01:46:23 +02:00
Sucukdeluxe
d594afe93a UI Phase 3: Account-Verwaltung als JDownloader-artige Liste (eine Zeile pro Account, Status inline) + Pruefung beim Hinzufuegen
Account-Rework (User-Wunsch nach JDownloader-Vorlage-Screenshot):

- Tabelle zeigt jetzt EINE ZEILE PRO EINZELNEM ACCOUNT statt eine Zeile pro
  Anbieter. Mega-Debrid mit 4 Accounts = 4 Zeilen, Debrid-Link je Key eine Zeile,
  Single-Token-Anbieter je eine Zeile. Neues geflachtes Modell accountRows
  (useMemo) aus configuredAccounts: Mega ueber parseMegaDebridAccounts, DL ueber
  entry.debridLinkKeys, Rest 1:1.
- Spalten wie JDownloader: aktiviert-Checkbox | Hoster (+Modus) | Download-Traffic
  (Rest von Limit "X von Y uebrig" bzw. "Unbeschraenkt") | Status (farbig) |
  Benutzername | Verfallsdatum | Aktion (Bearbeiten/Entfernen).
- STATUS INLINE + farbig (gruen Premium / gelb Free / rot ungueltig / grau nicht
  geprueft / Deaktiviert) direkt in der Zeile, ohne erst "Bearbeiten" zu oeffnen.
  Quelle: settings.debridAccountStatuses[accountId] (Mega/DL werden geprueft),
  Benutzername aus status.email, Verfallsdatum aus premiumUntilMs. Single-Token-
  Anbieter (Real-Debrid, AllDebrid, 1Fichier, ...) werden nicht geprueft -> "Konfiguriert".
- Problemzeilen (Login ungueltig) rot hinterlegt, deaktivierte Zeilen ausgegraut.
- aktiviert-Checkbox schaltet den EINZELNEN Account: Mega via neuem
  onToggleMegaAccountEnabled (megaDebridDisabledAccountIds), DL via bestehendem
  onToggleDebridLinkApiKeyEnabled, Single via onToggleAccountEnabled. Entfernen je
  Account: Mega/DL ueber neue Handler (Zeile aus megaCredentials/debridLinkApiKeys
  raus), Single ueber onRemoveAccount.
- PRUEFUNG BEIM HINZUFUEGEN: onSaveAccountDialog stoesst nach dem Speichern
  checkAllAccounts() an -> Status erscheint sofort in der Liste + Toast meldet
  "X/Y Login gueltig, Z Premium" (Speichern bleibt erlaubt, wie gewuenscht).
- Hoster-Reihenfolge- und Rotations-Verlauf-Panel unveraendert darunter. Alte
  resizable Spalten + "Zugang einzeln"-Toggle entfernt (durch Zeilen ersetzt).
  Web-Login-/AllDebrid-Status-Aktion bleibt als Knopf in der Single-Zeile.
- account-validity-badge.ok von Neon-Verlauf auf flaches Gruen, .disabled ergaenzt.

Reine Renderer-Aenderung. 810 Tests gruen, tsc=6 Baseline, build ok.
Erste Version nach Screenshot — Feinschliff der Optik nach User-Feedback.
2026-06-15 01:11:56 +02:00
Sucukdeluxe
de154ab783 UI Phase 2: Einstellungen-Tab neu strukturiert (Untergruppen + Erklaertexte) + konfigurierbarer Verlauf (Obergrenze + Zeitlimit)
Settings-Rework (User-Wunsch, mit Multi-Agent-Design-Runde fuer die Taxonomie:
3 Lenses -> Synthese, gegen das echte settingsDraft-Inventar auf Vollstaendigkeit
geprueft, 51 Einstellungen je genau einmal platziert).

UI (App.tsx + styles.css):
- 5 der 6 Bereiche (Allgemein/Entpacken/Geschwindigkeit/Bereinigung/Updates) in
  klare Untergruppen mit Unter-Ueberschriften (.settings-subhead) gegliedert, je
  Bereich ein Intro, und unter JEDER Einstellung ein knapper Erklaertext
  (.setting-hint, <= ~90 Zeichen, echte Umlaute). Reihenfolge nach Aufgaben-Logik
  (z.B. Allgemein: Speicherort / Download-Verhalten / Verlauf / Oberflaeche /
  Discord; Entpacken: Ziel & Ablauf / Deutsche Tonspur / Ablageform / Leistung /
  Passwoerter). Einige Labels praezisiert (z.B. "Codeberg Repo" -> "Update-Quelle",
  "Light Mode" -> "Heller Modus"). Account-Bereich bleibt fuer Phase 3 unangetastet.

Verlauf-Retention konfigurierbar (vorher: hart 500, kein Zeitlimit):
- Neue Settings historyMaxEntries (Standard 500) + historyMaxAgeDays (Standard 0=aus)
  in types/constants/normalizeSettings (geclamped 50..100000 bzw. 0..3650) + App-
  Default-Snapshot. Zwei neue Zahlenfelder im Bereich Allgemein -> Verlauf, direkt
  unter "Verlauf speichern"; ausgegraut wenn nicht "Dauerhaft".
- storage.ts: pruneHistoryEntries(entries, limits) wendet Alters- (completedAt <
  jetzt - Tage) und Anzahl-Grenze an; load/save/addHistoryEntry + die *ForRetention-
  Wrapper nehmen optionale Limits. app-controller reicht die Limits aus den Settings
  durch (historyLimits()) und schneidet den Verlauf bei Aenderung der Grenzen aktiv
  neu (damit "aelter als X Tage" wirklich von der Platte fliegt).

2 neue storage-Tests (Anzahl-Cap, Alters-Pruning). 810 Tests gruen, tsc=6 Baseline,
self-check + build ok.
2026-06-15 00:49:19 +02:00
Sucukdeluxe
4c09c9a2f3 UI Phase 1: Statistik 50/50, Footer rechts, Linksammler bis Footer, Bandbreiten-Graph oben rechts, Stat-Karten + Hilfe-Untermenues
Sichtbarkeits-/Layout-Politur (User-Wunsch, Quick-Wins-Paket vor den groesseren
Reworks von Einstellungen-Tab und Account-Verwaltung):

- Statistik: Bandbreitenverlauf und Hoster-Statistik jetzt 50/50 statt 40/60
  (grid-template-columns 1fr 1fr).
- Footer: die Zaehler (Pakete/Links/Session/Gesamt/Hoster/Speed/ETA) wandern
  nach unten-RECHTS, die Aktions-Buttons (Ein-/Ausklappen, Leeren, Clipboard)
  nach links.
- Linksammler: das Textfeld fuellt jetzt die volle Hoehe bis zum Footer
  (collector-view: grid-row 1fr, textarea flex:1) statt bei 220px zu enden.
- Downloads-Tab: neuer Bandbreiten-Graph oben rechts (DownloadSpeedSparkline)
  neben der Suche. Eigener 250ms-Timer mit geglaettetem Verlauf: bei kurzem
  Einbruch auf 0 faellt die Kurve nicht hart ab, sondern gleitet weich runter
  (asymmetrisches Easing: schnell hoch 0.45, langsam runter 0.12) und
  korrigiert sich wieder; die angezeigte Zahl bleibt der echte aktuelle Wert.
  Erste Version - Optik wird nach JDownloader-Screenshot nachgezogen.
- Stat-Karten professioneller: Wert in Zahl + Einheit getrennt (Einheit
  dezent), ruhige Leerzustaende (idle '0'/'—' gedaempft statt nacktem grossen
  '0'), kompaktere Karten, dezentere Eyebrow-Labels.
- Hoster-Balken: flacher Akzent statt Neon-Verlauf (kein Gradient).
- Hilfe-Menue umstrukturiert mit Hover-Untermenues: 'Logs oeffnen' (Haupt-,
  Audit-, Rename-, Session-, Trace-Log), 'Remote-Support' (Support-Bundle +
  Support-Trace), 'Diagnose' (Debug-Setup + Debug-Token); 'Letzte Fehler
  anzeigen' und 'Suche Aktualisierungen' bleiben direkt.

Reine Renderer-Aenderung (App.tsx + styles.css). 808 Tests gruen, tsc=6
Baseline, Build ok.
2026-06-15 00:18:14 +02:00
Sucukdeluxe
86d935e449 Fix: Testen-Button — Speichern-Hinweis + kein stilles Verschlucken
Audit-Befunde R1, R2:
- Nach erfolgreichem Test mit ungespeicherten Einstellungen sagt der Toast
  jetzt "Einstellungen jetzt noch speichern!" — vorher konnte man testen
  (klappt!), nie speichern, und nach dem naechsten App-Neustart/Auto-Update
  feuerte kein einziger Webhook, weil notifyUrl nie persistiert war.
- Button ist waehrend einer laufenden Quick-Action deaktiviert statt den
  Klick still zu verschlucken (performQuickAction returnt sonst kommentarlos).
2026-06-10 00:36:39 +02:00
Sucukdeluxe
25f226db43 Feature: Testen-Button neben der Webhook-URL
Schickt sofort eine Test-Nachricht (inkl. Discord-Ping falls gesetzt) an die
EINGETRAGENEN Entwurfs-Werte — funktioniert also schon vor dem Speichern der
Einstellungen. Toast meldet Erfolg bzw. verweist bei Fehlschlag auf
Hilfe -> Letzte Fehler (dort steht der HTTP-Status/Fehlertext aus notify.ts).
Neuer IPC TEST_NOTIFY (main.ts ruft sendNotification direkt), Button im
input-row-Muster, deaktiviert solange die URL leer ist.
2026-06-09 23:42:15 +02:00
Sucukdeluxe
8ab87bda51 Feature: Discord-Ping in Benachrichtigungen (optionale Erwaehnung)
Neues Settings-Feld "Discord-Ping" unter der Webhook-URL: User-ID, @everyone
oder @here. Wird jeder Webhook-Nachricht vorangestellt, damit Discord wirklich
pingt statt nur still in den Kanal zu schreiben. Eine nackte Zahl wird als
<@id> verpackt (nur so pingt eine User-Erwaehnung); @everyone/@here und fertige
<@...>-Mentions gehen unveraendert durch. Default leer = Verhalten wie bisher.
5 neue Tests (Normalisierung + Content-Prefix).
2026-06-09 21:52:47 +02:00
Sucukdeluxe
41cf36890b Benachrichtigungen: ntfy ersetzt durch Discord-Webhooks
User-Wunsch: Discord statt ntfy. notify.ts sendet jetzt einen JSON-Webhook-POST
({username, content} mit fettem Titel + Nachricht, auf Discords 2000-Zeichen-
Limit gekappt) statt ntfy-Headern. Emoji-Status im Titel (OK/Fehler/Ziel-
flagge) ersetzt Priority/Tags. Settings-UI: Label/Placeholder/Hinweis auf
Discord-Webhook umgestellt (Servereinstellungen -> Integrationen -> Webhooks).
Hooks, Dedup und Guards unveraendert. Tests auf das JSON-Format angepasst
(inkl. Discord-204-Antwort und 2000-Zeichen-Cap).
2026-06-09 21:40:39 +02:00
Sucukdeluxe
e753ea1296 Feature: Push-Benachrichtigungen (ntfy/Webhook) bei Paket fertig/fehlgeschlagen + Run-Ende
Headless-Server: Paket-Ausgaenge waren bisher nur per RDP+Log sichtbar. Neues
Modul notify.ts schickt einen fire-and-forget POST (ntfy-kompatibel: Title/
Priority/Tags als Header, Nachricht als Body) an eine konfigurierbare URL —
mit der kostenlosen ntfy-App aufs Handy, ohne Account/Port/Firewall (outbound).

- Settings: notifyUrl + 3 Ereignis-Toggles (Default aus) in Allgemein.
- Hook 1: Post-Processing-Ende (Paket completed/failed nach Entpacken).
- Hook 2: refreshPackageStatus fuer den Alle-Items-fehlgeschlagen-Fall (Link
  tot -> Paket erreicht das Post-Processing nie; ohne diesen Hook schwiege
  ausgerechnet der haeufigste Fehlerfall).
- Hook 3: finishRun mit Run-Summary (X/Y erfolgreich, Dauer, Schnitt).
- Dedup-Set pro Paket+Run, Lifecycle gespiegelt an historyRecordedPackages
  (Run-Start-Clear, Retry-Deletes, removePackageFromSession). Guard
  session.running || runPackageIds.has(id): nachlaufendes Entpacken nach
  Run-Ende benachrichtigt noch, Startup-Recovery nach App-Neustart nicht
  (sonst Doppel-Push fuer laengst fertige Pakete).
- 5s-Timeout, Fehler nur als logger.warn — blockiert nie den Download-Pfad.
- 9 Unit-Tests fuer notify.ts.
2026-06-09 20:50:58 +02:00
Sucukdeluxe
be4d54a6b5 Feature: "Letzte Fehler anzeigen" im Hilfe-Menue (Error-Ring ins UI)
Der Error-Ring aus v1.7.185 war bisher nur ueber die Debug-Server-URL mit
Token erreichbar — per RDP ist ein Menueklick drastisch schneller als curl.
Neuer Menuepunkt im Hilfe-Dropdown zeigt die letzten 200 WARN/ERROR-Eintraege
(Kopf: "X Fehler, Y Warnungen") im bestehenden Bestaetigungs-Dialog mit
aufklappbaren Details; der Bestaetigen-Knopf kopiert die komplette Liste in
die Zwischenablage — direkt verwertbar fuer Bug-Reports.

IPC-Kette nach dem GET_DEBUG_SETUP_CHECK-Muster (ipc.ts, main.ts mit direktem
error-ring-Import wie debug-server/support-bundle, preload, preload-api).
Read-only auf den In-Memory-Snapshot, kein neues CSS.
2026-06-09 20:45:21 +02:00
Sucukdeluxe
2a1a55401e Feature: Tonspur-Ergebnis sichtbar am Paket (audioStripSummary)
Die Antwort auf "warum hat Paket X noch .DL.?" steht bisher nur in den
Rename-/Item-Logs — "kein Deutsch-Tag" ist INFO-Level und taucht nirgends im
UI auf. Jetzt speichert keepGermanAudioOnlyImpl pro Paket eine Zusammenfassung
(remuxed/kept-single/ohne-DE-Tag/ffmpeg-fehlt/Fehler + bis zu 100 Datei-Details
mit Aktion, Grund und erkannten Sprachen) direkt am PackageEntry:

- Status-Spalte zeigt "Tonspur: 5 OK / 1 ohne DE-Tag / ffmpeg fehlt" (rot bei
  Auffaelligkeiten, flacher Stil), Datei-Details als Tooltip.
- Auch der ffmpeg-nicht-gefunden-Fruehausstieg schreibt die Summary.
- pkg.updatedAt wird gesetzt + Feld im Paket-Delta-Hash, damit der Snapshot
  die Aenderung pusht; normalizeLoadedSession whitelistet das Feld mit
  Shape-Validierung, sonst waere es nach jedem App-Neustart weg.
- 2 neue Integrationstests (Summary-Zaehler + ffmpeg-fehlt-Pfad).
2026-06-09 20:42:22 +02:00
Sucukdeluxe
aa65f56c28 Fix Mega-Web rotation skipping accounts on a timeout abort
When a Mega-Web account's unrestrict aborts because the shared unrestrict
timeout fired while it was running, give that account a 2-min cooldown
(only if it actually ran >=8s, so a quick user-cancel does not cool it
down). The download-manager retry then skips the cooled-down account and
rotates to the next one, instead of hammering the same account every 60s.

- debrid.ts: handle the abort in the rotation catch before classifyAccountFailure
- rotation log event TIMEOUT_COOLDOWN (+ renderer label) replaces the misleading
  red "fataler Fehler" for this case
- RD_MEGA_ABORT_MIN_RUN_MS env override for the run-length threshold
- 2 regression tests (cooldown set -> next call rotates; quick abort -> no cooldown)
2026-06-08 13:33:49 +02:00
Sucukdeluxe
77661389f3 Add "keep only German audio" post-extract step for .DL. files
- New video-processor.ts: ffmpeg/ffprobe remux that keeps only the German
  audio track (by language tag, with safe fallbacks) and strips the ".DL."
  marker from the filename
- Runs after extraction in both the deferred and hybrid post-process paths,
  inside the per-package file-op chain; abortable, disk-space checked,
  mtime-preserving, atomic temp->replace so the original is never lost
- System ffmpeg via PATH / RD_FFMPEG_BIN; toggle + track-mode select in settings
2026-06-07 21:17:26 +02:00
Sucukdeluxe
d006a60553 Backup: nur Settings als Default + 4 Selektions/Flicker-Bugfixes
Backup:
- Neues Setting backupIncludeDownloads (Default aus) — Backup sichert
  standardmaessig NUR Einstellungen, nicht die Download-Liste/History.
- buildBackupPayload/planBackupImport (testbare backup-payload.ts): Export
  omittet session+history wenn Flag aus (explizites kind-Marker); Import folgt
  dem FILE-Inhalt, nicht dem lokalen Toggle.
- importBackup: settings-only -> frueher Return nach setSettings, KEIN stop/
  Queue-Wipe/Relaunch. Return {restored,relaunch,message}; main.ts gated den
  Auto-Relaunch auf relaunch. Renderer re-seeded settingsDraft bei !relaunch.

Bugfixes:
- Ctrl+A waehlte das ungefilterte Paket-Map -> Loeschen nach Suche traf
  versteckte Pakete. Jetzt visibleOrderIds (sichtbare Zeilen, inkl. Items).
- selectedIds nie geprunt bei Delta-Removal -> aufgeblaehte Counts. Neue pure
  pruneSelection (selection.ts) + Effect.
- link-status-dot conditional -> Dateiname sprang ~14px. Platzhalter-Slot.
- sortPackagesForDisplay sortierte aktive Pakete nach Live-Progress -> Reshuffle
  pro Tick. Jetzt stabile Queue-Reihenfolge je Gruppe (Anti-Flicker).

+17 Tests (backup-payload 9, selection 5, package-order anti-flicker 3).
2026-06-07 04:40:54 +02:00
Sucukdeluxe
3ed3877ac9 chore: remove all source code comments and internal artifacts
Strip every comment from the source (parsed with the TypeScript compiler so
strings, template literals, regex literals and JSX are never touched), and drop
internal/working artifacts that do not belong in the public repository
(design mockups, internal analysis docs, a stray backup file and an old log).
No functional change: build is green, the full test suite passes.
2026-06-06 04:53:54 +02:00
Sucukdeluxe
ffcd0817cf Mega-Debrid: Account am Tageslimit bis Neustart parken (Streak-Heuristik) statt endlos neu testen
User-Entscheidung: ein Mega-Debrid-Account am Tageslimit soll bis zum Programm-Neustart
uebersprungen werden, nicht alle 20s/2min neu getestet.

Ground Truth (Support-Bundle gegrept): der limitierte Account liefert im Web-Pfad NIE eine
unterscheidbare Meldung — "Kein Server" = 0 Treffer, "Antwort leer" = 20.861. Tageslimit und
transienter Blip sind auf Message-Ebene nicht trennbar (generate() findet ohne processDebrid-
Code keinen Code -> return null -> "Antwort leer"). Ein Trigger auf "Kein Server" waere toter Code.

Loesung (Verhaltens-Signal statt Wortlaut):
- megaDebridEmptyResponseStreaks zaehlt aufeinanderfolgende "Antwort leer"/"Kein Server"-
  Treffer je Account; ab 3 wird der Account bis Neustart geparkt (until=MAX_SAFE_INTEGER,
  nur In-Memory -> Neustart loescht). Erfolg/anderer Fehler setzt zurueck.
- classifyAccountFailure markiert beide Signale als limitSignal (Symmetrie: ein einzelner
  evtl. transienter Treffer parkt NICHT, behaelt kurzen Cooldown).
- Skip-Branch: "uebersprungen (bis Neustart gesperrt)", traegt nicht zu earliestCooldownUntil
  bei (kein absurder Retry-Timer); Post-Loop wirft klare Endmeldung wenn alle geparkt.
- generate() surfacet "Kein Server" zusaetzlich als Page-Error (falls es doch im HTML steht).
- UI: Rotations-Verlauf zeigt "bis Neustart gesperrt".

Verifiziert: tsc 9 (Baseline), 655 Tests + 5 neue (inkl. Wiring-E2E der eine echte leere
Antwort durch unrestrictWithAccounts->classify->catch->Park treibt), Build gruen.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-31 21:08:43 +02:00
Sucukdeluxe
efb5696c13 Feature: Mega-Debrid-Account beim Hinzufuegen sofort pruefen (Gueltigkeit + Premium)
Beim "Hinzufuegen" eines Mega-Debrid-Accounts im Bearbeiten-Dialog wird der Account
jetzt sofort einzeln geprueft (connectUser) — Login-Gueltigkeit + Premium-Restlaufzeit
erscheinen direkt als Badge, ohne den Tab schliessen und "Alle pruefen" klicken zu
muessen. Waehrend der Pruefung zeigt das Badge "Pruefe…".

Neue Einzel-Check-IPC (Spiegel von checkDebridAccounts): CHECK_MEGA_DEBRID_ACCOUNT
-> app-controller.checkSingleMegaDebridAccount(login, password) baut den Account-Entry
(id via getMegaDebridAccountId), ruft die bestehende checkMegaDebridAccount() und merged
das Ergebnis via applyDebridAccountStatuses -> Snapshot -> Badge (gleicher Pfad wie
"Alle pruefen"). Funktioniert fuer den noch nicht gespeicherten Draft-Account, weil
applyDebridAccountStatuses merged (kein Pruning) + emitState.

Kern-Check-Logik unveraendert + weiterhin durch account-check.test.ts gedeckt.
643 Tests gruen, tsc 9 (unveraendert), Build sauber. GUI compile-/build-verifiziert,
im laufenden Electron noch nicht click-getestet.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-31 14:20:21 +02:00
Sucukdeluxe
66878174e6 Feature: Mega-Debrid-Accounts einzeln (temporaer) deaktivieren — UI-Toggle
Backend war bereits vorhanden (megaDebridDisabledAccountIds + Rotation-Skip +
Storage-Normalisierung); es fehlte nur das UI. Spiegelt das Debrid-Link-Muster:
im Account-Bearbeiten-Dialog bekommt jeder Mega-Account einen Aktivieren/
Deaktivieren-Toggle (+ "Deaktiviert"-Badge). Der Disabled-Zustand wird im Dialog-
Draft gehalten (megaDisabledIds) und beim Speichern via applyAccountDialogToSettings
in megaDebridDisabledAccountIds uebernommen (gefiltert auf vorhandene Accounts).
Kein Live-Persist mitten im Dialog -> kohaerent mit dem draft-then-Save-Modell.

Wirkt OHNE Neustart: DebridService.unrestrictLink liest this.settings live
(setSettings propagiert die Liste), unrestrictWithAccounts ueberspringt deaktivierte
Accounts (gleicher Mechanismus wie Daily-Limit/Cooldown-Skip).

Test: "skips a manually disabled Mega-Debrid account" — acc1 disabled -> acc2 loest
auf (beweist den ID-Seam getMegaDebridAccountId). 643 Tests gruen, tsc 9, Build sauber.
GUI-Toggle compile-/build-verifiziert, im laufenden Electron noch nicht click-getestet.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-31 13:08:09 +02:00
Sucukdeluxe
3977184fd4 Account-Rotation: Login/Premium-Badges + Live-Rotations-Panel + "Alle pruefen"
- Pro Mega-Debrid-Account UND Debrid-Link-Key im Bearbeiten-Dialog: Badge mit
  Login-Gueltigkeit + Premium-Restlaufzeit (connectUser vip_end / account/infos premiumLeft)
- "Alle pruefen"-Button oben rechts; prueft alle Accounts (Concurrency-Cap 4),
  Ergebnis persistiert (debridAccountStatuses), ueberlebt Neustart
- Rotations-Verlauf-Panel: zeigt live welcher Account/Key versucht wurde + warum
  gewechselt (Ring-Buffer -> Snapshot -> UI), statt nur "Link-Umwandlung erneut"
- Bug A: Mega-Debrid Per-Account-Verbrauch wurde nie erfasst (Heute/Insgesamt immer 0)
- Bug B: isProviderConfigured erkannte reine megaCredentials-Multi-Config nicht
- Neu: account-check.ts (standalone), CHECK_DEBRID_ACCOUNTS IPC, 13 Tests

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-30 21:19:23 +02:00
Sucukdeluxe
96bcbd13d7 Ember-Theme: warmer Amber-Akzent auf kühlem Navy
Redesign-Entscheid des Users (siehe design-mockups/): Aurora-Flavor "Ember".
Re-Skin der Dark+Light-Theme-Variablen + hartcodierte Cyan-Stellen:

- --accent Cyan #38bdf8 -> Amber #f2942d, neue --accent-2 Koral #ff7a5c
- Surfaces/Text/Muted leicht ins Warme verschoben (Warm-Kalt-Spannung:
  Amber-Signal auf kühlem Navy bleibt erhalten)
- Download-Progress Cyan-Gradient -> Amber->Koral (3 Stellen)
- Accent-Button + Border -> Amber
- Speed-Chart (App.tsx Canvas) Akzent -> Amber
- Grün (Entpacken/Online/Erfolg) bleibt semantisch unverändert

Bewusst KEINE Glas-/Glow-/Gradient-Mesh-Effekte (User lehnt KI-Look ab) —
nur die warme Farbwelt auf der bestehenden flachen Struktur.

design-mockups/: 4 Erst-Richtungen + Aurora-Flavor-Switcher + Forge (Referenz).
tasks/todo.md: Bug-/Feature-Analyse (3 parallele Subagents).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-23 16:17:47 +02:00
Sucukdeluxe
4d1f3c3fdc Performance: hash-based IPC state diffing (the big one)
Implements per-item / per-package hash-based diffing for the IPC state-update
channel. This is the architecturally biggest performance win — for queues
with thousands of items where most are idle between emits, this can cut
IPC payload size by 80-95%.

How it works:
1. New `getSnapshotForEmit()` method computes a compact hash per item and
   per package covering the visible/mutable fields. On each emit it includes
   only items/packages whose hash changed since the last emit, plus a list
   of removed IDs. Every 30 seconds a full resync is sent for safety.

2. A new `payloadKind: "full" | "delta"` field on UiSnapshot signals the
   format. `removedItemIds` and `removedPackageIds` lists carry deletions.

3. The renderer maintains a `masterSnapshotRef` and merges incoming deltas:
   spreads new items over master items, deletes the removed-IDs, then sets
   the merged snapshot as React state. Full payloads replace the master
   entirely (initial sync + 30s resync).

4. The existing direct `getSnapshot()` API used by app-controller, debug-server,
   and link-export is unchanged — they still get a full snapshot. Only the
   "state" emit channel uses delta encoding.

Trade-offs accepted:
- Hash computation cost: ~13 string concats per item per emit. With 5000
  items at 700ms intervals that's ~7100 hash ops/sec — well under 1ms total.
- The 30s full resync ensures any drift bug self-heals within 30s without
  user-visible glitch.
- Server keeps two extra Maps (item/package hash tracking).

Items / packages that are completely idle between emits add ZERO bytes to
the IPC payload now, instead of ~450 bytes per item. For a normal queue of
5000 items where ~30 are actively downloading, payload drops from ~3.6 MB
to ~30 KB per emit — a 100x reduction.

Tests: 140/140 download-manager + 133/133 storage+auto-rename green.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-19 14:10:48 +02:00
Sucukdeluxe
d71dd3af0b Performance: visiblePackages dep fix + ItemRow date memo + small Object.keys cuts
Five more low-risk hot-path optimizations:

1. visiblePackages no longer re-runs the sort callback on every item update.
   The sort is only meaningful when running && autoSort && >1 packages, so we
   pass null as items dep otherwise. Previously fired the full O(N) sort
   pass on every progress tick even when it would have returned the input
   array unchanged.

2. ItemRow memoizes formattedCreatedAt + displayStatus + statusTitle so a
   row that re-renders because of progress/speed changes no longer pays for
   formatDateTime() and computeDisplayedItemStatus() twice (title+body).

3. resetSessionTotalsIfQueueEmpty: removed redundant Object.keys() check.
   itemCount + packageOrder.length cover the same condition without
   allocating two intermediate arrays.

4. markQueuedAsReconnectWait: replaced Object.keys() array allocation with
   for-in iteration when runItemIds is empty. Saves a 5000-element string
   array allocation every 900ms during reconnect.

5. columnOrderJson useEffect dep: replaced JSON.stringify with cached
   join() + useMemo. Stringifying a 7-element settings array on every
   render was ~2-3ms per render for nothing.

All 140 download-manager tests green. Renderer + main both build clean.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-19 13:46:57 +02:00
Sucukdeluxe
3c9894c7b0 Performance: ItemRow extraction + scheduler single-pass + selectedIds memo fix
Major optimizations to reduce UI lag with large queues (5000+ items):

1. ItemRow extracted to its own memoized component (renderer)
   Previously every package re-render mapped all its items inline,
   producing N×M re-renders per state update. Now each item-row only
   re-renders when ITS specific data changes, with custom equality on
   the visible fields (status, progress, speed, fullStatus, etc.).
   Also adds stable useCallback handlers per item.

2. PackageCard stats consolidated into single useMemo (renderer)
   Replaces 5 separate filter()/some() + 2 reduce() calls (O(7N)) with
   one O(N) pass collecting all aggregates (done/failed/cancelled/
   extracted/extracting/activeProgress/extractingProgress).

3. selectedIds memo comparator fixed (renderer)
   Custom equality now checks if selection state changed for items in
   THIS package only. Previously any selection anywhere broke memo on
   all 200+ visible PackageCards.

4. Scheduler single-pass queue presence (main)
   New getQueuePresence() returns hasImmediate + hasDelayed in one
   iteration. Replaces hasQueuedItems() + hasDelayedQueuedItems() that
   each scanned packages independently. Saves one full O(n) iteration
   per scheduler tick.

No functional changes. All 565 tests green.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-19 13:07:42 +02:00
Sucukdeluxe
bece2f3e85 Performance: prune long-lived caches, hoist regexes, idle chart redraws
Three low-risk optimizations that reduce CPU/memory footprint without
changing user-visible behavior:

1. Periodic cleanup of unbounded module-level Maps (24/7 stability):
   - debridLinkKeyCooldowns, debridLinkKeyCooldownDetails,
     debridLinkKeyRuntimeStatuses (debrid.ts)
   - megaDebridAccountCooldowns (debrid.ts)
   - allDebridHostInfoCache (download-manager.ts)
   - All pruned every 10 min via existing resetStaleRetryState() with a
     1h grace window for debugging
   - Without this, modules accumulated entries indefinitely over days
     of continuous server operation

2. Hoist regex literals in resolveArchiveItemsFromList() to module scope.
   Avoids 5 RegExp constructions per call. The function is called per
   archive set during extraction discovery — adds up on packages with
   many archives.

3. BandwidthChart: skip the 250ms redraw interval while the session is
   stopped or paused. The chart renders once on state change to show the
   latest history, then sleeps until downloads resume. Saves 4 canvas
   redraws per second when idle (renderer CPU).

No functional changes. All 565 tests green.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-19 12:32:38 +02:00
Sucukdeluxe
38179881f5 Fix Debrid-Link key rotation cascade failure, case-sensitive rename, and sample filter
- notDebrid (host-level) no longer burns all keys: stops rotation immediately
  with 5min cooldown instead of cycling through all 9 keys pointlessly
- Remove double provider-blockade: debrid_link_cooldown no longer stacks
  recordProviderFailure + applyProviderBusyBackoff on top of key cooldowns
- Detect timeout cascades: 2+ consecutive transport failures trigger 3min
  cooldown instead of burning remaining keys
- Case-sensitive rename: files with different casing (e.g. lowercase scene
  names) now get properly renamed instead of being skipped as "already matching"
- Extended sample filter: detect -s.mkv suffix and \Sample\ subdirectories
  in auto-rename (already worked in MKV-move)
- Add key status display with state pills in Debrid-Link key stats popup
- Add parseDebridLinkTerminalFailure for fast-fail on exhausted keys

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 13:04:42 +01:00
Sucukdeluxe
65650737b1 Refactor Mega-Debrid account UI from textarea to proper account list
Replace the raw login:password textarea with a proper form-based UI:
- Individual Login + Password input fields with "Hinzufügen" button
- List of configured accounts with masked logins and "Entfernen" button
- Duplicate login detection
- Storage format unchanged (megaCredentials stays login:password pairs)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 21:35:17 +01:00
Sucukdeluxe
6df0834b67 Add Mega-Debrid multi-account support with automatic fallback
Multiple Mega-Debrid accounts can now be configured as login:password
pairs (one per line). When an account hits Fair-Use limits or errors,
the next account is tried automatically.

- New parser module mega-debrid-accounts.ts (parse, ID generation,
  masking, serialization)
- Per-account daily limits, usage tracking, enable/disable
- Account rotation with per-mode cooldowns (API failures don't
  block Web attempts)
- Backward compatible: existing single megaLogin/megaPassword
  is auto-migrated to the new format
- UI: textarea for credentials, account list with masked logins

Follows the existing Debrid-Link multi-key pattern.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 20:12:51 +01:00
Sucukdeluxe
17e947fc6b Harden type safety and recovery guards 2026-03-10 05:54:19 +01:00
Sucukdeluxe
6d7b3686dc Add AVI video-library support and startup recovery fixes 2026-03-10 00:43:51 +01:00
Sucukdeluxe
51d4e2100f Rename backup menu actions 2026-03-09 18:16:30 +01:00
Sucukdeluxe
05df79d518 Refine statistics overview layout 2026-03-09 05:53:05 +01:00
Sucukdeluxe
40f097249c Fix manual extract relabeling 2026-03-09 05:38:56 +01:00
Sucukdeluxe
3de4ba3e90 Fix final post-process requeue stall 2026-03-09 05:33:09 +01:00
Sucukdeluxe
1afce943ae Fix history timing and retention controls 2026-03-09 05:16:41 +01:00
Sucukdeluxe
1f9a26e4b0 Add app runtime statistics 2026-03-09 04:59:00 +01:00
Sucukdeluxe
55e0ebd0f8 Add dedicated rename support logging 2026-03-09 04:48:58 +01:00
Sucukdeluxe
2066d0ad26 Keep manually collapsed packages closed 2026-03-09 04:30:08 +01:00
Sucukdeluxe
85a9a2fa9f Add package and item link export 2026-03-09 04:11:18 +01:00
Sucukdeluxe
7027e11cbd Add support self-check diagnostics 2026-03-09 03:00:36 +01:00
Sucukdeluxe
fc4fafa0d6 Harden support logging and debug setup 2026-03-09 02:47:49 +01:00
Sucukdeluxe
f5f7f14104 Add support bundle and trace tooling 2026-03-09 02:15:32 +01:00
Sucukdeluxe
56ce7c2aea Add remote host and item diagnostics 2026-03-09 01:21:11 +01:00
Sucukdeluxe
87212ddf76 Fix Real-Debrid resume size mismatch handling 2026-03-09 00:32:41 +01:00
Sucukdeluxe
83c0c18dca Hide generic waiting states in queue 2026-03-08 22:02:27 +01:00
Sucukdeluxe
63f404285f Tighten idle queue and disk busy status display 2026-03-08 21:18:18 +01:00
Sucukdeluxe
6a0079f9d0 Harden Debrid-Link cooldown and quota handling 2026-03-08 20:30:33 +01:00
Sucukdeluxe
38c9058beb Fix session stats, extraction UX, and queue UI issues 2026-03-08 03:42:06 +01:00
Sucukdeluxe
9eb28cee2e Add per-package detailed logs 2026-03-08 01:41:23 +01:00
Sucukdeluxe
934f24ae22 Add shift-click range selection for downloads list
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 20:18:27 +01:00