5.5 KiB
#115 / BUG-078 / #117 — Barre d'outils épinglée, coloration syntaxique des fichiers de code & avatars prédéfinis
Statut : 🟢 livré (en attente vérification utilisateur) Impact : 🟡 (#115, BUG-078) · 🟢 (#117) Zone : frontend (
frontend/js/viewer.js,frontend/js/themes.js,frontend/js/ui.js,frontend/js/config.js,frontend/index.html,frontend/style.css,frontend/popout.html,frontend/locales/fr.json,frontend/locales/en.json,frontend/icons/avatar/*)
Trois demandes traitées dans la même livraison, toutes côté frontend.
#115 — Barre d'outils de lecture toujours visible
Problème
La barre d'actions d'un document (pop-out, bookmark, Editer, Source, Copier, PDF, Export,
Partager…) était rendue dans .file-header, un conteneur court placé en haut de la
zone de lecture. Or un élément position: sticky reste borné par son parent : dès que
.file-header sortait de l'écran au défilement d'un document long, la barre disparaissait.
Correctif
-
frontend/js/viewer.jsetfrontend/popout.htmlsortent la barre d'actions de.file-headeret la placent dans un nouveau conteneur.file-toolbar, enfant direct de.content-area(le conteneur de défilement). La barre peut donc se coller au haut de la zone de lecture pour toute la hauteur du document. -
frontend/style.css:.file-toolbar { position: sticky; top: 0; z-index: 30; margin: 0 0 16px; padding: 8px 0; background: var(--bg-primary); border-bottom: 1px solid var(--border); }Le fond est opaque pour qu'aucun texte ne transparaisse dessous.
-
body.reading-mode .file-toolbar { display: none }: la barre reste masquée en mode lecture, comme les autres actions.
BUG-078 — Coloration syntaxique des fichiers de code
Problème
Les fichiers .py, .sh, .ps1, .yml, .json… (et les blocs de code Markdown)
s'affichaient en texte brut, sans couleurs. Le code était pourtant correctement
généré côté backend (<pre><code class="language-python">…) et safeHighlight() appelait
bien hljs.highlightElement().
La cause était ailleurs : les deux feuilles de style de highlight.js (#hljs-theme-dark
et #hljs-theme-light, chargées depuis le CDN dans index.html) étaient basculées à
partir de la clé de thème persistée (obsigate-theme = defaut-obsigate, …) :
darkSheet.disabled = theme !== "dark"; // "defaut-obsigate" !== "dark" → true
lightSheet.disabled = theme !== "light"; // "defaut-obsigate" !== "light" → true
Les deux feuilles finissaient donc désactivées, privant tous les tokens de leurs couleurs.
Le résultat dépendait de l'ordre de deux initialisations concurrentes — UI.initTheme()
(clé de thème) au démarrage et themes.initThemes() (mode) via Sync.init() — d'où un
comportement non déterministe (parfois coloré, le plus souvent non).
Correctif
-
frontend/js/themes.js—applyTheme(themeKey, mode)bascule désormais les feuilles highlight.js selon le mode :var isDark = mode === 'dark'; darkSheet.disabled = !isDark; lightSheet.disabled = isDark;(
sepiaethigh-contrastréutilisent la palette claire.) -
frontend/js/ui.js—initTheme()lit le mode persisté (obsigate-theme-mode) etapplyTheme()résout un mode avant de fixerdata-themeet de basculer les feuilles, au lieu de comparer la clé de thème à"dark"/"light".
Le basculement est ainsi déterministe dès le premier rendu et à chaque changement de mode.
#117 — Avatars prédéfinis dans le profil
Ce qui a été livré
- Galerie de 12 avatars dans la section
Profil(#cfg-profile), servis depuisfrontend/icons/avatar/(/static/icons/avatar/<fichier>.jpg) : Chat, chien, elephan, hibou, koala, lapin, lion, ours, penda, pingouin, raton, tigre. - Un clic charge l'image, la fait passer par le même pipeline que l'import (recadrage
carré central, redimensionnement 256 px, export JPEG 0,85) et l'enregistre via
PATCH /api/auth/me— aucune modification backend n'a été nécessaire, la validation data-URL PNG/JPEG/WebP existante (BUG-113) s'applique telle quelle. - L'avatar actif est surligné ; le choix est mémorisé dans
localStorage(obsigate-avatar-preset) et purgé dès qu'on importe une photo personnalisée ou qu'on supprime l'avatar. - L'import d'une photo et la suppression restent disponibles.
- i18n : nouvelle clé
config.avatar_presets_label(FR/EN).
Tests
tests/frontend/unit.test.mjs—syntax highlight theme(BUG-078) :themes.applyThemebascule les feuilles selon le mode etui.jsne compare plus la clé au mode.tests/frontend/toolbar-order.test.mjs— #115 :.file-toolbardansviewer.jsetpopout.html, règle CSSposition: sticky; top: 0, masquage en mode lecture.tests/frontend/settings-order-avatar.test.mjs— #117 : 12 avatars présents dans#cfg-profile, fichiers d'images existants, pipelineconfig.js, règles CSS, clé i18n FR/EN.- Vérification Playwright (instance locale, auth désactivée) : coloration déterministe sur
5 chargements successifs d'un
.py;.file-toolbardont letopne bouge plus après défilement (épinglage effectif).
Limitations
- L'avatar reste stocké en data-URL 256 px dans
data/users.json(comportement #113 conservé). - Le mode
high-contrast/sepiautilise le thème highlight.js clair (pas de palette dédiée).