feat: 增强日历功能并集成 AgentScope 代理服务
This commit is contained in:
@@ -2,6 +2,7 @@ import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:lucide_icons/lucide_icons.dart';
|
||||
import '../../../../core/di/injection.dart';
|
||||
import '../../../../core/notifications/local_notification_service.dart';
|
||||
import '../../../../core/theme/design_tokens.dart';
|
||||
import '../../data/models/schedule_item_model.dart';
|
||||
import '../../data/services/mock_calendar_service.dart';
|
||||
@@ -63,6 +64,7 @@ class _CreateEventSheetState extends State<CreateEventSheet>
|
||||
DateTime? _endDate;
|
||||
DateTime? _endTime;
|
||||
String _selectedColor = '#3B82F6';
|
||||
int? _reminderMinutes = 15;
|
||||
bool _saving = false;
|
||||
List<Attachment> _attachments = const [];
|
||||
|
||||
@@ -84,11 +86,13 @@ class _CreateEventSheetState extends State<CreateEventSheet>
|
||||
_endDate = event.endAt;
|
||||
_endTime = event.endAt;
|
||||
_selectedColor = event.metadata?.color ?? '#3B82F6';
|
||||
_reminderMinutes = event.metadata?.reminderMinutes ?? 15;
|
||||
_attachments = List<Attachment>.from(
|
||||
event.metadata?.attachments ?? const [],
|
||||
);
|
||||
} else {
|
||||
final now = widget.initialDate ?? DateTime.now();
|
||||
final now =
|
||||
widget.initialDate ?? _roundToNearestMinute(DateTime.now(), 5);
|
||||
_startDate = now;
|
||||
_startTime = now;
|
||||
_endDate = now;
|
||||
@@ -108,6 +112,11 @@ class _CreateEventSheetState extends State<CreateEventSheet>
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
DateTime _roundToNearestMinute(DateTime dt, int interval) {
|
||||
final minute = (dt.minute / interval).round() * interval;
|
||||
return DateTime(dt.year, dt.month, dt.day, dt.hour, minute % 60);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
@@ -254,6 +263,8 @@ class _CreateEventSheetState extends State<CreateEventSheet>
|
||||
const SizedBox(height: 20),
|
||||
_buildTextField('地点', _locationController, '请输入地点'),
|
||||
const SizedBox(height: 20),
|
||||
_buildReminderPicker(),
|
||||
const SizedBox(height: 20),
|
||||
_buildColorPicker(),
|
||||
const SizedBox(height: 20),
|
||||
_buildAttachmentsSection(),
|
||||
@@ -706,6 +717,68 @@ class _CreateEventSheetState extends State<CreateEventSheet>
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildReminderPicker() {
|
||||
const options = <int?>[null, 0, 5, 10, 15, 30, 60, 120];
|
||||
String labelOf(int? value) {
|
||||
if (value == null) {
|
||||
return '无提醒';
|
||||
}
|
||||
if (value == 0) {
|
||||
return '准时提醒';
|
||||
}
|
||||
return '开始前$value分钟';
|
||||
}
|
||||
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const Text(
|
||||
'提醒时间',
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: AppColors.slate700,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
Container(
|
||||
width: double.infinity,
|
||||
padding: const EdgeInsets.symmetric(horizontal: 12),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(AppRadius.lg),
|
||||
border: Border.all(color: AppColors.border),
|
||||
),
|
||||
child: DropdownButtonHideUnderline(
|
||||
child: DropdownButton<int?>(
|
||||
value: _reminderMinutes,
|
||||
isExpanded: true,
|
||||
items: options
|
||||
.map(
|
||||
(value) => DropdownMenuItem<int?>(
|
||||
value: value,
|
||||
child: Text(
|
||||
labelOf(value),
|
||||
style: const TextStyle(
|
||||
fontSize: 14,
|
||||
color: AppColors.slate700,
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
.toList(),
|
||||
onChanged: (value) {
|
||||
setState(() {
|
||||
_reminderMinutes = value;
|
||||
});
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> _saveEvent() async {
|
||||
if (_titleController.text.trim().isEmpty || _saving) return;
|
||||
setState(() {
|
||||
@@ -739,6 +812,7 @@ class _CreateEventSheetState extends State<CreateEventSheet>
|
||||
notes: _notesController.text.trim().isNotEmpty
|
||||
? _notesController.text.trim()
|
||||
: null,
|
||||
reminderMinutes: _reminderMinutes,
|
||||
attachments: _attachments,
|
||||
version: widget.editingEvent?.metadata?.version ?? 1,
|
||||
);
|
||||
@@ -758,22 +832,21 @@ class _CreateEventSheetState extends State<CreateEventSheet>
|
||||
|
||||
try {
|
||||
final service = sl<CalendarService>();
|
||||
debugPrint('CalendarService: $service');
|
||||
debugPrint('Is mock: ${service.runtimeType}');
|
||||
final notificationService = sl<LocalNotificationService>();
|
||||
late final ScheduleItemModel saved;
|
||||
|
||||
if (_isEditing) {
|
||||
await service.updateEvent(event);
|
||||
saved = await service.updateEvent(event);
|
||||
} else {
|
||||
await service.addEvent(event);
|
||||
saved = await service.addEvent(event);
|
||||
}
|
||||
await notificationService.upsertEventReminder(saved);
|
||||
|
||||
widget.onSaved?.call();
|
||||
if (mounted) {
|
||||
Navigator.pop(context);
|
||||
}
|
||||
} catch (e, stack) {
|
||||
debugPrint('Save error: $e');
|
||||
debugPrint('Stack: $stack');
|
||||
} catch (e) {
|
||||
if (mounted) {
|
||||
ScaffoldMessenger.of(
|
||||
context,
|
||||
|
||||
Reference in New Issue
Block a user