Files
IKAR/lib/frontend/screens/profile/customization_section.dart

192 lines
5.5 KiB
Dart

import 'package:flutter/material.dart';
import 'package:material_symbols_icons/symbols.dart';
import '../../../core/config/ios_release.dart';
import '../../../core/utils/haptics.dart';
import '../../../l10n/app_localizations.dart';
import '../../widgets/glossy_pill.dart';
import '../../widgets/settings_card.dart';
import 'app_icon_screen.dart';
import 'appearance_screen.dart';
import 'chat_background_screen.dart';
import 'font_settings_screen.dart';
import 'message_actions_screen.dart';
import 'message_status_size_screen.dart';
import 'theme_settings_screen.dart';
class _CustomizationCategory {
final IconData icon;
final String Function(AppLocalizations l10n) title;
final WidgetBuilder builder;
final bool Function() isAvailable;
const _CustomizationCategory({
required this.icon,
required this.title,
required this.builder,
this.isAvailable = _always,
});
static bool _always() => true;
}
class CustomizationSection extends StatefulWidget {
const CustomizationSection({super.key});
@override
State<CustomizationSection> createState() => _CustomizationSectionState();
}
class _CustomizationSectionState extends State<CustomizationSection> {
bool _expanded = false;
static final List<_CustomizationCategory> _categories = [
_CustomizationCategory(
icon: Symbols.dark_mode,
title: (l10n) => l10n.themeSettingsTitle,
builder: (context) => const ThemeSettingsScreen(),
),
_CustomizationCategory(
icon: Symbols.styler,
title: (l10n) => l10n.appearanceTitle,
builder: (context) => const AppearanceScreen(),
),
_CustomizationCategory(
icon: Symbols.wallpaper,
title: (l10n) => l10n.customizationChatBackground,
builder: (context) => const ChatBackgroundScreen(),
),
_CustomizationCategory(
icon: Symbols.text_fields,
title: (l10n) => l10n.fontSettingsTitle,
builder: (context) => const FontSettingsScreen(),
),
_CustomizationCategory(
icon: Symbols.done_all,
title: (l10n) => l10n.messageStatusSizeTitle,
builder: (context) => const MessageStatusSizeScreen(),
),
_CustomizationCategory(
icon: Symbols.touch_app,
title: (l10n) => l10n.customizationMessageActions,
builder: (context) => const MessageActionsScreen(),
isAvailable: _messageActionsStyleChoice,
),
_CustomizationCategory(
icon: Symbols.apps,
title: (l10n) => l10n.customizationAppIcon,
builder: (context) => const AppIconScreen(),
),
];
static bool _messageActionsStyleChoice() =>
IosRelease.messageActionsStyleChoice;
void _toggle() {
Haptics.tap();
setState(() => _expanded = !_expanded);
}
void _open(_CustomizationCategory category) {
Haptics.tap();
Navigator.push(context, MaterialPageRoute(builder: category.builder));
}
@override
Widget build(BuildContext context) {
final cs = Theme.of(context).colorScheme;
return GlossyPill(
color: cs.surfaceContainerHigh,
borderRadius: BorderRadius.circular(20),
depth: 6,
child: Column(
children: [
_buildHeader(cs),
AnimatedSize(
duration: const Duration(milliseconds: 220),
curve: Curves.easeInOut,
alignment: Alignment.topCenter,
child: _expanded
? Column(children: _buildCategoryTiles(cs))
: const SizedBox(width: double.infinity),
),
],
),
);
}
Widget _buildHeader(ColorScheme cs) {
return Material(
color: Colors.transparent,
child: InkWell(
onTap: _toggle,
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 17),
child: Row(
children: [
Icon(
Symbols.palette,
color: cs.onSurfaceVariant,
size: 22,
weight: 400,
),
const SizedBox(width: 16),
Expanded(
child: Text(
AppLocalizations.of(context)!.customizationTitle,
style: TextStyle(
color: cs.onSurface,
fontSize: 16,
fontWeight: FontWeight.w500,
),
),
),
AnimatedRotation(
duration: const Duration(milliseconds: 200),
turns: _expanded ? 0.5 : 0,
child: Icon(
Symbols.expand_more,
color: cs.outline,
size: 22,
weight: 400,
),
),
],
),
),
),
);
}
List<Widget> _buildCategoryTiles(ColorScheme cs) {
final l10n = AppLocalizations.of(context)!;
final tiles = <Widget>[];
final categories = [
for (final category in _categories)
if (category.isAvailable()) category,
];
for (var i = 0; i < categories.length; i++) {
final category = categories[i];
tiles.add(
Padding(
padding: const EdgeInsets.only(left: 58),
child: Divider(
height: 1,
thickness: 1,
color: cs.outlineVariant.withValues(alpha: 0.35),
),
),
);
tiles.add(
SettingsNavTile(
icon: category.icon,
label: category.title(l10n),
onTap: () => _open(category),
isLast: i == categories.length - 1,
),
);
}
return tiles;
}
}