mirror of
https://github.com/PR0M3TH3AN/bitvid.git
synced 2026-10-27 07:52:24 +00:00
fix(video-modal): wire the share popover's Copy URL / Magnet / CDN buttons
The share popover's menu items (Copy URL, Copy Magnet, Copy CDN Link, Share on Nostr) only set `data-action` — like the ⋯ menu — but unlike the ⋯ menu (which moreMenuController delegates) nothing wired their clicks, so they did nothing. Only the bottom "forced-source" test links self-wire. Same dead-button class as the old embed/creator-link bugs. Add a delegated click handler on the share panel (bindShareMenuActions) that routes each action to the event videoModalController already handles: copy-magnet → video:copy-magnet, copy-cdn → video:copy-cdn, share-nostr → video:share-nostr, and share (Copy URL) → a new video:copy-url (buildShareUrl makes the plain `?v=<nevent>` deep link; controller copies it with a toast). Forced-source links are skipped (they self-wire). Tests: tests/video-modal-controllers.test.mjs (+5 routing scenarios, 24/24). Lint + build clean. Co-Authored-By: Claude Opus 4.8 <[email protected]>
This commit is contained in:
1 parent
0df1f7e2ad
commit
793d609d6a
3 files changed
+178
No files matched your search
@@ -308,3 +308,76 @@ test("reaction click with no matching button does not dispatch", async (t) => {
|
||||
modal.handleReactionClick({});
|
||||
assert.equal(fired, false, "no reaction event for an unrelated/empty target");
|
||||
});
|
||||
|
||||
// Share popover (reported: "Copy URL / Copy Magnet / Copy CDN don't work"). The
|
||||
// share menu buttons only set data-action (like the ⋯ menu), but unlike the ⋯
|
||||
// menu nothing wired their clicks, so they were dead. handleShareMenuAction now
|
||||
// routes each to the event videoModalController already handles.
|
||||
//
|
||||
// test_integrity_note:
|
||||
// change_type: ["new_tests"]
|
||||
// scenarios:
|
||||
// - id: SCN-video-modal-share-menu-routing
|
||||
// given: "a video modal with an active video"
|
||||
// when: "handleShareMenuAction runs for a share-menu action"
|
||||
// then: "it dispatches the matching video:* event; forced-source actions do not re-route"
|
||||
// determinism_controls:
|
||||
// - "JSDOM modal via setupModal; synchronous dispatch"
|
||||
// relaxation:
|
||||
// did_relax_any_assertion: false
|
||||
|
||||
test("share menu Copy Magnet routes to video:copy-magnet", async (t) => {
|
||||
const { modal, cleanup } = await setupModal();
|
||||
t.after(cleanup);
|
||||
modal.activeVideo = { id: "e".repeat(64), url: "https://x/v.mp4", magnet: "" };
|
||||
const events = [];
|
||||
modal.addEventListener("video:copy-magnet", (e) => events.push(e.detail));
|
||||
modal.handleShareMenuAction("copy-magnet");
|
||||
assert.equal(events.length, 1, "Copy Magnet dispatches video:copy-magnet");
|
||||
assert.equal(events[0].video.id, "e".repeat(64));
|
||||
});
|
||||
|
||||
test("share menu Copy CDN routes to video:copy-cdn", async (t) => {
|
||||
const { modal, cleanup } = await setupModal();
|
||||
t.after(cleanup);
|
||||
modal.activeVideo = { id: "e".repeat(64), url: "https://x/v.mp4" };
|
||||
const events = [];
|
||||
modal.addEventListener("video:copy-cdn", (e) => events.push(e.detail));
|
||||
modal.handleShareMenuAction("copy-cdn");
|
||||
assert.equal(events.length, 1, "Copy CDN dispatches video:copy-cdn");
|
||||
assert.equal(events[0].video.url, "https://x/v.mp4");
|
||||
});
|
||||
|
||||
test("share menu Copy URL routes to video:copy-url", async (t) => {
|
||||
const { modal, cleanup } = await setupModal();
|
||||
t.after(cleanup);
|
||||
modal.activeVideo = { id: "e".repeat(64) };
|
||||
const events = [];
|
||||
modal.addEventListener("video:copy-url", (e) => events.push(e.detail));
|
||||
modal.handleShareMenuAction("share");
|
||||
assert.equal(events.length, 1, "Copy URL dispatches video:copy-url");
|
||||
assert.equal(typeof events[0].url, "string");
|
||||
});
|
||||
|
||||
test("share menu Share on Nostr routes to video:share-nostr", async (t) => {
|
||||
const { modal, cleanup } = await setupModal();
|
||||
t.after(cleanup);
|
||||
modal.activeVideo = { id: "e".repeat(64) };
|
||||
const events = [];
|
||||
modal.addEventListener("video:share-nostr", (e) => events.push(e.detail));
|
||||
modal.handleShareMenuAction("share-nostr");
|
||||
assert.equal(events.length, 1, "Share on Nostr dispatches video:share-nostr");
|
||||
});
|
||||
|
||||
test("share menu forced-source actions do not re-route through handleShareMenuAction", async (t) => {
|
||||
const { modal, cleanup } = await setupModal();
|
||||
t.after(cleanup);
|
||||
modal.activeVideo = { id: "e".repeat(64) };
|
||||
let fired = false;
|
||||
["video:copy-magnet", "video:copy-cdn", "video:copy-url", "video:share-nostr"].forEach(
|
||||
(name) => modal.addEventListener(name, () => { fired = true; })
|
||||
);
|
||||
modal.handleShareMenuAction("copy-cdn-url");
|
||||
modal.handleShareMenuAction("copy-webtorrent-url");
|
||||
assert.equal(fired, false, "forced-source links self-wire; not routed here");
|
||||
});
|
||||
Reference in new issue
Block a user