Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
353 changes: 184 additions & 169 deletions static/embed.js
Original file line number Diff line number Diff line change
@@ -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
Expand Down
Loading