created alram form widget placeholders
This commit is contained in:
@@ -1,11 +1,16 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
import '../app_theme.dart';
|
import '../app_theme.dart';
|
||||||
|
import '../model/alarm.dart';
|
||||||
|
import '../model/callback_models/create_alarm_request.dart';
|
||||||
|
import '../model/callback_models/create_fixed_time_alarm_request.dart';
|
||||||
|
import '../model/callback_models/create_location_alarm_request.dart';
|
||||||
import '../model/callback_models/create_task_request.dart';
|
import '../model/callback_models/create_task_request.dart';
|
||||||
import '../model/extensions/controller_context.dart';
|
import '../model/extensions/controller_context.dart';
|
||||||
import '../model/task.dart';
|
import '../model/task.dart';
|
||||||
import '../service/controllers/task_controller.dart';
|
import '../service/controllers/task_controller.dart';
|
||||||
import '../service/tools.dart';
|
import '../service/tools.dart';
|
||||||
|
import '../widgets/alarm_widgets/alarm_form_widget.dart';
|
||||||
import '../widgets/time_selector.dart';
|
import '../widgets/time_selector.dart';
|
||||||
|
|
||||||
class TaskEditPage extends StatefulWidget {
|
class TaskEditPage extends StatefulWidget {
|
||||||
@@ -32,6 +37,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 = [];
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void didChangeDependencies() {
|
void didChangeDependencies() {
|
||||||
@@ -80,46 +86,84 @@ class _TaskEditPageState extends State<TaskEditPage> {
|
|||||||
padding: EdgeInsets.symmetric(
|
padding: EdgeInsets.symmetric(
|
||||||
horizontal: MediaQuery.of(context).size.width * 0.05,
|
horizontal: MediaQuery.of(context).size.width * 0.05,
|
||||||
),
|
),
|
||||||
child: Column(
|
child: SingleChildScrollView(
|
||||||
spacing: AppTheme.formColumnSpacing,
|
child: Column(
|
||||||
children: [
|
spacing: AppTheme.formColumnSpacing,
|
||||||
SizedBox(height: 6),
|
children: [
|
||||||
TextFormField(
|
SizedBox(height: 6),
|
||||||
autofocus: true,
|
TextFormField(
|
||||||
controller: titleController,
|
autofocus: true,
|
||||||
decoration: InputDecoration(label: Text('Title')),
|
controller: titleController,
|
||||||
keyboardType: TextInputType.text,
|
decoration: InputDecoration(label: Text('Title')),
|
||||||
textInputAction: TextInputAction.next,
|
keyboardType: TextInputType.text,
|
||||||
),
|
textInputAction: TextInputAction.next,
|
||||||
TextFormField(
|
),
|
||||||
controller: descriptionController,
|
TextFormField(
|
||||||
decoration: InputDecoration(label: Text('Description')),
|
controller: descriptionController,
|
||||||
keyboardType: TextInputType.multiline,
|
decoration: InputDecoration(label: Text('Description')),
|
||||||
textInputAction: TextInputAction.newline,
|
keyboardType: TextInputType.multiline,
|
||||||
minLines: 3,
|
textInputAction: TextInputAction.newline,
|
||||||
maxLines: 10,
|
minLines: 3,
|
||||||
),
|
maxLines: 10,
|
||||||
TimeSelector(
|
),
|
||||||
initialDueDateTime: task?.due,
|
TimeSelector(
|
||||||
nextFocusNode: categoryFocusNode,
|
initialDueDateTime: task?.due,
|
||||||
dueDateController: dueDateController,
|
nextFocusNode: categoryFocusNode,
|
||||||
dueTimeController: dueTimeController,
|
dueDateController: dueDateController,
|
||||||
formKey: formKey,
|
dueTimeController: dueTimeController,
|
||||||
),
|
formKey: formKey,
|
||||||
TextFormField(
|
),
|
||||||
focusNode: categoryFocusNode,
|
TextFormField(
|
||||||
controller: categoryController,
|
focusNode: categoryFocusNode,
|
||||||
decoration: InputDecoration(label: Text('Category')),
|
controller: categoryController,
|
||||||
keyboardType: TextInputType.text,
|
decoration: InputDecoration(label: Text('Category')),
|
||||||
textInputAction: TextInputAction.next,
|
keyboardType: TextInputType.text,
|
||||||
),
|
textInputAction: TextInputAction.next,
|
||||||
TextFormField(
|
),
|
||||||
controller: urlController,
|
TextFormField(
|
||||||
decoration: InputDecoration(label: Text('Url')),
|
controller: urlController,
|
||||||
keyboardType: TextInputType.text,
|
decoration: InputDecoration(label: Text('Url')),
|
||||||
textInputAction: TextInputAction.next,
|
keyboardType: TextInputType.text,
|
||||||
),
|
textInputAction: TextInputAction.next,
|
||||||
],
|
),
|
||||||
|
Text(
|
||||||
|
'Alarms',
|
||||||
|
style: Theme.of(context).textTheme.headlineLarge,
|
||||||
|
),
|
||||||
|
Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
|
spacing: AppTheme.formColumnSpacing,
|
||||||
|
children: [
|
||||||
|
ElevatedButton.icon(
|
||||||
|
onPressed: () => onAddAlarmPressed(AlarmType.timeFixed),
|
||||||
|
label: Text('Fixed Time'),
|
||||||
|
icon: Icon(Icons.alarm_add),
|
||||||
|
),
|
||||||
|
ElevatedButton.icon(
|
||||||
|
onPressed: () =>
|
||||||
|
onAddAlarmPressed(AlarmType.timeRelative),
|
||||||
|
label: Text('Relative Time'),
|
||||||
|
icon: Icon(Icons.timer_outlined),
|
||||||
|
),
|
||||||
|
ElevatedButton.icon(
|
||||||
|
onPressed: () => onAddAlarmPressed(AlarmType.location),
|
||||||
|
label: Text('Location'),
|
||||||
|
icon: Icon(Icons.location_on),
|
||||||
|
),
|
||||||
|
for (final (index, alarm) in alarms.indexed)
|
||||||
|
AlarmForm(
|
||||||
|
request: alarm,
|
||||||
|
onChanged: (updated) {
|
||||||
|
setState(() {
|
||||||
|
alarms[index] = updated;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -174,4 +218,17 @@ class _TaskEditPageState extends State<TaskEditPage> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void onAddAlarmPressed(AlarmType alarmType) {
|
||||||
|
switch (alarmType) {
|
||||||
|
case AlarmType.location:
|
||||||
|
alarms.add(CreateLocationAlarmRequest());
|
||||||
|
case AlarmType.timeFixed:
|
||||||
|
alarms.add(CreateFixedTimeAlarmRequest());
|
||||||
|
|
||||||
|
case AlarmType.timeRelative:
|
||||||
|
alarms.add(CreateFixedTimeAlarmRequest());
|
||||||
|
}
|
||||||
|
setState(() {});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,40 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
import '../../model/alarm.dart' show AlarmType;
|
||||||
|
import '../../model/callback_models/create_alarm_request.dart';
|
||||||
|
import '../../model/callback_models/create_fixed_time_alarm_request.dart';
|
||||||
|
import '../../model/callback_models/create_location_alarm_request.dart';
|
||||||
|
import '../../model/callback_models/create_relative_time_alarm_request.dart';
|
||||||
|
import 'fixed_time_alarm_form.dart';
|
||||||
|
import 'location_alarm_form.dart';
|
||||||
|
import 'relative_time_alarm_form.dart';
|
||||||
|
|
||||||
|
class AlarmForm extends StatelessWidget {
|
||||||
|
const AlarmForm({super.key, required this.request, required this.onChanged});
|
||||||
|
|
||||||
|
final CreateAlarmRequest request;
|
||||||
|
final ValueChanged<CreateAlarmRequest> onChanged;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
switch (request.alarmType) {
|
||||||
|
case AlarmType.timeFixed:
|
||||||
|
return FixedTimeAlarmForm(
|
||||||
|
request: request as CreateFixedTimeAlarmRequest,
|
||||||
|
onChanged: onChanged,
|
||||||
|
);
|
||||||
|
|
||||||
|
case AlarmType.timeRelative:
|
||||||
|
return RelativeTimeAlarmForm(
|
||||||
|
request: request as CreateRelativeTimeAlarmRequest,
|
||||||
|
onChanged: onChanged,
|
||||||
|
);
|
||||||
|
|
||||||
|
case AlarmType.location:
|
||||||
|
return LocationAlarmForm(
|
||||||
|
request: request as CreateLocationAlarmRequest,
|
||||||
|
onChanged: onChanged,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
import '../../model/callback_models/create_alarm_request.dart';
|
||||||
|
import '../../model/callback_models/create_fixed_time_alarm_request.dart';
|
||||||
|
|
||||||
|
class FixedTimeAlarmForm extends StatelessWidget {
|
||||||
|
const FixedTimeAlarmForm({
|
||||||
|
super.key,
|
||||||
|
required this.request,
|
||||||
|
required this.onChanged,
|
||||||
|
});
|
||||||
|
final CreateFixedTimeAlarmRequest request;
|
||||||
|
final ValueChanged<CreateAlarmRequest> onChanged;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return const Placeholder();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
import '../../model/callback_models/create_alarm_request.dart';
|
||||||
|
import '../../model/callback_models/create_location_alarm_request.dart';
|
||||||
|
|
||||||
|
class LocationAlarmForm extends StatelessWidget {
|
||||||
|
const LocationAlarmForm({
|
||||||
|
super.key,
|
||||||
|
required this.request,
|
||||||
|
required this.onChanged,
|
||||||
|
});
|
||||||
|
final CreateLocationAlarmRequest request;
|
||||||
|
final ValueChanged<CreateAlarmRequest> onChanged;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return const Placeholder();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
import '../../model/callback_models/create_alarm_request.dart';
|
||||||
|
import '../../model/callback_models/create_relative_time_alarm_request.dart';
|
||||||
|
|
||||||
|
class RelativeTimeAlarmForm extends StatelessWidget {
|
||||||
|
const RelativeTimeAlarmForm({
|
||||||
|
super.key,
|
||||||
|
required this.request,
|
||||||
|
required this.onChanged,
|
||||||
|
});
|
||||||
|
final CreateRelativeTimeAlarmRequest request;
|
||||||
|
final ValueChanged<CreateAlarmRequest> onChanged;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return const Placeholder();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -12,6 +12,7 @@ class TimeSelector extends StatefulWidget {
|
|||||||
required this.dueDateController,
|
required this.dueDateController,
|
||||||
required this.dueTimeController,
|
required this.dueTimeController,
|
||||||
this.formKey,
|
this.formKey,
|
||||||
|
this.onChanged,
|
||||||
});
|
});
|
||||||
|
|
||||||
final DateTime? initialDueDateTime;
|
final DateTime? initialDueDateTime;
|
||||||
@@ -19,6 +20,7 @@ class TimeSelector extends StatefulWidget {
|
|||||||
final FocusNode? nextFocusNode;
|
final FocusNode? nextFocusNode;
|
||||||
final TextEditingController dueDateController;
|
final TextEditingController dueDateController;
|
||||||
final TextEditingController dueTimeController;
|
final TextEditingController dueTimeController;
|
||||||
|
final void Function(DateTime dateTime)? onChanged;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<TimeSelector> createState() => _TimeSelectorState();
|
State<TimeSelector> createState() => _TimeSelectorState();
|
||||||
@@ -48,7 +50,18 @@ class _TimeSelectorState extends State<TimeSelector> {
|
|||||||
child: TextFormField(
|
child: TextFormField(
|
||||||
focusNode: dueDateFocusNode,
|
focusNode: dueDateFocusNode,
|
||||||
controller: widget.dueDateController,
|
controller: widget.dueDateController,
|
||||||
onChanged: maybeEnableDueTime,
|
onChanged: (value) {
|
||||||
|
maybeEnableDueTime(value);
|
||||||
|
if (dateTimeValidator(value) == null &&
|
||||||
|
widget.onChanged != null) {
|
||||||
|
final dateTime = DateTime.tryParse(
|
||||||
|
'$value ${widget.dueTimeController.text}'.trim(),
|
||||||
|
);
|
||||||
|
if (dateTime != null) {
|
||||||
|
widget.onChanged!(dateTime);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
onFieldSubmitted: (_) {
|
onFieldSubmitted: (_) {
|
||||||
isDueTimeEnabled
|
isDueTimeEnabled
|
||||||
? dueDateFocusNode.nextFocus()
|
? dueDateFocusNode.nextFocus()
|
||||||
@@ -85,6 +98,16 @@ class _TimeSelectorState extends State<TimeSelector> {
|
|||||||
onFieldSubmitted: (_) => dueTimeFocusNode.nextFocus(),
|
onFieldSubmitted: (_) => dueTimeFocusNode.nextFocus(),
|
||||||
controller: widget.dueTimeController,
|
controller: widget.dueTimeController,
|
||||||
enabled: isDueTimeEnabled,
|
enabled: isDueTimeEnabled,
|
||||||
|
onChanged: (value) {
|
||||||
|
if (timeValidator(value) == null && widget.onChanged != null) {
|
||||||
|
final dateTime = DateTime.tryParse(
|
||||||
|
'${widget.dueDateController.text} $value'.trim(),
|
||||||
|
);
|
||||||
|
if (dateTime != null) {
|
||||||
|
widget.onChanged!(dateTime);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
label: Text('Due Time'),
|
label: Text('Due Time'),
|
||||||
suffixIcon: IconButton(
|
suffixIcon: IconButton(
|
||||||
|
|||||||
Reference in New Issue
Block a user