Compare commits
5
Commits
2c3e52ba53
...
1141ab8f3c
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1141ab8f3c | ||
|
|
a130757daa | ||
|
|
cd719cd641 | ||
|
|
4061b4bf73 | ||
|
|
e122cd0bf5 |
@@ -4,7 +4,7 @@ class RelativeTimeAlarm implements Alarm {
|
|||||||
@override
|
@override
|
||||||
final String id;
|
final String id;
|
||||||
|
|
||||||
final DateTime triggerAt;
|
final Duration triggerAt;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final AlarmType alarmType;
|
final AlarmType alarmType;
|
||||||
@@ -15,7 +15,7 @@ class RelativeTimeAlarm implements Alarm {
|
|||||||
factory RelativeTimeAlarm.fromJson(Map<String, dynamic> json) {
|
factory RelativeTimeAlarm.fromJson(Map<String, dynamic> json) {
|
||||||
return RelativeTimeAlarm(
|
return RelativeTimeAlarm(
|
||||||
id: json['id'] as String,
|
id: json['id'] as String,
|
||||||
triggerAt: DateTime.parse(json['triggerAt'] as String),
|
triggerAt: Duration(minutes: json['triggerAt'] as int),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -23,7 +23,7 @@ class RelativeTimeAlarm implements Alarm {
|
|||||||
Map<String, dynamic> toJson() {
|
Map<String, dynamic> toJson() {
|
||||||
return {
|
return {
|
||||||
'id': id,
|
'id': id,
|
||||||
'triggerAt': triggerAt.toIso8601String(),
|
'triggerAt': triggerAt.inMinutes,
|
||||||
'alarmType': alarmType.toJson(),
|
'alarmType': alarmType.toJson(),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import '../alarm/relative_time_alarm.dart';
|
|||||||
import 'create_alarm_request.dart';
|
import 'create_alarm_request.dart';
|
||||||
|
|
||||||
class CreateRelativeTimeAlarmRequest extends CreateAlarmRequest {
|
class CreateRelativeTimeAlarmRequest extends CreateAlarmRequest {
|
||||||
final DateTime? triggerAt;
|
final Duration? triggerAt;
|
||||||
|
|
||||||
const CreateRelativeTimeAlarmRequest({this.triggerAt})
|
const CreateRelativeTimeAlarmRequest({this.triggerAt})
|
||||||
: super(alarmType: AlarmType.timeRelative);
|
: super(alarmType: AlarmType.timeRelative);
|
||||||
|
|||||||
@@ -268,9 +268,8 @@ class _TaskEditPageState extends State<TaskEditPage> {
|
|||||||
alarmRequests.add(CreateLocationAlarmRequest());
|
alarmRequests.add(CreateLocationAlarmRequest());
|
||||||
case AlarmType.timeFixed:
|
case AlarmType.timeFixed:
|
||||||
alarmRequests.add(CreateFixedTimeAlarmRequest());
|
alarmRequests.add(CreateFixedTimeAlarmRequest());
|
||||||
|
|
||||||
case AlarmType.timeRelative:
|
case AlarmType.timeRelative:
|
||||||
alarmRequests.add(CreateFixedTimeAlarmRequest());
|
alarmRequests.add(CreateRelativeTimeAlarmRequest());
|
||||||
}
|
}
|
||||||
setState(() {});
|
setState(() {});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,6 +45,7 @@ class _FixedTimeAlarmFormState extends State<FixedTimeAlarmForm> {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Flex(
|
return Flex(
|
||||||
direction: Axis.horizontal,
|
direction: Axis.horizontal,
|
||||||
|
spacing: AppTheme.formColumnSpacing,
|
||||||
children: [
|
children: [
|
||||||
Flexible(
|
Flexible(
|
||||||
flex: 3,
|
flex: 3,
|
||||||
@@ -76,9 +77,6 @@ class _FixedTimeAlarmFormState extends State<FixedTimeAlarmForm> {
|
|||||||
textInputAction: TextInputAction.next,
|
textInputAction: TextInputAction.next,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Padding(
|
|
||||||
padding: EdgeInsetsGeometry.only(left: AppTheme.formColumnSpacing),
|
|
||||||
),
|
|
||||||
Flexible(
|
Flexible(
|
||||||
flex: 2,
|
flex: 2,
|
||||||
child: TextFormField(
|
child: TextFormField(
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
import '../../app_theme.dart';
|
||||||
import '../../model/requests/create_alarm_request.dart';
|
import '../../model/requests/create_alarm_request.dart';
|
||||||
import '../../model/requests/create_relative_time_alarm_request.dart';
|
import '../../model/requests/create_relative_time_alarm_request.dart';
|
||||||
|
import '../../service/validators.dart';
|
||||||
|
|
||||||
class RelativeTimeAlarmForm extends StatelessWidget {
|
class RelativeTimeAlarmForm extends StatefulWidget {
|
||||||
const RelativeTimeAlarmForm({
|
const RelativeTimeAlarmForm({
|
||||||
super.key,
|
super.key,
|
||||||
required this.request,
|
required this.request,
|
||||||
@@ -12,8 +14,134 @@ class RelativeTimeAlarmForm extends StatelessWidget {
|
|||||||
final CreateRelativeTimeAlarmRequest request;
|
final CreateRelativeTimeAlarmRequest request;
|
||||||
final ValueChanged<CreateAlarmRequest> onChanged;
|
final ValueChanged<CreateAlarmRequest> onChanged;
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<RelativeTimeAlarmForm> createState() => _RelativeTimeAlarmFormState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _RelativeTimeAlarmFormState extends State<RelativeTimeAlarmForm> {
|
||||||
|
final timeController = TextEditingController();
|
||||||
|
|
||||||
|
static const List<DropdownMenuEntry<TimeUnit>> timeUnitOptions = [
|
||||||
|
DropdownMenuEntry<TimeUnit>(value: TimeUnit.minute, label: 'Minutes'),
|
||||||
|
DropdownMenuEntry<TimeUnit>(value: TimeUnit.hour, label: 'Hours'),
|
||||||
|
DropdownMenuEntry<TimeUnit>(value: TimeUnit.day, label: 'Days'),
|
||||||
|
];
|
||||||
|
|
||||||
|
static const List<DropdownMenuEntry<TimeRelation>> timeRelationOptions = [
|
||||||
|
DropdownMenuEntry<TimeRelation>(
|
||||||
|
value: TimeRelation.before,
|
||||||
|
label: 'Before',
|
||||||
|
),
|
||||||
|
DropdownMenuEntry<TimeRelation>(value: TimeRelation.after, label: 'After'),
|
||||||
|
];
|
||||||
|
|
||||||
|
late TimeUnit selectedTimeUnit;
|
||||||
|
late TimeRelation selectedTimeRelation;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
|
||||||
|
if (widget.request.triggerAt == null) {
|
||||||
|
selectedTimeUnit = TimeUnit.minute;
|
||||||
|
selectedTimeRelation = TimeRelation.before;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final duration = widget.request.triggerAt!;
|
||||||
|
|
||||||
|
selectedTimeRelation = duration.isNegative
|
||||||
|
? TimeRelation.before
|
||||||
|
: TimeRelation.after;
|
||||||
|
|
||||||
|
final absDuration = duration.abs();
|
||||||
|
|
||||||
|
if (absDuration.inMinutes <= 99 && absDuration.inMinutes % 60 != 0) {
|
||||||
|
selectedTimeUnit = TimeUnit.minute;
|
||||||
|
timeController.text = absDuration.inMinutes.toString();
|
||||||
|
} else if (absDuration.inHours <= 99 && absDuration.inHours % 24 != 0) {
|
||||||
|
selectedTimeUnit = TimeUnit.hour;
|
||||||
|
timeController.text = absDuration.inHours.toString();
|
||||||
|
} else {
|
||||||
|
selectedTimeUnit = TimeUnit.day;
|
||||||
|
timeController.text = absDuration.inDays.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return const Placeholder();
|
return Flex(
|
||||||
|
direction: Axis.horizontal,
|
||||||
|
spacing: AppTheme.formColumnSpacing,
|
||||||
|
children: [
|
||||||
|
Flexible(
|
||||||
|
flex: 7,
|
||||||
|
child: TextFormField(
|
||||||
|
controller: timeController,
|
||||||
|
maxLength: 2,
|
||||||
|
onChanged: onTimeChanged,
|
||||||
|
validator: (value) =>
|
||||||
|
notEmptyValidator(value) ?? wholeNumberValidator(value),
|
||||||
|
keyboardType: TextInputType.number,
|
||||||
|
textInputAction: TextInputAction.next,
|
||||||
|
decoration: InputDecoration(label: Text('Time'), counterText: ''),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Flexible(
|
||||||
|
flex: 10,
|
||||||
|
child: DropdownMenuFormField<TimeUnit>(
|
||||||
|
dropdownMenuEntries: timeUnitOptions,
|
||||||
|
initialSelection: selectedTimeUnit,
|
||||||
|
showTrailingIcon: false,
|
||||||
|
onSelected: (value) {
|
||||||
|
selectedTimeUnit = value!;
|
||||||
|
onTimeChanged(timeController.text);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Flexible(
|
||||||
|
flex: 10,
|
||||||
|
child: DropdownMenuFormField<TimeRelation>(
|
||||||
|
dropdownMenuEntries: timeRelationOptions,
|
||||||
|
initialSelection: selectedTimeRelation,
|
||||||
|
showTrailingIcon: false,
|
||||||
|
onSelected: (value) {
|
||||||
|
selectedTimeRelation = value!;
|
||||||
|
onTimeChanged(timeController.text);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void onTimeChanged(String value) {
|
||||||
|
int? time = int.tryParse(value);
|
||||||
|
if (wholeNumberValidator(value) != null || time == null) return;
|
||||||
|
Duration duration;
|
||||||
|
int signedTime = selectedTimeRelation.apply(time);
|
||||||
|
|
||||||
|
switch (selectedTimeUnit) {
|
||||||
|
case TimeUnit.minute:
|
||||||
|
duration = Duration(minutes: signedTime);
|
||||||
|
case TimeUnit.hour:
|
||||||
|
duration = Duration(hours: signedTime);
|
||||||
|
case TimeUnit.day:
|
||||||
|
duration = Duration(days: signedTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
widget.onChanged(CreateRelativeTimeAlarmRequest(triggerAt: duration));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum TimeRelation {
|
||||||
|
before,
|
||||||
|
after;
|
||||||
|
|
||||||
|
int apply(int value) => switch (this) {
|
||||||
|
TimeRelation.before => -value,
|
||||||
|
TimeRelation.after => value,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
enum TimeUnit { minute, hour, day }
|
||||||
|
|||||||
Reference in New Issue
Block a user