Barre de saisie cohérente et étiquettes d'identité stables

Deux retours, deux vrais défauts.

Boutons de la saisie
  Ils avaient trois générations de règles empilées — pilule large « Envoyer »,
  aplat noir, aplat sauge — si bien que chaque bouton tirait sa taille, sa forme
  et son alignement d'une couche différente : rond pour l'envoi et l'arrêt,
  carré de 15 px pour l'icône stop contre 16 pour ses voisines, et un
  align-self:center sur deux boutons seulement (les deux autres tombaient au
  bas de la pilule). Une seule règle les décrit désormais : 34x34, coins doux
  de 10 px — jamais un rond, la maquette n'en a pas —, icône de 18 px centrée,
  fond seulement au survol. Seule la couleur les distingue : atténué pour
  joindre et fichiers, sauge pour envoyer, rouille pour arrêter.

Étiquettes des bulles
  Une bulle changeait de nom en cours de route. Envoyée en direct, elle
  s'appelait « USER » (confirmPending réécrivait l'étiquette en dur) ; rejouée
  au chargement, elle portait l'avatar et le prénom. Même chose côté réponse :
  labelTokens remplaçait « Loki » par « assistant · 75 tok · 21.5 tok/s »
  pendant la génération, et le nom ne revenait qu'au rechargement de la page.
  L'étiquette porte maintenant l'identité DANS TOUS LES CAS ; les mesures de
  génération vont dans la ligne dédiée, à l'endroit exact où les stats de fin
  de tour les écrivent déjà. L'envoi en cours se lit à la bulle grisée et à son
  infobulle, plus à un libellé qui écrase le prénom.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LPyFxVHNAN9u5pVzSYMwjd
This commit is contained in:
Claude committed 2026-08-16 18:35:04 +00:00
1 parent a44f3c763a
commit 6efd2a362e
4 files changed
+86 -60

No files matched your search

+17 -4
View File
@@ -22,7 +22,10 @@ function addPending(text){
clearPending();
PENDING=addMsg('user', text);
PENDING.classList.add('pending');
const l=PENDING.querySelector('.label'); if(l) l.textContent='envoi…';
// L'étiquette garde l'avatar et le prénom (paintLabel, posé par addMsg) : une
// bulle ne doit JAMAIS s'appeler autrement d'un tour à l'autre. L'envoi en
// cours se lit à la bulle grisée (.pending) et à l'infobulle.
const l=PENDING.querySelector('.label'); if(l) l.title='envoi en cours…';
jumpBottom();
return PENDING;
}
@@ -33,7 +36,11 @@ function confirmPending(text){
const b=PENDING.querySelector('.body');
if(!b || b.textContent!==text) return false;
PENDING.classList.remove('pending');
const l=PENDING.querySelector('.label'); if(l) l.textContent='user';
// ⚠️ NE PAS réécrire l'étiquette ici : elle porte l'avatar et le prénom
// (17-identity.js). Elle y était remise à « user », si bien que le message
// qu'on venait d'envoyer s'affichait « USER » alors que ceux rejoués au
// chargement portaient le prénom — deux bulles identiques, deux libellés.
const l=PENDING.querySelector('.label'); if(l) l.removeAttribute('title');
PENDING=null;
return true;
}
@@ -114,8 +121,14 @@ function renderStats(el, s){
function labelTokens(el, role, n, firstTs, lastTs){
if(!el) return;
const secs=(lastTs-firstTs)/1000;
if(secs>0.05 && n>1){ setLabel(el, role+' · '+n+' tok · '+(n/secs).toFixed(1)+' tok/s'); }
else { setLabel(el, role+' · '+n+' tok'); }
const m = (secs>0.05 && n>1) ? n+' tok · '+(n/secs).toFixed(1)+' tok/s' : n+' tok';
// Bulle technique : son étiquette EST le bouton de repli, les mesures y vont.
// Réponse de l'assistant : son étiquette porte l'avatar et le nom, les mesures
// vont dans la ligne dédiée — comme le font déjà les stats de fin de tour
// (applyStats). Sans ce partage, le libellé « Loki » était remplacé en direct
// par « assistant · 75 tok · 21.5 tok/s », et ne revenait qu'au rechargement.
if(el.classList.contains('collapsible')) setLabel(el, role+' · '+m);
else setStats(el, m);
}
// Pendant le replay on met à jour l'état `busy` mais on NE touche PAS aux boutons
// (sinon user→stop puis turn_done→send à chaque tour rejoué = flottement visible).