diff --git a/js/app.js b/js/app.js index 69e91851..763ef7cd 100644 --- a/js/app.js +++ b/js/app.js @@ -3849,6 +3849,21 @@ class bitvidApp { this.pubkey = pubkey; + let reloadScheduled = false; + if (saveToStorage) { + try { + localStorage.setItem("userPubKey", pubkey); + reloadScheduled = true; + } catch (err) { + console.warn("[app.js] Failed to persist pubkey:", err); + } + } + + if (reloadScheduled) { + window.location.reload(); + return; + } + // Hide login button if present if (this.loginButton) { this.loginButton.classList.add("hidden"); @@ -3877,11 +3892,6 @@ class bitvidApp { // (Optional) load the user's own Nostr profile this.loadOwnProfile(pubkey); - // Save pubkey locally if requested - if (saveToStorage) { - localStorage.setItem("userPubKey", pubkey); - } - // Refresh the video list so the user sees any private videos, etc. await this.loadVideos(); diff --git a/js/webtorrent.js b/js/webtorrent.js index ee8aac8b..8e8add87 100644 --- a/js/webtorrent.js +++ b/js/webtorrent.js @@ -713,6 +713,74 @@ export class TorrentClient { }); } + async destroyWithTimeout( + target, + { label = "resource", args = [], timeoutMs = 8000 } = {} + ) { + if (!target || typeof target.destroy !== "function") { + return; + } + + const safeTimeout = Math.max( + 1000, + Math.min( + Number.isFinite(timeoutMs) ? timeoutMs : 8000, + this.TIMEOUT_DURATION + ) + ); + + await new Promise((resolve) => { + let settled = false; + + const finalize = () => { + if (settled) { + return; + } + settled = true; + clearTimeout(timeoutId); + resolve(); + }; + + const logError = (error) => { + if (error) { + this.log(`[cleanup] ${label} destroy error:`, error); + } + }; + + const timeoutId = setTimeout(() => { + this.log( + `[cleanup] ${label} destroy timed out after ${safeTimeout}ms; forcing resolution.` + ); + finalize(); + }, safeTimeout); + + const callback = (error) => { + logError(error); + finalize(); + }; + + let result; + try { + result = target.destroy(...args, callback); + } catch (error) { + logError(error); + finalize(); + return; + } + + if (result && typeof result.then === "function") { + result + .then(() => { + finalize(); + }) + .catch((error) => { + logError(error); + finalize(); + }); + } + }); + } + /** * Initiates streaming of a torrent magnet to a