const storage = chrome.storage.sync; chrome.storage.sync.get(['chatbotUrl'], function(result) { window.difyChatbotConfig = { chatbotUrl: result.chatbotUrl, }; }); document.body.onload = embedChatbot; async function embedChatbot() { const difyChatbotConfig = window.difyChatbotConfig; if (!difyChatbotConfig) { console.warn('Dify Chatbot Url is empty or is not provided'); return; } const openIcon = ` `; const closeIcon = ` `; // create iframe function createIframe() { const iframe = document.createElement('iframe'); iframe.allow = "fullscreen;microphone" iframe.title = "dify chatbot bubble window" iframe.id = 'dify-chatbot-bubble-window' iframe.src = difyChatbotConfig.chatbotUrl iframe.style.cssText = 'border: none; position: fixed; flex-direction: column; justify-content: space-between; box-shadow: rgba(150, 150, 150, 0.2) 0px 10px 30px 0px, rgba(150, 150, 150, 0.2) 0px 0px 0px 1px; bottom: 6.7rem; right: 1rem; width: 30rem; height: 48rem; border-radius: 0.75rem; display: flex; z-index: 2147483647; overflow: hidden; left: unset; background-color: #F3F4F6;' document.body.appendChild(iframe); } /** * rem to px * @param {*} rem :30rem */ function handleRemToPx(rem) { if (!rem) return; let pxValue = 0; try { const regex = /\d+/; // extract the numeric part and convert it to a numeric type const remValue = parseInt(regex.exec(rem)[0], 10); const rootFontSize = parseFloat( window.getComputedStyle(document.documentElement).fontSize ); pxValue = remValue * rootFontSize; } catch (error) { console.error(error); } return pxValue; } /** * support element drag * @param {*} targetButton entry element */ function handleElementDrag(targetButton) { // define a variable to hold the mouse position let mouseX = 0, mouseY = 0, offsetX = 0, offsetY = 0; // Listen for mouse press events, get mouse position and element position targetButton.addEventListener("mousedown", function (event) { // calculate mouse position mouseX = event.clientX; mouseY = event.clientY; // calculate element position const rect = targetButton.getBoundingClientRect(); offsetX = mouseX - rect.left; offsetY = mouseY - rect.top; // listen for mouse movement events document.addEventListener("mousemove", onMouseMove); }); // listen for mouse lift events and stop listening for mouse move events document.addEventListener("mouseup", function () { document.removeEventListener("mousemove", onMouseMove); }); // the mouse moves the event handler to update the element position function onMouseMove(event) { // calculate element position let newX = event.clientX - offsetX, newY = event.clientY - offsetY; // 计算视线边界 const viewportWidth = window.innerWidth, viewportHeight = window.innerHeight; const maxX = viewportWidth - targetButton.offsetWidth, maxY = viewportHeight - targetButton.offsetHeight; // application limitation newX = Math.max(12, Math.min(newX, maxX)); newY = Math.max(12, Math.min(newY, maxY)); // update element position targetButton.style.left = newX + "px"; targetButton.style.top = newY + "px"; } } const targetButton = document.getElementById("dify-chatbot-bubble-button"); if (!targetButton) { // create button const containerDiv = document.createElement("div"); containerDiv.id = 'dify-chatbot-bubble-button'; containerDiv.style.cssText = `position: fixed; bottom: 3rem; right: 1rem; width: 50px; height: 50px; border-radius: 25px; background-color: #155EEF; box-shadow: rgba(0, 0, 0, 0.2) 0px 4px 8px 0px; cursor: move; z-index: 2147483647; transition: all 0.2s ease-in-out 0s; left: unset; transform: scale(1); :hover {transform: scale(1.1);}`; const displayDiv = document.createElement('div'); displayDiv.style.cssText = "display: flex; align-items: center; justify-content: center; width: 100%; height: 100%; z-index: 2147483647;"; displayDiv.innerHTML = openIcon; containerDiv.appendChild(displayDiv); document.body.appendChild(containerDiv); handleElementDrag(containerDiv); // add click event to control iframe display containerDiv.addEventListener('click', function () { const targetIframe = document.getElementById('dify-chatbot-bubble-window'); if (!targetIframe) { createIframe(); displayDiv.innerHTML = closeIcon; return; } if (targetIframe.style.display === "none") { targetIframe.style.display = "block"; displayDiv.innerHTML = closeIcon; } else { targetIframe.style.display = "none"; displayDiv.innerHTML = openIcon; } }); } else { // add any drag and drop to the floating icon handleElementDrag(targetButton); } }