Ajoute l'assistant IA "Ruby" (Claude + Scenario) et corrige plusieurs bugs de la scène
Build and deploy / test-python (push) Successful in 12m24s
Build and deploy / test-js (push) Successful in 1m9s
Build and deploy / build-and-push (push) Skipped
Build and deploy / deploy (push) Skipped

Intègre un chat IA capable de manipuler la scène via les mêmes fonctions
que l'éditeur manuel (objets, variables, déclencheurs, images générées),
avec conversations multiples par écran façon Claude. Corrige au passage
le rafraîchissement pjax hors-ordre, l'onglet IA/déclencheurs vide après
sélection d'un objet, la comparaison de booléens dans les conditions, et
le blocage du glisser-déposer hors du cadre caméra après un redimensionnement
de fond par l'IA.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
william
2026-09-09 19:40:31 +02:00
co-authored by Claude Sonnet 5
parent ab6635eee0
commit b07b231a61
62 changed files with 2928 additions and 62 deletions
+105
View File
@@ -1110,6 +1110,111 @@ body.builderBody > main.content{ flex:1 1 auto; min-height:0; overflow:hidden; d
}
.questTriggerAddChainedActionBtn:hover{ border-color:var(--accent); color:var(--accent); }
/* Onglet "Générer avec l'IA" (voir static/js/ia/ia-chat.js) — maquette
validée (Artifact "Maquette Ruby") : une div occupe TOUTE la hauteur/
largeur de l'onglet, coupée en 2 colonnes (gauche 40%, droite 60%),
chacune header/body/footer. #iaTabPanelBody remplit exactement
#iaTabPanel (déjà display:flex/min-height:0 quand actif, voir
.builderTabPanel plus haut) pour que CET onglet précis n'ait jamais
rien à faire défiler lui-même — seuls les .iaColBody de chaque colonne
défilent, indépendamment l'un de l'autre. */
#iaTabPanelBody{ display:flex; flex-direction:column; flex:1 1 auto; min-height:0; }
.iaTabLayout{
display:flex; width:100%; flex:1 1 auto; min-height:0;
border:1px solid var(--border); border-radius:10px; overflow:hidden;
}
.iaCol{ display:flex; flex-direction:column; min-width:0; min-height:0; }
.iaCol-left{ flex:0 0 40%; border-right:1px solid var(--border); }
.iaCol-right{ flex:1 1 60%; }
.iaColHeader{
flex:0 0 auto; min-height:52px; display:flex; align-items:center; gap:10px;
padding:0 16px; border-bottom:1px solid var(--border);
}
.iaColBody{ flex:1 1 auto; min-height:0; display:flex; flex-direction:column; }
.iaColFooter{ flex:0 0 auto; border-top:1px solid var(--border); }
/* Header gauche : logo + nom (identité "Ruby") */
.iaHeaderLogo{ width:26px; height:26px; border-radius:6px; }
.iaHeaderName{ font-size:15px; font-weight:700; }
/* Body gauche : bouton "+ Nouvelle conversation" (fixe) puis la liste,
seule à défiler (CRUD des conversations, comme claude.ai). */
.iaCol-left .iaColBody{ padding:14px; gap:10px; }
.iaNewConvBtn{ flex:0 0 auto; }
.iaConversationsList{ flex:1 1 auto; min-height:0; overflow-y:auto; display:flex; flex-direction:column; gap:4px; }
.iaConversationItem{
display:flex; align-items:center; justify-content:space-between; gap:6px; width:100%;
padding:8px 10px; border-radius:8px; border:1px solid transparent; background:transparent;
color:var(--text-dim); text-align:left; cursor:pointer; font-size:13px;
}
.iaConversationItem:hover{ background:var(--panel2); }
.iaConversationItem.active{ background:var(--panel2); border-color:var(--accent); color:var(--text); }
.iaConversationTitle{ overflow:hidden; text-overflow:ellipsis; white-space:nowrap; flex:1; }
.iaConversationDelete{ opacity:0; flex-shrink:0; }
.iaConversationItem:hover .iaConversationDelete, .iaConversationItem.active .iaConversationDelete{ opacity:1; }
/* Body droite : le fil de dialogue, seul à défiler ici. */
.iaChatLog{
flex:1 1 auto; min-height:0; overflow-y:auto;
display:flex; flex-direction:column; gap:16px; padding:18px;
}
.iaChatEmpty{
margin:auto; text-align:center; color:var(--text-dim); max-width:360px;
display:flex; flex-direction:column; align-items:center; gap:8px;
}
.iaChatEmpty strong{ color:var(--text); font-size:15px; }
.iaChatAvatar{ width:16px; height:16px; border-radius:4px; vertical-align:-3px; margin-right:4px; }
.iaChatAvatar-large{ width:40px; height:40px; border-radius:10px; margin:0; }
.iaChatRow{ display:flex; flex-direction:column; max-width:78%; }
.iaChatRow-user{ align-self:flex-end; align-items:flex-end; }
.iaChatRow-assistant{ align-self:flex-start; align-items:flex-start; }
.iaChatSender{
font-size:11px; font-weight:600; text-transform:uppercase; letter-spacing:.04em;
color:var(--text-dim); margin:0 4px 4px; display:flex; align-items:center;
}
.iaChatBubble{
padding:10px 14px; border-radius:14px; white-space:pre-wrap; line-height:1.5; font-size:14px;
}
.iaChatRow-user .iaChatBubble{ background:var(--accent); color:#fff; border-bottom-right-radius:4px; }
.iaChatRow-assistant .iaChatBubble{ background:var(--panel2); color:var(--text); border:1px solid var(--border); border-bottom-left-radius:4px; }
/* Footer droite : le champ de saisie prend tout le footer. */
.iaCol-right .iaColFooter{ padding:12px 16px; }
.iaChatInputBar{
display:flex; align-items:flex-end; gap:8px; background:var(--panel);
border:1px solid var(--border); border-radius:16px; padding:8px 8px 8px 16px;
width:100%;
}
.iaChatInputBar textarea{
flex:1; background:transparent; border:none; color:var(--text); resize:none;
min-height:24px; max-height:200px; padding:8px 0; font:inherit; line-height:1.5;
}
.iaChatInputBar textarea:focus{ outline:none; }
.iaChatSendBtn{
flex-shrink:0; width:36px; height:36px; border-radius:50%; border:none; cursor:pointer;
background:var(--accent); color:#fff; display:flex; align-items:center; justify-content:center;
font-size:16px; line-height:1;
}
.iaChatSendBtn:disabled{ opacity:.5; cursor:default; }
.iaChatSendBtn:hover:not(:disabled){ background:var(--accent-2); }
/* Loader "IA en train d'écrire" (demande explicite : sans ça, un
créateur qui ne voit rien bouger pendant qu'un écran complet s'enchaîne
sur plusieurs appels d'outils reclique, pensant que ça n'a pas marché). */
.iaChatTyping{ display:flex; gap:4px; padding:14px; align-items:center; }
.iaChatTyping span{
width:6px; height:6px; border-radius:50%; background:var(--text-dim);
animation:iaChatTypingBounce 1.2s infinite ease-in-out;
}
.iaChatTyping span:nth-child(2){ animation-delay:.15s; }
.iaChatTyping span:nth-child(3){ animation-delay:.3s; }
@keyframes iaChatTypingBounce{
0%, 60%, 100%{ opacity:.3; transform:translateY(0); }
30%{ opacity:1; transform:translateY(-3px); }
}
@media (prefers-reduced-motion: reduce){
.iaChatTyping span{ animation:none; opacity:.6; }
}
/* Losange "condition" — lecture ENTIÈREMENT VERTICALE (demande explicite :
"il faut tout mettre verticalement", le losange lui-même ne change
pas) : le losange reste petit et centré, la branche qui MÈNE à cette