diff --git a/static/embed.js b/static/embed.js index 8047cf79af..bf2322ddab 100644 --- a/static/embed.js +++ b/static/embed.js @@ -1,182 +1,197 @@ +function createButton() { + const button = document.createElement('div'); + button.id = "wiseengage-guests-embed-button"; + + // 初始化样式 + Object.assign(button.style, { + overflow: "hidden", + position: "fixed", + userSelect: "none", + right: "20px", + bottom: "40px", + zIndex: "9999", + width: "50px", + height: "50px", + borderRadius: "50%", + display: "flex", + justifyContent: "center", + alignItems: "center", + boxShadow: "0px 4px 8px rgba(0, 0, 0, 0.2)", + cursor: "pointer", + }); + button.style.backgroundColor = '#2160fd' + button.style.padding = '8px' + const iconImgEl = document.createElement('img'); + iconImgEl.src = '/logo/iframe-enter-icon-logo.svg'; + iconImgEl.style.width = '100%'; + iconImgEl.style.height = '100%'; + button.appendChild(iconImgEl); + + return button; +} + +function createIframe() { + const iframeWrap = document.createElement('div'); + const iframe = document.createElement('iframe'); + + iframeWrap.id = "wiseengage-guests-embed-iframe-wrap"; + iframe.id = "wiseengage-guests-embed-iframe"; + + Object.assign(iframeWrap.style, { + position: "fixed", + zIndex: "10000", + borderRadius: "10px", + boxShadow: "0px 10px 30px rgba(150, 150, 150, 0.2), 0px 0px 0px 1px rgba(150, 150, 150, 0.2)", + transition: "transform 0.3s ease, opacity 0.3s ease", + transform: "scale(0)", + transformOrigin: "right bottom", + opacity: 0, + }); + + Object.assign(iframe.style, { + width: "100%", + height: "100%", + }); + + return { iframeWrap, iframe }; +} + (function () { - console.log('[IFRAME] hello, embed injected') - - const isMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent); - - const button = document.createElement('div'); - const iframe = document.createElement('iframe'); - - button.id = "openim-customer-service-embed-button"; - iframe.id = "openim-customer-service-embed-iframe"; - - let isMinMode = false; - let isInit = false; - const iframeSrc = "https://web.rentsoft.cn"; - const allowedOrigins = [iframeSrc]; - - function initUI() { - Object.assign(button.style, { - overflow: "hidden", - position: "fixed", - userSelect: "none", - right: "20px", - bottom: "40px", - zIndex: "9999", - width: "50px", - height: "50px", - borderRadius: "50%", - display: "flex", - justifyContent: "center", - alignItems: "center", - boxShadow: "0px 4px 8px rgba(0, 0, 0, 0.2)", - cursor: "pointer", - }); - button.style.backgroundColor = '#2160fd' - button.style.padding = '8px' - const iconImgEl = document.createElement('img'); - iconImgEl.src = '/logo/iframe-enter-icon-logo.svg'; - iconImgEl.style.width = '100%'; - iconImgEl.style.height = '100%'; - button.appendChild(iconImgEl); + console.log('[IFRAME] hello, embed injected') + + const isMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent); + + let isMinMode = false; + let isInit = false; + let isLoadIframe = false; + + // DEBUG: + const iframeSrc = "https://web.rentsoft.cn"; + const allowedOrigins = [iframeSrc]; + + const { iframeWrap, iframe } = createIframe(); + const button = createButton(); + function initUI() { + document.body.appendChild(iframeWrap); + document.body.appendChild(button); + isInit = true; + + adjustIframeStyleForSmallScreens(); + } + + const fireToIframe = (event, data) => { + iframe.contentWindow?.postMessage({ event, data }, '*'); + }; + + button.onclick = function () { + console.log('[embed] click button') + + const isMinWidth = window.matchMedia("(max-width: 768px)").matches || isMobile; + const isHidden = iframeWrap.style.transform === "scale(0)"; + + if (isHidden) { + if (!isLoadIframe) { iframe.src = iframeSrc; - Object.assign(iframe.style, { - position: "fixed", - zIndex: "10000", - borderRadius: "10px", - boxShadow: "0px 10px 30px rgba(150, 150, 150, 0.2), 0px 0px 0px 1px rgba(150, 150, 150, 0.2)", - transition: "transform 0.3s ease, opacity 0.3s ease", - transform: "scale(0)", - transformOrigin: "right bottom", - opacity: 0, - }); - - document.body.appendChild(iframe); - isInit = true; - - adjustIframeStyleForSmallScreens(); + iframeWrap.appendChild(iframe); + isLoadIframe = true; + } + fireToIframe('openIframe', isMinWidth); + iframeWrap.style.transform = "scale(1)"; + iframeWrap.style.opacity = 1; + } else { + iframeWrap.style.transform = "scale(0)"; + iframeWrap.style.opacity = 0; + } + if (isMinWidth && isHidden) { + document.body.style.overflow = 'hidden'; + document.documentElement.style.overflow = 'hidden'; } + }; - const fireToIframe = (event, data) => { - iframe.contentWindow?.postMessage({ event, data }, '*'); - }; - - button.onclick = function () { - console.log('[embed] click button') - - const isMinWidth = window.matchMedia("(max-width: 768px)").matches || isMobile; - const isHidden = iframe.style.transform === "scale(0)"; - - if (isHidden) { - fireToIframe('openIframe', isMinWidth); - iframe.style.transform = "scale(1)"; - iframe.style.opacity = 1; - } else { - iframe.style.transform = "scale(0)"; - iframe.style.opacity = 0; - } - if (isMinWidth && isHidden) { - document.body.style.overflow = 'hidden'; - document.documentElement.style.overflow = 'hidden'; + let isGetConfig = false; + const rpc = setupParentRPCListener({ + allowedOrigins: allowedOrigins, // ★ 必填:子页面来源 + debug: true, + handler: async function ({ action, data }) { + if (action === 'closeIframe') { + iframeWrap.style.transform = "scale(0)"; + iframeWrap.style.opacity = 0; + document.body.style.overflow = ''; + document.documentElement.style.overflow = ''; + } + if (action === 'toogleSize') { + iframeWrap.style.width = isMinMode ? "720px" : "420px"; + iframeWrap.style.height = isMinMode ? "80vh" : "60vh"; + isMinMode = !isMinMode; + } + if (action === 'getConfig') { + console.log('get config', data, isGetConfig); + if(isGetConfig) return; + document.body.appendChild(button); + isGetConfig = true; + } + }, + }); + + // 在页面关闭/刷新时清理监听,避免内存泄漏,并使变量被有效使用 + try { + window.addEventListener('beforeunload', function () { + try { + if (rpc && typeof rpc.dispose === 'function') { + rpc.dispose(); } - }; - - let isGetConfig = false; - const rpc = setupParentRPCListener({ - allowedOrigins: allowedOrigins, // ★ 必填:子页面来源 - debug: true, - handler: async function ({ action, data }) { - if (action === 'closeIframe') { - iframe.style.transform = "scale(0)"; - iframe.style.opacity = 0; - document.body.style.overflow = ''; - document.documentElement.style.overflow = ''; - } - if (action === 'toogleSize') { - iframe.style.width = isMinMode ? "720px" : "420px"; - iframe.style.height = isMinMode ? "80vh" : "60vh"; - isMinMode = !isMinMode; - } - if (action === 'getConfig') { - console.log('get config', data, isGetConfig); - if(isGetConfig) return; - // if(data){ - // button.style.backgroundColor = '#2160fd' - // button.style.padding = '8px' - // const iconImgEl = document.createElement('img'); - // iconImgEl.src = data.iconUrl; - // iconImgEl.style.width = '100%'; - // iconImgEl.style.height = '100%'; - // button.appendChild(iconImgEl); - // }else { - // button.innerHTML = "Ask"; - // button.style.color = "white"; - // button.style.backgroundColor = "#2160fd"; - // } - document.body.appendChild(button); - isGetConfig = true; - } - }, + } catch (e) { + /* ignore dispose errors */ + console.error(e); + } }); + } catch (e) { + /* ignore addEventListener errors */ + console.error(e); + } - // 在页面关闭/刷新时清理监听,避免内存泄漏,并使变量被有效使用 - try { - window.addEventListener('beforeunload', function () { - try { - if (rpc && typeof rpc.dispose === 'function') { - rpc.dispose(); - } - } catch (e) { - /* ignore dispose errors */ - console.error(e); - } - }); - } catch (e) { - /* ignore addEventListener errors */ - console.error(e); + window.onload = initUI; + + function adjustIframeStyleForSmallScreens() { + if (!isInit) return; + const isMinWidth = window.matchMedia("(max-width: 768px)").matches || isMobile; + const isHidden = iframeWrap.style.transform === "scale(0)"; + + if (isMinWidth) { + Object.assign(iframeWrap.style, { + width: "100%", + height: "100%", + right: "0", + bottom: "0", + left: "0", + top: "0", + borderRadius: "0", + boxShadow: "none", + }); + if (!isHidden) { + document.body.style.overflow = 'hidden'; + document.documentElement.style.overflow = 'hidden'; + fireToIframe('resizeIframe', true); + } + } else { + Object.assign(iframeWrap.style, { + width: isMinMode ? "420px" : "640px", + height: isMinMode ? "60vh" : "80vh", + right: "20px", + bottom: "100px", + left: "unset", + top: "unset", + borderRadius: "10px", + boxShadow: "0px 10px 30px rgba(150, 150, 150, 0.2), 0px 0px 0px 1px rgba(150, 150, 150, 0.2)", + }); + document.body.style.overflow = ''; + document.documentElement.style.overflow = ''; + fireToIframe('resizeIframe', false); } + } - window.onload = initUI; - - function adjustIframeStyleForSmallScreens() { - if (!isInit) return; - const isMinWidth = window.matchMedia("(max-width: 768px)").matches || isMobile; - const isHidden = iframe.style.transform === "scale(0)"; - - if (isMinWidth) { - Object.assign(iframe.style, { - width: "100%", - height: "100%", - right: "0", - bottom: "0", - left: "0", - top: "0", - borderRadius: "0", - boxShadow: "none", - }); - if (!isHidden) { - document.body.style.overflow = 'hidden'; - document.documentElement.style.overflow = 'hidden'; - fireToIframe('resizeIframe', true); - } - } else { - Object.assign(iframe.style, { - width: isMinMode ? "420px" : "640px", - height: isMinMode ? "60vh" : "80vh", - right: "20px", - bottom: "100px", - left: "unset", - top: "unset", - borderRadius: "10px", - boxShadow: "0px 10px 30px rgba(150, 150, 150, 0.2), 0px 0px 0px 1px rgba(150, 150, 150, 0.2)", - }); - document.body.style.overflow = ''; - document.documentElement.style.overflow = ''; - fireToIframe('resizeIframe', false); - } - } - - window.addEventListener('resize', adjustIframeStyleForSmallScreens); + window.addEventListener('resize', adjustIframeStyleForSmallScreens); })(); // parent-rpc.js