declare global { interface Window { Raychat?: { openWidget?: () => void; open?: () => void; isWidgetOpen?: () => boolean; }; } } const RAYCHAT_FOREGROUND_Z_INDEX = "2000000002"; const RAYCHAT_BACKGROUND_Z_INDEX = "1"; let launcherSyncTimer: number | null = null; let openRetryTimer: number | null = null; let shouldKeepLauncherHidden = false; let raychatOpenOverrideUntil = 0; const clearLauncherSyncTimer = () => { if (launcherSyncTimer !== null) { window.clearInterval(launcherSyncTimer); launcherSyncTimer = null; } }; const clearOpenRetryTimer = () => { if (openRetryTimer !== null) { window.clearInterval(openRetryTimer); openRetryTimer = null; } }; const getRaychatIframe = () => { return document.getElementById("raychat_widget") as HTMLIFrameElement | null; }; const isRaychatAvailable = () => { if (typeof document === "undefined" || typeof window === "undefined") { return false; } return ( typeof window.Raychat?.openWidget === "function" || typeof window.Raychat?.open === "function" || !!getRaychatIframe() ); }; const isIframeOpen = (iframe: HTMLIFrameElement) => { const rect = iframe.getBoundingClientRect(); return rect.width > 120 || rect.height > 120; }; const isRaychatWidgetOpen = () => { if (typeof window === "undefined") { return false; } try { return window.Raychat?.isWidgetOpen?.() === true; } catch { return false; } }; const setIframeVisibilityHidden = ( iframe: HTMLIFrameElement, hidden: boolean, ) => { iframe.style.visibility = hidden ? "hidden" : ""; iframe.style.opacity = hidden ? "0" : ""; iframe.style.pointerEvents = hidden ? "none" : ""; iframe.style.zIndex = hidden ? RAYCHAT_BACKGROUND_Z_INDEX : RAYCHAT_FOREGROUND_Z_INDEX; }; const setIframeVisible = () => { const iframe = getRaychatIframe(); if (!iframe) { return; } setIframeVisibilityHidden(iframe, false); }; const getLauncherButton = (frameDocument: Document | undefined) => { if (!frameDocument) { return null; } return frameDocument.querySelector( ".sc_launcher .launcher_centered, .sc_launcher_inner .launcher_centered, .sc_launcher_inner", ) as HTMLElement | null; }; const setIframeLauncherHidden = (hidden: boolean) => { try { const iframe = getRaychatIframe(); if (!iframe) { return false; } const frameDocument = iframe?.contentWindow?.document; const shouldHideIframe = hidden && Date.now() >= raychatOpenOverrideUntil && !isIframeOpen(iframe) && !isRaychatWidgetOpen(); if (!frameDocument) { setIframeVisibilityHidden(iframe, shouldHideIframe); return true; } const launcher = frameDocument.querySelector( ".sc_launcher", ) as HTMLElement | null; const greeting = frameDocument.querySelector( ".greeting_container_wrapper", ) as HTMLElement | null; if (launcher) { launcher.style.display = hidden ? "none" : ""; } if (greeting) { greeting.style.display = hidden ? "none" : ""; } setIframeVisibilityHidden(iframe, shouldHideIframe); return true; } catch { return false; } }; const tryOpenRaychat = () => { if (typeof window.Raychat?.openWidget === "function") { try { window.Raychat.openWidget(); return true; } catch { console.debug("[mori-widget] Raychat openWidget failed"); } } if (typeof window.Raychat?.open === "function") { try { window.Raychat.open(); return true; } catch { console.debug("[mori-widget] Raychat open failed"); } } try { const iframe = getRaychatIframe(); const frameDocument = iframe?.contentWindow?.document; const launcherButton = getLauncherButton(frameDocument); if (iframe && !isIframeOpen(iframe) && launcherButton) { launcherButton.click(); return true; } } catch { console.debug("[mori-widget] Raychat iframe open failed"); } return false; }; export const openRaychatChat = () => { if (!isRaychatAvailable()) { console.debug("[mori-widget] Raychat is not available"); return; } raychatOpenOverrideUntil = Date.now() + 10000; setIframeVisible(); setIframeLauncherHidden(false); tryOpenRaychat(); clearOpenRetryTimer(); let attempts = 0; openRetryTimer = window.setInterval(() => { attempts += 1; setIframeVisible(); setIframeLauncherHidden(false); tryOpenRaychat(); const iframe = getRaychatIframe(); if ( isRaychatWidgetOpen() || (iframe ? isIframeOpen(iframe) : false) || attempts >= 20 ) { clearOpenRetryTimer(); } }, 250); console.debug("[mori-widget] Opening Raychat chat"); }; export const setRaychatLauncherHidden = (hidden: boolean) => { if (typeof document === "undefined") { return; } shouldKeepLauncherHidden = hidden; if (!hidden) { raychatOpenOverrideUntil = 0; clearOpenRetryTimer(); clearLauncherSyncTimer(); setIframeLauncherHidden(false); return; } setIframeLauncherHidden(true); if (launcherSyncTimer !== null) { return; } launcherSyncTimer = window.setInterval(() => { if (!shouldKeepLauncherHidden) { clearLauncherSyncTimer(); return; } setIframeLauncherHidden(true); }, 300); }; export {};