mirror of
https://github.com/go-vikunja/app
synced 2024-06-08 13:39:47 +00:00
further improved landing page. always sets due date. shows due date in list.
This commit is contained in:
parent
644ebbd13f
commit
0277af9b6c
|
@ -1,24 +1,49 @@
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
class AddDialog extends StatelessWidget {
|
import '../models/task.dart';
|
||||||
final ValueChanged<String> onAdd;
|
|
||||||
final InputDecoration decoration;
|
|
||||||
|
|
||||||
const AddDialog({Key key, this.onAdd, this.decoration}) : super(key: key);
|
enum NewTaskDue {day,week, month}
|
||||||
|
Map<NewTaskDue, Duration> newTaskDueToDuration = {
|
||||||
|
NewTaskDue.day: Duration(days: 1),
|
||||||
|
NewTaskDue.week: Duration(days: 7),
|
||||||
|
NewTaskDue.month: Duration(days: 30),
|
||||||
|
};
|
||||||
|
|
||||||
|
class AddDialog extends StatefulWidget {
|
||||||
|
final ValueChanged<String> onAdd;
|
||||||
|
final ValueChanged<Task> onAddTask;
|
||||||
|
final InputDecoration decoration;
|
||||||
|
const AddDialog({Key key, this.onAdd, this.decoration, this.onAddTask}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<StatefulWidget> createState() => AddDialogState();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
class AddDialogState extends State<AddDialog> {
|
||||||
|
NewTaskDue newTaskDue = NewTaskDue.day;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
var textController = TextEditingController();
|
var textController = TextEditingController();
|
||||||
return new AlertDialog(
|
return new AlertDialog(
|
||||||
contentPadding: const EdgeInsets.all(16.0),
|
contentPadding: const EdgeInsets.all(16.0),
|
||||||
content: new Row(children: <Widget>[
|
content: new Column(
|
||||||
Expanded(
|
mainAxisSize: MainAxisSize.min,
|
||||||
child: new TextField(
|
children: [
|
||||||
autofocus: true,
|
Row(children: <Widget>[
|
||||||
decoration: this.decoration,
|
Expanded(
|
||||||
controller: textController,
|
child: new TextField(
|
||||||
|
autofocus: true,
|
||||||
|
decoration: widget.decoration,
|
||||||
|
controller: textController,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
)
|
]),
|
||||||
|
widget.onAddTask != null ? taskDueList("1 Day", NewTaskDue.day) : new Container(),
|
||||||
|
widget.onAddTask != null ? taskDueList("1 Week", NewTaskDue.week) : new Container(),
|
||||||
|
widget.onAddTask != null ? taskDueList("1 Month", NewTaskDue.month) : new Container(),
|
||||||
|
//],)
|
||||||
]),
|
]),
|
||||||
actions: <Widget>[
|
actions: <Widget>[
|
||||||
new TextButton(
|
new TextButton(
|
||||||
|
@ -28,12 +53,33 @@ class AddDialog extends StatelessWidget {
|
||||||
new TextButton(
|
new TextButton(
|
||||||
child: const Text('ADD'),
|
child: const Text('ADD'),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
if (this.onAdd != null && textController.text.isNotEmpty)
|
if (widget.onAdd != null && textController.text.isNotEmpty)
|
||||||
this.onAdd(textController.text);
|
widget.onAdd(textController.text);
|
||||||
|
if(widget.onAddTask != null && textController.text.isNotEmpty)
|
||||||
|
widget.onAddTask(Task(id: null, title: textController.text, done: false, owner: null, due: DateTime.now().add(newTaskDueToDuration[newTaskDue])));
|
||||||
Navigator.pop(context);
|
Navigator.pop(context);
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Widget taskDueList(String name, NewTaskDue thisNewTaskDue) {
|
||||||
|
// TODO: I know you can do better
|
||||||
|
return Row(children: [
|
||||||
|
Checkbox(value: newTaskDue == thisNewTaskDue, onChanged: (value) { setState(() => newTaskDue = value ? thisNewTaskDue: newTaskDue);}, shape: CircleBorder(),),
|
||||||
|
Text(name),
|
||||||
|
]);
|
||||||
|
/*Row(children: [
|
||||||
|
Checkbox(value: newTaskDue == NewTaskDue.week, onChanged: (value) { setState(() => newTaskDue = value ? NewTaskDue.week: newTaskDue);}, shape: CircleBorder(),),
|
||||||
|
Text("1 Week"),
|
||||||
|
]),
|
||||||
|
Row(children: [
|
||||||
|
Checkbox(value: newTaskDue == NewTaskDue.month, onChanged: (value) { setState(() => newTaskDue = value ? NewTaskDue.month: newTaskDue);}, shape: CircleBorder(),),
|
||||||
|
Text("1 Month"),
|
||||||
|
])
|
||||||
|
];
|
||||||
|
|
||||||
|
*/
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@ import 'package:flutter/material.dart';
|
||||||
import 'package:vikunja_app/global.dart';
|
import 'package:vikunja_app/global.dart';
|
||||||
import 'package:vikunja_app/models/task.dart';
|
import 'package:vikunja_app/models/task.dart';
|
||||||
import 'package:vikunja_app/pages/task/edit_task.dart';
|
import 'package:vikunja_app/pages/task/edit_task.dart';
|
||||||
|
import 'package:vikunja_app/utils/misc.dart';
|
||||||
|
|
||||||
class TaskTile extends StatefulWidget {
|
class TaskTile extends StatefulWidget {
|
||||||
final Task task;
|
final Task task;
|
||||||
|
@ -34,6 +35,7 @@ class TaskTileState extends State<TaskTile> {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
Duration durationUntilDue = _currentTask.due.difference(DateTime.now());
|
||||||
if (_currentTask.loading) {
|
if (_currentTask.loading) {
|
||||||
return ListTile(
|
return ListTile(
|
||||||
leading: Padding(
|
leading: Padding(
|
||||||
|
@ -69,7 +71,7 @@ class TaskTileState extends State<TaskTile> {
|
||||||
controlAffinity: ListTileControlAffinity.leading,
|
controlAffinity: ListTileControlAffinity.leading,
|
||||||
value: _currentTask.done ?? false,
|
value: _currentTask.done ?? false,
|
||||||
subtitle: widget.showInfo && _currentTask.due.year > 2 ?
|
subtitle: widget.showInfo && _currentTask.due.year > 2 ?
|
||||||
Text("Due in " + _currentTask.due.difference(DateTime.now()).inDays.toString() + " days.")
|
Text("Due in " + durationToHumanReadable(durationUntilDue),style: TextStyle(color: durationUntilDue.isNegative ? Colors.red : null),)
|
||||||
: _currentTask.description == null || _currentTask.description.isEmpty
|
: _currentTask.description == null || _currentTask.description.isEmpty
|
||||||
? null
|
? null
|
||||||
: Text(_currentTask.description),
|
: Text(_currentTask.description),
|
||||||
|
|
|
@ -47,7 +47,7 @@ class Task {
|
||||||
'created': created?.toIso8601String(),
|
'created': created?.toIso8601String(),
|
||||||
'reminder_dates':
|
'reminder_dates':
|
||||||
reminders?.map((date) => date.toIso8601String())?.toList(),
|
reminders?.map((date) => date.toIso8601String())?.toList(),
|
||||||
'due_date': due?.toIso8601String(),
|
'due_date': due.toUtc()?.toIso8601String(),
|
||||||
'description': description,
|
'description': description,
|
||||||
'title': title,
|
'title': title,
|
||||||
'done': done ?? false,
|
'done': done ?? false,
|
||||||
|
|
|
@ -15,9 +15,9 @@ class User {
|
||||||
|
|
||||||
String avatarUrl(BuildContext context) {
|
String avatarUrl(BuildContext context) {
|
||||||
return VikunjaGlobal.of(context).client.base +
|
return VikunjaGlobal.of(context).client.base +
|
||||||
"/" +
|
"/avatar/ " +
|
||||||
this.username +
|
this.username+
|
||||||
"/avatar";
|
"?size=50";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -72,16 +72,14 @@ class LandingPageState extends State<LandingPage> {
|
||||||
showDialog(
|
showDialog(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (_) => AddDialog(
|
builder: (_) => AddDialog(
|
||||||
onAdd: (name) => _addItem(name, context),
|
onAddTask: (task) => _addTask(task, context),
|
||||||
decoration: new InputDecoration(
|
decoration: new InputDecoration(
|
||||||
labelText: 'Task Name', hintText: 'eg. Milk')));
|
labelText: 'Task Name', hintText: 'eg. Milk')));
|
||||||
}
|
}
|
||||||
|
|
||||||
_addItem(String name, BuildContext context) {
|
_addTask(Task task, BuildContext context) {
|
||||||
var globalState = VikunjaGlobal.of(context);
|
var globalState = VikunjaGlobal.of(context);
|
||||||
var newTask = Task(
|
globalState.taskService.add(defaultList, task).then((_) {
|
||||||
id: null, title: name, owner: globalState.currentUser, done: false, loading: true);
|
|
||||||
globalState.taskService.add(defaultList, newTask).then((_) {
|
|
||||||
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
|
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
|
||||||
content: Text('The task was added successfully!'),
|
content: Text('The task was added successfully!'),
|
||||||
));
|
));
|
||||||
|
|
|
@ -62,7 +62,6 @@ class TaskServiceOptions {
|
||||||
|
|
||||||
if(result.startsWith('&'))
|
if(result.startsWith('&'))
|
||||||
result.substring(1);
|
result.substring(1);
|
||||||
log(result);
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
11
lib/utils/misc.dart
Normal file
11
lib/utils/misc.dart
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
String durationToHumanReadable(Duration dur) {
|
||||||
|
if(dur.inDays.abs() > 1)
|
||||||
|
return dur.inDays.toString() + " days";
|
||||||
|
if(dur.inDays.abs() == 1)
|
||||||
|
return dur.inDays.toString() + " day";
|
||||||
|
if(dur.inHours.abs() > 1)
|
||||||
|
return dur.inHours.toString() + " hours";
|
||||||
|
if(dur.inHours.abs() == 1)
|
||||||
|
return dur.inHours.toString() + "1 hour";
|
||||||
|
return "under 1 hour";
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user