Add floating AI button with skills menu
Added always-on floating 'uncloseai.' button in bottom right corner that provides quick access to all AI skills: Chat, Read Page, TTS Anything, Upload File, and Refresh Models. Button uses ChunkFive font and gradient styling with smooth animations.
This commit is contained in:
parent
84a90f4dc2
commit
af67a7be99
1 changed files with 117 additions and 0 deletions
117
uncloseai.js
117
uncloseai.js
|
|
@ -1029,11 +1029,128 @@ document.getElementById("user-input").addEventListener("keydown", function(event
|
|||
});
|
||||
|
||||
|
||||
// Function to create floating AI button
|
||||
function createFloatingAIButton() {
|
||||
// Create the main floating button
|
||||
const floatingButton = document.createElement('button');
|
||||
floatingButton.id = 'floating-ai-button';
|
||||
floatingButton.textContent = 'uncloseai.';
|
||||
floatingButton.style.cssText = `
|
||||
position: fixed;
|
||||
bottom: 20px;
|
||||
right: 20px;
|
||||
width: 80px;
|
||||
height: 60px;
|
||||
border-radius: 30px;
|
||||
background: linear-gradient(45deg, #667eea 0%, #764ba2 100%);
|
||||
border: none;
|
||||
color: white;
|
||||
font-family: 'ChunkFiveRegular', monospace;
|
||||
font-size: 14px;
|
||||
cursor: pointer;
|
||||
box-shadow: 0 4px 12px rgba(0,0,0,0.3);
|
||||
z-index: 1000;
|
||||
transition: all 0.3s ease;
|
||||
`;
|
||||
|
||||
// Create the skills menu
|
||||
const skillsMenu = document.createElement('div');
|
||||
skillsMenu.id = 'ai-skills-menu';
|
||||
skillsMenu.style.cssText = `
|
||||
position: fixed;
|
||||
bottom: 90px;
|
||||
right: 20px;
|
||||
background: white;
|
||||
border-radius: 12px;
|
||||
box-shadow: 0 8px 24px rgba(0,0,0,0.2);
|
||||
padding: 16px;
|
||||
min-width: 200px;
|
||||
z-index: 999;
|
||||
display: none;
|
||||
border: 1px solid #e0e0e0;
|
||||
`;
|
||||
|
||||
// Skills buttons
|
||||
const skills = [
|
||||
{ name: 'Chat', icon: '💬', action: () => scrollToChatBox() },
|
||||
{ name: 'Read Page', icon: '📖', action: readPageWithHermes },
|
||||
{ name: 'TTS Anything', icon: '🔊', action: openTTSModal },
|
||||
{ name: 'Upload File', icon: '📁', action: () => document.getElementById('file-input')?.click() },
|
||||
{ name: 'Refresh Models', icon: '🔄', action: () => document.querySelector('#refresh-models-container button')?.click() }
|
||||
];
|
||||
|
||||
skills.forEach(skill => {
|
||||
const skillButton = document.createElement('button');
|
||||
skillButton.style.cssText = `
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
width: 100%;
|
||||
padding: 12px;
|
||||
margin: 4px 0;
|
||||
border: none;
|
||||
background: transparent;
|
||||
border-radius: 8px;
|
||||
cursor: pointer;
|
||||
font-size: 14px;
|
||||
transition: background-color 0.2s ease;
|
||||
`;
|
||||
skillButton.innerHTML = `<span style="font-size: 18px;">${skill.icon}</span> ${skill.name}`;
|
||||
skillButton.onmouseover = () => skillButton.style.background = '#f5f5f5';
|
||||
skillButton.onmouseout = () => skillButton.style.background = 'transparent';
|
||||
skillButton.onclick = () => {
|
||||
skill.action();
|
||||
skillsMenu.style.display = 'none';
|
||||
};
|
||||
skillsMenu.appendChild(skillButton);
|
||||
});
|
||||
|
||||
// Toggle menu visibility
|
||||
let menuVisible = false;
|
||||
floatingButton.onclick = () => {
|
||||
menuVisible = !menuVisible;
|
||||
skillsMenu.style.display = menuVisible ? 'block' : 'none';
|
||||
floatingButton.style.transform = menuVisible ? 'rotate(180deg)' : 'rotate(0deg)';
|
||||
};
|
||||
|
||||
// Close menu when clicking outside
|
||||
document.addEventListener('click', (e) => {
|
||||
if (!floatingButton.contains(e.target) && !skillsMenu.contains(e.target)) {
|
||||
skillsMenu.style.display = 'none';
|
||||
menuVisible = false;
|
||||
floatingButton.style.transform = 'rotate(0deg)';
|
||||
}
|
||||
});
|
||||
|
||||
// Hover effects
|
||||
floatingButton.onmouseenter = () => {
|
||||
floatingButton.style.transform = 'scale(1.1)';
|
||||
floatingButton.style.boxShadow = '0 6px 16px rgba(0,0,0,0.4)';
|
||||
};
|
||||
floatingButton.onmouseleave = () => {
|
||||
if (!menuVisible) floatingButton.style.transform = 'scale(1)';
|
||||
floatingButton.style.boxShadow = '0 4px 12px rgba(0,0,0,0.3)';
|
||||
};
|
||||
|
||||
document.body.appendChild(floatingButton);
|
||||
document.body.appendChild(skillsMenu);
|
||||
}
|
||||
|
||||
// Helper function to scroll to chat box
|
||||
function scrollToChatBox() {
|
||||
const chatContainer = document.getElementById('chat-container');
|
||||
if (chatContainer) {
|
||||
chatContainer.scrollIntoView({ behavior: 'smooth' });
|
||||
document.getElementById('user-input')?.focus();
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize on page load
|
||||
window.onload = () => {
|
||||
initializeChatInterface();
|
||||
createModelSelectionDropdown();
|
||||
addRefreshModelsButton();
|
||||
createFloatingAIButton();
|
||||
};
|
||||
|
||||
// Export functions to global scope
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue