import 'package:flutter/material.dart'; import '../../../shared/theme/app_theme.dart'; import '../../../shared/utils/user_error_formatter.dart'; import '../../../shared/widgets/app_inline_alert.dart'; Widget settingsLoadError(Object error) { return AppInlineAlert(message: '加载失败:${formatUserError(error)}'); } class SettingsTabScroll extends StatelessWidget { final List children; const SettingsTabScroll({super.key, required this.children}); @override Widget build(BuildContext context) { return ListView( padding: const EdgeInsets.fromLTRB(0, 12, 0, 32), children: [ Center( child: ConstrainedBox( constraints: const BoxConstraints(maxWidth: 720), child: Padding( padding: const EdgeInsets.symmetric(horizontal: 24), child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: children, ), ), ), ), ], ); } } class SettingsCard extends StatelessWidget { final List children; const SettingsCard({super.key, required this.children}); @override Widget build(BuildContext context) { final theme = Theme.of(context); final isDark = theme.brightness == Brightness.dark; final dividerColor = isDark ? Colors.white.withValues(alpha: 0.08) : Colors.black.withValues(alpha: 0.06); return Padding( padding: const EdgeInsets.only(bottom: 16), child: Container( decoration: BoxDecoration( color: isDark ? const Color(0xFF2C2C2E) : Colors.white, borderRadius: BorderRadius.circular(12), border: Border.all(color: dividerColor, width: 0.5), ), clipBehavior: Clip.antiAlias, child: Column( children: [ for (int i = 0; i < children.length; i++) ...[ children[i], if (i < children.length - 1) Divider( height: 1, thickness: 0.5, indent: 16, endIndent: 16, color: dividerColor, ), ], ], ), ), ); } } class SettingRow extends StatelessWidget { final String title; final String? subtitle; final Widget? trailing; final VoidCallback? onTap; const SettingRow({ super.key, required this.title, this.subtitle, this.trailing, this.onTap, }); @override Widget build(BuildContext context) { final theme = Theme.of(context); final tokens = context.appTokens; Widget content = Padding( padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12), child: Row( children: [ Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( title, style: theme.textTheme.bodyMedium?.copyWith( fontWeight: FontWeight.w500, ), ), if (subtitle != null) ...[ const SizedBox(height: 2), Text( subtitle!, maxLines: 1, overflow: TextOverflow.ellipsis, style: theme.textTheme.bodySmall?.copyWith( color: tokens.mutedForeground, ), ), ], ], ), ), if (trailing != null) trailing!, ], ), ); if (onTap != null) { content = InkWell(onTap: onTap, child: content); } return content; } }