diff --git a/js/ui/components/VideoModal.js b/js/ui/components/VideoModal.js index a48758a9..c693e176 100644 --- a/js/ui/components/VideoModal.js +++ b/js/ui/components/VideoModal.js @@ -2997,8 +2997,12 @@ export class VideoModal { this.dispatch("action:copy", { video: this.activeVideo }); } - handleShareRequest() { - this.dispatch("action:share", { video: this.activeVideo }); + handleShareRequest(event) { + if (this.modalSharePopover) { + this.modalSharePopover.toggle(); + } else { + this.dispatch("action:share", { video: this.activeVideo }); + } } handleEmbedRequest() { @@ -3249,9 +3253,9 @@ export class VideoModal { this.modalMorePopover.destroy(); } - this.modalMorePopover = createPopover({ - trigger: this.modalMoreBtn, - content: (container) => { + this.modalMorePopover = createPopover( + this.modalMoreBtn, + ({ container }) => { if (!this.activeVideo) { container.innerHTML = ""; return; @@ -3269,18 +3273,21 @@ export class VideoModal { container.appendChild(panel); this.modalMoreMenuPanel = panel; } + return panel; }, - placement: "bottom-end", - offset: 8, - onOpen: () => { - if (this.activeVideo) { - this.syncMoreMenuData({ - currentVideo: this.activeVideo, - canManageBlacklist: this.modalMoreMenuContext.canManageBlacklist, - }); - } - }, - }); + { + placement: "bottom-end", + offset: 8, + onOpen: () => { + if (this.activeVideo) { + this.syncMoreMenuData({ + currentVideo: this.activeVideo, + canManageBlacklist: this.modalMoreMenuContext.canManageBlacklist, + }); + } + }, + } + ); } setupModalSharePopover() { @@ -3298,9 +3305,9 @@ export class VideoModal { this.modalSharePopover.destroy(); } - this.modalSharePopover = createPopover({ - trigger: this.shareBtn, - content: (container) => { + this.modalSharePopover = createPopover( + this.shareBtn, + ({ container }) => { if (!this.activeVideo) { container.innerHTML = ""; return; @@ -3316,10 +3323,14 @@ export class VideoModal { if (panel) { container.appendChild(panel); } + return panel; }, - placement: "top", // or "top-start" based on layout - offset: 8, - }); + { + placement: "top", // or "top-start" based on layout + offset: 8, + document: this.document, + } + ); } refreshModalMoreMenuPanel() { diff --git a/tests/e2e/relay-resilience.spec.ts b/tests/e2e/relay-resilience.spec.ts index acffee8d..1b98d347 100644 --- a/tests/e2e/relay-resilience.spec.ts +++ b/tests/e2e/relay-resilience.spec.ts @@ -241,7 +241,7 @@ test.describe("Relay resilience and management", () => { // Wait for initial feed await page.evaluate(() => { - return (window as any).__bitvidTest__.waitForFeedItems(1, 15000); + return (window as any).__bitvidTest__.waitForFeedItems(1, 30000); }); // When: clear and re-seed with different content diff --git a/tests/e2e/search-and-filter.spec.ts b/tests/e2e/search-and-filter.spec.ts index be4eab67..fdd0643d 100644 --- a/tests/e2e/search-and-filter.spec.ts +++ b/tests/e2e/search-and-filter.spec.ts @@ -75,7 +75,7 @@ test.describe("Search and filtering", () => { // Wait for all videos to load await page.evaluate(() => { - return (window as any).__bitvidTest__.waitForFeedItems(3, 20000); + return (window as any).__bitvidTest__.waitForFeedItems(3, 30000); }); // When: user searches for "Cooking" @@ -118,7 +118,7 @@ test.describe("Search and filtering", () => { await loginAs(page); await page.evaluate(() => { - return (window as any).__bitvidTest__.waitForFeedItems(1, 15000); + return (window as any).__bitvidTest__.waitForFeedItems(1, 30000); }); // When: user searches for something that doesn't match @@ -154,7 +154,7 @@ test.describe("Search and filtering", () => { await loginAs(page); await page.evaluate(() => { - return (window as any).__bitvidTest__.waitForFeedItems(1, 15000); + return (window as any).__bitvidTest__.waitForFeedItems(1, 30000); }); const searchInput = page.locator('[data-testid="search-input"]'); diff --git a/tests/e2e/video-edit-delete-execution.spec.ts b/tests/e2e/video-edit-delete-execution.spec.ts index 0b425667..94efda4d 100644 --- a/tests/e2e/video-edit-delete-execution.spec.ts +++ b/tests/e2e/video-edit-delete-execution.spec.ts @@ -35,7 +35,7 @@ async function setupAndOpenSettings( await loginAs(page); await page.evaluate(() => - (window as any).__bitvidTest__.waitForFeedItems(1, 15000), + (window as any).__bitvidTest__.waitForFeedItems(1, 30000), ); const card = page.locator("[data-video-card]").first(); diff --git a/tests/e2e/video-engagement.spec.ts b/tests/e2e/video-engagement.spec.ts index ffe7f180..bbe665b7 100644 --- a/tests/e2e/video-engagement.spec.ts +++ b/tests/e2e/video-engagement.spec.ts @@ -32,7 +32,7 @@ async function openVideoModal( await loginAs(page); await page.evaluate(() => { - return (window as any).__bitvidTest__.waitForFeedItems(1, 15000); + return (window as any).__bitvidTest__.waitForFeedItems(1, 30000); }); await page.locator("#playerModal").waitFor({ state: "attached", timeout: 15000 }); diff --git a/tests/e2e/video-modal-share-bug.spec.ts b/tests/e2e/video-modal-share-bug.spec.ts index b738f8ce..7ff8cd13 100644 --- a/tests/e2e/video-modal-share-bug.spec.ts +++ b/tests/e2e/video-modal-share-bug.spec.ts @@ -30,19 +30,23 @@ test.describe("video modal share button", () => { // Force loaded state and hydrate const playerModal = document.getElementById("playerModal"); if (playerModal) { + videoModal.document = document; videoModal.loaded = true; videoModal.hydrate(playerModal); // Mock an active video so the share menu has data - videoModal.activeVideo = { + const activeVideo = { id: "test-video-id", title: "Test Video", url: "https://example.com/video.mp4", magnet: "magnet:?xt=urn:btih:test", }; + videoModal.shareNostrAuthState = { isLoggedIn: true, hasSigner: true }; + // Open the modal - videoModal.open(videoModal.activeVideo); + videoModal.open(activeVideo); + videoModal.setShareEnabled(true); } window.__videoModal = videoModal; @@ -53,9 +57,10 @@ test.describe("video modal share button", () => { const modal = page.locator("#playerModal"); await expect(modal).not.toHaveClass(/hidden/); - // Click share button + // Ensure modal is visible and click share button const shareBtn = page.locator("#shareBtn"); await expect(shareBtn).toBeVisible(); + await shareBtn.click(); // Expect popover to be open diff --git a/tests/e2e/video-upload-flow.spec.ts b/tests/e2e/video-upload-flow.spec.ts index d0d81a5c..cde95798 100644 --- a/tests/e2e/video-upload-flow.spec.ts +++ b/tests/e2e/video-upload-flow.spec.ts @@ -92,7 +92,7 @@ test.describe("Video upload and discovery", () => { // Then: feed items should contain the seeded video const items = await page.evaluate(() => { - return (window as any).__bitvidTest__.waitForFeedItems(1, 15000); + return (window as any).__bitvidTest__.waitForFeedItems(1, 30000); }); expect(items.length).toBeGreaterThanOrEqual(1); @@ -123,7 +123,7 @@ test.describe("Video upload and discovery", () => { // Then: the video appears with magnet attribute const items = await page.evaluate(() => { - return (window as any).__bitvidTest__.waitForFeedItems(1, 15000); + return (window as any).__bitvidTest__.waitForFeedItems(1, 30000); }); expect(items.length).toBeGreaterThanOrEqual(1); @@ -165,7 +165,7 @@ test.describe("Video upload and discovery", () => { // Then: all three videos appear const items = await page.evaluate(() => { - return (window as any).__bitvidTest__.waitForFeedItems(3, 20000); + return (window as any).__bitvidTest__.waitForFeedItems(3, 30000); }); expect(items.length).toBeGreaterThanOrEqual(3); @@ -202,7 +202,7 @@ test.describe("Video upload and discovery", () => { await loginAs(page); await page.evaluate(() => { - return (window as any).__bitvidTest__.waitForFeedItems(1, 15000); + return (window as any).__bitvidTest__.waitForFeedItems(1, 30000); }); // Then: the video card DOM elements have correct data attributes diff --git a/tests/e2e/view-navigation.spec.ts b/tests/e2e/view-navigation.spec.ts index 61da2ba5..a97d7d62 100644 --- a/tests/e2e/view-navigation.spec.ts +++ b/tests/e2e/view-navigation.spec.ts @@ -171,7 +171,7 @@ test.describe("View navigation — direct hash routing", () => { // Then: the feed should populate with the seeded video const items = await page.evaluate(() => { - return (window as any).__bitvidTest__.waitForFeedItems(1, 15000); + return (window as any).__bitvidTest__.waitForFeedItems(1, 30000); }); expect(items.length).toBeGreaterThanOrEqual(1); }); @@ -256,7 +256,7 @@ test.describe("View navigation — feed with seeded content", () => { // Then: both videos should appear in the feed const items = await page.evaluate(() => { - return (window as any).__bitvidTest__.waitForFeedItems(2, 15000); + return (window as any).__bitvidTest__.waitForFeedItems(2, 30000); }); expect(items.length).toBeGreaterThanOrEqual(2); @@ -282,7 +282,7 @@ test.describe("View navigation — feed with seeded content", () => { await loginAs(page); await page.evaluate(() => { - return (window as any).__bitvidTest__.waitForFeedItems(1, 15000); + return (window as any).__bitvidTest__.waitForFeedItems(1, 30000); }); // When: user navigates to kids view and back