Skip to content

Commit 1d18aec

Browse files
authored
add route to getx (#501)
1 parent 85a5503 commit 1d18aec

File tree

8 files changed

+556
-29
lines changed

8 files changed

+556
-29
lines changed

lib/app/modules/home/views/show_tasks.dart

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import 'package:flutter_slidable/flutter_slidable.dart';
33
import 'package:get/get.dart';
44
import 'package:google_fonts/google_fonts.dart';
55
import 'package:taskwarrior/app/modules/home/controllers/home_controller.dart';
6-
import 'package:taskwarrior/app/modules/home/views/show_details.dart';
6+
import 'package:taskwarrior/app/routes/app_pages.dart';
77
import 'package:taskwarrior/app/utils/app_settings/app_settings.dart';
88
import 'package:taskwarrior/app/utils/constants/taskwarrior_colors.dart';
99
import 'package:taskwarrior/app/utils/constants/taskwarrior_fonts.dart';
@@ -178,12 +178,8 @@ class TaskViewBuilder extends StatelessWidget {
178178
color: tColors.secondaryBackgroundColor,
179179
child: InkWell(
180180
splashColor: tColors.primaryBackgroundColor,
181-
onTap: () => Navigator.push(
182-
context,
183-
MaterialPageRoute(
184-
builder: (context) => TaskDetails(task: task),
185-
),
186-
),
181+
onTap: () =>
182+
Get.toNamed(Routes.TASKC_DETAILS, arguments: task),
187183
child: Container(
188184
decoration: BoxDecoration(
189185
border: Border.all(
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import 'package:get/get.dart';
2+
3+
import '../controllers/taskc_details_controller.dart';
4+
5+
class TaskcDetailsBinding extends Bindings {
6+
@override
7+
void dependencies() {
8+
Get.lazyPut<TaskcDetailsController>(
9+
() => TaskcDetailsController(),
10+
);
11+
}
12+
}
Lines changed: 282 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,282 @@
1+
// ignore_for_file: deprecated_member_use, use_build_context_synchronously
2+
3+
import 'package:flutter/material.dart';
4+
import 'package:get/get.dart';
5+
import 'package:intl/intl.dart';
6+
import 'package:taskwarrior/app/utils/app_settings/app_settings.dart';
7+
import 'package:taskwarrior/app/utils/constants/utilites.dart';
8+
import 'package:taskwarrior/app/utils/themes/theme_extension.dart';
9+
import 'package:taskwarrior/app/utils/language/sentence_manager.dart';
10+
import 'package:taskwarrior/app/v3/db/task_database.dart';
11+
import 'package:taskwarrior/app/v3/models/annotation.dart';
12+
import 'package:taskwarrior/app/v3/models/task.dart';
13+
import 'package:taskwarrior/app/v3/net/modify.dart';
14+
15+
enum UnsavedChangesAction { save, discard, cancel }
16+
17+
class TaskcDetailsController extends GetxController {
18+
late final TaskForC initialTask;
19+
late TaskDatabase taskDatabase;
20+
21+
final hasChanges = false.obs;
22+
23+
late RxString description;
24+
late RxString project;
25+
late RxString status;
26+
late RxString priority;
27+
late RxString due;
28+
late RxString start;
29+
late RxString wait;
30+
late RxList<String> tags;
31+
late RxList<String> depends;
32+
late RxString rtype;
33+
late RxString recur;
34+
late RxList<Annotation> annotations;
35+
36+
@override
37+
void onInit() {
38+
super.onInit();
39+
initialTask = Get.arguments as TaskForC;
40+
_initializeState(initialTask);
41+
taskDatabase = TaskDatabase();
42+
taskDatabase.open();
43+
}
44+
45+
void _initializeState(TaskForC task) {
46+
description = task.description.obs;
47+
project = (task.project ?? '-').obs;
48+
status = task.status.obs;
49+
priority = (task.priority ?? '-').obs;
50+
due = formatDate(task.due).obs;
51+
start = formatDate(task.start).obs;
52+
wait = formatDate(task.wait).obs;
53+
tags = (task.tags ?? []).obs;
54+
depends = (task.depends ?? []).obs;
55+
rtype = (task.rtype ?? '-').obs;
56+
recur = (task.recur ?? '-').obs;
57+
annotations = (task.annotations ?? []).obs;
58+
}
59+
60+
String formatDate(String? dateString) {
61+
if (dateString == null || dateString.isEmpty || dateString == '-') {
62+
return '-';
63+
}
64+
try {
65+
DateTime parsedDate = DateTime.parse(dateString);
66+
return DateFormat('yyyy-MM-dd HH:mm:ss').format(parsedDate);
67+
} catch (e) {
68+
debugPrint('Error parsing date: $dateString');
69+
return '-';
70+
}
71+
}
72+
73+
void updateField<T>(Rx<T> field, T value) {
74+
if (field.value != value) {
75+
field.value = value;
76+
hasChanges.value = true;
77+
}
78+
}
79+
80+
void updateListField(RxList<String> field, String value) {
81+
final newList = value.split(',').map((e) => e.trim()).toList();
82+
if (field.toList().toString() != newList.toString()) {
83+
field.assignAll(newList);
84+
hasChanges.value = true;
85+
}
86+
}
87+
88+
Future<void> saveTask() async {
89+
final updatedTask = TaskForC(
90+
id: initialTask.id,
91+
description: description.value,
92+
project: project.value == '-' ? null : project.value,
93+
status: status.value,
94+
uuid: initialTask.uuid,
95+
urgency: initialTask.urgency, // Urgency is typically calculated
96+
priority: priority.value == '-' ? null : priority.value,
97+
due: due.value == '-' ? null : due.value,
98+
start: start.value == '-' ? null : start.value,
99+
end: initialTask.end, // 'end' is usually set when completed
100+
entry: initialTask.entry, // 'entry' is static
101+
wait: wait.value == '-' ? null : wait.value,
102+
modified: DateFormat('yyyy-MM-dd HH:mm:ss')
103+
.format(DateTime.now()), // Update modified time
104+
tags: tags.isEmpty ? null : tags.toList(),
105+
depends: depends.isEmpty ? null : depends.toList(),
106+
rtype: rtype.value == '-' ? null : rtype.value,
107+
recur: recur.value == '-' ? null : recur.value,
108+
annotations: annotations.isEmpty ? null : annotations.toList(),
109+
);
110+
await TaskDatabase().updateTask(updatedTask);
111+
hasChanges.value = false;
112+
await modifyTaskOnTaskwarrior(updatedTask);
113+
}
114+
115+
Future<bool> handleWillPop() async {
116+
if (hasChanges.value) {
117+
final action = await _showUnsavedChangesDialog();
118+
if (action == UnsavedChangesAction.save) {
119+
await saveTask();
120+
return true;
121+
} else if (action == UnsavedChangesAction.discard) {
122+
return true;
123+
} else {
124+
return false;
125+
}
126+
}
127+
return true;
128+
}
129+
130+
Future<void> pickDateTime(RxString field) async {
131+
final BuildContext context = Get.context!;
132+
final DateTime? pickedDate = await showDatePicker(
133+
context: context,
134+
initialDate: field.value != '-'
135+
? DateTime.tryParse(field.value) ?? DateTime.now()
136+
: DateTime.now(),
137+
firstDate: DateTime(2000),
138+
lastDate: DateTime(2101),
139+
);
140+
141+
if (pickedDate != null) {
142+
final TimeOfDay? pickedTime = await showTimePicker(
143+
context: context,
144+
initialTime: TimeOfDay.fromDateTime(field.value != '-'
145+
? DateTime.tryParse(field.value) ?? DateTime.now()
146+
: DateTime.now()),
147+
);
148+
149+
DateTime fullDateTime;
150+
if (pickedTime != null) {
151+
fullDateTime = DateTime(pickedDate.year, pickedDate.month,
152+
pickedDate.day, pickedTime.hour, pickedTime.minute);
153+
} else {
154+
fullDateTime = pickedDate;
155+
}
156+
updateField(
157+
field, DateFormat('yyyy-MM-dd HH:mm:ss').format(fullDateTime));
158+
}
159+
}
160+
161+
Future<String?> showEditDialog(String label, String initialValue) async {
162+
final BuildContext context = Get.context!;
163+
TaskwarriorColorTheme tColors =
164+
Theme.of(context).extension<TaskwarriorColorTheme>()!;
165+
final TextEditingController textController =
166+
TextEditingController(text: initialValue);
167+
168+
return await Get.dialog<String>(
169+
Utils.showAlertDialog(
170+
title: Text(
171+
'${SentenceManager(currentLanguage: AppSettings.selectedLanguage).sentences.edit} $label',
172+
style: TextStyle(color: tColors.primaryTextColor),
173+
),
174+
content: TextField(
175+
style: TextStyle(color: tColors.primaryTextColor),
176+
controller: textController,
177+
decoration: InputDecoration(
178+
hintText:
179+
'${SentenceManager(currentLanguage: AppSettings.selectedLanguage).sentences.enterNew} $label',
180+
hintStyle: TextStyle(color: tColors.primaryTextColor),
181+
),
182+
),
183+
actions: [
184+
TextButton(
185+
onPressed: () => Get.back(),
186+
child: Text(
187+
SentenceManager(currentLanguage: AppSettings.selectedLanguage)
188+
.sentences
189+
.cancel,
190+
style: TextStyle(color: tColors.primaryTextColor),
191+
),
192+
),
193+
TextButton(
194+
onPressed: () => Get.back(result: textController.text),
195+
child: Text(
196+
SentenceManager(currentLanguage: AppSettings.selectedLanguage)
197+
.sentences
198+
.save,
199+
style: TextStyle(color: tColors.primaryTextColor),
200+
),
201+
),
202+
],
203+
),
204+
);
205+
}
206+
207+
Future<String?> showSelectDialog(
208+
String label, String initialValue, List<String> options) async {
209+
final BuildContext context = Get.context!;
210+
TaskwarriorColorTheme tColors =
211+
Theme.of(context).extension<TaskwarriorColorTheme>()!;
212+
213+
return await Get.dialog<String>(
214+
Utils.showAlertDialog(
215+
title: Text(
216+
'${SentenceManager(currentLanguage: AppSettings.selectedLanguage).sentences.select} $label',
217+
style: TextStyle(color: tColors.primaryTextColor),
218+
),
219+
content: Column(
220+
mainAxisSize: MainAxisSize.min,
221+
children: options.map((option) {
222+
return RadioListTile<String>(
223+
title: Text(
224+
option,
225+
style: TextStyle(color: tColors.primaryTextColor),
226+
),
227+
value: option,
228+
groupValue: initialValue,
229+
onChanged: (value) => Get.back(result: value),
230+
);
231+
}).toList(),
232+
),
233+
),
234+
);
235+
}
236+
237+
Future<UnsavedChangesAction?> _showUnsavedChangesDialog() async {
238+
final BuildContext context = Get.context!;
239+
TaskwarriorColorTheme tColors =
240+
Theme.of(context).extension<TaskwarriorColorTheme>()!;
241+
return Get.dialog<UnsavedChangesAction>(
242+
barrierDismissible: false,
243+
Utils.showAlertDialog(
244+
title: Text(
245+
SentenceManager(currentLanguage: AppSettings.selectedLanguage)
246+
.sentences
247+
.unsavedChanges,
248+
style: TextStyle(color: tColors.primaryTextColor),
249+
),
250+
content: Text(
251+
SentenceManager(currentLanguage: AppSettings.selectedLanguage)
252+
.sentences
253+
.unsavedChangesWarning,
254+
style: TextStyle(color: tColors.primaryTextColor),
255+
),
256+
actions: <Widget>[
257+
TextButton(
258+
onPressed: () => Get.back(result: UnsavedChangesAction.cancel),
259+
child: Text(
260+
SentenceManager(currentLanguage: AppSettings.selectedLanguage)
261+
.sentences
262+
.cancel),
263+
),
264+
TextButton(
265+
onPressed: () => Get.back(result: UnsavedChangesAction.discard),
266+
child: Text(
267+
SentenceManager(currentLanguage: AppSettings.selectedLanguage)
268+
.sentences
269+
.dontSave),
270+
),
271+
TextButton(
272+
onPressed: () => Get.back(result: UnsavedChangesAction.save),
273+
child: Text(
274+
SentenceManager(currentLanguage: AppSettings.selectedLanguage)
275+
.sentences
276+
.save),
277+
),
278+
],
279+
),
280+
);
281+
}
282+
}

0 commit comments

Comments
 (0)