feat(ui): add Beta badge to Backup & Restore settings entry

Extract the BETA pill into a reusable BetaBadge widget in settings_group.dart and add titleTrailing support to SettingsItem. Show the badge on the Backup & Restore entry in the settings list, and reuse the shared widget in the download settings page (removing the duplicated private badge).
This commit is contained in:
zarzet
2026-06-26 22:16:21 +07:00
parent f0bf769f0d
commit 58e615462c
3 changed files with 46 additions and 25 deletions
@@ -199,7 +199,7 @@ class _DownloadSettingsPageState extends ConsumerState<DownloadSettingsPage> {
SettingsSwitchItem(
icon: Icons.downloading_outlined,
title: context.l10n.downloadNativeWorker,
titleTrailing: const _BetaBadge(),
titleTrailing: BetaBadge(label: context.l10n.badgeBeta),
subtitle: hasDownloadExtensions
? context.l10n.downloadNativeWorkerSubtitle
: context.l10n.extensionsNoDownloadProvider,
@@ -845,29 +845,6 @@ class _DownloadSettingsPageState extends ConsumerState<DownloadSettingsPage> {
}
}
class _BetaBadge extends StatelessWidget {
const _BetaBadge();
@override
Widget build(BuildContext context) {
final colorScheme = Theme.of(context).colorScheme;
return Container(
padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 2),
decoration: BoxDecoration(
color: colorScheme.tertiaryContainer,
borderRadius: BorderRadius.circular(6),
),
child: Text(
context.l10n.badgeBeta,
style: Theme.of(context).textTheme.labelSmall?.copyWith(
color: colorScheme.onTertiaryContainer,
fontWeight: FontWeight.w700,
),
),
);
}
}
class _QualityOption extends StatelessWidget {
final String title;
final String subtitle;
+1
View File
@@ -164,6 +164,7 @@ class SettingsTab extends ConsumerWidget {
SettingsItem(
icon: Icons.settings_backup_restore,
title: l10n.settingsBackup,
titleTrailing: BetaBadge(label: l10n.badgeBeta),
subtitle: l10n.settingsBackupSubtitle,
onTap: () =>
_navigateTo(context, const BackupRestorePage()),
+44 -1
View File
@@ -49,6 +49,7 @@ class SettingsGroup extends StatelessWidget {
class SettingsItem extends StatelessWidget {
final IconData? icon;
final String title;
final Widget? titleTrailing;
final String? subtitle;
final Widget? trailing;
final VoidCallback? onTap;
@@ -58,6 +59,7 @@ class SettingsItem extends StatelessWidget {
super.key,
this.icon,
required this.title,
this.titleTrailing,
this.subtitle,
this.trailing,
this.onTap,
@@ -87,7 +89,21 @@ class SettingsItem extends StatelessWidget {
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(title, style: Theme.of(context).textTheme.bodyLarge),
Row(
mainAxisSize: MainAxisSize.min,
children: [
Flexible(
child: Text(
title,
style: Theme.of(context).textTheme.bodyLarge,
),
),
if (titleTrailing != null) ...[
const SizedBox(width: 8),
titleTrailing!,
],
],
),
if (subtitle != null) ...[
const SizedBox(height: 2),
Text(
@@ -257,3 +273,30 @@ class SettingsSectionHeader extends StatelessWidget {
);
}
}
/// Small "BETA" pill, used as a [SettingsItem.titleTrailing] /
/// [SettingsSwitchItem.titleTrailing] marker for experimental features.
class BetaBadge extends StatelessWidget {
final String label;
const BetaBadge({super.key, required this.label});
@override
Widget build(BuildContext context) {
final colorScheme = Theme.of(context).colorScheme;
return Container(
padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 2),
decoration: BoxDecoration(
color: colorScheme.tertiaryContainer,
borderRadius: BorderRadius.circular(6),
),
child: Text(
label,
style: Theme.of(context).textTheme.labelSmall?.copyWith(
color: colorScheme.onTertiaryContainer,
fontWeight: FontWeight.w700,
),
),
);
}
}