CI / lint (push) Successful in 57s
CI / security (push) Successful in 39s
CI / test (push) Successful in 1m16s
CI / build (push) Successful in 43s
CI / e2e (push) Successful in 19m16s
Desktop Build / build-windows (push) Canceled after 0s
Desktop Build / build-linux (push) Canceled after 0s
Sur mobile, la pastille flottante etait masquee par la barre d'outils. - Masque .ai-fab sur mobile - Ajoute un bouton rond sureleve #mt-ai au centre de la barre (5 items) - Extrait openAssistant() dans ai-fab.js (reutilise par la FAB et le bouton mobile) - mobile-toolbar.js : branche le bouton sur openAssistant()
64 lines
2.1 KiB
JavaScript
64 lines
2.1 KiB
JavaScript
// ObsiGate — Floating Action Button (FAB) for the AI Assistant sidebar.
|
|
// Always visible in the bottom-right corner; hides while the assistant panel
|
|
// is expanded. Clicking it opens the assistant in the context that matches
|
|
// the current application state (open documents, or General when none).
|
|
import booksLM from './bookslm.js';
|
|
import { t } from './i18n.js';
|
|
import { safeCreateIcons } from './utils.js';
|
|
|
|
let _fab = null;
|
|
|
|
// The panel is visible when it has `.open` without `.hidden`.
|
|
function isBooksLmVisible() {
|
|
const panel = document.querySelector('.bookslm-panel');
|
|
return !!(panel && panel.classList.contains('open') && !panel.classList.contains('hidden'));
|
|
}
|
|
|
|
function syncVisibility() {
|
|
if (!_fab) return;
|
|
const visible = isBooksLmVisible();
|
|
_fab.hidden = visible;
|
|
const label = visible ? t('fab.close') : t('fab.open');
|
|
_fab.title = label;
|
|
_fab.setAttribute('aria-label', label);
|
|
}
|
|
|
|
// Shared entry point used by the floating FAB and the mobile toolbar button.
|
|
// Reopens a collapsed panel, otherwise opens (or re-focuses) the assistant
|
|
// for the current application context.
|
|
export async function openAssistant() {
|
|
const panel = document.querySelector('.bookslm-panel');
|
|
// Collapsed panel: reveal it instead of reopening.
|
|
if (panel && panel.classList.contains('open') && panel.classList.contains('hidden')) {
|
|
booksLM._toggleSidebar();
|
|
return;
|
|
}
|
|
// Otherwise open (or re-focus) the assistant for the current context.
|
|
await booksLM.openForCurrentContext();
|
|
}
|
|
|
|
async function onClick() {
|
|
await openAssistant();
|
|
}
|
|
|
|
export function initAIFab() {
|
|
if (_fab) return;
|
|
|
|
const btn = document.createElement('button');
|
|
btn.type = 'button';
|
|
btn.id = 'ai-fab';
|
|
btn.className = 'ai-fab';
|
|
btn.innerHTML = '<i data-lucide="bot" style="width:24px;height:24px"></i>';
|
|
document.body.appendChild(btn);
|
|
_fab = btn;
|
|
|
|
btn.addEventListener('click', onClick);
|
|
document.addEventListener('bookslm:opened', syncVisibility);
|
|
document.addEventListener('bookslm:closed', syncVisibility);
|
|
|
|
if (typeof safeCreateIcons === 'function') safeCreateIcons();
|
|
syncVisibility();
|
|
}
|
|
|
|
export default initAIFab;
|