From efb5696c13e84e6970596231a6cb19958125a3d2 Mon Sep 17 00:00:00 2001 From: Sucukdeluxe Date: Sun, 31 May 2026 14:20:21 +0200 Subject: [PATCH] Feature: Mega-Debrid-Account beim Hinzufuegen sofort pruefen (Gueltigkeit + Premium) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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) --- src/main/app-controller.ts | 17 +++++++++++++- src/main/main.ts | 4 ++++ src/preload/preload.ts | 1 + src/renderer/App.tsx | 48 +++++++++++++++++++++++++++++++------- src/shared/ipc.ts | 1 + src/shared/preload-api.ts | 1 + 6 files changed, 63 insertions(+), 9 deletions(-) diff --git a/src/main/app-controller.ts b/src/main/app-controller.ts index 745d61b..c642549 100644 --- a/src/main/app-controller.ts +++ b/src/main/app-controller.ts @@ -24,7 +24,8 @@ import { importDlcContainers } from "./container"; import { APP_VERSION } from "./constants"; import { DownloadManager } from "./download-manager"; import { fetchAllDebridHostInfo, fetchDebridLinkHostLimits } from "./debrid"; -import { checkAllDebridAccounts } from "./account-check"; +import { checkAllDebridAccounts, checkMegaDebridAccount } from "./account-check"; +import { parseMegaDebridAccounts } from "../shared/mega-debrid-accounts"; import { parseCollectorInput } from "./link-parser"; import { configureLogger, getLogFilePath, logger } from "./logger"; import { AllDebridWebFallback } from "./all-debrid-web"; @@ -389,6 +390,20 @@ public async checkDebridAccounts(): Promise { }); return statuses; } + + /** Check a SINGLE Mega-Debrid account by raw credentials (used when an account + * is added in the dialog, before it is saved) and merge the result so the + * validity/premium badge updates immediately — without a full "Alle pruefen". */ + public async checkSingleMegaDebridAccount(login: string, password: string): Promise { + const entry = parseMegaDebridAccounts(`${login.trim()}:${password.trim()}`)[0]; + if (!entry) { + return null; + } + const status = await checkMegaDebridAccount(entry); + this.manager.applyDebridAccountStatuses([status]); + this.audit("INFO", "Mega-Debrid-Account einzeln geprueft", { valid: status.valid, premium: status.isPremium }); + return status; + } public async checkUpdates(): Promise { const result = await checkGitHubUpdate(this.settings.updateRepo); if (!result.error) { diff --git a/src/main/main.ts b/src/main/main.ts index 40c0d5c..3d916f4 100644 --- a/src/main/main.ts +++ b/src/main/main.ts @@ -648,6 +648,10 @@ function registerIpcHandlers(): void { return controller.checkDebridAccounts(); }); + ipcMain.handle(IPC_CHANNELS.CHECK_MEGA_DEBRID_ACCOUNT, async (_event, login: string, password: string) => { + return controller.checkSingleMegaDebridAccount(String(login || ""), String(password || "")); + }); + ipcMain.handle(IPC_CHANNELS.IMPORT_BACKUP, async () => { const options = { properties: ["openFile"] as Array<"openFile">, diff --git a/src/preload/preload.ts b/src/preload/preload.ts index 99fd059..4ee9ee6 100644 --- a/src/preload/preload.ts +++ b/src/preload/preload.ts @@ -77,6 +77,7 @@ const api: ElectronApi = { getAllDebridHostInfo: (): Promise => ipcRenderer.invoke(IPC_CHANNELS.GET_ALLDEBRID_HOST_INFO), getDebridLinkHostLimits: (): Promise => ipcRenderer.invoke(IPC_CHANNELS.GET_DEBRIDLINK_HOST_LIMITS), checkDebridAccounts: (): Promise => ipcRenderer.invoke(IPC_CHANNELS.CHECK_DEBRID_ACCOUNTS), + checkMegaDebridAccount: (login: string, password: string): Promise => ipcRenderer.invoke(IPC_CHANNELS.CHECK_MEGA_DEBRID_ACCOUNT, login, password), retryExtraction: (packageId: string): Promise => ipcRenderer.invoke(IPC_CHANNELS.RETRY_EXTRACTION, packageId), extractNow: (packageId: string): Promise => ipcRenderer.invoke(IPC_CHANNELS.EXTRACT_NOW, packageId), resetPackage: (packageId: string): Promise => ipcRenderer.invoke(IPC_CHANNELS.RESET_PACKAGE, packageId), diff --git a/src/renderer/App.tsx b/src/renderer/App.tsx index 35d9868..35cd8ad 100644 --- a/src/renderer/App.tsx +++ b/src/renderer/App.tsx @@ -1611,6 +1611,8 @@ export function App(): ReactElement { const [showAllPackages, setShowAllPackages] = useState(false); const [actionBusy, setActionBusy] = useState(false); const [accountCheckBusy, setAccountCheckBusy] = useState(false); + // Account-IDs, die gerade beim Hinzufügen einzeln geprüft werden (Mega-Debrid). + const [megaCheckingIds, setMegaCheckingIds] = useState>(() => new Set()); const actionBusyRef = useRef(false); const actionUnlockTimerRef = useRef | null>(null); const mountedRef = useRef(true); @@ -2663,6 +2665,24 @@ export function App(): ReactElement { } }, [showToast]); + const runMegaAccountCheck = useCallback(async (login: string, password: string): Promise => { + const trimmedLogin = login.trim(); + const trimmedPassword = password.trim(); + if (!trimmedLogin || !trimmedPassword) return; + const accId = getMegaDebridAccountId(trimmedLogin); + setMegaCheckingIds((prev) => { const next = new Set(prev); next.add(accId); return next; }); + try { + const status = await window.rd.checkMegaDebridAccount(trimmedLogin, trimmedPassword); + if (status) { + showToast(status.valid ? `Account geprüft — ${status.message}` : `Account ungültig — ${status.message}`, 3200); + } + } catch (error) { + showToast(`Account-Check fehlgeschlagen: ${String(error)}`, 3200); + } finally { + setMegaCheckingIds((prev) => { const next = new Set(prev); next.delete(accId); return next; }); + } + }, [showToast]); + const openCreateAccountDialog = (): void => { setAccountDialogSearch(""); setAccountDialog(createAccountDialogState("create", null, settingsDraft)); @@ -5677,13 +5697,23 @@ export function App(): ReactElement { @@ -5700,7 +5730,9 @@ export function App(): ReactElement { Account {index + 1} {maskMegaDebridLogin(account.login)} {accDisabled && Deaktiviert} - {(() => { + {megaCheckingIds.has(accId) + ? Prüfe… + : (() => { const st = snapshot?.settings?.debridAccountStatuses?.[accId]; if (!st) return Noch nicht geprüft; const checkedAgo = formatCheckedAgo(st.checkedAt); diff --git a/src/shared/ipc.ts b/src/shared/ipc.ts index 91b1a6e..9c1211f 100644 --- a/src/shared/ipc.ts +++ b/src/shared/ipc.ts @@ -56,6 +56,7 @@ export const IPC_CHANNELS = { GET_ALLDEBRID_HOST_INFO: "app:get-alldebrid-host-info", GET_DEBRIDLINK_HOST_LIMITS: "app:get-debridlink-host-limits", CHECK_DEBRID_ACCOUNTS: "app:check-debrid-accounts", + CHECK_MEGA_DEBRID_ACCOUNT: "app:check-mega-debrid-account", RETRY_EXTRACTION: "queue:retry-extraction", EXTRACT_NOW: "queue:extract-now", RESET_PACKAGE: "queue:reset-package", diff --git a/src/shared/preload-api.ts b/src/shared/preload-api.ts index 6841c99..7cdd158 100644 --- a/src/shared/preload-api.ts +++ b/src/shared/preload-api.ts @@ -74,6 +74,7 @@ export interface ElectronApi { getAllDebridHostInfo: () => Promise; getDebridLinkHostLimits: () => Promise; checkDebridAccounts: () => Promise; + checkMegaDebridAccount: (login: string, password: string) => Promise; retryExtraction: (packageId: string) => Promise; extractNow: (packageId: string) => Promise; resetPackage: (packageId: string) => Promise;