Refresh UI on manual login and guard torrent cleanup

This commit is contained in:
thePR0M3TH3AN
2025-09-27 23:07:08 -04:00
parent c638b273fe
commit 546fb4d1d2
2 changed files with 110 additions and 13 deletions

View File

@@ -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();

View File

@@ -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 <video> element.
* Ensures the service worker is set up only once and the client is reused.
@@ -778,19 +846,38 @@ export class TorrentClient {
async cleanup() {
try {
if (this.currentTorrent) {
this.currentTorrent.destroy();
try {
await this.destroyWithTimeout(this.currentTorrent, {
label: "current torrent",
args: [{ destroyStore: true }],
});
} finally {
this.currentTorrent = null;
}
}
// Destroy client entirely and set to null so a future streamVideo call starts fresh
if (this.client) {
await this.client.destroy();
this.client = null;
try {
await this.destroyWithTimeout(this.client, {
label: "WebTorrent client",
});
} finally {
this.client = null;
this.serverCreated = false;
}
} else {
this.serverCreated = false;
}
if (this.probeClient) {
await this.probeClient.destroy();
this.probeClient = null;
try {
await this.destroyWithTimeout(this.probeClient, {
label: "probe client",
});
} finally {
this.probeClient = null;
}
}
this.currentTorrent = null;
this.serverCreated = false;
} catch (error) {
this.log("Cleanup error:", error);
}