Files
sm-emby-share/lib/features/settings/widgets/settings_card.dart
T
2026-07-14 11:11:36 +08:00

139 lines
3.7 KiB
Dart

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<Widget> 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<Widget> 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;
}
}