feat: chat — suivi du document, chat général en onglet sidebar, onglets au-dessus du filtre #190
- **A — Suivi du document** : l'en-tête du panneau chat affiche le document ciblé (titre + chemin) et `followFileChat()` appelé par `renderFile()` re-cible le panneau ouvert à chaque changement de document. - **B — Chat général** : onglet « Chat » (dernier) dans la sidebar, conversation centrale stockée dans le store #169 via les sentinelles `__global__/general` (`GET/POST /api/chat`) ; pastille de messages non lus sur l'onglet ; pièces jointes image/vidéo (`POST /api/chat/upload` : allow-list d'extensions, 25 MB, nom UUID ; `GET /api/chat/attachment/{name}` résolu contre l'allow-list) ; URL cliquables au rendu ; date/heure d'envoi. - **C — Ordre des onglets** : la barre de filtre passe sous les onglets et sert de recherche dans le chat (texte + auteur) quand l'onglet Chat est actif (`switchSidebarTab` + `routeFilter`). - Transport : broadcast SSE `chat_message` réutilisé (`vault __global__` route vers la sidebar, sinon le panneau fichier) — pas de 2ᵉ WebSocket. - i18n FR/EN (6 clés), CSS bloc #190, `initSidebarChat()` dans l'orchestrateur. - Tests : pytest 27 chat (12 nouveaux) ; JSDOM `filechat.test.mjs` 11 (5 nouveaux) ; suite 1655 passed, ruff/mypy 0, validate-imports 42 modules. - Docs : CHANGELOG [Unreleased], ROADMAP #190 → index, fiche `file-chat-169.md` §#190, guide « Chat général », journal des interventions.
This commit is contained in:
@@ -16,7 +16,7 @@ import { t, getLocale } from './i18n.js';
|
||||
import { onFileRender } from './plugins.js';
|
||||
import { NowPlaying } from './now-playing.js';
|
||||
import { openAssistant } from './ai-fab.js';
|
||||
import { toggleFileChat } from './filechat.js';
|
||||
import { toggleFileChat, followFileChat } from './filechat.js';
|
||||
import { parseRef, columnName, findTd, invalidateCellIndex, sheetOfRef, firstCellOfRange } from './xlsx/refs.js';
|
||||
import { createColourPicker } from './xlsx/color-picker.js';
|
||||
import { buildCommandBar } from './xlsx/command-bar.js';
|
||||
@@ -6897,6 +6897,8 @@ export function renderFile(data) {
|
||||
// state (CodeMirror view, Forge iframe, Yjs session) is torn down cleanly
|
||||
// instead of being wiped mid-session by a tab switch / sidebar click.
|
||||
if (isInlineEditorActive()) detachInlineEditor();
|
||||
// #190 A — an open chat panel follows the document being rendered.
|
||||
followFileChat(data.vault, data.path, data.title);
|
||||
// #108 — release the image viewer's document-level shortcuts before swapping
|
||||
// the content area (otherwise they leak on every re-render).
|
||||
if (_imageViewerCleanup) { _imageViewerCleanup(); _imageViewerCleanup = null; }
|
||||
@@ -7227,7 +7229,7 @@ export function renderFile(data) {
|
||||
// #169 — Chat intégré par fichier (panneau latéral)
|
||||
const chatBtn = el("button", { class: "btn-action btn-chat", title: t("chat.button_title") }, [icon("message-square", 14), document.createTextNode(t("chat.button"))]);
|
||||
chatBtn.addEventListener("click", () => {
|
||||
toggleFileChat(data.vault, data.path);
|
||||
toggleFileChat(data.vault, data.path, data.title);
|
||||
});
|
||||
// Check bookmark status and color the button
|
||||
(async () => {
|
||||
|
||||
Reference in New Issue
Block a user