List edit (#21)
the build failed Details

This commit is contained in:
konrad 2019-03-11 20:29:15 +00:00 committed by Gitea
parent d30ea0f91c
commit c285120034
9 changed files with 187 additions and 51 deletions

View File

@ -2,7 +2,7 @@ import 'dart:async';
import 'package:vikunja_app/api/client.dart';
import 'package:vikunja_app/api/service.dart';
import 'package:vikunja_app/models/task.dart';
import 'package:vikunja_app/models/list.dart';
import 'package:vikunja_app/service/services.dart';
class ListAPIService extends APIService implements ListService {
@ -40,7 +40,7 @@ class ListAPIService extends APIService implements ListService {
@override
Future<TaskList> update(TaskList tl) {
return client
.put('/lists/${tl.id}', body: tl.toJSON())
.post('/lists/${tl.id}', body: tl.toJSON())
.then((map) => TaskList.fromJson(map));
}
}

View File

@ -46,7 +46,11 @@ class TaskTileState extends State<TaskTile> {
_currentTask.description == null || _currentTask.description.isEmpty
? null
: Text(_currentTask.description),
trailing: IconButton(icon: Icon(Icons.settings), onPressed: null),
trailing: IconButton(
icon: Icon(Icons.settings),
onPressed: () {
null;
}),
);
}
return CheckboxListTile(

View File

@ -4,6 +4,7 @@ import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:vikunja_app/components/AddDialog.dart';
import 'package:vikunja_app/global.dart';
import 'package:vikunja_app/models/list.dart';
import 'package:vikunja_app/models/namespace.dart';
import 'package:vikunja_app/models/task.dart';
import 'package:vikunja_app/pages/list_page.dart';

42
lib/models/list.dart Normal file
View File

@ -0,0 +1,42 @@
import 'package:meta/meta.dart';
import 'package:vikunja_app/models/task.dart';
import 'package:vikunja_app/models/user.dart';
class TaskList {
final int id;
final String title, description;
final User owner;
final DateTime created, updated;
final List<Task> tasks;
TaskList(
{@required this.id,
@required this.title,
this.description,
this.owner,
this.created,
this.updated,
this.tasks});
TaskList.fromJson(Map<String, dynamic> json)
: id = json['id'],
owner = User.fromJson(json['owner']),
description = json['description'],
title = json['title'],
updated = DateTime.fromMillisecondsSinceEpoch(json['updated']),
created = DateTime.fromMillisecondsSinceEpoch(json['created']),
tasks = (json['tasks'] as List<dynamic>)
?.map((taskJson) => Task.fromJson(taskJson))
?.toList();
toJSON() {
return {
"id": this.id,
"title": this.title,
"description": this.description,
"owner": this.owner?.toJSON(),
"created": this.created?.millisecondsSinceEpoch,
"updated": this.updated?.millisecondsSinceEpoch,
};
}
}

View File

@ -46,41 +46,3 @@ class Task {
'createdBy': owner?.toJSON()
};
}
class TaskList {
final int id;
final String title, description;
final User owner;
final DateTime created, updated;
final List<Task> tasks;
TaskList(
{@required this.id,
@required this.title,
this.description,
this.owner,
this.created,
this.updated,
@required this.tasks});
TaskList.fromJson(Map<String, dynamic> json)
: id = json['id'],
owner = User.fromJson(json['owner']),
description = json['description'],
title = json['title'],
updated = DateTime.fromMillisecondsSinceEpoch(json['updated']),
created = DateTime.fromMillisecondsSinceEpoch(json['created']),
tasks = (json['tasks'] as List<dynamic>)
?.map((taskJson) => Task.fromJson(taskJson))
?.toList();
toJSON() {
return {
"created": this.created?.millisecondsSinceEpoch,
"updated": this.updated?.millisecondsSinceEpoch,
"id": this.id,
"title": this.title,
"owner": this.owner?.toJSON()
};
}
}

View File

@ -0,0 +1,119 @@
import 'package:flutter/material.dart';
import 'package:vikunja_app/global.dart';
import 'package:vikunja_app/models/list.dart';
class ListEditPage extends StatefulWidget {
final TaskList list;
ListEditPage({this.list}) : super(key: Key(list.toString()));
@override
State<StatefulWidget> createState() => _ListEditPageState();
}
class _ListEditPageState extends State<ListEditPage> {
final _formKey = GlobalKey<FormState>();
bool _loading = false;
String _title, _description;
@override
Widget build(BuildContext ctx) {
return Scaffold(
appBar: AppBar(
title: Text('Edit List'),
),
body: Builder(
builder: (BuildContext context) => SafeArea(
child: Form(
key: _formKey,
child: ListView(
padding: const EdgeInsets.symmetric(horizontal: 16.0),
children: <Widget>[
Padding(
padding: EdgeInsets.symmetric(vertical: 10.0),
child: TextFormField(
maxLines: null,
keyboardType: TextInputType.multiline,
initialValue: widget.list.title,
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'),
),
),
Padding(
padding: EdgeInsets.symmetric(vertical: 10.0),
child: TextFormField(
maxLines: null,
keyboardType: TextInputType.multiline,
initialValue: widget.list.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'),
),
),
Builder(
builder: (context) => RaisedButton(
padding:
EdgeInsets.symmetric(vertical: 10.0),
onPressed: !_loading
? () {
if (_formKey.currentState
.validate()) {
Form.of(context)
.save(); // Why does this not work?
_saveList(context);
} else {
print(
"sdf"); // TODO: handle error
}
}
: null,
child: _loading
? CircularProgressIndicator()
: Text('Save'),
)),
])),
)));
}
_saveList(BuildContext context) async {
setState(() => _loading = true);
// FIXME: is there a way we can update the list without creating a new list object?
// aka updating the existing list we got from context (setters?)
TaskList updatedList = TaskList(
id: widget.list.id, title: _title, description: _description);
VikunjaGlobal.of(context).listService.update(updatedList)
.then((_) {
setState(() => _loading = false);
final scaffold = Scaffold.of(context);
scaffold.showSnackBar(SnackBar(
content: Text('The list was updated successfully!'),
));
})
.catchError((err) {
setState(() => _loading = false);
final scaffold = Scaffold.of(context);
scaffold.showSnackBar(
SnackBar(
content: Text('Something went wrong: ' + err.toString()),
action: SnackBarAction(
label: 'CLOSE', onPressed: scaffold.hideCurrentSnackBar),
),
);
});
}
}

View File

@ -4,7 +4,9 @@ import 'package:flutter/material.dart';
import 'package:vikunja_app/components/AddDialog.dart';
import 'package:vikunja_app/components/TaskTile.dart';
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_edit_page.dart';
class ListPage extends StatefulWidget {
final TaskList taskList;
@ -16,13 +18,13 @@ class ListPage extends StatefulWidget {
}
class _ListPageState extends State<ListPage> {
TaskList _items;
TaskList _list;
List<Task> _loadingTasks = [];
bool _loading = true;
@override
void initState() {
_items = TaskList(
_list = TaskList(
id: widget.taskList.id, title: widget.taskList.title, tasks: []);
super.initState();
}
@ -37,12 +39,16 @@ class _ListPageState extends State<ListPage> {
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: new Text(_items.title),
title: new Text(_list.title),
actions: <Widget>[
IconButton(
icon: Icon(Icons.edit),
onPressed: () => {/* TODO add edit list functionality */},
)
icon: Icon(Icons.edit),
onPressed: () => Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ListEditPage(
list: _list,
))))
],
),
body: !this._loading
@ -62,7 +68,7 @@ class _ListPageState extends State<ListPage> {
}
List<Widget> _listTasks() {
var tasks = (_items?.tasks?.map(_buildTile) ?? []).toList();
var tasks = (_list?.tasks?.map(_buildTile) ?? []).toList();
tasks.addAll(_loadingTasks.map(_buildLoadingTile));
return tasks;
}
@ -85,7 +91,7 @@ class _ListPageState extends State<ListPage> {
.then((tasks) {
setState(() {
_loading = false;
_items = tasks;
_list = tasks;
});
});
}
@ -104,9 +110,9 @@ class _ListPageState extends State<ListPage> {
var newTask =
Task(id: null, text: name, owner: globalState.currentUser, done: false);
setState(() => _loadingTasks.add(newTask));
globalState.taskService.add(_items.id, newTask).then((task) {
globalState.taskService.add(_list.id, newTask).then((task) {
setState(() {
_items.tasks.add(task);
_list.tasks.add(task);
});
}).then((_) => _updateList()
.then((_) => setState(() => _loadingTasks.remove(newTask))));

View File

@ -1,5 +1,6 @@
import 'dart:async';
import 'package:vikunja_app/models/list.dart';
import 'package:vikunja_app/models/namespace.dart';
import 'package:vikunja_app/models/task.dart';
import 'package:vikunja_app/models/user.dart';

View File

@ -1,5 +1,6 @@
import 'dart:async';
import 'package:vikunja_app/models/list.dart';
import 'package:vikunja_app/models/namespace.dart';
import 'package:vikunja_app/models/task.dart';
import 'package:vikunja_app/models/user.dart';