Studio lot 8bis : présenter les personnages au visiteur

Écran d'entrée au chargement de la configuration.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011VxSQeGQYUvPmSEoGdnidA
This commit is contained in:
Thomas Fransolet 2026-09-15 22:41:40 +02:00
parent 172530e00a
commit 8979ab2e63
2 changed files with 124 additions and 0 deletions

View File

@ -0,0 +1,118 @@
import 'package:flutter/material.dart';
import 'package:manager_api_new/api.dart';
/// Écran d'entrée « les personnes que vous allez rencontrer » (plan Studio décision 25).
///
/// Le serveur n'envoie le casting qu'avec l'interrupteur armé et au moins deux portraits. Montré une
/// fois par configuration et par lancement de l'app : revenir à la liste ne le rouvre pas. Comme la
/// mention IA, les libellés sont portés ici l'app n'a pas de traductions pour ses propres textes.
class CastingIntroDialog extends StatelessWidget {
const CastingIntroDialog({Key? key, required this.casting, required this.language}) : super(key: key);
final List<CastingVisitorMemberDTO> casting;
final String? language;
static final Set<String> _shown = {};
static const _titles = {
'FR': 'Les personnes que vous allez rencontrer',
'NL': 'De personen die u zult ontmoeten',
'EN': 'The people you will meet',
'DE': 'Die Menschen, denen Sie begegnen werden',
'ES': 'Las personas que va a conocer',
'IT': 'Le persone che incontrerete',
'PL': 'Osoby, które spotkasz',
'CN': '您将遇到的人物',
'AR': 'الشخصيات التي ستلتقيها',
'UK': 'Люди, яких ви зустрінете',
'LB': "D'Leit, déi Dir kenne léiert",
};
static const _starts = {
'FR': 'Commencer la visite',
'NL': 'Het bezoek beginnen',
'EN': 'Start the visit',
'DE': 'Besuch beginnen',
'ES': 'Empezar la visita',
'IT': 'Inizia la visita',
'PL': 'Rozpocznij zwiedzanie',
'CN': '开始参观',
'AR': 'ابدأ الزيارة',
'UK': 'Почати відвідування',
'LB': 'Besuch ufänken',
};
static void showIfNeeded(BuildContext context, ConfigurationDTO configuration, String? language) {
final casting = configuration.casting;
if (casting == null || casting.length < 2 || configuration.id == null) return;
if (!_shown.add(configuration.id!)) return;
showDialog(
context: context,
builder: (_) => CastingIntroDialog(casting: casting, language: language),
);
}
String _label(Map<String, String> labels) => labels[(language ?? 'FR').toUpperCase()] ?? labels['FR']!;
@override
Widget build(BuildContext context) {
return Dialog(
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(22)),
child: Padding(
padding: const EdgeInsets.fromLTRB(20, 24, 20, 20),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Text(
_label(_titles),
textAlign: TextAlign.center,
style: const TextStyle(fontSize: 18, fontWeight: FontWeight.w700, color: Color(0xFF1E2A33)),
),
const SizedBox(height: 20),
Wrap(
alignment: WrapAlignment.center,
spacing: 16,
runSpacing: 16,
children: casting
.map((member) => SizedBox(
width: 110,
child: Column(
children: [
ClipOval(
child: SizedBox(
width: 88,
height: 88,
child: Image.network(
member.portraitUrl ?? '',
fit: BoxFit.cover,
errorBuilder: (_, __, ___) => Container(color: const Color(0xFFE8E3DA)),
),
),
),
const SizedBox(height: 6),
Text(member.name ?? '',
textAlign: TextAlign.center,
style: const TextStyle(fontSize: 14, fontWeight: FontWeight.w600)),
if ((member.role ?? '').isNotEmpty)
Text(member.role!,
textAlign: TextAlign.center,
style: const TextStyle(fontSize: 12, color: Color(0xFF6B7B86))),
],
),
))
.toList(),
),
const SizedBox(height: 24),
SizedBox(
width: double.infinity,
child: FilledButton(
onPressed: () => Navigator.of(context).pop(),
child: Text(_label(_starts)),
),
),
],
),
),
);
}
}

View File

@ -1,3 +1,4 @@
import 'package:tablet_app/Components/casting_intro_dialog.dart';
import 'dart:async';
import 'dart:convert';
import 'dart:io';
@ -328,6 +329,11 @@ class _MainViewWidget extends State<MainViewWidget> {
await getCurrentConfiguration(appContext);
final loadedConfiguration = tabletAppContext.configuration;
if (mounted && loadedConfiguration != null) {
CastingIntroDialog.showIfNeeded(context, loadedConfiguration, tabletAppContext.language);
}
// Load applicationInstanceDTO to check if assistant/statistics are enabled
try {
if (tabletAppContext.instanceId != null) {