Ajoute la fonctionnalite quiz autonome/plein ecran a la boite a quiz
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:
co-authored by
Claude Sonnet 5
parent
559331f9cf
commit
7db4803b93
@@ -0,0 +1,97 @@
|
||||
import json
|
||||
|
||||
# Réglages "❓ Boîte à quiz" propres au quiz AUTONOME/plein écran (demande
|
||||
# explicite : "étendre les fonctionnalités de la boîte à quiz pour les RH
|
||||
# qui veulent juste faire un quiz") — DISTINCT de "🎨 Style"
|
||||
# (dialogue_box_style.py, partagé avec dialogue_box/score_widget) : ce
|
||||
# fichier ne gère QUE plein écran/minuteur/modèle, jamais police/couleur.
|
||||
#
|
||||
# DEUX catégories de modèles bien distinctes (demande explicite, précisée
|
||||
# après coup — les 5 premiers modèles construits avant cette précision
|
||||
# étaient tous de la première catégorie) :
|
||||
# - "dialog_template" (modèles "boîte de dialogue", visibles SEULEMENT
|
||||
# quand fullscreen=False) : variantes de forme/couleur/interaction sur
|
||||
# une structure HTML qui reste globalement la même que "Classique".
|
||||
# - "page_template" (modèles "page de quiz", visibles SEULEMENT quand
|
||||
# fullscreen=True) : thème complet et autonome — police, formes,
|
||||
# couleurs ET structure HTML totalement propres à CHAQUE modèle,
|
||||
# aucune structure partagée entre eux ni avec les modèles "boîte".
|
||||
# Les deux réglages sont conservés INDÉPENDAMMENT (jamais écrasés l'un par
|
||||
# l'autre) : activer/désactiver le plein écran change juste lequel des
|
||||
# deux s'applique, sans jamais perdre le choix de l'autre.
|
||||
DEFAULT_QUIZ_BOX_CONFIG = {
|
||||
"fullscreen": False,
|
||||
"timer_mode": "aucun",
|
||||
"timer_seconds": 20,
|
||||
"dialog_template": "defaut",
|
||||
"page_template": "classique",
|
||||
}
|
||||
|
||||
# "aucun" : pas de minuteur (réglage par défaut, jamais imposé — demande
|
||||
# explicite du créateur). "question" : redémarre à chaque question.
|
||||
# "quiz" : un seul compte à rebours pour l'ensemble du quiz.
|
||||
TIMER_MODES = ["aucun", "question", "quiz"]
|
||||
|
||||
# "defaut" (Classique) = le CSS/HTML déjà existant, AUCUN changement
|
||||
# visuel pour un quiz non reconfiguré (voir quiz_box_templates.py) —
|
||||
# "Verre dépoli"/"Néon"/"Minimal"/"Ludique" ont été retirés (demande
|
||||
# explicite : "supprime tous les modele de boite sauf le base").
|
||||
# "manga_dialogue" (Manga) : pendant, en petite carte flottante (jamais
|
||||
# plein écran), du modèle "page de quiz" "Manga" — validé par le créateur
|
||||
# via une maquette interactive avant intégration (voir
|
||||
# screens/rendering/quiz_box_templates.py::render_quiz_box_manga_dialogue).
|
||||
# Clé DIFFÉRENTE du modèle "page" "manga" (registre d'effets JS partagé
|
||||
# entre les deux catégories, voir static/js/play/quiz-box-templates.js)
|
||||
# — reste proche de la structure de "Classique" (demande explicite :
|
||||
# les modèles "boîte" ne changent que forme/couleur/interaction).
|
||||
QUIZ_BOX_DIALOG_TEMPLATES = ["defaut", "manga_dialogue"]
|
||||
QUIZ_BOX_DIALOG_TEMPLATE_LABELS = {
|
||||
"defaut": "Classique",
|
||||
"manga_dialogue": "Manga",
|
||||
}
|
||||
|
||||
# "classique" (Classique) : modèle de PAGE DE QUIZ de base — sobre/
|
||||
# professionnel, reprend les couleurs par défaut du modèle "boîte de
|
||||
# dialogue" de base (demande explicite : "respecte les couleurs du modele
|
||||
# de boite de base pour le modele de page de base") plutôt que sa propre
|
||||
# palette, contrairement à "manga" qui est un thème pleinement autonome.
|
||||
# "manga" : thème/typographie/structure entièrement dédiés, validé par le
|
||||
# créateur via une maquette interactive avant intégration (voir
|
||||
# screens/rendering/quiz_box_templates.py::render_quiz_box_page_manga).
|
||||
QUIZ_BOX_PAGE_TEMPLATES = ["classique", "manga"]
|
||||
QUIZ_BOX_PAGE_TEMPLATE_LABELS = {
|
||||
"classique": "Classique",
|
||||
"manga": "Manga",
|
||||
}
|
||||
|
||||
_MIN_TIMER_SECONDS = 3
|
||||
_MAX_TIMER_SECONDS = 600
|
||||
|
||||
|
||||
def sanitize_quiz_box_config(raw_config):
|
||||
config = dict(DEFAULT_QUIZ_BOX_CONFIG)
|
||||
if not isinstance(raw_config, dict):
|
||||
return config
|
||||
config["fullscreen"] = bool(raw_config.get("fullscreen"))
|
||||
if raw_config.get("timer_mode") in TIMER_MODES:
|
||||
config["timer_mode"] = raw_config["timer_mode"]
|
||||
try:
|
||||
config["timer_seconds"] = max(_MIN_TIMER_SECONDS, min(_MAX_TIMER_SECONDS, int(raw_config.get("timer_seconds"))))
|
||||
except (TypeError, ValueError):
|
||||
pass
|
||||
if raw_config.get("dialog_template") in QUIZ_BOX_DIALOG_TEMPLATES:
|
||||
config["dialog_template"] = raw_config["dialog_template"]
|
||||
if raw_config.get("page_template") in QUIZ_BOX_PAGE_TEMPLATES:
|
||||
config["page_template"] = raw_config["page_template"]
|
||||
return config
|
||||
|
||||
|
||||
def resolve_quiz_box_config(obj):
|
||||
raw = (obj.get("attributes") or {}).get("_quiz_box_config")
|
||||
if not raw:
|
||||
return dict(DEFAULT_QUIZ_BOX_CONFIG)
|
||||
try:
|
||||
parsed = json.loads(raw)
|
||||
except (TypeError, ValueError):
|
||||
return dict(DEFAULT_QUIZ_BOX_CONFIG)
|
||||
return sanitize_quiz_box_config(parsed)
|
||||
Reference in New Issue
Block a user