fix(ai): liens sans vault, navigation clavier des menus et purge caches (BUG-013, BUG-014)
CI / lint (push) Successful in 1m9s
CI / security (push) Successful in 45s
CI / test (push) Successful in 2m27s
CI / build (push) Successful in 40s
CI / e2e (push) Successful in 10m47s

BUG-013: _openFileLink/_revealPath utilisent _activeVault() (contexte -> selection -> premier vault). BUG-014: navigation up/down geree au niveau du panneau en phase de capture, independante du focus. Caches: SW_VERSION v6 + migration qui purge tous les caches obsigate-*.
This commit is contained in:
2026-09-12 16:44:12 -04:00
parent ee4c273d73
commit a5201a62e0
7 changed files with 108 additions and 14 deletions
+3 -3
View File
@@ -5158,12 +5158,12 @@ curl -X POST https://votre-serveur.com/webhook \
if (!('serviceWorker' in navigator) || !('caches' in window)) return;
var MIGRATION_KEY = 'obsigate-sw-migration';
try {
if (localStorage.getItem(MIGRATION_KEY) === 'v2') return;
localStorage.setItem(MIGRATION_KEY, 'v2');
if (localStorage.getItem(MIGRATION_KEY) === 'v3') return;
localStorage.setItem(MIGRATION_KEY, 'v3');
} catch (e) { return; }
caches.keys().then(function (names) {
return Promise.all(names.map(function (name) {
return /^obsigate-(v1|offline-v1)$/.test(name) ? caches.delete(name) : null;
return /^obsigate-/.test(name) ? caches.delete(name) : null;
}));
}).then(function () {
return navigator.serviceWorker.getRegistration();
+23 -8
View File
@@ -336,11 +336,11 @@ class BooksLM {
}
/**
* Concrete vault used to browse files in the `@` mention menu. Falls back to
* the sidebar's selected context vault (then the first vault) so the menu can
* list files even in General mode where no vault is otherwise resolved.
* Concrete vault used by the assistant when none is explicitly resolved:
* falls back to the sidebar's selected context vault, then the first
* available vault. Used to browse `@` files and to open/reveal links.
*/
_mentionVault() {
_activeVault() {
const resolved = this._contextVault();
if (resolved) return resolved;
const selected = state.selectedContextVault;
@@ -351,7 +351,7 @@ class BooksLM {
/** Open a file mentioned in an assistant answer in the main viewer. */
async _openFileLink(path) {
const vault = this._resolveVault();
const vault = this._activeVault();
if (!vault || !path) {
showToast(t('bookslm.no_vault'), 'error');
return;
@@ -376,7 +376,7 @@ class BooksLM {
/** Reveal a directory (or file) path in the sidebar tree. */
async _revealPath(path) {
const vault = this._resolveVault();
const vault = this._activeVault();
if (!vault || !path) {
showToast(t('bookslm.no_vault'), 'error');
return;
@@ -583,6 +583,21 @@ class BooksLM {
this._onComposerInput();
});
textarea.addEventListener('paste', (e) => this._onPaste(e));
// Menu navigation is handled at the panel level (capture phase) so the
// arrow keys keep working even if focus is not exactly on the textarea
// (e.g. after interacting with the menu). It runs before the textarea
// handler and stops propagation when it consumes the event.
panel.addEventListener('keydown', (e) => {
if (!this._menuKind) return;
const isComposer = e.target && e.target.tagName === 'TEXTAREA';
const isNav = e.key === 'ArrowDown' || e.key === 'ArrowUp' || e.key === 'Escape';
const isPick = e.key === 'Enter' && isComposer && !e.ctrlKey && !e.metaKey;
if ((isNav || isPick) && this._handleMenuKey(e)) {
e.stopPropagation();
}
}, true);
textarea.addEventListener('keydown', (e) => {
// Menu navigation (mention/command) takes precedence over submit.
if (this._handleMenuKey(e)) return;
@@ -841,7 +856,7 @@ class BooksLM {
async _showMentionMenu(query) {
if (!this._panel) return;
const seq = ++this._menuSeq;
const vault = this._mentionVault();
const vault = this._activeVault();
try {
let results = [];
if (query) {
@@ -880,7 +895,7 @@ class BooksLM {
textarea.focus();
}
const path = item.id;
const vault = item.vault || this._resolveVault();
const vault = item.vault || this._activeVault();
if (IMAGE_EXT_RE.test(path)) {
this._addImagePath(path, vault);
} else if (item.type === 'dir' || this._classifyPath(path) === 'dir') {
+1 -1
View File
@@ -11,7 +11,7 @@
* cache or Cloudflare does NOT clear the Service Worker Cache Storage, which is
* a separate store. Bumping SW_VERSION invalidates it on every release.
*/
const SW_VERSION = 'v5';
const SW_VERSION = 'v6';
const CODE_CACHE = `obsigate-code-${SW_VERSION}`;
const RUNTIME_CACHE = `obsigate-runtime-${SW_VERSION}`;
const API_CACHE = `obsigate-api-${SW_VERSION}`;