From e5556c938e8e696da36944892e73d0fe9f192f2b Mon Sep 17 00:00:00 2001 From: thePR0M3TH3AN <53631862+PR0M3TH3AN@users.noreply.github.com> Date: Mon, 27 Oct 2025 18:19:14 -0400 Subject: [PATCH] Fix edit modal magnet hint refresh --- js/ui/components/EditModal.js | 36 +++++++++--- tests/edit-modal-submit-state.test.mjs | 80 ++++++++++++++++++++++++++ 2 files changed, 109 insertions(+), 7 deletions(-) diff --git a/js/ui/components/EditModal.js b/js/ui/components/EditModal.js index a6c336d0..92d1c70d 100644 --- a/js/ui/components/EditModal.js +++ b/js/ui/components/EditModal.js @@ -891,11 +891,29 @@ export class EditModal { const finalTitle = titleWasEdited ? newTitle : original.title || ""; const finalUrl = urlWasEdited ? newUrl : original.url || ""; - const shouldUseOriginalWs = wsInput ? wsInput.readOnly !== false : true; - const shouldUseOriginalXs = xsInput ? xsInput.readOnly !== false : true; - let finalWs = shouldUseOriginalWs ? original.ws || "" : newWs; - let finalXs = shouldUseOriginalXs ? original.xs || "" : newXs; - let finalMagnet = magnetWasEdited ? newMagnet : original.magnet || ""; + const originalMagnetValue = + typeof original.magnet === "string" ? original.magnet.trim() : ""; + const originalWsValue = + typeof original.ws === "string" ? original.ws.trim() : ""; + const originalXsValue = + typeof original.xs === "string" ? original.xs.trim() : ""; + + const wsWasManuallyEdited = wsInput ? wsInput.readOnly === false : false; + const xsWasManuallyEdited = xsInput ? xsInput.readOnly === false : false; + + let finalMagnet = magnetWasEdited ? newMagnet : originalMagnetValue; + let finalWs = wsWasManuallyEdited ? newWs : originalWsValue; + let finalXs = xsWasManuallyEdited ? newXs : originalXsValue; + + if (magnetWasEdited) { + const magnetHintCandidates = extractMagnetHints(finalMagnet); + if (!wsWasManuallyEdited) { + finalWs = magnetHintCandidates.ws || ""; + } + if (!xsWasManuallyEdited) { + finalXs = magnetHintCandidates.xs || ""; + } + } const finalThumbnail = isEditing(thumbnailInput) ? newThumbnail : original.thumbnail || ""; @@ -990,6 +1008,10 @@ export class EditModal { finalXs = ""; } + const magnetChanged = magnetWasEdited && finalMagnet !== originalMagnetValue; + const wsEditedFlag = wsWasManuallyEdited || magnetChanged; + const xsEditedFlag = xsWasManuallyEdited || magnetChanged; + const updatedData = { version: original.version || 2, title: finalTitle, @@ -1000,8 +1022,8 @@ export class EditModal { mode: this.resolveModeForSubmit(), ws: finalWs, xs: finalXs, - wsEdited: !shouldUseOriginalWs, - xsEdited: !shouldUseOriginalXs, + wsEdited: wsEditedFlag, + xsEdited: xsEditedFlag, urlEdited: urlWasEdited, magnetEdited: magnetWasEdited, enableComments: finalEnableComments, diff --git a/tests/edit-modal-submit-state.test.mjs b/tests/edit-modal-submit-state.test.mjs index 97f3d7fd..56d4ecfc 100644 --- a/tests/edit-modal-submit-state.test.mjs +++ b/tests/edit-modal-submit-state.test.mjs @@ -192,6 +192,86 @@ test('ignores additional submissions while pending without spurious errors', asy modal.setSubmitState({ pending: false }); }); +test('editing the magnet refreshes torrent hints when ws/xs remain locked', async () => { + const modal = createModal(); + await modal.load({ container }); + + const originalMagnet = + 'magnet:?xt=urn:btih:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&ws=https://old.example/video.mp4&xs=https://old.example/video.torrent'; + const video = { + id: 'video-magnet-locked', + pubkey: 'pubkey-magnet-locked', + title: 'Locked hints example', + url: 'https://example.com/locked.mp4', + magnet: originalMagnet, + ws: 'https://old.example/video.mp4', + xs: 'https://old.example/video.torrent', + }; + + await modal.open(video); + + const submissions = []; + modal.addEventListener('video:edit-submit', (event) => { + submissions.push(event.detail); + }); + + const magnetButton = modal.root.querySelector( + '[data-edit-target="editVideoMagnet"]', + ); + assert.ok(magnetButton, 'expected magnet unlock button to exist'); + magnetButton.dispatchEvent(new dom.window.Event('click', { bubbles: true })); + + const magnetInput = modal.fields.magnet; + assert.ok(magnetInput, 'expected magnet input to exist'); + magnetInput.value = + 'magnet:?xt=urn:btih:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb&ws=https://new.example/video.mp4&xs=https://new.example/video.torrent'; + + modal.submit(); + + assert.equal(submissions.length, 1, 'should emit a single submission payload'); + const submission = submissions[0]; + assert.ok(submission, 'expected edit submission detail'); + + assert.equal( + submission.updatedData.wsEdited, + true, + 'ws should be marked as edited when magnet changes', + ); + assert.equal( + submission.updatedData.xsEdited, + true, + 'xs should be marked as edited when magnet changes', + ); + assert.equal( + submission.updatedData.ws, + 'https://new.example/video.mp4', + 'ws hint should refresh to the new magnet hint', + ); + assert.equal( + submission.updatedData.xs, + 'https://new.example/video.torrent', + 'xs hint should refresh to the new magnet hint', + ); + assert.ok( + submission.updatedData.magnet.includes( + 'urn:btih:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb', + ), + 'normalized magnet should contain the updated info hash', + ); + assert.ok( + submission.updatedData.magnet.includes('ws=https://new.example/video.mp4'), + 'normalized magnet should include the refreshed ws hint', + ); + assert.ok( + submission.updatedData.magnet.includes( + 'xs=https://new.example/video.torrent', + ), + 'normalized magnet should include the refreshed xs hint', + ); + + modal.setSubmitState({ pending: false }); +}); + test('does not show missing video error after modal closes', async () => { const errorMessages = []; const modal = createModal({