diff --git a/js/ui/components/VideoModal.js b/js/ui/components/VideoModal.js index dbdbf833..a612b40e 100644 --- a/js/ui/components/VideoModal.js +++ b/js/ui/components/VideoModal.js @@ -2994,7 +2994,10 @@ export class VideoModal { } handleCopyRequest() { - this.dispatch("action:copy", { video: this.activeVideo }); + // ModalManager listens for "video:copy-magnet" (it runs app.handleCopyMagnet). + // The previous "action:copy" name had no listener, so the copy-magnet button + // did nothing — same dead-event bug as the embed button. + this.dispatch("video:copy-magnet", { video: this.activeVideo }); } handleShareRequest(event) { diff --git a/tests/video-modal-zap.test.mjs b/tests/video-modal-zap.test.mjs index 20f0df54..b1cd121e 100644 --- a/tests/video-modal-zap.test.mjs +++ b/tests/video-modal-zap.test.mjs @@ -1026,6 +1026,20 @@ const { VideoModal } = await import("../js/ui/components/VideoModal.js"); assert.ok(embedDetail, 'embed must dispatch "video:embed" (the listened name)'); assert.equal(embedDetail.video?.id, "vid-embed", "carries the active video"); assert.equal(staleFired, false, 'must not use the dead "action:embed" name'); + + // Same bug class on copy-magnet: manager listens for "video:copy-magnet". + let copyDetail = null; + modal.addEventListener("video:copy-magnet", (event) => { + copyDetail = event?.detail || null; + }); + let staleCopy = false; + modal.addEventListener("action:copy", () => { + staleCopy = true; + }); + modal.handleCopyRequest(); + assert.ok(copyDetail, 'copy must dispatch "video:copy-magnet" (the listened name)'); + assert.equal(copyDetail.video?.id, "vid-embed", "carries the active video"); + assert.equal(staleCopy, false, 'must not use the dead "action:copy" name'); })(); process.exit(0); diff --git a/todo/TODO_2026-06-20_pre-launch.md b/todo/TODO_2026-06-20_pre-launch.md index 0057247b..751d910e 100644 --- a/todo/TODO_2026-06-20_pre-launch.md +++ b/todo/TODO_2026-06-20_pre-launch.md @@ -232,11 +232,11 @@ un-hides when WebTorrent flips green). The real gaps: embed button fired an event into the void. (Share survives the same mismatch only because `shareBtn` also toggles a popover directly.) Now dispatches `"video:embed"`. Regression test in `tests/video-modal-zap.test.mjs`. -- [ ] **Sibling bug (not yet fixed):** `handleCopyRequest` has the SAME mismatch — - dispatches `"action:copy"` with no listener (manager listens for - `"video:copy-magnet"`), and `#copyMagnetBtn` has no popover fallback. So the - standalone copy-magnet button is also dead. Lower urgency (copy is also - available in the share/⋯ menus), but fix it the same way when convenient. +- [x] **Sibling bug FIXED (2026-06-23):** `handleCopyRequest` had the SAME mismatch — + dispatched `"action:copy"` with no listener (manager listens for + `"video:copy-magnet"` → `app.handleCopyMagnet`), and `#copyMagnetBtn` has no + popover fallback, so the standalone copy-magnet button was also dead. Now + dispatches `"video:copy-magnet"`. Covered by the same regression test. ### 19. Direct messages: can read but cannot SEND — deep audit (BUG) - [ ] DMs are pulled in and readable, but sending appears to do nothing / fails.