declare global { interface Window { $gapify?: { isOpen?: boolean; toggle?: (state?: "open" | "close") => void; toggleBubbleVisibility?: (state: "hide" | "show") => void; }; } } const GAPIFY_FOREGROUND_Z_INDEX = "2000000002"; const GAPIFY_BACKGROUND_Z_INDEX = "1"; let launcherSyncTimer: number | null = null; let openRetryTimer: number | null = null; let shouldKeepLauncherHidden = false; let gapifyOpenOverrideUntil = 0; const clearLauncherSyncTimer = () => { if (launcherSyncTimer !== null) { window.clearInterval(launcherSyncTimer); launcherSyncTimer = null; } }; const clearOpenRetryTimer = () => { if (openRetryTimer !== null) { window.clearInterval(openRetryTimer); openRetryTimer = null; } }; const getGapifyWidgetHolder = () => { return ( (document.getElementById("cw-widget-holder") as HTMLElement | null) || (document.querySelector(".woot-widget-holder") as HTMLElement | null) ); }; const getGapifyBubbleHolder = () => { return ( (document.getElementById("cw-bubble-holder") as HTMLElement | null) || (document.querySelector(".woot--bubble-holder") as HTMLElement | null) ); }; const getGapifyBubbleButton = () => { return document.querySelector(".woot-widget-bubble") as HTMLElement | null; }; const isGapifyAvailable = () => { if (typeof document === "undefined" || typeof window === "undefined") { return false; } return ( typeof window.$gapify?.toggle === "function" || !!getGapifyWidgetHolder() || !!getGapifyBubbleHolder() ); }; const isGapifyWidgetOpen = () => { if (typeof window === "undefined") { return false; } const holder = getGapifyWidgetHolder(); if (holder && !holder.classList.contains("woot--hide")) { return true; } return window.$gapify?.isOpen === true; }; const setElementVisibility = (element: HTMLElement, hidden: boolean) => { element.style.visibility = hidden ? "hidden" : ""; element.style.opacity = hidden ? "0" : ""; element.style.pointerEvents = hidden ? "none" : ""; element.style.zIndex = hidden ? GAPIFY_BACKGROUND_Z_INDEX : GAPIFY_FOREGROUND_Z_INDEX; }; const setGapifyLauncherVisibilityHidden = (hidden: boolean) => { const widgetHolder = getGapifyWidgetHolder(); const bubbleHolder = getGapifyBubbleHolder(); if (!widgetHolder && !bubbleHolder) { return false; } const shouldHideWidgetHolder = hidden && Date.now() >= gapifyOpenOverrideUntil && !isGapifyWidgetOpen(); if (typeof window.$gapify?.toggleBubbleVisibility === "function") { try { window.$gapify.toggleBubbleVisibility(hidden ? "hide" : "show"); } catch { console.debug("[mori-widget] Gapify toggleBubbleVisibility failed", { hidden, }); } } if (bubbleHolder) { setElementVisibility(bubbleHolder, hidden); } if (widgetHolder) { setElementVisibility(widgetHolder, shouldHideWidgetHolder); } console.debug("[mori-widget] Gapify launcher hidden", { hidden }); return true; }; const tryOpenGapify = () => { if (typeof window.$gapify?.toggleBubbleVisibility === "function") { try { window.$gapify.toggleBubbleVisibility("show"); } catch { console.debug("[mori-widget] Gapify open failed"); } } if (typeof window.$gapify?.toggle === "function") { try { window.$gapify.toggle("open"); return true; } catch { console.debug("[mori-widget] Gapify open failed"); } } const bubbleButton = getGapifyBubbleButton(); if (bubbleButton) { bubbleButton.click(); return true; } return false; }; export const openGapifyChat = () => { if (!isGapifyAvailable()) { console.debug("[mori-widget] Gapify is not available"); return; } gapifyOpenOverrideUntil = Date.now() + 10000; setGapifyLauncherVisibilityHidden(false); tryOpenGapify(); clearOpenRetryTimer(); let attempts = 0; openRetryTimer = window.setInterval(() => { attempts += 1; setGapifyLauncherVisibilityHidden(false); tryOpenGapify(); if (isGapifyWidgetOpen() || attempts >= 20) { clearOpenRetryTimer(); } }, 250); console.debug("[mori-widget] Opening Gapify chat"); }; export const setGapifyLauncherHidden = (hidden: boolean) => { if (typeof document === "undefined") { return; } shouldKeepLauncherHidden = hidden; if (!hidden) { gapifyOpenOverrideUntil = 0; clearOpenRetryTimer(); clearLauncherSyncTimer(); setGapifyLauncherVisibilityHidden(false); return; } setGapifyLauncherVisibilityHidden(true); if (launcherSyncTimer !== null) { return; } launcherSyncTimer = window.setInterval(() => { if (!shouldKeepLauncherHidden) { clearLauncherSyncTimer(); return; } setGapifyLauncherVisibilityHidden(true); }, 300); }; export {};