Ajoute la fonctionnalite quiz autonome/plein ecran a la boite a quiz
Build and deploy / test-python (push) Successful in 12m10s
Build and deploy / test-js (push) Successful in 1m27s
Build and deploy / build-and-push (push) Skipped
Build and deploy / deploy (push) Skipped

Introduit la double categorie de modeles (boite de dialogue / page de
quiz plein ecran) avec plein ecran, minuteur, score integre et ecran de
resultat pour les modeles page ; ajoute les modeles "Manga" (boite et
page) et "Classique" (page), pilotables aussi par l'assistant IA Ruby.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
william
2026-09-13 15:07:23 +02:00
co-authored by Claude Sonnet 5
parent 559331f9cf
commit 7db4803b93
26 changed files with 3173 additions and 60 deletions
+74
View File
@@ -796,6 +796,80 @@ function saveDialogueBoxStyle(objectId) {
});
}
// "🖼️ Modèles" (voir templates/scene_edit.html, "❓ Boîte à quiz") — DEUX
// galeries INDÉPENDANTES (demande explicite : "boîte de dialogue" hors
// plein écran, "page de quiz" en plein écran, jamais confondues) — une
// SEULE des deux est rendue à la fois (voir quiz_box_config.fullscreen
// côté serveur), chacune surligne la vignette cliquée sur sa propre
// grille (data-selected-template) puis sauvegarde tout de suite (même
// geste qu'un clic sur une tuile de personnage/décor).
function _selectQuizBoxTemplate(objectId, key, gridId) {
var grid = document.getElementById(gridId);
if (grid) {
grid.setAttribute('data-selected-template', key);
var tiles = grid.querySelectorAll('.quizTemplateTile');
for (var i = 0; i < tiles.length; i++) {
tiles[i].classList.toggle('is-selected', tiles[i].getAttribute('data-template') === key);
}
}
saveQuizBoxConfig(objectId);
}
function selectQuizBoxDialogTemplate(objectId, key) { _selectQuizBoxTemplate(objectId, key, 'quizDialogTemplateGrid'); }
function selectQuizBoxPageTemplate(objectId, key) { _selectQuizBoxTemplate(objectId, key, 'quizPageTemplateGrid'); }
// "⚙️ Options du quiz" + "🖼️ Modèles" (demande explicite : quiz RH
// autonome — plein écran/minuteur/DEUX modèles indépendants) — mirror de
// saveDialogueBoxStyle, mais un objet de config à PART (voir
// screens/rendering/quiz_box_config.py), jamais mélangé à "🎨 Style"
// (couleurs/police, inchangé, voir plus haut). Remplace l'aperçu par le
// HTML fraîchement rendu une fois sauvegardé — un modèle change la
// STRUCTURE du balisage (voir screens/rendering/quiz_box_templates.py),
// pas juste une classe CSS : deviner quelle balise ajouter/retirer côté
// client casserait la plupart des modèles.
//
// dialog_template/page_template : SEULE une des deux grilles est rendue
// à la fois (voir templates/scene_edit.html) — celle qui est ABSENTE
// garde sa valeur via #quizBoxTemplateMeta (posé par le serveur), jamais
// écrasée par un défaut.
//
// "Plein écran" (demande explicite : "elle doit occuper tout l'écran",
// "être visible par défaut", "la notion de caméra disparaît" — DANS CET
// ÉDITEUR aussi, pas seulement au jeu) : rechargement complet dès que ce
// réglage CHANGE de valeur — le cadre "🎥 Champ de la caméra" dépend de
// TOUS les quiz de l'écran (pas seulement celui-ci, voir
// routes/scenes/scene_edit_view.py::any_quiz_box_fullscreen), ET la
// galerie de modèles à afficher change entièrement (boîte <-> page) :
// un simple patch DOM ne pourrait recalculer ni l'un ni l'autre ici.
function saveQuizBoxConfig(objectId) {
var meta = document.getElementById('quizBoxTemplateMeta');
function currentTemplate(gridId, metaAttr) {
var grid = document.getElementById(gridId);
if (!grid) return meta ? meta.getAttribute(metaAttr) : null;
var selectedTile = grid.querySelector('.quizTemplateTile.is-selected');
return grid.getAttribute('data-selected-template') || (selectedTile && selectedTile.getAttribute('data-template'));
}
var fullscreenEl = document.getElementById('quiz-fullscreen');
var fullscreenChanged = fullscreenEl.checked !== (fullscreenEl.getAttribute('data-was-checked') === '1');
var config = {
fullscreen: fullscreenEl.checked,
timer_mode: document.getElementById('quiz-timer-mode').value,
timer_seconds: Number(document.getElementById('quiz-timer-seconds').value),
dialog_template: currentTemplate('quizDialogTemplateGrid', 'data-dialog-template') || 'defaut',
page_template: currentTemplate('quizPageTemplateGrid', 'data-page-template') || 'manga',
};
fetch('/game/' + GAME_SLUG + '/scene-objects/' + objectId + '/quiz-config', {
method: 'POST', headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ config: config }),
})
.then(function (r) { return r.json(); })
.then(function (data) {
if (fullscreenChanged) { window.location.reload(); return; }
var el = document.getElementById('el-' + objectId);
var widget = el && el.querySelector('.quizBoxWidget');
if (widget && data.rendered_html) widget.outerHTML = data.rendered_html;
});
}
function initPersonnageCommandsPanel() {
var body = document.getElementById('personnageCommandsBody');
if (!body) return;