Ported working the Edit Task dialog
This commit is contained in:
parent
74f7756626
commit
21ef483c32
|
@ -22,18 +22,20 @@ class ListAPIService extends APIService implements ListService {
|
|||
|
||||
@override
|
||||
Future<TaskList> get(int listId) {
|
||||
/*
|
||||
return client
|
||||
.get('/lists/$listId')
|
||||
.then((response) => TaskList.fromJson(response.body));
|
||||
/*
|
||||
return client.get('/lists/$listId').then((map) {
|
||||
*/
|
||||
return client.get('/lists/$listId').then((response) {
|
||||
final map = response.body;
|
||||
if (map.containsKey('id')) {
|
||||
return client.get("/lists/$listId/tasks").then((tasks) => TaskList.fromJson(
|
||||
map, tasksJson: tasks));
|
||||
return client.get("/lists/$listId/tasks")
|
||||
.then((tasks) => TaskList.fromJson(
|
||||
map, tasksJson: tasks.body));
|
||||
}
|
||||
return TaskList.fromJson(map);
|
||||
});
|
||||
*/
|
||||
}
|
||||
|
||||
@override
|
||||
|
|
|
@ -26,8 +26,8 @@ class Label {
|
|||
color = json['hex_color'] == ''
|
||||
? null
|
||||
: new Color(int.parse(json['hex_color'], radix: 16) + 0xFF000000),
|
||||
updated = DateTime.fromMillisecondsSinceEpoch(json['updated']),
|
||||
created = DateTime.fromMillisecondsSinceEpoch(json['created']),
|
||||
updated = DateTime.parse(json['updated']),
|
||||
created = DateTime.parse(json['created']),
|
||||
createdBy = User.fromJson(json['created_by']);
|
||||
|
||||
toJSON() => {
|
||||
|
|
|
@ -40,16 +40,16 @@ class Task {
|
|||
title = json['title'],
|
||||
description = json['description'],
|
||||
done = json['done'],
|
||||
reminderDates = (json['reminderDates'] as List<dynamic>)
|
||||
?.map((ts) => dateTimeFromUnixTimestamp(ts))
|
||||
reminderDates = (json['reminder_dates'] as List<dynamic>)
|
||||
?.map((ts) => DateTime.parse(ts))
|
||||
?.cast<DateTime>()
|
||||
?.toList(),
|
||||
dueDate = dateTimeFromUnixTimestamp(json['dueDate']),
|
||||
startDate = dateTimeFromUnixTimestamp(json['startDate']),
|
||||
endDate = dateTimeFromUnixTimestamp(json['endDate']),
|
||||
parentTaskId = json['parentTaskID'],
|
||||
dueDate = DateTime.parse(json['due_date']),
|
||||
startDate = DateTime.parse(json['start_date']),
|
||||
endDate = DateTime.parse(json['end_date']),
|
||||
parentTaskId = json['parent_task_id'],
|
||||
priority = json['priority'],
|
||||
repeatAfter = Duration(seconds: json['repeatAfter']),
|
||||
repeatAfter = Duration(seconds: json['repeat_after']),
|
||||
labels = (json['labels'] as List<dynamic>)
|
||||
?.map((label) => Label.fromJson(label))
|
||||
?.cast<Label>()
|
||||
|
@ -58,9 +58,9 @@ class Task {
|
|||
?.map((subtask) => Task.fromJson(subtask))
|
||||
?.cast<Task>()
|
||||
?.toList(),
|
||||
updated = dateTimeFromUnixTimestamp(json['updated']),
|
||||
created = dateTimeFromUnixTimestamp(json['created']),
|
||||
createdBy = User.fromJson(json['createdBy']);
|
||||
updated = DateTime.parse(json['updated']),
|
||||
created = DateTime.parse(json['created']),
|
||||
createdBy = User.fromJson(json['created_by']);
|
||||
|
||||
toJSON() => {
|
||||
'id': id,
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import 'dart:async';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:vikunja_app/components/AddDialog.dart';
|
||||
import 'package:vikunja_app/components/TaskTile.dart';
|
||||
import 'package:vikunja_app/global.dart';
|
||||
|
@ -9,7 +8,6 @@ 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';
|
||||
import 'package:vikunja_app/stores/list_store.dart';
|
||||
|
||||
class ListPage extends StatefulWidget {
|
||||
final TaskList taskList;
|
||||
|
@ -22,10 +20,8 @@ class ListPage extends StatefulWidget {
|
|||
|
||||
class _ListPageState extends State<ListPage> {
|
||||
TaskList _list;
|
||||
List<Task> _tasks = [];
|
||||
List<Task> _loadingTasks = [];
|
||||
bool _loading = true;
|
||||
int _currentPage = 1;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
|
@ -48,65 +44,44 @@ class _ListPageState extends State<ListPage> {
|
|||
var tasks = (_list?.tasks?.map(_buildTile) ?? []).toList();
|
||||
tasks.addAll(_loadingTasks.map(_buildLoadingTile));
|
||||
|
||||
final taskState = Provider.of<ListProvider>(context);
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text(_list.title),
|
||||
actions: <Widget>[
|
||||
IconButton(
|
||||
icon: Icon(Icons.edit),
|
||||
onPressed: () => Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) => ListEditPage(
|
||||
list: _list,
|
||||
)
|
||||
)
|
||||
appBar: AppBar(
|
||||
title: Text(_list.title),
|
||||
actions: <Widget>[
|
||||
IconButton(
|
||||
icon: Icon(Icons.edit),
|
||||
onPressed: () => Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) => ListEditPage(
|
||||
list: _list,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
body: !taskState.isLoading
|
||||
? RefreshIndicator(
|
||||
child: taskState.tasks.length > 0
|
||||
? ListView.builder(
|
||||
padding: EdgeInsets.symmetric(vertical: 8.0),
|
||||
// children: ListTile.divideTiles(context: context, tiles: _listTasks()).toList(),
|
||||
itemBuilder: (context, i) {
|
||||
if (i.isOdd) return Divider();
|
||||
|
||||
final index = i ~/ 2;
|
||||
|
||||
// This handles the case if there are no more elements in the list left which can be provided by the api
|
||||
if (taskState.maxPages == _currentPage &&
|
||||
index == taskState.tasks.length - 1) return null;
|
||||
|
||||
if (index >= taskState.tasks.length &&
|
||||
_currentPage < taskState.maxPages) {
|
||||
_currentPage++;
|
||||
_loadTasksForPage(_currentPage);
|
||||
}
|
||||
return index < taskState.tasks.length
|
||||
? TaskTile(
|
||||
task: taskState.tasks[index],
|
||||
)
|
||||
: null;
|
||||
})
|
||||
: Center(child: Text('This list is empty.')),
|
||||
onRefresh: _loadList,
|
||||
)
|
||||
: Center(child: CircularProgressIndicator()),
|
||||
floatingActionButton: Builder(
|
||||
builder: (context) => FloatingActionButton(
|
||||
onPressed: () => _addItemDialog(context), child: Icon(Icons.add),
|
||||
),
|
||||
),
|
||||
));
|
||||
}
|
||||
|
||||
List<Widget> _listTasks() {
|
||||
var tasks = (_tasks?.map(_buildTile) ?? []).toList();
|
||||
tasks.addAll(_loadingTasks.map(_buildLoadingTile));
|
||||
return tasks;
|
||||
],
|
||||
),
|
||||
body: !this._loading
|
||||
? RefreshIndicator(
|
||||
onRefresh: _loadList,
|
||||
child: _list.tasks.length > 0
|
||||
? ListView(
|
||||
padding: EdgeInsets.symmetric(vertical: 8.0),
|
||||
children: ListTile.divideTiles(
|
||||
context: context,
|
||||
tiles: tasks,
|
||||
).toList(),
|
||||
)
|
||||
: Center(child: Text('This list is empty.')),
|
||||
)
|
||||
: Center(child: CircularProgressIndicator()),
|
||||
floatingActionButton: Builder(
|
||||
builder: (context) => FloatingActionButton(
|
||||
onPressed: () => _addItemDialog(context),
|
||||
child: Icon(Icons.add),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
TaskTile _buildTile(Task task) {
|
||||
|
@ -127,16 +102,17 @@ class _ListPageState extends State<ListPage> {
|
|||
.update(Task(
|
||||
id: task.id,
|
||||
done: done,
|
||||
))
|
||||
.then((newTask) => setState(() {
|
||||
// FIXME: This is ugly. We should use a redux to not have to do these kind of things.
|
||||
// This is enough for now (it works™) but we should definitly fix it later.
|
||||
_list.tasks.asMap().forEach((i, t) {
|
||||
if (newTask.id == t.id) {
|
||||
_list.tasks[i] = newTask;
|
||||
}
|
||||
});
|
||||
}));
|
||||
)
|
||||
).then((newTask) => setState(() {
|
||||
// FIXME: This is ugly. We should use a redux to not have to do these kind of things.
|
||||
// This is enough for now (it works™) but we should definitly fix it later.
|
||||
_list.tasks.asMap().forEach((i, t) {
|
||||
if (newTask.id == t.id) {
|
||||
_list.tasks[i] = newTask;
|
||||
}
|
||||
});
|
||||
})
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
@ -145,53 +121,39 @@ class _ListPageState extends State<ListPage> {
|
|||
return TaskTile(
|
||||
task: task,
|
||||
loading: true,
|
||||
onEdit: () => Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) => TaskEditPage(
|
||||
task: task,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void _loadTasksForPage(int page) {
|
||||
Provider.of<ListProvider>(context, listen: false).loadTasks(
|
||||
context: context,
|
||||
listId: _list.id,
|
||||
page: page,
|
||||
);
|
||||
}
|
||||
|
||||
// Future<void> _loadTasksForPage(int page) {
|
||||
// return VikunjaGlobal.of(context).taskService.getAll(_list.id, {
|
||||
// "sort_by": ["done", "id"],
|
||||
// "order_by": ["asc", "desc"],
|
||||
// "page": [page.toString()]
|
||||
// }).then((tasks) {
|
||||
// setState(() {
|
||||
// _loading = false;
|
||||
// _tasks.addAll(tasks);
|
||||
// });
|
||||
// });
|
||||
// }
|
||||
|
||||
Future<void> _loadList() {
|
||||
return VikunjaGlobal.of(context)
|
||||
.listService
|
||||
.get(widget.taskList.id)
|
||||
.then((list) {
|
||||
setState(() {
|
||||
_loading = true;
|
||||
_loading = false;
|
||||
_list = list;
|
||||
});
|
||||
_loadTasksForPage(_currentPage);
|
||||
});
|
||||
}
|
||||
|
||||
_addItemDialog(BuildContext context) {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (_) => AddDialog(
|
||||
onAdd: (title) => _addItem(title, context),
|
||||
decoration: InputDecoration(
|
||||
labelText: 'Task Name',
|
||||
hintText: 'eg. Milk',
|
||||
),
|
||||
),
|
||||
context: context,
|
||||
builder: (_) => AddDialog(
|
||||
onAdd: (name) => _addItem(name, context),
|
||||
decoration: new InputDecoration(
|
||||
labelText: 'Task Name',
|
||||
hintText: 'eg. Milk',
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -207,7 +169,7 @@ class _ListPageState extends State<ListPage> {
|
|||
setState(() => _loadingTasks.add(newTask));
|
||||
globalState.taskService.add(_list.id, newTask).then((task) {
|
||||
setState(() {
|
||||
_tasks.add(task);
|
||||
_list.tasks.add(task);
|
||||
});
|
||||
}).then((_) {
|
||||
_loadList();
|
||||
|
@ -217,12 +179,4 @@ class _ListPageState extends State<ListPage> {
|
|||
));
|
||||
});
|
||||
}
|
||||
|
||||
Future<Task> _updateTask(Task task, bool checked) {
|
||||
// TODO use copyFrom
|
||||
return VikunjaGlobal.of(context).taskService.update(Task(
|
||||
id: task.id,
|
||||
done: checked,
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -30,14 +30,14 @@ class _TaskEditPageState extends State<TaskEditPage> {
|
|||
List<Label> _labels;
|
||||
List<Label>
|
||||
_suggestedLabels; // we use this to find the label object after a user taps on the suggestion, because the typeahead only uses strings, not full objects.
|
||||
var _reminderInputs = new List<Widget>();
|
||||
var _reminderInputs = <Widget>[];
|
||||
final _labelTypeAheadController = TextEditingController();
|
||||
|
||||
@override
|
||||
Widget build(BuildContext ctx) {
|
||||
// This builds the initial list of reminder inputs only once.
|
||||
if (_reminderDates == null) {
|
||||
_reminderDates = widget.task.reminderDates ?? new List();
|
||||
_reminderDates = widget.task.reminderDates ?? [];
|
||||
|
||||
_reminderDates?.asMap()?.forEach((i, time) =>
|
||||
setState(() => _reminderInputs?.add(VikunjaDateTimePicker(
|
||||
|
@ -48,7 +48,7 @@ class _TaskEditPageState extends State<TaskEditPage> {
|
|||
}
|
||||
|
||||
if (_labels == null) {
|
||||
_labels = widget.task.labels ?? new List();
|
||||
_labels = widget.task.labels ?? [];
|
||||
}
|
||||
|
||||
return Scaffold(
|
||||
|
@ -59,8 +59,7 @@ class _TaskEditPageState extends State<TaskEditPage> {
|
|||
builder: (BuildContext context) => SafeArea(
|
||||
child: Form(
|
||||
key: _formKey,
|
||||
child: ListView(padding: const EdgeInsets.all(16.0), children: <
|
||||
Widget>[
|
||||
child: ListView(padding: const EdgeInsets.all(16.0), children: <Widget>[
|
||||
Padding(
|
||||
padding: EdgeInsets.symmetric(vertical: 10.0),
|
||||
child: TextFormField(
|
||||
|
@ -321,7 +320,7 @@ class _TaskEditPageState extends State<TaskEditPage> {
|
|||
.update(updatedTask, _labels)
|
||||
.catchError((err) {
|
||||
setState(() => _loading = false);
|
||||
Scaffold.of(context).showSnackBar(
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text('Something went wrong: ' + err.toString()),
|
||||
),
|
||||
|
@ -330,17 +329,17 @@ class _TaskEditPageState extends State<TaskEditPage> {
|
|||
|
||||
VikunjaGlobal.of(context).taskService.update(updatedTask).then((_) {
|
||||
setState(() => _loading = false);
|
||||
Scaffold.of(context).showSnackBar(SnackBar(
|
||||
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
|
||||
content: Text('The task was updated successfully!'),
|
||||
));
|
||||
}).catchError((err) {
|
||||
setState(() => _loading = false);
|
||||
Scaffold.of(context).showSnackBar(
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text('Something went wrong: ' + err.toString()),
|
||||
action: SnackBarAction(
|
||||
label: 'CLOSE',
|
||||
onPressed: Scaffold.of(context).hideCurrentSnackBar),
|
||||
onPressed: ScaffoldMessenger.of(context).hideCurrentSnackBar),
|
||||
),
|
||||
);
|
||||
});
|
||||
|
|
Reference in New Issue