diff --git a/lib/components/TaskTile.dart b/lib/components/TaskTile.dart index c49ea45..f976950 100644 --- a/lib/components/TaskTile.dart +++ b/lib/components/TaskTile.dart @@ -47,10 +47,9 @@ class TaskTileState extends State { ? null : Text(_currentTask.description), trailing: IconButton( - icon: Icon(Icons.settings), - onPressed: () { - null; // TODO: implement edit task - }), + icon: Icon(Icons.settings), + onPressed: () => widget.onEdit, + ), ); } return CheckboxListTile( @@ -61,8 +60,10 @@ class TaskTileState extends State { _currentTask.description == null || _currentTask.description.isEmpty ? null : Text(_currentTask.description), - secondary: - IconButton(icon: Icon(Icons.settings), onPressed: widget.onEdit), + secondary: IconButton( + icon: Icon(Icons.settings), + onPressed: widget.onEdit, + ), onChanged: _change, ); } @@ -83,9 +84,6 @@ class TaskTileState extends State { return VikunjaGlobal.of(context).taskService.update(Task( id: task.id, done: checked, - text: task.text, - description: task.description, - owner: null, )); } } diff --git a/lib/pages/list/list.dart b/lib/pages/list/list.dart index f0a3a4e..732a9d6 100644 --- a/lib/pages/list/list.dart +++ b/lib/pages/list/list.dart @@ -7,6 +7,7 @@ import 'package:vikunja_app/global.dart'; import 'package:vikunja_app/models/list.dart'; import 'package:vikunja_app/models/task.dart'; import 'package:vikunja_app/pages/list/list_edit.dart'; +import 'package:vikunja_app/pages/list/task_edit.dart'; class ListPage extends StatefulWidget { final TaskList taskList; @@ -75,13 +76,32 @@ class _ListPageState extends State { } TaskTile _buildTile(Task task) { - return TaskTile(task: task, loading: false); + return TaskTile( + task: task, + loading: false, + onEdit: () => Navigator.push( + context, + MaterialPageRoute( + builder: (context) => TaskEditPage( + task: task, + ), + ), + ), + ); } TaskTile _buildLoadingTile(Task task) { return TaskTile( task: task, loading: true, + onEdit: () => Navigator.push( + context, + MaterialPageRoute( + builder: (context) => TaskEditPage( + task: task, + ), + ), + ), ); } @@ -109,7 +129,7 @@ class _ListPageState extends State { _addItem(String name, BuildContext context) { var globalState = VikunjaGlobal.of(context); var newTask = - Task(id: null, text: name, owner: globalState.currentUser, done: false); + Task(id: null, text: name, createdBy: globalState.currentUser, done: false); setState(() => _loadingTasks.add(newTask)); globalState.taskService.add(_list.id, newTask).then((task) { setState(() { diff --git a/lib/pages/list/task_edit.dart b/lib/pages/list/task_edit.dart new file mode 100644 index 0000000..b6466e3 --- /dev/null +++ b/lib/pages/list/task_edit.dart @@ -0,0 +1,126 @@ +import 'package:flutter/material.dart'; +import 'package:vikunja_app/global.dart'; +import 'package:vikunja_app/models/task.dart'; +import 'package:vikunja_app/theme/button.dart'; +import 'package:vikunja_app/theme/buttonText.dart'; + +class TaskEditPage extends StatefulWidget { + final Task task; + + TaskEditPage({this.task}) : super(key: Key(task.toString())); + + @override + State createState() => _TaskEditPageState(); +} + +class _TaskEditPageState extends State { + final _formKey = GlobalKey(); + bool _loading = false; + String _title, _description; + List _reminders; + + @override + Widget build(BuildContext ctx) { + return Scaffold( + appBar: AppBar( + title: Text('Edit Task'), + ), + body: Builder( + builder: (BuildContext context) => SafeArea( + child: Form( + key: _formKey, + child: ListView( + padding: const EdgeInsets.all(16.0), + children: [ + Padding( + padding: EdgeInsets.symmetric(vertical: 10.0), + child: TextFormField( + maxLines: null, + keyboardType: TextInputType.multiline, + initialValue: widget.task.text, + onSaved: (title) => _title = title, + validator: (title) { + if (title.length < 3 || title.length > 250) { + return 'The title needs to have between 3 and 250 characters.'; + } + return null; + }, + decoration: new InputDecoration( + labelText: 'Title', + border: OutlineInputBorder(), + ), + ), + ), + Padding( + padding: EdgeInsets.symmetric(vertical: 10.0), + child: TextFormField( + maxLines: null, + keyboardType: TextInputType.multiline, + initialValue: widget.task.description, + onSaved: (description) => _description = description, + validator: (description) { + if (description.length > 1000) { + return 'The description can have a maximum of 1000 characters.'; + } + return null; + }, + decoration: new InputDecoration( + labelText: 'Description', + border: OutlineInputBorder(), + ), + ), + ), + Builder( + builder: (context) => Padding( + padding: EdgeInsets.symmetric(vertical: 10.0), + child: FancyButton( + onPressed: !_loading + ? () { + if (_formKey.currentState.validate()) { + Form.of(context).save(); + _saveTask(context); + } + } + : null, + child: _loading + ? CircularProgressIndicator() + : VikunjaButtonText('Save'), + ))), + ]), + ), + ), + ), + ); + } + + _saveTask(BuildContext context) async { + setState(() => _loading = true); + // FIXME: is there a way we can update the task without creating a new task object? + // aka updating the existing task we got from context (setters?) + Task updatedTask = Task( + id: widget.task.id, + done: widget.task.done, + text: _title, + description: _description, + reminderDates: null, + createdBy: widget.task.createdBy, + ); + + VikunjaGlobal.of(context).taskService.update(updatedTask).then((_) { + setState(() => _loading = false); + Scaffold.of(context).showSnackBar(SnackBar( + content: Text('The task was updated successfully!'), + )); + }).catchError((err) { + setState(() => _loading = false); + Scaffold.of(context).showSnackBar( + SnackBar( + content: Text('Something went wrong: ' + err.toString()), + action: SnackBarAction( + label: 'CLOSE', + onPressed: Scaffold.of(context).hideCurrentSnackBar), + ), + ); + }); + } +}