from flask import jsonify, request import screens from core.flask_app import app @app.route("/game//screens//triggers", methods=["GET"]) def screen_triggers_get(slug, screen_id): """Déclencheurs D'ÉCRAN de CET écran (voir "Déclencheurs de l'écran", screens/rendering/screen_triggers.py) — SANS objet requis, pour de la narration/cinématique dès l'affichage.""" screen = screens.get_screen(slug, screen_id) if screen is None: return jsonify({"error": "écran introuvable"}), 404 rules = screens.resolve_screen_triggers(screen) # Rétro-remplissage des feuilles sans id (voir screens/rendering/ # trigger_graph.py::list_all_triggers, même logique côté objet) — # persisté dès ce premier affichage. if screens.backfill_missing_leaf_ids(rules): screens.set_screen_triggers(slug, screen_id, rules) return jsonify(rules) @app.route("/game//screens//triggers", methods=["POST"]) def screen_triggers_add(slug, screen_id): """Ajoute une règle "déclencheur d'écran -> action" — body {rule}, même contrat "liste ENTIÈRE" que routes/triggers/triggers.py::triggers_add : on recharge les règles existantes de l'écran, on y ajoute la nouvelle, on sauvegarde la liste complète.""" screen = screens.get_screen(slug, screen_id) if screen is None: return jsonify({"error": "écran introuvable"}), 404 body = request.get_json(silent=True) or {} new_rule = body.get("rule") if not isinstance(new_rule, dict): return jsonify({"error": "rule invalide"}), 400 rules = screens.resolve_screen_triggers(screen) rules.append(new_rule) sanitized = screens.sanitize_screen_triggers(rules) screens.set_screen_triggers(slug, screen_id, sanitized) return jsonify({"ok": True}) @app.route("/game//screens//triggers", methods=["DELETE"]) def screen_triggers_clear(slug, screen_id): """Retire TOUTES les règles d'écran de CET écran.""" if screens.get_screen(slug, screen_id) is None: return jsonify({"error": "écran introuvable"}), 404 screens.set_screen_triggers(slug, screen_id, []) return jsonify({"ok": True}) @app.route("/game//screens//triggers/", methods=["DELETE"]) def screen_trigger_delete_one(slug, screen_id, index): """Retire UNE SEULE règle d'écran (son index dans la liste) — contrairement aux déclencheurs d'objet (un seul par objet en pratique), un écran peut porter plusieurs règles "affichage" côte à côte : la suppression doit donc cibler l'une d'elles, pas tout vider (voir screen_triggers_clear ci-dessus, conservée pour un vidage complet).""" screen = screens.get_screen(slug, screen_id) if screen is None: return jsonify({"error": "écran introuvable"}), 404 rules = screens.resolve_screen_triggers(screen) if index < 0 or index >= len(rules): return jsonify({"error": "règle introuvable"}), 404 del rules[index] screens.set_screen_triggers(slug, screen_id, rules) return jsonify({"ok": True}) @app.route("/game//screens//triggers/action/", methods=["DELETE"]) def screen_trigger_remove_action(slug, screen_id, leaf_id): """Retire UNE action précise d'un déclencheur d'écran — même contrat que routes/triggers/triggers.py::trigger_remove_action.""" if not screens.remove_action_from_screen_trigger(slug, screen_id, leaf_id): return jsonify({"error": "action introuvable"}), 404 return jsonify({"ok": True}) @app.route("/game//screens//triggers/action//move", methods=["POST"]) def screen_trigger_move_action(slug, screen_id, leaf_id): """Déplace une action précise d'un cran ("up"/"down") dans sa chaîne, pour un déclencheur d'écran — même contrat que routes/triggers/triggers.py::trigger_move_action.""" body = request.get_json(silent=True) or {} direction = body.get("direction") if direction not in ("up", "down"): return jsonify({"error": "direction invalide"}), 400 if not screens.move_action_in_screen_trigger(slug, screen_id, leaf_id, direction): return jsonify({"error": "action introuvable"}), 404 return jsonify({"ok": True}) @app.route("/game//screens//triggers/dialogue", methods=["POST"]) def screen_trigger_dialogue_update(slug, screen_id): """Édition EN LIGNE des répliques d'un dialogue porté par un déclencheur d'écran — même contrat que routes/triggers/triggers.py::trigger_dialogue_update.""" screen = screens.get_screen(slug, screen_id) if screen is None: return jsonify({"error": "écran introuvable"}), 404 body = request.get_json(silent=True) or {} dialogue_id = body.get("dialogue_id") if not isinstance(dialogue_id, str) or not dialogue_id.strip(): return jsonify({"error": "dialogue_id invalide"}), 400 rules = screens.resolve_screen_triggers(screen) if not screens.set_dialogue_lines_in_rules(rules, dialogue_id, body.get("lines")): return jsonify({"error": "dialogue introuvable"}), 404 sanitized = screens.sanitize_screen_triggers(rules) screens.set_screen_triggers(slug, screen_id, sanitized) return jsonify({"ok": True}) @app.route("/game//screens//triggers/append-action", methods=["POST"]) def screen_trigger_append_action(slug, screen_id): """"+ Ajouter une action" en bout de chaîne, pour un déclencheur d'écran — même contrat que routes/triggers/triggers.py::trigger_append_action.""" if screens.get_screen(slug, screen_id) is None: return jsonify({"error": "écran introuvable"}), 404 body = request.get_json(silent=True) or {} after_id = body.get("after_id") if not isinstance(after_id, str) or not after_id.strip(): return jsonify({"error": "after_id invalide"}), 400 if not screens.append_action_to_screen_trigger(slug, screen_id, after_id, body.get("action")): return jsonify({"error": "action précédente introuvable"}), 404 return jsonify({"ok": True})