import 'package:date_field/date_field.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:nextcloud_reminder/repeating_task.dart'; import 'package:nextcloud_reminder/types/repeat.dart'; import 'package:nextcloud_reminder/types/tasks.dart'; import 'package:tuple/tuple.dart'; class AddTaskWidget extends StatefulWidget { const AddTaskWidget({super.key, this.restorationId, required this.onSave}); final ValueChanged onSave; final String? restorationId; @override State createState() => _AddTaskWidgetState(); } //TODO: make _repeat changeable. class _AddTaskWidgetState extends State { final _formKey = GlobalKey(); final _titleController = TextEditingController(); static _emptyRepetition() { return Tuple2(TextEditingController(text: "1"), ValueNotifier(DateInterval.daily)); } final List>> _repeatEveryController = [_emptyRepetition()]; DateTime _beginDate = DateTime.now(); @override void dispose() { _titleController.dispose(); super.dispose(); } String _prettyInterval(DateInterval d) { switch (d) { default: return d.toString(); } } Widget _repeatBuilder(BuildContext context, Tuple2> data) { return Row( children: [ Text("Repeat every " ), Expanded( flex: 1, child: TextFormField( controller: data.item1, decoration: const InputDecoration( hintText: "1", ), keyboardType: const TextInputType.numberWithOptions(signed: false, decimal: false), inputFormatters: [FilteringTextInputFormatter.digitsOnly], ), ), Expanded( flex: 3, child: DropdownButton( items: DateInterval.values.map((v) => DropdownMenuItem(value: v, child: Text(_prettyInterval(v)))).toList(), onChanged: (v) => setState(() { data.item2.value = v ?? data.item2.value; }), value: data.item2.value, ), ), IconButton(onPressed: () => setState(() { _repeatEveryController.remove(data); }), icon: Icon(Icons.remove, color: Theme.of(context).errorColor,)), ], ); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text('Add new repeating Task') ), body: Form( key: _formKey, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ TextFormField( // The validator receives the text that the user has entered. validator: (value) { if (value == null || value.isEmpty) { return 'Please enter a name'; } return null; }, controller: _titleController, decoration: const InputDecoration( labelText: "Taskname" ), ), DateTimeField( onDateSelected: (v) => setState(() { _beginDate = v; }), selectedDate: _beginDate, decoration: const InputDecoration( suffixIcon: Icon(Icons.event_note), labelText: "Begin" ), mode: DateTimeFieldPickerMode.date, ), ] + _repeatEveryController.map((c) => _repeatBuilder(context,c)).toList() + [ ElevatedButton(onPressed: () => setState(() { _repeatEveryController.add(_emptyRepetition()); }), child: const Text("add repetition")), Padding( padding: const EdgeInsets.symmetric(vertical: 16.0), child: ElevatedButton( onPressed: () { // Validate returns true if the form is valid, or false otherwise. if (_formKey.currentState!.validate()) { // If the form is valid, display a snackbar. In the real world, // you'd often call a server or save the information in a database. ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text('Task added.')), ); var repeats = _repeatEveryController.map((e) => RepeatInterval(interval: e.item2.value, every: int.parse(e.item1.text))).toList(); var meta = repeats.map((e) => e.toString()).join("/"); widget.onSave(RepeatingTask( task: TaskExtra( title: _titleController.text, begin: _beginDate, meta: {"repeat": meta}, repeat: repeats, ) )); Navigator.pop(context); } }, child: const Text('Submit'), ), ), ], ), ) ); } }