Skip to content

Commit

Permalink
feat(wip, broken): task progress
Browse files Browse the repository at this point in the history
  • Loading branch information
orl0pl committed Nov 23, 2024
1 parent 7cb8bf5 commit d3ad40f
Show file tree
Hide file tree
Showing 6 changed files with 255 additions and 39 deletions.
1 change: 1 addition & 0 deletions l10n.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ arb-dir: lib/l10n
template-arb-file: app_en.arb
output-localization-file: app_localizations.dart
nullable-getter: false
untranslated-messages-file: lib/l10n/untranslated_messages.txt
4 changes: 4 additions & 0 deletions lib/l10n/app_en.arb
Original file line number Diff line number Diff line change
Expand Up @@ -408,6 +408,10 @@
"other": "Other",
"mark_as_done": "Mark as done",
"mark_as_not_done": "Mark as not done",
"marked_as_done": "Marked as done",
"@marked_as_done": {},
"marked_as_not_done": "Marked as not done",
"@marked_as_not_done": {},
"@attachment_not_picked": {},
"@change_attachment": {},
"@image": {},
Expand Down
17 changes: 17 additions & 0 deletions lib/l10n/untranslated_messages.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"pl": [
"add_attachment",
"pick_attachment",
"attachment_not_picked",
"change_attachment",
"image",
"video",
"audio",
"document",
"other",
"mark_as_done",
"mark_as_not_done",
"marked_as_done",
"marked_as_not_done"
]
}
214 changes: 214 additions & 0 deletions lib/screens/progress.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,214 @@
import 'dart:math';

import 'package:flutter/material.dart';
import 'package:flutter_material_design_icons/flutter_material_design_icons.dart';
import 'package:intl/intl.dart';
import 'package:maximum/data/database_helper.dart';
import 'package:maximum/data/models/place.dart';
import 'package:maximum/data/models/repeat_data.dart';
import 'package:maximum/data/models/tags.dart';
import 'package:maximum/data/models/task.dart';
import 'package:maximum/data/models/task_status.dart';
import 'package:maximum/screens/edit_task.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:maximum/screens/task_info.dart';
import 'package:maximum/widgets/add_screen/task.dart';
import 'package:maximum/widgets/common/info_chip.dart';
import 'package:maximum/widgets/common/tag_label.dart';

class TaskProgressScreen extends StatefulWidget {
final int taskId;

const TaskProgressScreen({Key? key, required this.taskId}) : super(key: key);

@override
State<TaskProgressScreen> createState() => _TaskProgressScreenState();
}

class _TaskProgressScreenState extends State<TaskProgressScreen> {
Task? task;
bool loaded = false;
List<TaskStatus>? taskStatuses;
Map<DateTime, List<TaskStatus>> taskStatusesByDate = {};

void fetchTask() async {
DatabaseHelper dh = DatabaseHelper();
task = await dh.getTask(widget.taskId);
taskStatuses = await dh.getTaskStatuses(widget.taskId);
taskStatuses?.forEach((status) {
DateTime date = DateTime.fromMillisecondsSinceEpoch(status.datetime)
.copyWith(
hour: 0, minute: 0, second: 0, millisecond: 0, microsecond: 0);
if (!taskStatusesByDate.containsKey(date)) {
taskStatusesByDate[date] = [];
}
taskStatusesByDate[date]?.add(status);
});
setState(() {
loaded = true;
});
}

@override
void initState() {
super.initState();
fetchTask();
}

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(AppLocalizations.of(context)!.progress_title),
),
body: loaded
? task == null
? Center(
child: Text(AppLocalizations.of(context)!.task_not_found))
: Padding(
padding: const EdgeInsets.symmetric(horizontal: 16.0),
child: Column(
children: [
if (task?.targetValue == 1 && task?.repeat == null) ...[
Column(
children: taskStatusesByDate.keys.map((date) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(DateFormat.yMMMMEEEEd().format(date),
style:
Theme.of(context).textTheme.titleSmall),
...taskStatusesByDate[date]!.map((status) =>
TaskStatusEventItem(
status: status, task: task!))
],
);
}).toList())
] else if (task?.repeat?.repeatType ==
RepeatType.daily &&
task?.targetValue == 1) ...[
GridView.count(
crossAxisCount: 7,
shrinkWrap: true,
physics: ClampingScrollPhysics(),
children: List.generate(
max(
0,
(task!.datetime!
.difference(DateTime.now())
.inDays *
-1 +
2) ~/
(task?.repeat?.repeatInterval ?? 1)),
(index) {
DateTime date = task!.datetime!
.copyWith(
hour: 0,
minute: 0,
second: 0,
millisecond: 0,
microsecond: 0)
.add(Duration(
days: index *
(task?.repeat?.repeatInterval ??
1) +
1));
bool done = false;

if (taskStatusesByDate.containsKey(date)) {
done =
taskStatusesByDate[date]?.last.value == 1;
}
return Container(
color: done
? Theme.of(context).colorScheme.primary
: Theme.of(context)
.colorScheme
.primaryContainer,
margin: EdgeInsets.all(8),
alignment: Alignment.center,
child: Text(
'${taskStatusesByDate[date]?.last.value}', //Text(DateFormat.Md().format(date),
style: Theme.of(context)
.textTheme
.labelSmall
?.copyWith(
color: done
? Theme.of(context)
.colorScheme
.onPrimary
: Theme.of(context)
.colorScheme
.onPrimaryContainer)),
// child: Icon(
// done
// ? MdiIcons.checkboxMarkedCircleOutline
// : MdiIcons.circleOutline,
// ),
);
},
),
)
]
],
),
)
: Center(child: CircularProgressIndicator()));
}
}

class TaskStatusEventItem extends StatelessWidget {
final TaskStatus status;
final Task task;
const TaskStatusEventItem(
{super.key, required this.status, required this.task});
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 8.0),
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text(DateFormat.jm().format(status.dt),
style: Theme.of(context).textTheme.bodyLarge),
Container(
decoration: BoxDecoration(
shape: BoxShape.circle,
color: Theme.of(context).colorScheme.primaryContainer,
),
padding: EdgeInsets.all(8),
margin: EdgeInsets.symmetric(horizontal: 8),
child: Icon(status.value == task.targetValue
? MdiIcons.checkboxMarkedCircleOutline
: MdiIcons.circleOutline),
),
Text(status.value == task.targetValue
? AppLocalizations.of(context).marked_as_done
: AppLocalizations.of(context).marked_as_not_done)
],
));
}
}

class TaskStatusItem extends StatelessWidget {
final TaskStatus status;
final Task task;
const TaskStatusItem({super.key, required this.status, required this.task});
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 8.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text(DateFormat.jm().format(status.dt),
style: Theme.of(context).textTheme.bodyLarge),
InfoChip(
subtitle: "${status.value} / ${task.targetValue}",
variant: ChipVariant.secondary,
),
],
));
}
}
29 changes: 5 additions & 24 deletions lib/screens/task_info.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import 'package:maximum/data/models/task.dart';
import 'package:maximum/data/models/task_status.dart';
import 'package:maximum/screens/edit_task.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:maximum/screens/progress.dart';
import 'package:maximum/widgets/add_screen/task.dart';
import 'package:maximum/widgets/common/info_chip.dart';
import 'package:maximum/widgets/common/tag_label.dart';
Expand Down Expand Up @@ -167,7 +168,10 @@ class _TaskInfoScreenState extends State<TaskInfoScreen> {
children: [
TextButton.icon(
onPressed: () {
// TODO
Navigator.of(context).push(MaterialPageRoute(
builder: (context) => TaskProgressScreen(
taskId: widget.taskId,
)));
},
label: Text(l.progress_title),
icon: const Icon(Icons.timeline),
Expand Down Expand Up @@ -360,26 +364,3 @@ class _TaskInfoScreenState extends State<TaskInfoScreen> {
});
}
}

class TaskStatusItem extends StatelessWidget {
final TaskStatus status;
final Task task;
const TaskStatusItem({super.key, required this.status, required this.task});
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 8.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text(DateFormat.jm().format(status.dt),
style: Theme.of(context).textTheme.bodyLarge),
InfoChip(
subtitle: "${status.value} / ${task.targetValue}",
variant: ChipVariant.secondary,
),
],
));
}
}
29 changes: 14 additions & 15 deletions lib/widgets/add_screen/task.dart
Original file line number Diff line number Diff line change
Expand Up @@ -242,22 +242,21 @@ class _TaskAddingState extends State<TaskAdding> {
showCheckmark: false,
selected: widget.taskDraft.repeat != null,
onSelected: (value) async {
if (value) {
if (context.mounted) {
Future.delayed(Duration.zero, () async {
RepeatData? newRepeat = await showDialog(
// ignore: use_build_context_synchronously
context: context,
builder: (context) => PickRepeatDialog(
taskDraft: widget.taskDraft));
widget.taskDraft.replaceRepeat(newRepeat);
widget.updateDataForTask(widget.taskDraft);
});
}
} else {
widget.taskDraft.replaceRepeat(null);
widget.updateDataForTask(widget.taskDraft);
if (context.mounted) {
Future.delayed(Duration.zero, () async {
RepeatData? newRepeat = await showDialog(
// ignore: use_build_context_synchronously
context: context,
builder: (context) =>
PickRepeatDialog(taskDraft: widget.taskDraft));
widget.taskDraft.replaceRepeat(newRepeat);
widget.updateDataForTask(widget.taskDraft);
});
}
// } else {
// widget.taskDraft.replaceRepeat(null);
// widget.updateDataForTask(widget.taskDraft);
// }
},
),
]
Expand Down

0 comments on commit d3ad40f

Please sign in to comment.