diff --git a/js/forYouView.js b/js/forYouView.js index 8fceac2d..dcef54ec 100644 --- a/js/forYouView.js +++ b/js/forYouView.js @@ -1,5 +1,6 @@ import { getApplication } from "./applicationContext.js"; import { devLogger } from "./utils/logger.js"; +import { attachFeedInfoPopover } from "./ui/components/FeedInfoPopover.js"; const VIDEO_CARD_SELECTOR = "[data-component=\"video-card\"]"; const EMPTY_STATE_SELECTOR = "[data-for-you-empty-state]"; @@ -23,6 +24,14 @@ class ForYouView { this.container.addEventListener("click", this.handleContainerClick); this.observeContainer(); this.updateEmptyState(); + + const infoTrigger = this.document.getElementById("feedInfoTrigger"); + if (infoTrigger) { + attachFeedInfoPopover( + infoTrigger, + "Most Recent Video - Disinterests Tags - Watch History + Interests Tags" + ); + } } observeContainer() { diff --git a/js/ui/components/FeedInfoPopover.js b/js/ui/components/FeedInfoPopover.js new file mode 100644 index 00000000..904694a8 --- /dev/null +++ b/js/ui/components/FeedInfoPopover.js @@ -0,0 +1,44 @@ +import createPopover from "../overlay/popoverEngine.js"; + +/** + * Attaches an informational popover to a trigger element. + * + * @param {HTMLElement} triggerElement - The element that triggers the popover. + * @param {string} text - The text content to display in the popover. + * @param {object} [options] - Optional configuration. + * @param {string} [options.placement="bottom-start"] - Popover placement. + * @returns {object|null} - The popover instance or null if failed. + */ +export function attachFeedInfoPopover(triggerElement, text, options = {}) { + if (!triggerElement || typeof text !== "string") { + return null; + } + + const render = ({ document: doc, close }) => { + const panel = doc.createElement("div"); + panel.className = "popover-panel p-4 max-w-xs text-sm text-text-strong bg-surface-elevated border border-surface-line rounded-lg shadow-lg z-50"; + panel.textContent = text; + // Ensure the panel can receive focus if needed, but primarily it's informational. + // Making it a "tooltip" or "dialog" role might be appropriate depending on interaction. + // Since it's a click-toggle info box, standard popover behavior is fine. + + // Add a simple close behavior if clicked outside (handled by popoverEngine), + // but maybe we want to close if clicked inside too? + // Usually info popovers stay open until clicked away. + + return panel; + }; + + const popover = createPopover(triggerElement, render, { + placement: options.placement || "bottom-start", + ...options, + }); + + triggerElement.addEventListener("click", (event) => { + event.preventDefault(); + event.stopPropagation(); + popover.toggle(); + }); + + return popover; +} diff --git a/verification/feed_info.png b/verification/feed_info.png new file mode 100644 index 00000000..7a90fed1 Binary files /dev/null and b/verification/feed_info.png differ diff --git a/verification/verify_feed_info.py b/verification/verify_feed_info.py new file mode 100644 index 00000000..92274637 --- /dev/null +++ b/verification/verify_feed_info.py @@ -0,0 +1,54 @@ +import sys +import os +import time +from playwright.sync_api import sync_playwright + +def verify_feed_info(page): + print("Pre-seeding localStorage...") + page.goto("http://localhost:8000") # Go to root first to set storage origin + page.evaluate("window.localStorage.setItem('hasSeenDisclaimer', 'true')") + + print("Navigating to For You view...") + page.goto("http://localhost:8000/#view=for-you") + + print("Waiting for feed info trigger...") + trigger = page.locator("#feedInfoTrigger") + try: + trigger.wait_for(state="visible", timeout=10000) + except Exception: + page.screenshot(path="verification/debug_not_found.png") + raise + + # Ensure no modals are blocking + # We can try to force click or wait for potential overlays to disappear + # But pre-seeding should handle the main one. + + print("Clicking trigger...") + trigger.click() + + print("Waiting for popover...") + popover = page.locator(".popover-panel") + popover.wait_for(state="visible", timeout=5000) + + text = popover.inner_text() + print(f"Popover text: {text}") + + expected = "Most Recent Video - Disinterests Tags - Watch History + Interests Tags" + if expected not in text: + raise Exception(f"Unexpected text: {text}") + + page.screenshot(path="verification/feed_info.png") + print("Screenshot saved to verification/feed_info.png") + +if __name__ == "__main__": + with sync_playwright() as p: + browser = p.chromium.launch(headless=True) + context = browser.new_context() + page = context.new_page() + try: + verify_feed_info(page) + except Exception as e: + print(f"Error: {e}") + sys.exit(1) + finally: + browser.close() diff --git a/views/for-you.html b/views/for-you.html index 64f03865..c02a06ab 100644 --- a/views/for-you.html +++ b/views/for-you.html @@ -1,6 +1,30 @@
-

For You

+
+

For You

+ +