121 lines
4.8 KiB
Dart
121 lines
4.8 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:package_info_plus/package_info_plus.dart';
|
|
import 'package:provider/provider.dart';
|
|
|
|
import '../../estado/estado_radio.dart';
|
|
import '../../l10n/gen/app_localizations.dart';
|
|
import '../../widgets/pluri_glass_surface.dart';
|
|
import '../../widgets/pluri_icon.dart';
|
|
import '../../widgets/pluri_layout.dart';
|
|
import '../../widgets/pluri_onboarding_dialog.dart';
|
|
import '../../widgets/pluri_push_scaffold.dart';
|
|
|
|
/// APLICACIÓN group · "Info" (design ADR-3). Body moved verbatim from the
|
|
/// former `_SeccionInfo` in `pantalla_ajustes.dart`. Unlike the other four
|
|
/// sections in this batch, `_SeccionInfo` never had its own header
|
|
/// icon+title row — its first tile (app name + version) already served that
|
|
/// role — so there is no header row to strip here; the body below is
|
|
/// unchanged in full. `infoSectionTitle` is the one new ARB key this screen
|
|
/// needed, since no existing in-body header string covers a bare "Info"
|
|
/// label (see WU3b's apply-progress note).
|
|
class PantallaAjustesInfo extends StatelessWidget {
|
|
const PantallaAjustesInfo({super.key});
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
final l10n = AppLocalizations.of(context);
|
|
return PluriPushScaffold(
|
|
title: l10n.infoSectionTitle,
|
|
body: ListView(
|
|
padding: PluriLayout.pageContentPadding,
|
|
children: const [_CuerpoInfo()],
|
|
),
|
|
);
|
|
}
|
|
}
|
|
|
|
class _CuerpoInfo extends StatelessWidget {
|
|
const _CuerpoInfo();
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Consumer<EstadoRadio>(
|
|
builder:
|
|
(ctx, estado, _) => PluriGlassSurface(
|
|
child: Column(
|
|
children: [
|
|
FutureBuilder<PackageInfo>(
|
|
future: PackageInfo.fromPlatform(),
|
|
builder: (ctx, snap) {
|
|
final version =
|
|
snap.hasData
|
|
? 'v${snap.data!.version}+${snap.data!.buildNumber}'
|
|
: AppLocalizations.of(ctx).appVersionLoading;
|
|
return ListTile(
|
|
contentPadding: EdgeInsets.zero,
|
|
leading: const PluriIcon(
|
|
glyph: PluriIconGlyph.settings,
|
|
variant: PluriIconVariant.filled,
|
|
),
|
|
title: Text(AppLocalizations.of(ctx).appTitle),
|
|
subtitle: Text(
|
|
AppLocalizations.of(ctx).appVersionSubtitle(version),
|
|
),
|
|
);
|
|
},
|
|
),
|
|
FutureBuilder<int>(
|
|
future: estado.favoritos.obtenerTodos().then((l) => l.length),
|
|
builder:
|
|
(ctx, snap) => ListTile(
|
|
contentPadding: EdgeInsets.zero,
|
|
leading: const Icon(Icons.favorite_outline_rounded),
|
|
title: Text(
|
|
AppLocalizations.of(ctx).savedFavoritesTitle,
|
|
),
|
|
trailing: Text(
|
|
snap.data?.toString() ??
|
|
AppLocalizations.of(ctx).dash,
|
|
style: Theme.of(ctx).textTheme.bodyLarge,
|
|
),
|
|
),
|
|
),
|
|
ListTile(
|
|
contentPadding: EdgeInsets.zero,
|
|
leading: const Icon(Icons.help_outline_rounded),
|
|
title: Text(AppLocalizations.of(ctx).helpTitle),
|
|
subtitle: Text(AppLocalizations.of(ctx).helpSubtitle),
|
|
trailing: const Icon(Icons.chevron_right_rounded),
|
|
onTap: () => PluriOnboardingDialog.mostrar(ctx),
|
|
),
|
|
ListTile(
|
|
contentPadding: EdgeInsets.zero,
|
|
leading: const Icon(Icons.verified_outlined),
|
|
title: Text(AppLocalizations.of(ctx).stationFilterTitle),
|
|
subtitle: Text(
|
|
AppLocalizations.of(ctx).stationFilterSubtitle,
|
|
),
|
|
trailing: Icon(
|
|
Icons.check_circle_rounded,
|
|
color: Theme.of(ctx).colorScheme.secondary,
|
|
),
|
|
),
|
|
ListTile(
|
|
contentPadding: EdgeInsets.zero,
|
|
leading: const Icon(Icons.music_note_outlined),
|
|
title: Text(AppLocalizations.of(ctx).backgroundAudioTitle),
|
|
subtitle: Text(
|
|
AppLocalizations.of(ctx).backgroundAudioSubtitle,
|
|
),
|
|
trailing: Icon(
|
|
Icons.check_circle_rounded,
|
|
color: Theme.of(ctx).colorScheme.secondary,
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
);
|
|
}
|
|
}
|