feat(tutorial): add 9-screen help/tutorial carousel

Add PantallaTutorialAyuda, a PageView-based carousel covering saved
stations/groups, per-station equalizer, recording, adaptive alarms,
Android Auto favorites, auto-reconnect, snooze duration, custom
stations, and a closing summary with a "watch it again" reminder.

ServicioTutorialAyuda persists a one-time seen flag so the carousel
shows once via mostrarSiProcede, independent of entry point; the
final page's CTA label depends on the primerArranque constructor
parameter ("Empezar a escuchar" vs "Cerrar").

Translate the new copy into all 13 supported locales and update
helpSubtitle to describe the new entry point.
This commit is contained in:
2026-08-01 11:34:53 +02:00
parent d945e1a313
commit 015a20a823
34 changed files with 2262 additions and 61 deletions
@@ -0,0 +1,32 @@
import 'package:shared_preferences/shared_preferences.dart';
/// Persists whether the 9-screen help/tutorial carousel (`PantallaTutorialAyuda`)
/// has already been shown, so it renders once on the genuine first-run
/// sequence rather than on every launch.
///
/// Same injectable-`SharedPreferences`, versioned-key convention as
/// `ServicioBienvenida` -- a plain one-time boolean flag, not a per-app-version
/// "due again" scheme like `ServicioContenidoApp` uses: no existing user has
/// this flag set yet, regardless of whether they are a fresh install or an
/// upgrade, so a single flag already satisfies "show once, ever".
class ServicioTutorialAyuda {
ServicioTutorialAyuda({SharedPreferences? prefs}) : _prefs = prefs;
static const _keyTutorialVisto = 'pluri_tutorial_visto_v1';
final SharedPreferences? _prefs;
/// Injected startup instance (S3-R4); getInstance() is only a fallback.
Future<SharedPreferences> _resolverPrefs() async =>
_prefs ?? SharedPreferences.getInstance();
Future<bool> debeMostrarTutorial() async {
final prefs = await _resolverPrefs();
return !(prefs.getBool(_keyTutorialVisto) ?? false);
}
Future<void> marcarTutorialVisto() async {
final prefs = await _resolverPrefs();
await prefs.setBool(_keyTutorialVisto, true);
}
}