From 9c7f5283cfc85340b8f099b4d8f806c4ccca5181 Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 16 Aug 2026 19:33:22 +0000 Subject: [PATCH] =?UTF-8?q?Fl=C3=A8che=20d'envoi=20:=20la=20centrer=20pour?= =?UTF-8?q?=20de=20bon?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit La flèche était décalée de 8 px vers la gauche dans son pavé — mesuré, pas supposé : centre du bouton 1339, centre du dessin 1331. La cause n'était pas dans la feuille de style mais dans le JS. syncSendBtn montrait et cachait les deux boutons avec `style.display = 'inline-block'` ; ce style INLINE l'emportait sur le `display:flex` de la règle commune. Le bouton gardait donc sa boîte de 34 px, mais son icône de 18 px se collait au bord gauche, `justify-content` n'ayant plus rien à centrer. Invisible tant que l'icône était un glyphe de texte (qui remplit sa ligne), flagrant depuis qu'elle est un SVG de taille fixe. L'état « génération en cours » passe désormais par un attribut sur (data-busy) et c'est la feuille qui décide lequel des deux boutons s'affiche — comme pour le thème, la barre latérale et le panneau Fichiers. Le style inline `display:none` du bouton d'arrêt disparaît aussi du gabarit. Vérifié au pixel dans les deux états : écart nul entre le centre du bouton et celui du dessin, pour les trois commandes de la barre (dépôt, fichiers, envoi) comme pour le bouton d'arrêt. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01LPyFxVHNAN9u5pVzSYMwjd --- internal/loki/ui/index.html | 16 +++++++++++++--- internal/loki/ui/src/index.tmpl.html | 2 +- internal/loki/ui/src/js/09-stream.js | 8 ++++++-- internal/loki/ui/src/styles.css | 6 ++++++ 4 files changed, 26 insertions(+), 6 deletions(-) diff --git a/internal/loki/ui/index.html b/internal/loki/ui/index.html index e89a032..f31524e 100644 --- a/internal/loki/ui/index.html +++ b/internal/loki/ui/index.html @@ -1651,6 +1651,12 @@ button:active:not(:disabled){transform:translateY(1px)} display:inline-flex;align-items:center;justify-content:center;align-self:center; border:0;border-radius:10px;background:transparent;color:var(--dim); transition:background .15s ease,color .15s ease,transform .08s ease} +/* Envoyer / arrêter : un seul des deux à la fois, décidé par data-busy (posé par + syncSendBtn). C'est la feuille qui garde la main sur `display` — un style + inline y substituait `inline-block`, et le centrage flex tombait avec lui. */ +#stop{display:none} +html[data-busy="1"] #send{display:none} +html[data-busy="1"] #stop{display:inline-flex} #inputbar #attach svg,#inputbar #files-btn svg,#send svg,#stop svg{display:block;width:18px;height:18px} #inputbar #attach:hover,#inputbar #files-btn:hover{background:var(--row-bg-on);color:var(--text)} html[data-files="1"] #files-btn{color:var(--accent)} @@ -2218,7 +2224,7 @@ html[data-files="1"] #files-btn{color:var(--accent)} - @@ -5461,8 +5467,12 @@ function labelTokens(el, role, n, firstTs, lastTs){ function setBusy(on){ busy=on; if(!REPLAYING) syncSendBtn(); } function syncSendBtn(){ const sb=document.getElementById('send'); - sb.style.display=busy?'none':'inline-block'; - document.getElementById('stop').style.display=busy?'inline-block':'none'; + // ⚠️ L'état passe par un ATTRIBUT, jamais par un style inline. Ces deux + // boutons étaient montrés/cachés avec `style.display='inline-block'`, qui + // l'emportait sur le `display:flex` de la feuille : le bouton gardait sa + // boîte de 34 px mais son icône de 18 px se collait à gauche, décalée de 8 px. + // C'est invisible tant que l'icône est un glyphe de texte, flagrant en SVG. + document.documentElement.setAttribute('data-busy', busy ? '1' : '0'); // Tant que le moteur n'a pas fini de charger le modèle, envoyer ne mène à rien : // on bloque le bouton et l'Entrée, et on le DIT sous le champ. `STATUS_SEEN` // évite de verrouiller le chat quand /api/status n'a pas encore répondu (ou ne diff --git a/internal/loki/ui/src/index.tmpl.html b/internal/loki/ui/src/index.tmpl.html index 6b49c35..9eb1480 100644 --- a/internal/loki/ui/src/index.tmpl.html +++ b/internal/loki/ui/src/index.tmpl.html @@ -419,7 +419,7 @@ document.documentElement.setAttribute('data-side',localStorage.getItem('loki-sid - diff --git a/internal/loki/ui/src/js/09-stream.js b/internal/loki/ui/src/js/09-stream.js index 3a0a07a..29ea230 100644 --- a/internal/loki/ui/src/js/09-stream.js +++ b/internal/loki/ui/src/js/09-stream.js @@ -136,8 +136,12 @@ function labelTokens(el, role, n, firstTs, lastTs){ function setBusy(on){ busy=on; if(!REPLAYING) syncSendBtn(); } function syncSendBtn(){ const sb=document.getElementById('send'); - sb.style.display=busy?'none':'inline-block'; - document.getElementById('stop').style.display=busy?'inline-block':'none'; + // ⚠️ L'état passe par un ATTRIBUT, jamais par un style inline. Ces deux + // boutons étaient montrés/cachés avec `style.display='inline-block'`, qui + // l'emportait sur le `display:flex` de la feuille : le bouton gardait sa + // boîte de 34 px mais son icône de 18 px se collait à gauche, décalée de 8 px. + // C'est invisible tant que l'icône est un glyphe de texte, flagrant en SVG. + document.documentElement.setAttribute('data-busy', busy ? '1' : '0'); // Tant que le moteur n'a pas fini de charger le modèle, envoyer ne mène à rien : // on bloque le bouton et l'Entrée, et on le DIT sous le champ. `STATUS_SEEN` // évite de verrouiller le chat quand /api/status n'a pas encore répondu (ou ne diff --git a/internal/loki/ui/src/styles.css b/internal/loki/ui/src/styles.css index 7923423..0ea05fd 100644 --- a/internal/loki/ui/src/styles.css +++ b/internal/loki/ui/src/styles.css @@ -1620,6 +1620,12 @@ button:active:not(:disabled){transform:translateY(1px)} display:inline-flex;align-items:center;justify-content:center;align-self:center; border:0;border-radius:10px;background:transparent;color:var(--dim); transition:background .15s ease,color .15s ease,transform .08s ease} +/* Envoyer / arrêter : un seul des deux à la fois, décidé par data-busy (posé par + syncSendBtn). C'est la feuille qui garde la main sur `display` — un style + inline y substituait `inline-block`, et le centrage flex tombait avec lui. */ +#stop{display:none} +html[data-busy="1"] #send{display:none} +html[data-busy="1"] #stop{display:inline-flex} #inputbar #attach svg,#inputbar #files-btn svg,#send svg,#stop svg{display:block;width:18px;height:18px} #inputbar #attach:hover,#inputbar #files-btn:hover{background:var(--row-bg-on);color:var(--text)} html[data-files="1"] #files-btn{color:var(--accent)}