import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:go_router/go_router.dart'; import '../../providers/appearance_provider.dart'; import '../../providers/sm_account_provider.dart'; import '../../shared/app_info.dart'; import '../../shared/theme/app_theme.dart'; import '../../shared/widgets/app_card.dart'; import '../../shared/widgets/app_sliver_header.dart'; import '../../shared/widgets/page_background.dart'; import 'settings_page.dart'; import 'settings_tab_key.dart'; class SettingsFullPage extends ConsumerWidget { const SettingsFullPage({super.key}); @override Widget build(BuildContext context, WidgetRef ref) { final account = ref.watch(smAccountProvider).value; final appVersion = ref.watch(appVersionProvider).value ?? kSmPlayerVersionFallback; final appearance = ref.watch(appearanceProvider).value; return Scaffold( backgroundColor: Colors.transparent, extendBodyBehindAppBar: true, body: Stack( children: [ const Positioned.fill(child: PageBackground()), CustomScrollView( physics: const AlwaysScrollableScrollPhysics( parent: BouncingScrollPhysics(), ), slivers: [ AppSliverHeader( title: '设置', actions: [ Padding( padding: const EdgeInsets.only(right: 16), child: Container( padding: const EdgeInsets.symmetric( horizontal: 10, vertical: 4, ), decoration: BoxDecoration( border: Border.all( color: Theme.of( context, ).colorScheme.onSurface.withValues(alpha: 0.15), ), borderRadius: BorderRadius.circular(14), ), child: Text( appVersion, style: Theme.of(context).textTheme.bodySmall, ), ), ), ], ), SliverPadding( padding: const EdgeInsets.fromLTRB(16, 12, 16, 100), sliver: SliverList( delegate: SliverChildListDelegate.fixed([ _SmAccountBanner( account: account, onTap: () => context.push('/account-center'), ), const SizedBox(height: 24), const _SectionTitle('常规设置'), _SettingsGroupCard( children: [ _SettingsItem( icon: Icons.palette_outlined, color: const Color(0xFF8B5CF6), title: '主题', trailing: _ThemeModeSelector( currentMode: appearance?.themeMode, onChanged: (mode) => ref .read(appearanceProvider.notifier) .setThemeMode(mode), ), ), _SettingsItem( icon: Icons.settings_outlined, color: const Color(0xFF6B7280), title: '通用', onTap: () => showSettingsSectionSheet( context, initialTab: kSettingsTabGeneral, ), ), ], ), const SizedBox(height: 24), const _SectionTitle('播放设置'), _SettingsGroupCard( children: [ _SettingsItem( icon: Icons.play_circle_outline_rounded, color: const Color(0xFF22C55E), title: '播放', onTap: () => showSettingsSectionSheet( context, initialTab: kSettingsTabPlayback, ), ), _SettingsItem( icon: Icons.headphones_outlined, color: const Color(0xFFA855F7), title: '音频', onTap: () => showSettingsSectionSheet( context, initialTab: kSettingsTabAudio, ), ), _SettingsItem( icon: Icons.chat_bubble_outline_rounded, color: const Color(0xFFEF4444), title: '弹幕', onTap: () => showSettingsSectionSheet( context, initialTab: kSettingsTabDanmaku, ), ), ], ), const SizedBox(height: 24), const _SectionTitle('扩展服务'), _SettingsGroupCard( children: [ _SettingsItem( icon: Icons.extension_rounded, color: const Color(0xFF6366F1), title: '模块中心', onTap: () => showSettingsSectionSheet( context, initialTab: kSettingsTabModules, ), ), _SettingsItem( icon: Icons.movie_filter_outlined, color: const Color(0xFF0EA5E9), title: 'TMDB', onTap: () => showSettingsSectionSheet( context, initialTab: kSettingsTabTmdb, ), ), _SettingsItem( icon: Icons.link_outlined, color: const Color(0xFFEF4444), title: 'Trakt', onTap: () => showSettingsSectionSheet( context, initialTab: kSettingsTabTrakt, ), ), _SettingsItem( icon: Icons.palette_outlined, color: const Color(0xFFF59E0B), title: '图标库', onTap: () => showSettingsSectionSheet( context, initialTab: kSettingsTabIconLibrary, ), ), ], ), ]), ), ), ], ), ], ), ); } } class _SmAccountBanner extends StatelessWidget { final SmAccountState? account; final VoidCallback onTap; const _SmAccountBanner({required this.account, required this.onTap}); @override Widget build(BuildContext context) { final theme = Theme.of(context); final loggedIn = account?.status == SmAuthStatus.authenticated; final email = account?.email ?? ''; final isVip = account?.isVip ?? false; final title = loggedIn ? (email.isNotEmpty ? email : 'Player 账号') : '登录 Player 账号'; final subtitle = loggedIn ? (isVip ? 'VIP 会员' : '已登录') : '登录以使用云同步等扩展服务'; return AppCard( onTap: onTap, padding: const EdgeInsets.all(16), child: Row( children: [ Container( width: 48, height: 48, decoration: BoxDecoration( color: loggedIn ? (isVip ? const Color(0xFFFAAD14).withValues(alpha: 0.15) : theme.colorScheme.primary.withValues(alpha: 0.12)) : theme.colorScheme.onSurface.withValues(alpha: 0.08), shape: BoxShape.circle, ), child: Icon( loggedIn ? (isVip ? Icons.workspace_premium_rounded : Icons.person_rounded) : Icons.person_outline_rounded, size: 24, color: loggedIn ? (isVip ? const Color(0xFFFAAD14) : theme.colorScheme.primary) : theme.colorScheme.onSurface.withValues(alpha: 0.4), ), ), const SizedBox(width: 14), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( title, maxLines: 1, overflow: TextOverflow.ellipsis, style: theme.textTheme.titleSmall?.copyWith( fontWeight: FontWeight.w700, fontSize: 16, ), ), const SizedBox(height: 3), Text( subtitle, maxLines: 1, overflow: TextOverflow.ellipsis, style: theme.textTheme.bodySmall?.copyWith( color: theme.colorScheme.onSurface.withValues(alpha: 0.58), ), ), ], ), ), if (isVip) Container( margin: const EdgeInsets.only(right: 8), padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 2), decoration: BoxDecoration( color: const Color(0xFFFAAD14), borderRadius: BorderRadius.circular(4), ), child: const Text( 'VIP', style: TextStyle( color: Colors.white, fontSize: 11, fontWeight: FontWeight.w700, ), ), ), const Icon(Icons.chevron_right_rounded), ], ), ); } } class _SectionTitle extends StatelessWidget { final String text; const _SectionTitle(this.text); @override Widget build(BuildContext context) { return Padding( padding: const EdgeInsets.fromLTRB(4, 0, 4, 8), child: Text( text, style: Theme.of(context).textTheme.labelLarge?.copyWith( color: context.appTokens.mutedForeground, fontWeight: FontWeight.w600, ), ), ); } } class _SettingsGroupCard extends StatelessWidget { final List children; const _SettingsGroupCard({required this.children}); @override Widget build(BuildContext context) { return AppCard( padding: EdgeInsets.zero, child: Column( children: [ for (var i = 0; i < children.length; i++) ...[ if (i > 0) Divider( height: 1, indent: 56, color: Theme.of( context, ).colorScheme.onSurface.withValues(alpha: 0.08), ), children[i], ], ], ), ); } } class _SettingsItem extends StatelessWidget { final IconData icon; final Color color; final String title; final Widget? trailing; final VoidCallback? onTap; const _SettingsItem({ required this.icon, required this.color, required this.title, this.trailing, this.onTap, }); @override Widget build(BuildContext context) { final theme = Theme.of(context); return InkWell( onTap: onTap, child: Padding( padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 13), child: Row( children: [ Container( width: 32, height: 32, decoration: BoxDecoration(color: color, shape: BoxShape.circle), child: Icon(icon, size: 18, color: Colors.white), ), const SizedBox(width: 14), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [Text(title, style: theme.textTheme.bodyMedium)], ), ), if (trailing != null) trailing! else if (onTap != null) const Icon(Icons.chevron_right_rounded, size: 20), ], ), ), ); } } class _ThemeModeSelector extends StatelessWidget { final ThemeMode? currentMode; final ValueChanged onChanged; const _ThemeModeSelector({ required this.currentMode, required this.onChanged, }); @override Widget build(BuildContext context) { final theme = Theme.of(context); final mode = currentMode ?? ThemeMode.system; Widget chip(ThemeMode m, IconData icon) { final selected = mode == m; return GestureDetector( onTap: () => onChanged(m), child: AnimatedContainer( duration: const Duration(milliseconds: 200), padding: const EdgeInsets.all(6), decoration: BoxDecoration( color: selected ? theme.colorScheme.primary.withValues(alpha: 0.15) : Colors.transparent, borderRadius: BorderRadius.circular(8), ), child: Icon( icon, size: 18, color: selected ? theme.colorScheme.primary : theme.colorScheme.onSurface.withValues(alpha: 0.4), ), ), ); } return Container( decoration: BoxDecoration( color: theme.colorScheme.onSurface.withValues(alpha: 0.06), borderRadius: BorderRadius.circular(10), ), padding: const EdgeInsets.all(2), child: Row( mainAxisSize: MainAxisSize.min, children: [ chip(ThemeMode.light, Icons.light_mode_outlined), chip(ThemeMode.system, Icons.settings_outlined), chip(ThemeMode.dark, Icons.dark_mode_outlined), ], ), ); } }