feat: 实现 Auth 全局状态机与 401 统一处理机制
- 新增 AuthSessionInvalidated 事件处理 token 失效场景 - ApiInterceptor 新增 authFailureCallback 单飞机制 - AuthBloc 区分 manual logout 与 auto expiry 语义 - 新增 startup recovery fallback 防止启动卡死 feat: 重构 Calendar DayWeek 视图事件布局引擎 - 新增 DayEventLayoutEngine 解耦事件计算与渲染 - 新增 DayTimelineMetrics 统一时间轴常量 - 新增 DayViewScale 支持捏合缩放 feat: 新增 Settings 页面共享 UI 组件 - 新增 BackTitlePageHeader 统一页面 header - 新增 DetailHeaderActionMenu 统一操作菜单 - 新增 DestructiveActionSheet 统一删除确认 - 新增 AppToggleSwitch 统一开关组件 feat: Chat UI Schema 支持导航操作 - 支持 navigation 类型 action 触发内部路由跳转 - 新增路径验证与参数处理 chore: 更新相关测试覆盖 auth 失效路径
This commit is contained in:
@@ -57,6 +57,17 @@ class CreateEventSheet extends StatefulWidget {
|
||||
|
||||
class _CreateEventSheetState extends State<CreateEventSheet>
|
||||
with SingleTickerProviderStateMixin {
|
||||
static const List<int?> _defaultReminderOptions = [
|
||||
null,
|
||||
0,
|
||||
5,
|
||||
10,
|
||||
15,
|
||||
30,
|
||||
60,
|
||||
120,
|
||||
];
|
||||
|
||||
late TabController _tabController;
|
||||
final _titleController = TextEditingController();
|
||||
final _descriptionController = TextEditingController();
|
||||
@@ -89,7 +100,9 @@ class _CreateEventSheetState extends State<CreateEventSheet>
|
||||
_endDate = event.endAt;
|
||||
_endTime = event.endAt;
|
||||
_selectedColor = event.metadata?.color ?? '#3B82F6';
|
||||
_reminderMinutes = event.metadata?.reminderMinutes ?? 15;
|
||||
_reminderMinutes = _sanitizeReminderMinutes(
|
||||
event.metadata?.reminderMinutes,
|
||||
);
|
||||
} else {
|
||||
final now =
|
||||
widget.initialDate ?? _roundToNearestMinute(DateTime.now(), 5);
|
||||
@@ -512,7 +525,7 @@ class _CreateEventSheetState extends State<CreateEventSheet>
|
||||
}
|
||||
|
||||
Widget _buildReminderPicker() {
|
||||
const options = <int?>[null, 0, 5, 10, 15, 30, 60, 120];
|
||||
final options = _buildReminderOptions();
|
||||
String labelOf(int? value) {
|
||||
if (value == null) {
|
||||
return '无提醒';
|
||||
@@ -573,6 +586,24 @@ class _CreateEventSheetState extends State<CreateEventSheet>
|
||||
);
|
||||
}
|
||||
|
||||
int? _sanitizeReminderMinutes(int? minutes) {
|
||||
if (minutes == null || minutes < 0) {
|
||||
return null;
|
||||
}
|
||||
return minutes;
|
||||
}
|
||||
|
||||
List<int?> _buildReminderOptions() {
|
||||
final current = _sanitizeReminderMinutes(_reminderMinutes);
|
||||
final nonNull = _defaultReminderOptions.whereType<int>().toSet();
|
||||
if (current != null) {
|
||||
nonNull.add(current);
|
||||
}
|
||||
|
||||
final sorted = nonNull.toList()..sort();
|
||||
return [null, ...sorted];
|
||||
}
|
||||
|
||||
Future<void> _saveEvent() async {
|
||||
if (_titleController.text.trim().isEmpty || _saving) return;
|
||||
setState(() {
|
||||
|
||||
Reference in New Issue
Block a user