1
0
mirror of https://github.com/go-vikunja/app synced 2024-05-29 00:36:49 +00:00

Compare commits

...

2 Commits

2 changed files with 144 additions and 62 deletions

View File

@ -0,0 +1,63 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_widget_from_html/flutter_widget_from_html.dart';
import '../models/task.dart';
class TaskBottomSheet extends StatefulWidget {
final Task task;
final bool showInfo;
final bool loading;
final ValueSetter<bool>? onMarkedAsDone;
const TaskBottomSheet({
Key? key,
required this.task,
this.loading = false,
this.showInfo = false,
this.onMarkedAsDone,
}) : super(key: key);
/*
@override
TaskTileState createState() {
return new TaskTileState(this.task, this.loading);
}
*/
@override
TaskBottomSheetState createState() => TaskBottomSheetState(this.task);
}
class TaskBottomSheetState extends State<TaskBottomSheet> {
Task _currentTask;
TaskBottomSheetState(this._currentTask);
@override
Widget build(BuildContext context) {
return Container(
height: MediaQuery.of(context).size.height * 0.9,
child: Center(
child: Padding(
padding: EdgeInsets.fromLTRB(10, 10, 10, 10),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
mainAxisSize: MainAxisSize.max,
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(_currentTask.title),
BackButton(),
],
),
HtmlWidget(_currentTask.description),
],
),
)
),
);
}
}

View File

@ -3,6 +3,7 @@ import 'dart:async';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_widget_from_html/flutter_widget_from_html.dart'; import 'package:flutter_widget_from_html/flutter_widget_from_html.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:vikunja_app/components/TaskBottomSheet.dart';
import 'package:vikunja_app/models/task.dart'; import 'package:vikunja_app/models/task.dart';
import 'package:vikunja_app/utils/misc.dart'; import 'package:vikunja_app/utils/misc.dart';
import 'package:vikunja_app/pages/list/task_edit.dart'; import 'package:vikunja_app/pages/list/task_edit.dart';
@ -32,30 +33,35 @@ class TaskTile extends StatefulWidget {
} }
*/ */
@override @override
TaskTileState createState() => TaskTileState(this.task); TaskTileState createState() => TaskTileState(this.task);
} }
Widget? _buildTaskSubtitle(Task? task, bool showInfo) { Widget? _buildTaskSubtitle(Task? task, bool showInfo, BuildContext context) {
Duration? durationUntilDue = task?.dueDate?.difference(DateTime.now()); Duration? durationUntilDue = task?.dueDate?.difference(DateTime.now());
if(task == null) if (task == null) return null;
return null;
List<TextSpan> texts = []; List<TextSpan> texts = [];
if(showInfo && task.hasDueDate) { if (showInfo && task.hasDueDate) {
texts.add(TextSpan(text: "Due " + durationToHumanReadable(durationUntilDue!), style: durationUntilDue.isNegative ? TextStyle(color: Colors.red) : null)); texts.add(TextSpan(
text: "Due " + durationToHumanReadable(durationUntilDue!),
style: durationUntilDue.isNegative
? TextStyle(color: Colors.red)
: Theme.of(context).textTheme.bodyMedium));
} }
if(task.priority != null && task.priority != 0) { if (task.priority != null && task.priority != 0) {
texts.add(TextSpan(text: " !" + priorityToString(task.priority), style: TextStyle(color: Colors.orange))); texts.add(TextSpan(
text: " !" + priorityToString(task.priority),
style: TextStyle(color: Colors.orange)));
} }
//if(texts.isEmpty && task.description.isNotEmpty) { //if(texts.isEmpty && task.description.isNotEmpty) {
// return HtmlWidget(task.description); // return HtmlWidget(task.description);
// } // }
if(texts.isNotEmpty) { if (texts.isNotEmpty) {
return RichText(text: TextSpan(children: texts)); return RichText(text: TextSpan(children: texts));
} }
return null; return null;
@ -82,59 +88,73 @@ class TaskTileState extends State<TaskTile> with AutomaticKeepAliveClientMixin {
)), )),
), ),
title: Text(_currentTask.title), title: Text(_currentTask.title),
subtitle: subtitle: _currentTask.description.isEmpty
_currentTask.description.isEmpty ? null
? null : HtmlWidget(_currentTask.description),
: HtmlWidget(_currentTask.description),
trailing: IconButton( trailing: IconButton(
icon: Icon(Icons.settings), onPressed: () { }, icon: Icon(Icons.settings),
), onPressed: () {},
),
); );
} }
return return IntrinsicHeight(
IntrinsicHeight(child: child: Row(crossAxisAlignment: CrossAxisAlignment.stretch, children: [
Row( Container(
crossAxisAlignment: CrossAxisAlignment.stretch, width: 4.0, // Adjust the width of the red line
children: [ color: widget.task.color,
Container( //margin: EdgeInsets.only(left: 10.0),
width: 4.0, // Adjust the width of the red line ),
color: widget.task.color, Flexible(
//margin: EdgeInsets.only(left: 10.0), child: ListTile(
), onTap: () {
Flexible(child: CheckboxListTile( showModalBottomSheet<void>(
title: widget.showInfo ? context: context,
RichText( builder: (BuildContext context) {
text: TextSpan( return TaskBottomSheet(task: widget.task);
text: null, });
children: <TextSpan> [ },
// TODO: get list name of task title: widget.showInfo
//TextSpan(text: widget.task.list.title+" - ", style: TextStyle(color: Colors.grey)), ? RichText(
TextSpan(text: widget.task.title), text: TextSpan(
], text: null,
style: TextStyle( children: <TextSpan>[
color: Theme.of(context).brightness == Brightness.dark ? Colors.white : Colors.black, // TODO: get list name of task
), //TextSpan(text: widget.task.list.title+" - ", style: TextStyle(color: Colors.grey)),
) TextSpan(text: widget.task.title),
) : Text(_currentTask.title), ],
controlAffinity: ListTileControlAffinity.leading, style: TextStyle(
value: _currentTask.done, color: Theme.of(context).brightness == Brightness.dark
subtitle: _buildTaskSubtitle(widget.task, widget.showInfo), ? Colors.white
secondary: : Colors.black,
IconButton(icon: Icon(Icons.settings), onPressed: () {
Navigator.push<Task>(
context,
MaterialPageRoute(
builder: (buildContext) => TaskEditPage(
task: _currentTask,
taskState: taskState,
), ),
), ))
).then((task) => setState(() { : Text(_currentTask.title),
if (task != null) _currentTask = task; subtitle: _buildTaskSubtitle(widget.task, widget.showInfo, context),
})).whenComplete(() => widget.onEdit()); leading: Checkbox(
}), value: _currentTask.done,
onChanged: _change, onChanged: (bool? newValue) {
))])); _change(newValue);
},
),
trailing: IconButton(
icon: Icon(Icons.settings),
onPressed: () {
Navigator.push<Task>(
context,
MaterialPageRoute(
builder: (buildContext) => TaskEditPage(
task: _currentTask,
taskState: taskState,
),
),
)
.then((task) => setState(() {
if (task != null) _currentTask = task;
}))
.whenComplete(() => widget.onEdit());
}),
))
]));
} }
void _change(bool? value) async { void _change(bool? value) async {
@ -144,8 +164,7 @@ class TaskTileState extends State<TaskTile> with AutomaticKeepAliveClientMixin {
}); });
Task? newTask = await _updateTask(_currentTask, value); Task? newTask = await _updateTask(_currentTask, value);
setState(() { setState(() {
if(newTask != null) if (newTask != null) this._currentTask = newTask;
this._currentTask = newTask;
this._currentTask.loading = false; this._currentTask.loading = false;
}); });
widget.onEdit(); widget.onEdit();