Ajoute un didacticiel joué à la première utilisation : un voile sombre perce un trou de lumière autour de l'élément à découvrir, une main animée mime le geste attendu (tap, appui long, glisser, pincement à deux doigts pour zoomer) et une bulle explique l'étape avec sa progression. - visite d'accueil : nouvelle session, télémétrie, barre de navigation, réglages - visite de l'éditeur d'impacts : ajouter, déplacer, zoomer au pincement, valider - chaque visite n'est jouée qu'une fois (SharedPreferences) - Paramètres > Aide & didacticiel > Revoir le didacticiel : réinitialise tout et relance la visite au retour sur l'écran concerné Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
55 lines
1.7 KiB
Dart
55 lines
1.7 KiB
Dart
/// État global du didacticiel : quelles visites guidées restent à jouer.
|
|
///
|
|
/// Le provider est chargé au démarrage ; tant que les préférences ne sont pas
|
|
/// lues, aucune visite n'est déclenchée (évite un flash d'overlay au lancement).
|
|
library;
|
|
|
|
import 'package:flutter/foundation.dart';
|
|
import '../../services/tutorial_service.dart';
|
|
|
|
class TutorialProvider with ChangeNotifier {
|
|
TutorialProvider({TutorialService? service})
|
|
: _service = service ?? TutorialService() {
|
|
load();
|
|
}
|
|
|
|
final TutorialService _service;
|
|
|
|
final Set<String> _completed = {};
|
|
bool _loaded = false;
|
|
|
|
/// `true` une fois les préférences lues.
|
|
bool get isLoaded => _loaded;
|
|
|
|
/// `true` si l'utilisateur a déjà terminé (ou passé) la visite d'accueil.
|
|
bool get hasSeenIntro => _completed.contains(TutorialTours.home);
|
|
|
|
/// Lit les visites déjà vues. Les visites terminées pendant le chargement
|
|
/// sont conservées (le résultat est fusionné, jamais écrasé).
|
|
Future<void> load() async {
|
|
_completed.addAll(await _service.loadCompletedTours());
|
|
_loaded = true;
|
|
notifyListeners();
|
|
}
|
|
|
|
/// Faut-il jouer la visite [tourId] ?
|
|
bool shouldRun(String tourId) => _loaded && !_completed.contains(tourId);
|
|
|
|
/// Marque une visite comme vue (terminée ou passée) : elle ne rejouera plus.
|
|
Future<void> complete(String tourId) async {
|
|
if (_completed.add(tourId)) {
|
|
notifyListeners();
|
|
await _service.markCompleted(tourId);
|
|
}
|
|
}
|
|
|
|
/// Relance le didacticiel depuis les paramètres : toutes les visites
|
|
/// redeviennent disponibles et rejoueront dès l'affichage de leur écran.
|
|
Future<void> restart() async {
|
|
await _service.resetAll();
|
|
_completed.clear();
|
|
_loaded = true;
|
|
notifyListeners();
|
|
}
|
|
}
|