feat(tutorial): guide the first launch with spotlighted steps and gesture hands
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>
This commit is contained in:
co-authored by
Claude Opus 5
parent
32143c5bb1
commit
32582aba3d
@@ -0,0 +1,46 @@
|
||||
/// Persistance du didacticiel : mémorise les visites guidées déjà vues.
|
||||
///
|
||||
/// Chaque visite guidée (« tour ») possède un identifiant stocké dans les
|
||||
/// SharedPreferences sous la forme `tutorial_done_<id>`. Réinitialiser le
|
||||
/// didacticiel depuis les paramètres efface simplement ces clés.
|
||||
library;
|
||||
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
|
||||
/// Identifiants des visites guidées de l'application.
|
||||
class TutorialTours {
|
||||
const TutorialTours._();
|
||||
|
||||
/// Visite d'accueil : présentation générale et navigation.
|
||||
static const String home = 'home';
|
||||
|
||||
/// Visite de l'éditeur d'impacts : tap, appui long et pincement pour zoomer.
|
||||
static const String impactEditor = 'impact_editor';
|
||||
|
||||
/// Toutes les visites connues, dans l'ordre logique de découverte.
|
||||
static const List<String> all = [home, impactEditor];
|
||||
}
|
||||
|
||||
class TutorialService {
|
||||
static const String _prefix = 'tutorial_done_';
|
||||
|
||||
Future<Set<String>> loadCompletedTours() async {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
return TutorialTours.all
|
||||
.where((id) => prefs.getBool('$_prefix$id') ?? false)
|
||||
.toSet();
|
||||
}
|
||||
|
||||
Future<void> markCompleted(String tourId) async {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
await prefs.setBool('$_prefix$tourId', true);
|
||||
}
|
||||
|
||||
/// Efface la mémoire du didacticiel : toutes les visites seront rejouées.
|
||||
Future<void> resetAll() async {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
for (final id in TutorialTours.all) {
|
||||
await prefs.remove('$_prefix$id');
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user