From 11c7884366c0c0e30748d29a99be6b5956ea7b06 Mon Sep 17 00:00:00 2001 From: thePR0M3TH3AN <53631862+PR0M3TH3AN@users.noreply.github.com> Date: Thu, 2 Jul 2026 09:12:14 -0400 Subject: [PATCH] [edit] Derive a webseed torrent when editing a video's URL to an external link MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Mirror the upload-modal external-URL webseed for the Edit modal: when the user changes a video's URL to an external link with no magnet, auto-derive the webseed torrent (fetch + hash the remote file → magnet ws=url) so an edited external URL keeps the P2P benefit. Best-effort + size-capped; on CORS / too-large / any error it stays URL-only. Runs before the existing magnet normalization so the derived magnet's ws/xs are extracted the same way a pasted magnet's are. submit() is now async (it was fire-and-forget from the form handler; the pendingSubmit guard already prevents re-entry, so it just stays "pending" during the derivation). Known gap: hosting the tiny .torrent (xs=) on the edit path needs storage- credential plumbing the Edit modal doesn't currently have — so the edit path is ws=-only for now (upload path hosts xs= when storage is unlocked). Tracked as a follow-up. Edit-modal submit-state + upload-field tests green. Lint + build green. Co-Authored-By: Claude Opus 4.8 --- js/ui/components/EditModal.js | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/js/ui/components/EditModal.js b/js/ui/components/EditModal.js index 098a62f1..a76f0611 100644 --- a/js/ui/components/EditModal.js +++ b/js/ui/components/EditModal.js @@ -888,7 +888,7 @@ export class EditModal { } } - submit() { + async submit() { if (this.pendingSubmit) { return; } @@ -1076,6 +1076,34 @@ export class EditModal { return; } + // Auto-derive a webseed torrent when the URL was changed to an external link + // with no magnet, so an edited external URL keeps the P2P benefit (magnet + // ws=url). Best-effort + size-capped; on CORS / too-large / any error it stays + // URL-only. Runs before the magnet normalization below so the derived magnet's + // ws/xs are extracted the same way a pasted magnet's are. (Hosting the tiny + // .torrent (xs=) on the edit path needs credential plumbing — a follow-up.) + if ( + urlWasEdited && + finalUrl && + !finalMagnet && + typeof this.mediaUploader?.deriveTorrentForExternalUrl === "function" + ) { + try { + const derived = await this.mediaUploader.deriveTorrentForExternalUrl( + finalUrl, + {}, + ); + if (derived?.magnet) { + finalMagnet = derived.magnet; + } + } catch (error) { + devLogger.warn( + "[EditModal] External URL webseed derivation skipped:", + error?.message || error, + ); + } + } + if (finalMagnet) { // When the web seed list was manually edited, replace the magnet's full // ws= set with exactly what's in the field — this is what makes removal