feat: réactions dans le tiroir Comments (+ suppression) et refonte du menu de sélection (v7.67.0)
FlowDeck CI / lint (push) Canceled after 0s
FlowDeck CI / test (push) Canceled after 0s
FlowDeck CI / docker (push) Canceled after 0s

Tiroir Comments
- Section « Reactions » au-dessus des fils : émoji, compte (si >1) et texte
  ancré lu dans le DOM (reactionList() / _anchorText(), offsets source hors
  pastilles) ; l'état vide ne s'affiche plus s'il reste des réactions.
- Suppression : ✕ sur la ligne du tiroir (mes réactions) ET croix ::after au
  survol de la pastille sur l'émoji que j'ai posé (aucun nœud ajouté → offsets
  intacts). Deux entrées → removeReaction() → POST toggle → loadReactions().

Menu de sélection (maquette ASCII)
- Ligne 4 = rangée scannée : 💬 Comment (libellé) à gauche, 🙂+ réaction à
  droite (.ft-row-split) ; la réaction sort de la ligne 3.
- Entête Skills avec ≡ à droite (::after), liste Skills scrollable.
- ✨ Ask AI retiré de la toolbar : doublon exact de « Edit with AI » du pied.
- Écart volontaire à la maquette : le barré (T) de la ligne 2 est conservé.

Fix racine (flake de gate)
- _is_public_host attrape OSError (le garde SSRF renvoie un booléen, il ne
  lève plus) : un socket.timeout DNS ne bascule plus fetch_og_metadata dans
  son except Exception → repli silencieux → AssertionError.
- fixture stub_dns sur TestOGParser (même motif que test_agent_web_tools) :
  zéro vrai DNS dans les tests OG.

Tests: pytest tests/ -q -n auto → 1390 passed / 0 failed (flake corrigé) ;
ruff check app tests → OK ; e2e v764 (réactions dans le tiroir + suppression
A/B), v762 (nouvelle ligne 4), v766, v7641, v763 → 6 passed sur :8081
(image flowdeck:v7.67.0 rebuild + redéployée).
This commit is contained in:
2026-10-08 14:25:48 -04:00
parent db6bf03a00
commit d58c321c07
16 changed files with 345 additions and 17 deletions
+77
View File
@@ -3040,6 +3040,30 @@ button.breadcrumb-current { max-width: 260px; }
letter-spacing: 1px;
}
/* ── v7.67 : refonte façon capture — ligne Comment | réaction aux 2 extrémités,
entête « Skills » avec ≡ à droite, liste Skills scrollable ── */
.format-toolbar .ft-row-split {
justify-content: space-between;
gap: 4px;
}
.format-toolbar .ft-comment {
justify-content: flex-start;
}
.format-toolbar .ft-skills-head {
display: flex;
align-items: center;
justify-content: space-between;
}
.format-toolbar .ft-skills-head::after {
content: '≡';
font-size: 13px;
color: var(--text-dim);
}
.format-toolbar .ft-skills {
max-height: 132px;
overflow-y: auto;
}
/* Séparateurs, groupe « Skills », pied de page */
.format-toolbar .ft-sep {
height: 1px;
@@ -3212,6 +3236,28 @@ button.breadcrumb-current { max-width: 260px; }
.fd-react-chip img { width: 12px; height: 12px; object-fit: contain; }
.fd-react-n { font-size: 10px; color: var(--text-dim); }
/* v7.67 : suppression d'une réaction — au survol de la pastille, l'émoji que
J'ai posé devient une croix (un seul clic = retirer). Pas de reflow : c'est
un ::after, les offsets source ne bougent pas. */
.fd-react-emo { position: relative; display: inline-flex; align-items: center; }
.fd-react-emo.is-mine::after {
content: '✕';
position: absolute;
inset: -3px;
display: none;
align-items: center;
justify-content: center;
font-size: 9px;
line-height: 1;
color: var(--text-dim);
background: var(--bg-modal, #1f1f1f);
border: 1px solid var(--border, #333);
border-radius: 50%;
cursor: pointer;
}
.fd-react-chip:hover .fd-react-emo.is-mine::after { display: flex; }
.fd-react-emo.is-mine:hover::after { color: #e5484d; border-color: #e5484d; }
/* Tiroir de commentaires (fil + saisie) */
.comment-thread {
position: relative;
@@ -3251,6 +3297,37 @@ button.breadcrumb-current { max-width: 260px; }
.ct-menu-item.is-danger { color: #e5484d; }
.ct-body { font-size: 13px; white-space: pre-wrap; margin-top: 6px; color: var(--text-primary); }
.ct-anchor-label { font-size: 10px; color: var(--text-dim); margin-top: 6px; }
/* v7.67 : section Réactions du tiroir (liste des plages réagies + retirer) */
.ct-section-title {
font-size: 11px;
font-weight: 600;
letter-spacing: .5px;
text-transform: uppercase;
color: var(--text-dim);
margin-bottom: 8px;
}
.ct-reaction {
display: flex;
align-items: center;
gap: 8px;
padding: 6px 8px;
margin-bottom: 6px;
background: var(--bg-secondary, #2a2a2a);
border: 1px solid var(--border, #333);
border-radius: 8px;
font-size: 13px;
}
.ct-re-emoji { font-size: 14px; line-height: 1; flex-shrink: 0; }
.ct-re-count { font-size: 11px; color: var(--text-dim); }
.ct-re-text {
flex: 1;
min-width: 0;
color: var(--text-secondary);
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.comments-drawer-input { border-top: 1px solid var(--border, #333); padding: 12px 16px; }
.ct-input-row { display: flex; gap: 6px; align-items: flex-end; }
.ct-input-row textarea {