first commit

This commit is contained in:
ytc1012
2025-11-13 15:45:28 +08:00
commit 6b321890c0
54 changed files with 8412 additions and 0 deletions

View File

@@ -0,0 +1,252 @@
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
import '../theme/app_theme.dart';
import '../widgets/custom_time_picker_dialog.dart';
class NotificationSettingsScreen extends StatefulWidget {
const NotificationSettingsScreen({super.key});
@override
State<NotificationSettingsScreen> createState() => _NotificationSettingsScreenState();
}
class _NotificationSettingsScreenState extends State<NotificationSettingsScreen> {
bool _goalReminderEnabled = true;
bool _dailyReportEnabled = true;
bool _weeklyReportEnabled = false;
TimeOfDay _goalReminderTime = const TimeOfDay(hour: 20, minute: 0);
TimeOfDay _dailyReportTime = const TimeOfDay(hour: 22, minute: 0);
@override
void initState() {
super.initState();
_loadSettings();
}
Future<void> _loadSettings() async {
final prefs = await SharedPreferences.getInstance();
setState(() {
_goalReminderEnabled = prefs.getBool('goal_reminder_enabled') ?? true;
_dailyReportEnabled = prefs.getBool('daily_report_enabled') ?? true;
_weeklyReportEnabled = prefs.getBool('weekly_report_enabled') ?? false;
final goalReminderHour = prefs.getInt('goal_reminder_hour') ?? 20;
final goalReminderMinute = prefs.getInt('goal_reminder_minute') ?? 0;
_goalReminderTime = TimeOfDay(hour: goalReminderHour, minute: goalReminderMinute);
final dailyReportHour = prefs.getInt('daily_report_hour') ?? 22;
final dailyReportMinute = prefs.getInt('daily_report_minute') ?? 0;
_dailyReportTime = TimeOfDay(hour: dailyReportHour, minute: dailyReportMinute);
});
}
Future<void> _saveSettings() async {
final prefs = await SharedPreferences.getInstance();
await prefs.setBool('goal_reminder_enabled', _goalReminderEnabled);
await prefs.setBool('daily_report_enabled', _dailyReportEnabled);
await prefs.setBool('weekly_report_enabled', _weeklyReportEnabled);
await prefs.setInt('goal_reminder_hour', _goalReminderTime.hour);
await prefs.setInt('goal_reminder_minute', _goalReminderTime.minute);
await prefs.setInt('daily_report_hour', _dailyReportTime.hour);
await prefs.setInt('daily_report_minute', _dailyReportTime.minute);
}
@override
Widget build(BuildContext context) {
final theme = Theme.of(context);
return Scaffold(
appBar: AppBar(
title: const Text('通知设置'),
),
body: SingleChildScrollView(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// 目标提醒
Card(
child: Padding(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Icon(Icons.flag, color: AppTheme.primaryColor),
const SizedBox(width: 8),
Text(
'目标提醒',
style: theme.textTheme.titleMedium?.copyWith(
fontWeight: FontWeight.w600,
),
),
],
),
const SizedBox(height: 16),
SwitchListTile(
title: const Text('启用目标提醒'),
subtitle: const Text('当接近或超过时间目标时提醒'),
value: _goalReminderEnabled,
onChanged: (value) {
setState(() {
_goalReminderEnabled = value;
});
_saveSettings();
},
),
if (_goalReminderEnabled) ...[
const SizedBox(height: 8),
ListTile(
title: const Text('提醒时间'),
subtitle: Text(
'${_goalReminderTime.hour.toString().padLeft(2, '0')}:${_goalReminderTime.minute.toString().padLeft(2, '0')}',
),
trailing: const Icon(Icons.chevron_right),
onTap: () async {
final TimeOfDay? picked = await CustomTimePickerDialog.show(
context: context,
title: '选择提醒时间',
initialTime: _goalReminderTime,
);
if (picked != null) {
setState(() {
_goalReminderTime = picked;
});
await _saveSettings();
}
},
),
],
],
),
),
),
const SizedBox(height: 16),
// 每日报告
Card(
child: Padding(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Icon(Icons.today, color: AppTheme.primaryColor),
const SizedBox(width: 8),
Text(
'每日报告',
style: theme.textTheme.titleMedium?.copyWith(
fontWeight: FontWeight.w600,
),
),
],
),
const SizedBox(height: 16),
SwitchListTile(
title: const Text('启用每日报告'),
subtitle: const Text('每天发送使用时间摘要'),
value: _dailyReportEnabled,
onChanged: (value) {
setState(() {
_dailyReportEnabled = value;
});
_saveSettings();
},
),
if (_dailyReportEnabled) ...[
const SizedBox(height: 8),
ListTile(
title: const Text('报告时间'),
subtitle: Text(
'${_dailyReportTime.hour.toString().padLeft(2, '0')}:${_dailyReportTime.minute.toString().padLeft(2, '0')}',
),
trailing: const Icon(Icons.chevron_right),
onTap: () async {
final TimeOfDay? picked = await CustomTimePickerDialog.show(
context: context,
title: '选择报告时间',
initialTime: _dailyReportTime,
);
if (picked != null) {
setState(() {
_dailyReportTime = picked;
});
await _saveSettings();
}
},
),
],
],
),
),
),
const SizedBox(height: 16),
// 每周报告
Card(
child: Padding(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Icon(Icons.calendar_view_week, color: AppTheme.primaryColor),
const SizedBox(width: 8),
Text(
'每周报告',
style: theme.textTheme.titleMedium?.copyWith(
fontWeight: FontWeight.w600,
),
),
],
),
const SizedBox(height: 16),
SwitchListTile(
title: const Text('启用每周报告'),
subtitle: const Text('每周一发送周报摘要'),
value: _weeklyReportEnabled,
onChanged: (value) {
setState(() {
_weeklyReportEnabled = value;
});
_saveSettings();
},
),
],
),
),
),
const SizedBox(height: 24),
// 说明
Card(
color: AppTheme.infoColor.withOpacity(0.1),
child: Padding(
padding: const EdgeInsets.all(16),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Icon(Icons.info_outline, color: AppTheme.infoColor),
const SizedBox(width: 12),
Expanded(
child: Text(
'通知功能需要系统通知权限。请在系统设置中授予通知权限。',
style: theme.textTheme.bodySmall?.copyWith(
color: theme.colorScheme.onSurface.withOpacity(0.7),
),
),
),
],
),
),
),
],
),
),
);
}
}