4 Commits
Author SHA1 Message Date
marco e6951b4c25 handled saving and restoring fixed time alarms 2026-07-20 14:30:41 +02:00
marco cd97dada2a fixed enum serialization 2026-07-20 14:23:58 +02:00
marco 6778b6426f added toJson to enum 2026-07-20 14:14:44 +02:00
marco 1b9e096b77 correct implementation of toAlarm 2026-07-20 14:13:19 +02:00
10 changed files with 70 additions and 23 deletions
+12 -5
View File
@@ -9,12 +9,12 @@ abstract class Alarm {
factory Alarm.fromJson(Map<String, dynamic> json) { factory Alarm.fromJson(Map<String, dynamic> json) {
if (json.containsKey('alarmType')) { if (json.containsKey('alarmType')) {
switch (json['alarmType'] as String) { switch (AlarmType.fromJson(json['alarmType'])) {
case 'timeFixed': case AlarmType.timeFixed:
return FixedTimeAlarm.fromJson(json); return FixedTimeAlarm.fromJson(json);
case 'timeRelative': case AlarmType.timeRelative:
return RelativeTimeAlarm.fromJson(json); return RelativeTimeAlarm.fromJson(json);
case 'location': case AlarmType.location:
return LocationAlarm.fromJson(json); return LocationAlarm.fromJson(json);
} }
} }
@@ -33,4 +33,11 @@ abstract class Alarm {
int get hashCode => id.hashCode; int get hashCode => id.hashCode;
} }
enum AlarmType { timeFixed, timeRelative, location } enum AlarmType {
timeFixed,
timeRelative,
location;
String toJson() => name;
static AlarmType fromJson(String json) => values.byName(json);
}
+1 -1
View File
@@ -24,7 +24,7 @@ class FixedTimeAlarm implements Alarm {
return { return {
'id': id, 'id': id,
'triggerAt': triggerAt.toIso8601String(), 'triggerAt': triggerAt.toIso8601String(),
'alarmType': alarmType, 'alarmType': alarmType.toJson(),
}; };
} }
} }
+1 -1
View File
@@ -32,7 +32,7 @@ class LocationAlarm implements Alarm {
'id': id, 'id': id,
'location': location.toJson(), 'location': location.toJson(),
'radiusMeters': radiusMeters, 'radiusMeters': radiusMeters,
'alarmType': alarmType, 'alarmType': alarmType.toJson(),
}; };
} }
} }
+1 -1
View File
@@ -24,7 +24,7 @@ class RelativeTimeAlarm implements Alarm {
return { return {
'id': id, 'id': id,
'triggerAt': triggerAt.toIso8601String(), 'triggerAt': triggerAt.toIso8601String(),
'alarmType': alarmType, 'alarmType': alarmType.toJson(),
}; };
} }
} }
+4 -2
View File
@@ -1,7 +1,9 @@
import '../alarm/alarm.dart' show AlarmType; import '../alarm/alarm.dart' show AlarmType, Alarm;
class CreateAlarmRequest { abstract class CreateAlarmRequest {
const CreateAlarmRequest({required this.alarmType}); const CreateAlarmRequest({required this.alarmType});
final AlarmType alarmType; final AlarmType alarmType;
Alarm toAlarm(String id);
} }
@@ -12,6 +12,7 @@ class CreateFixedTimeAlarmRequest extends CreateAlarmRequest {
: triggerAt = alarm.triggerAt, : triggerAt = alarm.triggerAt,
super(alarmType: AlarmType.timeFixed); super(alarmType: AlarmType.timeFixed);
FixedTimeAlarm toFixedTimeAlarm(String id) => @override
FixedTimeAlarm toAlarm(String id) =>
FixedTimeAlarm(id: id, triggerAt: triggerAt!); FixedTimeAlarm(id: id, triggerAt: triggerAt!);
} }
@@ -16,6 +16,7 @@ class CreateLocationAlarmRequest extends CreateAlarmRequest {
radiusMeters = alarm.radiusMeters, radiusMeters = alarm.radiusMeters,
super(alarmType: AlarmType.location); super(alarmType: AlarmType.location);
LocationAlarm toLocationAlarm(String id) => @override
LocationAlarm toAlarm(String id) =>
LocationAlarm(id: id, location: location!, radiusMeters: radiusMeters!); LocationAlarm(id: id, location: location!, radiusMeters: radiusMeters!);
} }
@@ -12,6 +12,7 @@ class CreateRelativeTimeAlarmRequest extends CreateAlarmRequest {
: triggerAt = alarm.triggerAt, : triggerAt = alarm.triggerAt,
super(alarmType: AlarmType.timeRelative); super(alarmType: AlarmType.timeRelative);
RelativeTimeAlarm toRelativeTimeAlarm(String id) => @override
RelativeTimeAlarm toAlarm(String id) =>
RelativeTimeAlarm(id: id, triggerAt: triggerAt!); RelativeTimeAlarm(id: id, triggerAt: triggerAt!);
} }
+35 -8
View File
@@ -2,9 +2,13 @@ import 'package:flutter/material.dart';
import '../app_theme.dart'; import '../app_theme.dart';
import '../model/alarm/alarm.dart'; import '../model/alarm/alarm.dart';
import '../model/alarm/fixed_time_alarm.dart';
import '../model/alarm/location_alarm.dart';
import '../model/alarm/relative_time_alarm.dart';
import '../model/requests/create_alarm_request.dart'; import '../model/requests/create_alarm_request.dart';
import '../model/requests/create_fixed_time_alarm_request.dart'; import '../model/requests/create_fixed_time_alarm_request.dart';
import '../model/requests/create_location_alarm_request.dart'; import '../model/requests/create_location_alarm_request.dart';
import '../model/requests/create_relative_time_alarm_request.dart';
import '../model/requests/create_task_request.dart'; import '../model/requests/create_task_request.dart';
import '../model/extensions/controller_context.dart'; import '../model/extensions/controller_context.dart';
import '../model/task.dart'; import '../model/task.dart';
@@ -37,7 +41,7 @@ class _TaskEditPageState extends State<TaskEditPage> {
final formKey = GlobalKey<FormState>(debugLabel: 'taskEditFormKey'); final formKey = GlobalKey<FormState>(debugLabel: 'taskEditFormKey');
bool didFormChange = false; bool didFormChange = false;
bool isDueTimeEnabled = false; bool isDueTimeEnabled = false;
final List<CreateAlarmRequest> alarms = []; final List<CreateAlarmRequest> alarmRequests = [];
@override @override
void didChangeDependencies() { void didChangeDependencies() {
@@ -56,6 +60,18 @@ class _TaskEditPageState extends State<TaskEditPage> {
isDueTimeEnabled = true; isDueTimeEnabled = true;
} }
isInitialized = true; isInitialized = true;
alarmRequests.addAll(
task!.alarms.map((alarm) {
if (alarm is FixedTimeAlarm) {
return CreateFixedTimeAlarmRequest.fromAlarm(alarm);
} else if (alarm is RelativeTimeAlarm) {
return CreateRelativeTimeAlarmRequest.fromAlarm(alarm);
} else if (alarm is LocationAlarm) {
return CreateLocationAlarmRequest.fromAlarm(alarm);
}
throw TypeError();
}),
);
pageTitle = task!.title; pageTitle = task!.title;
} }
} }
@@ -151,12 +167,12 @@ class _TaskEditPageState extends State<TaskEditPage> {
label: Text('Location'), label: Text('Location'),
icon: Icon(Icons.location_on), icon: Icon(Icons.location_on),
), ),
for (final (index, alarm) in alarms.indexed) for (final (index, alarmRequest) in alarmRequests.indexed)
AlarmForm( AlarmForm(
request: alarm, request: alarmRequest,
onChanged: (updated) { onChanged: (updated) {
setState(() { setState(() {
alarms[index] = updated; alarmRequests[index] = updated;
}); });
}, },
), ),
@@ -187,7 +203,18 @@ class _TaskEditPageState extends State<TaskEditPage> {
category: categoryController.text, category: categoryController.text,
subtasks: [], subtasks: [],
url: urlController.text, url: urlController.text,
alarms: [], alarms: alarmRequests.map<Alarm>((e) {
if (e is CreateFixedTimeAlarmRequest) {
return e.toAlarm(generateId());
}
if (e is CreateRelativeTimeAlarmRequest) {
return e.toAlarm(generateId());
}
if (e is LocationAlarm) {
return e.toAlarm(generateId());
}
throw TypeError();
}).toList(),
), ),
); );
} }
@@ -223,12 +250,12 @@ class _TaskEditPageState extends State<TaskEditPage> {
void onAddAlarmPressed(AlarmType alarmType) { void onAddAlarmPressed(AlarmType alarmType) {
switch (alarmType) { switch (alarmType) {
case AlarmType.location: case AlarmType.location:
alarms.add(CreateLocationAlarmRequest()); alarmRequests.add(CreateLocationAlarmRequest());
case AlarmType.timeFixed: case AlarmType.timeFixed:
alarms.add(CreateFixedTimeAlarmRequest()); alarmRequests.add(CreateFixedTimeAlarmRequest());
case AlarmType.timeRelative: case AlarmType.timeRelative:
alarms.add(CreateFixedTimeAlarmRequest()); alarmRequests.add(CreateFixedTimeAlarmRequest());
} }
setState(() {}); setState(() {});
} }
@@ -26,11 +26,19 @@ class _FixedTimeAlarmFormState extends State<FixedTimeAlarmForm> {
bool isDueTimeEnabled = false; bool isDueTimeEnabled = false;
@override @override
void initState() { void didChangeDependencies() {
if (widget.request.triggerAt != null) {
dueDateController.text = getIsoDateString(widget.request.triggerAt!);
dueTimeController.text = TimeOfDay.fromDateTime(
widget.request.triggerAt!,
).format(context);
isDueTimeEnabled = true;
}
dueDateController.addListener(onDueDateChanged); dueDateController.addListener(onDueDateChanged);
dueTimeController.addListener(onDueTimeChanged); dueTimeController.addListener(onDueTimeChanged);
super.initState(); super.didChangeDependencies();
} }
@override @override