Files
tasks/lib/widgets/alarm_widgets/fixed_time_alarm_form.dart
T

169 lines
5.1 KiB
Dart

import 'package:flutter/material.dart';
import '../../app_theme.dart' show AppTheme;
import '../../model/requests/create_fixed_time_alarm_request.dart';
import '../../service/tools.dart';
import '../../service/validators.dart';
class FixedTimeAlarmForm extends StatefulWidget {
const FixedTimeAlarmForm({
super.key,
required this.request,
required this.onChanged,
});
final CreateFixedTimeAlarmRequest request;
final ValueChanged<CreateFixedTimeAlarmRequest> onChanged;
@override
State<FixedTimeAlarmForm> createState() => _FixedTimeAlarmFormState();
}
class _FixedTimeAlarmFormState extends State<FixedTimeAlarmForm> {
final dueDateController = TextEditingController();
final dueTimeController = TextEditingController();
final dueDateFocusNode = FocusNode();
final dueTimeFocusNode = FocusNode();
bool isDueTimeEnabled = false;
@override
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);
dueTimeController.addListener(onDueTimeChanged);
super.didChangeDependencies();
}
@override
Widget build(BuildContext context) {
return Flex(
direction: Axis.horizontal,
children: [
Flexible(
flex: 3,
child: TextFormField(
focusNode: dueDateFocusNode,
controller: dueDateController,
onFieldSubmitted: (_) {
isDueTimeEnabled ? dueDateFocusNode.nextFocus() : null;
},
decoration: InputDecoration(
label: Text('Due Date'),
suffixIcon: IconButton(
onPressed: () async {
final result = await onOpenCalendarPickerPressed();
if (result != null) {
final dateString = getIsoDateString(result);
dueDateController.text = dateString;
maybeEnableDueTime(dateString);
dueTimeFocusNode.requestFocus();
}
},
icon: Icon(Icons.calendar_month),
),
),
validator: dateTimeValidator,
keyboardType: TextInputType.datetime,
textInputAction: TextInputAction.next,
),
),
Padding(
padding: EdgeInsetsGeometry.only(left: AppTheme.formColumnSpacing),
),
Flexible(
flex: 2,
child: TextFormField(
focusNode: dueTimeFocusNode,
onFieldSubmitted: (_) => dueTimeFocusNode.nextFocus(),
controller: dueTimeController,
enabled: isDueTimeEnabled,
onChanged: (value) {},
decoration: InputDecoration(
label: Text('Due Time'),
suffixIcon: IconButton(
onPressed: () async {
final result = await onOpenTimePickerPressed();
if (result != null && context.mounted) {
dueTimeController.text = result.format(context);
}
},
icon: Icon(Icons.schedule),
),
),
validator: timeValidator,
keyboardType: TextInputType.text,
textInputAction: TextInputAction.next,
),
),
],
);
}
Future<DateTime?> onOpenCalendarPickerPressed() {
return showDialog<DateTime?>(
context: context,
builder: (context) => DatePickerDialog(
firstDate: DateTime(DateTime.now().year - 100),
lastDate: DateTime(DateTime.now().year + 100),
initialDate:
DateTime.tryParse(dueDateController.text) ?? DateTime.now(),
),
);
}
Future<TimeOfDay?> onOpenTimePickerPressed() {
return showDialog<TimeOfDay?>(
context: context,
builder: (context) => TimePickerDialog(
initialTime: TimeOfDay.fromDateTime(
widget.request.triggerAt ?? DateTime.now(),
),
),
);
}
void maybeEnableDueTime(String value) {
if (value.isNotEmpty && dateTimeValidator(value) == null) {
setState(() {
isDueTimeEnabled = true;
});
} else if (isDueTimeEnabled) {
setState(() {
isDueTimeEnabled = false;
});
}
}
void onDueDateChanged() {
final String value = dueDateController.text;
maybeEnableDueTime(value);
if (dateTimeValidator(value) == null) {
final dateTime = DateTime.tryParse(
'$value ${dueTimeController.text}'.trim(),
);
if (dateTime != null) {
widget.onChanged(CreateFixedTimeAlarmRequest(triggerAt: dateTime));
}
}
}
void onDueTimeChanged() {
final String value = dueTimeController.text;
if (timeValidator(value) == null) {
final dateTime = DateTime.tryParse(
'${dueDateController.text} $value'.trim(),
);
if (dateTime != null) {
widget.onChanged(CreateFixedTimeAlarmRequest(triggerAt: dateTime));
}
}
}
}