Skip to content

Commit 49a10ec

Browse files
anchored chatbot to bottom of window
1 parent 0745e6a commit 49a10ec

File tree

1 file changed

+94
-0
lines changed

1 file changed

+94
-0
lines changed

src/js/chatbot.js

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,101 @@
1818
style.textContent = `
1919
#dify-chatbot-bubble-button {
2020
background-color: #4B39EF !important;
21+
bottom: 0.25rem !important;
22+
right: 0.25rem !important;
2123
}
2224
`;
2325
document.head.appendChild(style);
26+
27+
// Function to force positioning
28+
function forceChatbotPosition() {
29+
// Handle all possible widget states
30+
const allWidgets = document.querySelectorAll('.dify-chatbot-widget, [class*="dify"], [id*="dify"]');
31+
const allWindows = document.querySelectorAll('#dify-chatbot-bubble-window, [class*="chat"], [class*="window"]');
32+
33+
// Position all widget containers
34+
allWidgets.forEach(widget => {
35+
widget.style.position = 'fixed';
36+
widget.style.bottom = '0';
37+
widget.style.right = '0';
38+
widget.style.top = 'auto';
39+
widget.style.left = 'auto';
40+
widget.style.zIndex = '1000';
41+
widget.style.margin = '0';
42+
widget.style.transform = 'none';
43+
});
44+
45+
// Position all window elements
46+
allWindows.forEach(window => {
47+
window.style.position = 'fixed';
48+
window.style.bottom = '0';
49+
window.style.right = '0';
50+
window.style.top = 'auto';
51+
window.style.left = 'auto';
52+
window.style.margin = '0';
53+
window.style.transform = 'none';
54+
});
55+
56+
// Also handle any iframe that might be created
57+
const iframes = document.querySelectorAll('iframe[src*="dify"], iframe[src*="udify"]');
58+
iframes.forEach(iframe => {
59+
iframe.style.position = 'fixed';
60+
iframe.style.bottom = '0';
61+
iframe.style.right = '0';
62+
iframe.style.top = 'auto';
63+
iframe.style.left = 'auto';
64+
iframe.style.margin = '0';
65+
iframe.style.transform = 'none';
66+
});
67+
68+
// Special handling for expanded state - target any element that might be the expanded window
69+
const expandedElements = document.querySelectorAll('[data-state="expanded"], [class*="expanded"], [style*="position: fixed"]');
70+
expandedElements.forEach(element => {
71+
element.style.position = 'fixed';
72+
element.style.bottom = '0';
73+
element.style.right = '0';
74+
element.style.top = 'auto';
75+
element.style.left = 'auto';
76+
element.style.margin = '0';
77+
element.style.transform = 'none';
78+
element.style.zIndex = '1000';
79+
});
80+
81+
// Also force any element with a high z-index to stay at bottom
82+
const highZIndexElements = document.querySelectorAll('[style*="z-index: 999"], [style*="z-index: 1000"], [style*="z-index: 1001"]');
83+
highZIndexElements.forEach(element => {
84+
if (element.style.position === 'fixed') {
85+
element.style.bottom = '0';
86+
element.style.right = '0';
87+
element.style.top = 'auto';
88+
element.style.left = 'auto';
89+
}
90+
});
91+
}
92+
93+
// Apply positioning after script loads
94+
setTimeout(forceChatbotPosition, 1000);
95+
setTimeout(forceChatbotPosition, 2000);
96+
setTimeout(forceChatbotPosition, 3000);
97+
setTimeout(forceChatbotPosition, 4000);
98+
setTimeout(forceChatbotPosition, 5000);
99+
100+
// Also watch for changes
101+
const observer = new MutationObserver(() => {
102+
forceChatbotPosition();
103+
// Run again after a short delay to catch any delayed changes
104+
setTimeout(forceChatbotPosition, 100);
105+
setTimeout(forceChatbotPosition, 500);
106+
});
107+
observer.observe(document.body, { childList: true, subtree: true, attributes: true });
108+
109+
// Also run continuously for the first 10 seconds
110+
let runCount = 0;
111+
const continuousInterval = setInterval(() => {
112+
forceChatbotPosition();
113+
runCount++;
114+
if (runCount > 20) { // Stop after 10 seconds (20 * 500ms)
115+
clearInterval(continuousInterval);
116+
}
117+
}, 500);
24118
})();

0 commit comments

Comments
 (0)