diff --git a/js/channelProfile.js b/js/channelProfile.js index 08f13623..a2825b87 100644 --- a/js/channelProfile.js +++ b/js/channelProfile.js @@ -936,7 +936,26 @@ function isZapControlsOpen() { function openZapControls({ focus = false } = {}) { const zapButton = getChannelZapButton(); - if (!zapButton || !zapPopover) { + if (!zapButton) { + return false; + } + + if (!zapPopover || zapPopoverTrigger !== zapButton) { + const initialized = setupZapButton({ force: true }); + if (!initialized || !zapPopover || zapPopoverTrigger !== zapButton) { + return false; + } + } + + if (typeof zapPopover?.preload === "function") { + try { + zapPopover.preload(); + } catch (error) { + devLogger.warn("[zap] Failed to preload zap popover before opening", error); + } + } + + if (!zapPopover) { return false; } zapShouldFocusOnOpen = focus; @@ -2473,6 +2492,31 @@ function setupZapButton({ force = false } = {}) { zapPopover = popover; zapPopoverTrigger = zapButton; + const warmZapPopover = () => { + if (!zapPopover || zapPopoverTrigger !== zapButton) { + return; + } + if (typeof zapPopover.preload === "function") { + try { + zapPopover.preload(); + } catch (error) { + devLogger.warn("[zap] Failed to preload zap popover", error); + } + } + }; + + warmZapPopover(); + + if (zapButton.dataset.zapPopoverWarmBound !== "true") { + const handleWarm = () => { + warmZapPopover(); + }; + zapButton.addEventListener("pointerenter", handleWarm, { once: true }); + zapButton.addEventListener("pointerdown", handleWarm, { once: true }); + zapButton.addEventListener("focus", handleWarm, { once: true }); + zapButton.dataset.zapPopoverWarmBound = "true"; + } + if (zapButton.dataset.initialized !== "true") { zapButton.addEventListener("click", handleZapButtonClick); zapButton.dataset.initialized = "true"; diff --git a/js/ui/overlay/popoverEngine.js b/js/ui/overlay/popoverEngine.js index 138b7d9c..d818c0e4 100644 --- a/js/ui/overlay/popoverEngine.js +++ b/js/ui/overlay/popoverEngine.js @@ -671,6 +671,10 @@ export function createPopover(trigger, render, options = {}) { return panel; } + function preload() { + return Boolean(ensurePanel()); + } + async function updatePosition() { if (!anchor || !panel) { return; @@ -918,6 +922,7 @@ export function createPopover(trigger, render, options = {}) { update: updatePosition, isOpen: () => isOpen, getPanel: () => panel, + preload, }; return api;