implemented relativetime input widget
This commit is contained in:
@@ -1,9 +1,11 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import '../../app_theme.dart';
|
||||
import '../../model/requests/create_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({
|
||||
super.key,
|
||||
required this.request,
|
||||
@@ -12,8 +14,134 @@ class RelativeTimeAlarmForm extends StatelessWidget {
|
||||
final CreateRelativeTimeAlarmRequest request;
|
||||
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
|
||||
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