整个课程和数据UI重新设计版本
This commit is contained in:
@@ -0,0 +1,112 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import '../../core/app_state.dart';
|
||||
import '../../core/app_theme.dart';
|
||||
import '../../core/sherpa_stt_service.dart';
|
||||
import '../../widgets/app_widgets.dart';
|
||||
import 'profile_widgets.dart';
|
||||
|
||||
/// 学习偏好:每日时长、中文提示与语音识别。
|
||||
class LearningPreferencesView extends StatelessWidget {
|
||||
const LearningPreferencesView({super.key, required this.state});
|
||||
final AppState state;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) => SpacedColumn(
|
||||
spacing: 16,
|
||||
children: [
|
||||
MenuGroup(
|
||||
children: [
|
||||
MenuTile(
|
||||
icon: Icons.timer_outlined,
|
||||
title: '每日学习时间',
|
||||
value: '${state.dailyMinutes} 分钟',
|
||||
onTap: () => _chooseDuration(context),
|
||||
),
|
||||
MenuSwitch(
|
||||
icon: Icons.translate,
|
||||
title: '默认显示中文提示',
|
||||
subtitle: 'A0 阶段建议开启',
|
||||
value: state.showChineseHints,
|
||||
onChanged: state.toggleChineseHints,
|
||||
),
|
||||
],
|
||||
),
|
||||
MenuGroup(
|
||||
title: '语音',
|
||||
children: [
|
||||
MenuTile(
|
||||
icon: Icons.graphic_eq,
|
||||
title: '离线语音识别',
|
||||
subtitle: SherpaSttService.instance.isReady
|
||||
? 'SenseVoice-Small · 已就绪,本地识别'
|
||||
: 'SenseVoice-Small · 已内置,无需下载',
|
||||
trailing: Icon(
|
||||
Icons.check_circle,
|
||||
color: AppColors.green,
|
||||
size: 20,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
);
|
||||
|
||||
Future<void> _chooseDuration(BuildContext context) async {
|
||||
final value = await showModalBottomSheet<int>(
|
||||
context: context,
|
||||
builder: (context) => SafeArea(
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
for (final minute in [10, 20, 30])
|
||||
ListTile(
|
||||
title: Text('$minute 分钟'),
|
||||
trailing: state.dailyMinutes == minute
|
||||
? const Icon(Icons.check)
|
||||
: null,
|
||||
onTap: () => Navigator.pop(context, minute),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
if (value != null) state.setDailyMinutes(value);
|
||||
}
|
||||
}
|
||||
|
||||
/// 外观:浅色 / 深色 / 跟随系统。
|
||||
class AppearanceView extends StatelessWidget {
|
||||
const AppearanceView({super.key, required this.state});
|
||||
final AppState state;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) => SpacedColumn(
|
||||
children: [
|
||||
SizedBox(
|
||||
width: double.infinity,
|
||||
child: SegmentedButton<AppThemeMode>(
|
||||
segments: const [
|
||||
ButtonSegment(value: AppThemeMode.system, label: Text('跟随系统')),
|
||||
ButtonSegment(value: AppThemeMode.light, label: Text('浅色')),
|
||||
ButtonSegment(value: AppThemeMode.dark, label: Text('深色')),
|
||||
],
|
||||
selected: {state.themeMode},
|
||||
showSelectedIcon: false,
|
||||
onSelectionChanged: (selection) =>
|
||||
state.setThemeMode(selection.first),
|
||||
),
|
||||
),
|
||||
Text(
|
||||
'深色模式适合夜间使用;跟随系统会随手机的深色开关自动切换。',
|
||||
style: TextStyle(fontSize: 12, color: AppColors.muted),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
String themeModeLabel(AppThemeMode mode) => switch (mode) {
|
||||
AppThemeMode.system => '跟随系统',
|
||||
AppThemeMode.light => '浅色',
|
||||
AppThemeMode.dark => '深色',
|
||||
};
|
||||
Reference in New Issue
Block a user