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);
}
}