From f133e5ce134b9d63c512cddc7e6a0bd25bb1dcbb Mon Sep 17 00:00:00 2001 From: Cxx0822 <1556464090@qq.com> Date: Fri, 21 Nov 2025 14:58:11 +0800 Subject: [PATCH] =?UTF-8?q?feat:=E6=9B=B4=E6=96=B0=E4=B8=BB=E9=A2=98?= =?UTF-8?q?=E8=89=B2=E5=85=BC=E5=AE=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/layout/app_drawer.dart | 23 +++++++++-------- lib/layout/main_screen.dart | 8 ++++-- lib/pages/todo_page.dart | 17 +++++++------ lib/utils/date_utils.dart | 6 +++++ lib/utils/todo_utils.dart | 19 +++++++++----- lib/widgets/calendar_form.dart | 22 ++++++++-------- lib/widgets/calendar_widget.dart | 2 +- lib/widgets/common.dart | 43 ++++++++++++++++++-------------- lib/widgets/flisp_form.dart | 20 ++++++++++++--- lib/widgets/todo_form.dart | 25 ++++++++----------- pubspec.yaml | 2 +- 11 files changed, 112 insertions(+), 75 deletions(-) diff --git a/lib/layout/app_drawer.dart b/lib/layout/app_drawer.dart index 1bfba64..4672de1 100644 --- a/lib/layout/app_drawer.dart +++ b/lib/layout/app_drawer.dart @@ -3,10 +3,15 @@ import 'package:flisp_app/utils/theme_utils.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; -class AppDrawer extends StatelessWidget { +class AppDrawer extends StatefulWidget { const AppDrawer({super.key}); - DrawerHeader _buildDrawerHeader(BuildContext context) { + @override + State createState() => AppDrawerState(); +} + +class AppDrawerState extends State { + DrawerHeader _buildDrawerHeader() { return DrawerHeader( decoration: BoxDecoration(color: Theme.of(context).colorScheme.primary), child: Column( @@ -39,7 +44,7 @@ class AppDrawer extends StatelessWidget { ); } - Widget _buildDarkModeSection(BuildContext context, AppProvider appProvider) { + Widget _buildDarkModeSection(AppProvider appProvider) { return ListTile( leading: Icon( appProvider.isDarkMode ? Icons.dark_mode : Icons.light_mode, @@ -58,7 +63,7 @@ class AppDrawer extends StatelessWidget { ); } - Widget _buildThemeSection(BuildContext context, AppProvider appProvider) { + Widget _buildThemeSection(AppProvider appProvider) { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ @@ -66,7 +71,7 @@ class AppDrawer extends StatelessWidget { padding: const EdgeInsets.fromLTRB(16, 16, 16, 8), child: Text('主题颜色', style: Theme.of(context).textTheme.titleMedium), ), - _buildDarkModeSection(context, appProvider), + _buildDarkModeSection(appProvider), buildThemeColorList(context, appProvider), ], ); @@ -74,7 +79,6 @@ class AppDrawer extends StatelessWidget { // 构建抽屉菜单项 Widget _buildDrawerItem({ - required BuildContext context, required IconData icon, required String title, required VoidCallback onTap, @@ -118,11 +122,10 @@ class AppDrawer extends StatelessWidget { child: ListView( padding: EdgeInsets.zero, children: [ - _buildDrawerHeader(context), - _buildThemeSection(context, appProvider), + _buildDrawerHeader(), + _buildThemeSection(appProvider), const Divider(), _buildDrawerItem( - context: context, icon: Icons.help, title: '帮助与反馈', onTap: () { @@ -136,7 +139,7 @@ class AppDrawer extends StatelessWidget { _buildVersionInfo( context: context, fullVersion: appProvider.fullVersion, - ) + ), ], ), ); diff --git a/lib/layout/main_screen.dart b/lib/layout/main_screen.dart index 9ff0ff4..1f82b78 100644 --- a/lib/layout/main_screen.dart +++ b/lib/layout/main_screen.dart @@ -42,7 +42,11 @@ class _MainScreenState extends State { TodoSortMode.priority, ); final List todayTodos = - todoResult.where((todo) => isToday(todo.scheduledTime)).toList(); + todoResult + .where( + (todo) => !todo.isCompleted && isAfterToday(todo.scheduledTime), + ) + .toList(); for (Todo todo in todayTodos) { await notifyService.scheduleNotification( @@ -57,7 +61,7 @@ class _MainScreenState extends State { final List calendarResult = calendarService.getAllCalendars(); final List todayCalendars = calendarResult - .where((calendar) => isToday(calendar.scheduledTime)) + .where((item) => isAfterToday(item.scheduledTime)) .toList(); for (Calendar calendar in todayCalendars) { diff --git a/lib/pages/todo_page.dart b/lib/pages/todo_page.dart index 60079ae..3168d87 100644 --- a/lib/pages/todo_page.dart +++ b/lib/pages/todo_page.dart @@ -86,7 +86,7 @@ class TodoPageState extends State { ), ButtonSegment( value: TodoSortMode.priority, - icon: Icon(Icons.flag_outlined, size: 16,), + icon: Icon(Icons.flag_outlined, size: 16), label: const Text('优先级', style: TextStyle(fontSize: 12)), ), ], @@ -123,13 +123,16 @@ class TodoPageState extends State { // 切换待办事项完成状态 void _toggleTodo(Todo todo) async { - await notifyService.cancelNotification(todo.id); + final bool? result = await showConfirmDialog(context, '确定已完成该待办吗?'); + if (result == true) { + await notifyService.cancelNotification(todo.id); - setState(() { - todo.isCompleted = !todo.isCompleted; - todo.scheduledTime = null; - todoService.updateTodo(todo); - }); + setState(() { + todo.isCompleted = !todo.isCompleted; + todo.scheduledTime = null; + todoService.updateTodo(todo); + }); + } } // 显示对话框 diff --git a/lib/utils/date_utils.dart b/lib/utils/date_utils.dart index 2f78d76..35f1317 100644 --- a/lib/utils/date_utils.dart +++ b/lib/utils/date_utils.dart @@ -16,3 +16,9 @@ bool isToday(DateTime? date) { date.month == now.month && date.day == now.day; } + +bool isAfterToday(DateTime? date) { + if (date == null) return false; + + return date.isAfter(DateTime.now()); +} diff --git a/lib/utils/todo_utils.dart b/lib/utils/todo_utils.dart index 934ba2d..bd5933d 100644 --- a/lib/utils/todo_utils.dart +++ b/lib/utils/todo_utils.dart @@ -25,16 +25,23 @@ List getActiveTodos(TodoTab currentTab, List todos) { // 格式化截止日期 String formatDueDate(DateTime dueDate, bool isToday, bool isTomorrow) { - if (isToday) return '今天截止'; - if (isTomorrow) return '明天截止'; - final now = DateTime.now(); - final difference = dueDate.difference(DateTime(now.year, now.month, now.day)); + final today = DateTime(now.year, now.month, now.day); + final dueDateStart = DateTime(dueDate.year, dueDate.month, dueDate.day); + final difference = dueDateStart.difference(today); - if (difference.inDays < 7) { - return '${difference.inDays}天后截止'; + // 处理过期情况 + if (difference.inDays < 0) { + final daysPast = -difference.inDays; + return '已过期$daysPast天'; } + // 处理未来日期 + if (difference.inDays == 0) return '今天截止'; + if (difference.inDays == 1) return '明天截止'; + if (difference.inDays == 2) return '后天截止'; + if (difference.inDays < 7) return '${difference.inDays}天后截止'; + return DateFormat("MM-dd").format(dueDate); } diff --git a/lib/widgets/calendar_form.dart b/lib/widgets/calendar_form.dart index 7d09939..113ba3e 100644 --- a/lib/widgets/calendar_form.dart +++ b/lib/widgets/calendar_form.dart @@ -80,7 +80,11 @@ class _CalendarFormState extends State { label: RichText( text: TextSpan( text: '内容', - style: TextStyle(color: Colors.grey.shade700, fontSize: 16), + style: TextStyle( + color: Colors.grey, + fontSize: 16, + fontFamily: 'CustomFont', + ), children: const [ TextSpan( text: '*', @@ -146,9 +150,7 @@ class _CalendarFormState extends State { decoration: InputDecoration( labelText: startTime == null ? '选择开始时间' : '开始时间: ${formatTime(startTime)}', - labelStyle: TextStyle( - color: startTime == null ? Colors.grey : Colors.black87, - ), + labelStyle: TextStyle(color: Colors.grey), prefixIcon: Icon(Icons.calendar_month, color: Colors.purple), border: buildFormBoard(), enabledBorder: buildFormEnabledBoard(), @@ -196,9 +198,7 @@ class _CalendarFormState extends State { }, decoration: InputDecoration( labelText: endTime == null ? '选择结束时间' : '结束时间: ${formatTime(endTime)}', - labelStyle: TextStyle( - color: endTime == null ? Colors.grey : Colors.black87, - ), + labelStyle: TextStyle(color: Colors.grey), prefixIcon: Icon(Icons.calendar_month, color: Colors.purple), border: buildFormBoard(), enabledBorder: buildFormEnabledBoard(), @@ -247,11 +247,9 @@ class _CalendarFormState extends State { decoration: InputDecoration( labelText: scheduledTime == null - ? '选择提醒日期' - : '提醒: ${formatTime(scheduledTime)}', - labelStyle: TextStyle( - color: scheduledTime == null ? Colors.grey : Colors.black87, - ), + ? '选择提醒时间' + : '提醒时间: ${formatTime(scheduledTime)}', + labelStyle: TextStyle(color: Colors.grey), prefixIcon: Icon(Icons.calendar_month, color: Colors.purple), border: buildFormBoard(), enabledBorder: buildFormEnabledBoard(), diff --git a/lib/widgets/calendar_widget.dart b/lib/widgets/calendar_widget.dart index ecd2d2b..898a407 100644 --- a/lib/widgets/calendar_widget.dart +++ b/lib/widgets/calendar_widget.dart @@ -107,7 +107,7 @@ Widget buildCalendar({ onLongPress: (CalendarLongPressDetails details) async { if (details.targetElement == CalendarElement.appointment) { if (details.appointments?.length == 1) { - final bool? result = await showDeleteConfirmationDialog(context); + final bool? result = await showConfirmDialog(context, '确定要删除这个项目吗?'); if (result == true) { onDelete(details.appointments!.first); } diff --git a/lib/widgets/common.dart b/lib/widgets/common.dart index 03fbc51..37e6a0c 100644 --- a/lib/widgets/common.dart +++ b/lib/widgets/common.dart @@ -143,7 +143,7 @@ Widget buildDismissible({ background: _buildDismissBackground(), confirmDismiss: (direction) async { // 这里实现二次确认 - return await showDeleteConfirmationDialog(context); + return await showConfirmDialog(context, '确定要删除这个项目吗?'); }, onDismissed: (direction) { onDelete(); @@ -153,22 +153,27 @@ Widget buildDismissible({ } // 确认对话框 -Future showDeleteConfirmationDialog(BuildContext context) async { +Future showConfirmDialog(BuildContext context, String text) async { + final colors = Theme.of(context).colorScheme; + return showDialog( context: context, builder: (BuildContext context) { return AlertDialog( - title: const Text('确认删除'), - backgroundColor: Theme.of(context).colorScheme.surfaceContainer, - content: const Text('确定要删除这个项目吗?'), + title: const Text('确认'), + backgroundColor: colors.surfaceContainer, + content: Text(text), actions: [ TextButton( onPressed: () => Navigator.of(context).pop(false), - child: const Text('取消'), + child: Text( + '取消', + style: TextStyle(color: colors.secondary.withAlpha(150)), + ), ), TextButton( onPressed: () => Navigator.of(context).pop(true), - child: const Text('删除', style: TextStyle(color: Colors.red)), + child: Text('确认', style: TextStyle(color: colors.primary)), ), ], ); @@ -220,25 +225,25 @@ ButtonStyle buildSegmentStyle(ColorScheme colors) { side: WidgetStateProperty.all( BorderSide(color: colors.surface, width: 0), ), - iconColor: WidgetStateProperty.resolveWith( - (Set states) { - if (states.contains(WidgetState.selected)) { - return colors.onPrimary; - } - return Colors.grey; - }, - ), + iconColor: WidgetStateProperty.resolveWith(( + Set states, + ) { + if (states.contains(WidgetState.selected)) { + return colors.onPrimary; + } + return Colors.grey; + }), backgroundColor: WidgetStateProperty.resolveWith(( - Set states, - ) { + Set states, + ) { if (states.contains(WidgetState.selected)) { return colors.primary; } return colors.surfaceContainer; }), foregroundColor: WidgetStateProperty.resolveWith(( - Set states, - ) { + Set states, + ) { if (states.contains(WidgetState.selected)) { return colors.onPrimary; } diff --git a/lib/widgets/flisp_form.dart b/lib/widgets/flisp_form.dart index 37625f5..1d6e885 100644 --- a/lib/widgets/flisp_form.dart +++ b/lib/widgets/flisp_form.dart @@ -77,8 +77,6 @@ class _FlispFormState extends State { decoration: InputDecoration( hintText: '记录你的灵感瞬间...', hintStyle: TextStyle(color: Colors.grey), - counterText: '', - suffixText: '${provider.formItem.content.length}/$maxContentCount', border: OutlineInputBorder( borderRadius: BorderRadius.circular(12), borderSide: BorderSide(color: Colors.grey.shade200), @@ -98,6 +96,22 @@ class _FlispFormState extends State { minLines: 4, maxLines: 8, maxLength: maxContentCount, + buildCounter: ( + context, { + required currentLength, + required isFocused, + maxLength, + }) { + return Text( + '$currentLength/$maxContentCount', + style: TextStyle( + color: + currentLength > maxLength! + ? Colors.red + : Theme.of(context).colorScheme.primary, + ), + ); + }, validator: (value) { if (value != null && value.isEmpty) { return '请输入内容'; @@ -204,7 +218,7 @@ class _FlispFormState extends State { width: 90, padding: EdgeInsets.all(8), decoration: BoxDecoration( - color: Colors.white, + color: Theme.of(context).colorScheme.surface, borderRadius: BorderRadius.circular(8), boxShadow: [ BoxShadow( diff --git a/lib/widgets/todo_form.dart b/lib/widgets/todo_form.dart index 6f319ed..69b2bd9 100644 --- a/lib/widgets/todo_form.dart +++ b/lib/widgets/todo_form.dart @@ -67,7 +67,11 @@ class _TodoFormState extends State { label: RichText( text: TextSpan( text: '标题', - style: TextStyle(color: Colors.grey.shade700, fontSize: 16), + style: TextStyle( + color: Colors.grey, + fontSize: 16, + fontFamily: 'CustomFont', + ), children: const [ TextSpan( text: '*', @@ -127,6 +131,7 @@ class _TodoFormState extends State { }, decoration: InputDecoration( labelText: '内容', + labelStyle: TextStyle(color: Colors.grey), hintText: '请输入待办事项内容...', hintStyle: TextStyle(color: Colors.grey), counterText: '', @@ -188,11 +193,8 @@ class _TodoFormState extends State { labelText: provider.formItem.dueDate == null ? '选择截止日期' - : '截止: ${DateFormat('yyyy-MM-dd').format(provider.formItem.dueDate!)}', - labelStyle: TextStyle( - color: - provider.formItem.dueDate == null ? Colors.grey : Colors.black87, - ), + : '截止日期: ${DateFormat('yyyy-MM-dd').format(provider.formItem.dueDate!)}', + labelStyle: TextStyle(color: Colors.grey), prefixIcon: Icon(Icons.calendar_month, color: Colors.purple), border: OutlineInputBorder( borderRadius: BorderRadius.circular(12), @@ -252,14 +254,9 @@ class _TodoFormState extends State { decoration: InputDecoration( labelText: provider.formItem.scheduledTime == null - ? '选择提醒日期' - : '提醒: ${DateFormat('yyyy-MM-dd HH:mm:ss').format(provider.formItem.scheduledTime!)}', - labelStyle: TextStyle( - color: - provider.formItem.scheduledTime == null - ? Colors.grey - : Colors.black87, - ), + ? '选择提醒时间' + : '提醒时间: ${DateFormat('yyyy-MM-dd HH:mm:ss').format(provider.formItem.scheduledTime!)}', + labelStyle: TextStyle(color: Colors.grey), prefixIcon: Icon(Icons.calendar_month, color: Colors.purple), border: OutlineInputBorder( borderRadius: BorderRadius.circular(12), diff --git a/pubspec.yaml b/pubspec.yaml index e881b68..ce3544d 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -2,7 +2,7 @@ name: flisp_app description: "闪灵" publish_to: 'none' # Remove this line if you wish to publish to pub.dev -version: 1.0.0+1 +version: 1.0.0+2 environment: sdk: ^3.7.0