Impossible d'ouvrir le dossier : ${err}
`; } } + +// Compare deux listes de fichiers indépendamment de l'ordre. +function sameFiles(a, b) { + if (a.length !== b.length) return false; + const key = arr => arr.slice().sort().join('\n'); + return key(a) === key(b); +} + +// Réaction à un changement filesystem signalé par le backend (événement débouncé, +// filtré sur les fichiers .md). +async function handleFileChanged(changedPath) { + if (!appState.baseDir || !appState.currentMode) return; + + // Rafraîchir la sidebar uniquement si l'arborescence a changé (ajout/suppression), + // pour ne pas replier les dossiers ouverts à chaque simple modification de contenu. + try { + const files = await listMdFiles(appState.baseDir); + if (!sameFiles(files, appState.files)) { + appState.files = files; + renderSidebar(appState.baseDir, files, appState.currentFile, navigate); + } + } catch { + // baseDir supprimé/illisible : on garde la sidebar en l'état. + } + + // Recharger le document affiché si c'est lui qui vient d'être modifié. + if (changedPath === appState.currentFile) { + await loadPage(appState.currentFile, appState.currentMode, sidebarEl); + } +} + +// À appeler une fois au démarrage : enregistre le listener global de changements. +export function initWatcher() { + return onFileChanged(event => { + handleFileChanged(event.payload.path); + }); +} diff --git a/src/state/app-state.js b/src/state/app-state.js index a81822b..6458599 100644 --- a/src/state/app-state.js +++ b/src/state/app-state.js @@ -1 +1,12 @@ -export const appState = { currentPath: null, currentMode: null }; +export const appState = { + currentPath: null, + currentMode: null, + // Dossier réellement surveillé (racine de la sidebar) : le dossier ouvert en + // mode « dir », ou le dossier parent du fichier ouvert en mode « file ». + baseDir: null, + // Fichier actuellement affiché dans le lecteur. + currentFile: null, + // Dernière liste de fichiers .md connue de `baseDir`, pour détecter les + // ajouts/suppressions et ne rafraîchir la sidebar que si l'arborescence change. + files: [], +}; diff --git a/src/ui/reader.js b/src/ui/reader.js index f96b9bd..318542c 100644 --- a/src/ui/reader.js +++ b/src/ui/reader.js @@ -1,4 +1,5 @@ import { convertFile } from '../services/markdown.js'; +import { appState } from '../state/app-state.js'; const win = window.__TAURI__.window.getCurrentWindow(); const titlebarTitle = document.getElementById('titlebar-title'); @@ -69,6 +70,7 @@ function addCopyButtons() { export async function loadPage(filePath, mode, sidebarEl) { try { const html = await convertFile(filePath); + appState.currentFile = filePath; content.innerHTML = html; addCopyButtons(); diff --git a/src/ui/sidebar-resize.js b/src/ui/sidebar-resize.js new file mode 100644 index 0000000..1178310 --- /dev/null +++ b/src/ui/sidebar-resize.js @@ -0,0 +1,49 @@ +const STORAGE_KEY = 'pena.sidebarWidth'; +const MIN_WIDTH = 180; +const MAX_WIDTH = 520; + +function clamp(width) { + return Math.min(MAX_WIDTH, Math.max(MIN_WIDTH, width)); +} + +function applyWidth(width) { + document.documentElement.style.setProperty('--sidebar-width', `${width}px`); +} + +export function initSidebarResize() { + const handle = document.getElementById('sidebar-resizer'); + if (!handle) return; + + const stored = parseInt(localStorage.getItem(STORAGE_KEY), 10); + if (!Number.isNaN(stored)) applyWidth(clamp(stored)); + + let dragging = false; + + const onMove = (e) => { + if (!dragging) return; + applyWidth(clamp(e.clientX)); + }; + + const onUp = () => { + if (!dragging) return; + dragging = false; + handle.classList.remove('is-dragging'); + document.body.classList.remove('is-resizing-sidebar'); + const width = parseInt( + getComputedStyle(document.documentElement).getPropertyValue('--sidebar-width'), + 10, + ); + if (!Number.isNaN(width)) localStorage.setItem(STORAGE_KEY, String(width)); + window.removeEventListener('mousemove', onMove); + window.removeEventListener('mouseup', onUp); + }; + + handle.addEventListener('mousedown', (e) => { + e.preventDefault(); + dragging = true; + handle.classList.add('is-dragging'); + document.body.classList.add('is-resizing-sidebar'); + window.addEventListener('mousemove', onMove); + window.addEventListener('mouseup', onUp); + }); +}