diff --git a/lib/app/models/filters.dart b/lib/app/models/filters.dart index a2296246..67b3ecae 100644 --- a/lib/app/models/filters.dart +++ b/lib/app/models/filters.dart @@ -1,11 +1,13 @@ -import 'package:taskwarrior/app/services/tag_filter.dart'; - class Filters { const Filters({ required this.pendingFilter, required this.waitingFilter, + required this.completedFilter, // NEW + required this.deletedFilter, // NEW required this.togglePendingFilter, required this.toggleWaitingFilter, + required this.toggleCompletedFilter, // NEW + required this.toggleDeletedFilter, // NEW required this.tagFilters, required this.projects, required this.projectFilter, @@ -14,8 +16,12 @@ class Filters { final bool pendingFilter; final bool waitingFilter; + final bool completedFilter; // NEW + final bool deletedFilter; // NEW final void Function() togglePendingFilter; final void Function() toggleWaitingFilter; + final void Function() toggleCompletedFilter; // NEW + final void Function() toggleDeletedFilter; // NEW final TagFilters tagFilters; final dynamic projects; final String projectFilter; diff --git a/lib/app/modules/home/controllers/home_controller.dart b/lib/app/modules/home/controllers/home_controller.dart index a882111a..e92c7902 100644 --- a/lib/app/modules/home/controllers/home_controller.dart +++ b/lib/app/modules/home/controllers/home_controller.dart @@ -50,6 +50,8 @@ class HomeController extends GetxController { final RxBool pendingFilter = false.obs; final RxBool waitingFilter = false.obs; final RxString projectFilter = ''.obs; + final RxBool completedFilter = false.obs; + final RxBool deletedFilter = false.obs; final RxBool tagUnion = false.obs; final RxString selectedSort = ''.obs; final RxSet selectedTags = {}.obs; @@ -101,6 +103,8 @@ class HomeController extends GetxController { everAll([ pendingFilter, waitingFilter, + completedFilter, + deletedFilter, projectFilter, tagUnion, selectedSort, @@ -237,15 +241,35 @@ class HomeController extends GetxController { } void _refreshTasks() { - if (pendingFilter.value) { + + if (deletedFilter.value) { + // Show ONLY deleted tasks + queriedTasks.value = storage.data + .completedData() + .where((task) => task.status == 'deleted') + .toList(); + } + else if (completedFilter.value) { + // Show completed tasks (EXCLUDE deleted) + queriedTasks.value = storage.data + .completedData() + .where((task) => task.status == 'completed') + .toList(); + } + else if (pendingFilter.value) { + // Show pending tasks (default behaviour) queriedTasks.value = storage.data .pendingData() .where((task) => task.status == 'pending') .toList(); - } else { - queriedTasks.value = storage.data.completedData(); + } + else { + // Fallback: pending tasks + queriedTasks.value = storage.data.pendingData(); } + + // Rest of the method stays the same... if (waitingFilter.value) { var currentTime = DateTime.now(); queriedTasks.value = queriedTasks @@ -347,6 +371,22 @@ class HomeController extends GetxController { _refreshTasks(); } + void toggleCompletedFilter() { + completedFilter.toggle(); + if (completedFilter.value) { + deletedFilter.value = false; + } + _refreshTasks(); + } + + void toggleDeletedFilter() { + deletedFilter.toggle(); + if (deletedFilter.value) { + completedFilter.value = false; + } + _refreshTasks(); + } + void toggleProjectFilter(String project) { Query(storage.tabs.tab()).toggleProjectFilter(project); projectFilter.value = Query(storage.tabs.tab()).projectFilter(); @@ -613,11 +653,17 @@ class HomeController extends GetxController { tags: tags, toggleTagFilter: toggleTagFilter, ); + + // REPLACE this entire Filters() instantiation: var filters = Filters( pendingFilter: pendingFilter.value, waitingFilter: waitingFilter.value, + completedFilter: completedFilter.value, // NEW - Add this line + deletedFilter: deletedFilter.value, // NEW - Add this line togglePendingFilter: togglePendingFilter, toggleWaitingFilter: toggleWaitingFilter, + toggleCompletedFilter: toggleCompletedFilter, // NEW - Add this line + toggleDeletedFilter: toggleDeletedFilter, // NEW - Add this line projects: projects, projectFilter: projectFilter.value, toggleProjectFilter: toggleProjectFilter, diff --git a/lib/app/modules/home/views/filter_drawer_home_page.dart b/lib/app/modules/home/views/filter_drawer_home_page.dart index 085a969d..e4a61518 100644 --- a/lib/app/modules/home/views/filter_drawer_home_page.dart +++ b/lib/app/modules/home/views/filter_drawer_home_page.dart @@ -97,17 +97,20 @@ class FilterDrawer extends StatelessWidget { color: tColors.primaryTextColor, )), TextSpan( - text: filters.pendingFilter - ? SentenceManager( - currentLanguage: homeController - .selectedLanguage.value) - .sentences - .filterDrawerPending - : SentenceManager( - currentLanguage: homeController - .selectedLanguage.value) - .sentences - .filterDrawerCompleted, + text: filters.deletedFilter + ? 'Deleted' + : filters.completedFilter + ? SentenceManager( + currentLanguage: + homeController.selectedLanguage.value) + .sentences + .filterDrawerCompleted + : SentenceManager( + currentLanguage: + homeController.selectedLanguage.value) + .sentences + .filterDrawerPending, + style: TextStyle( fontFamily: FontFamily.poppins, fontSize: TaskWarriorFonts.fontSizeMedium, @@ -116,7 +119,16 @@ class FilterDrawer extends StatelessWidget { ], ), ), - onTap: filters.togglePendingFilter, + onTap: () { + if (filters.deletedFilter) { + filters.toggleDeletedFilter(); + } else if (filters.completedFilter) { + filters.toggleCompletedFilter(); + } else { + filters.togglePendingFilter(); + } + }, + textColor: tColors.primaryTextColor, ), ), @@ -137,31 +149,23 @@ class FilterDrawer extends StatelessWidget { mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( - !filters.waitingFilter - ? SentenceManager( - currentLanguage: homeController - .selectedLanguage.value) - .sentences - .filterDrawerShowWaiting - : SentenceManager( - currentLanguage: homeController - .selectedLanguage.value) - .sentences - .filterDrawerHideWaiting, - style: TextStyle( - fontFamily: FontFamily.poppins, - fontSize: TaskWarriorFonts.fontSizeMedium, - color: tColors.primaryTextColor, - )), + 'Show Deleted', + style: TextStyle( + fontFamily: FontFamily.poppins, + fontSize: TaskWarriorFonts.fontSizeMedium, + color: tColors.primaryTextColor, + ), + ), Switch( - value: filters.waitingFilter, - onChanged: (_) => filters.toggleWaitingFilter(), - ) + value: filters.deletedFilter, + onChanged: (_) => filters.toggleDeletedFilter(), + ), ], ), ), ), ), + const Divider( color: Color.fromARGB(0, 48, 46, 46), ), diff --git a/lib/app/modules/manageTaskServer/controllers/manage_task_server_controller.dart b/lib/app/modules/manageTaskServer/controllers/manage_task_server_controller.dart index 2fe75484..02b478c2 100644 --- a/lib/app/modules/manageTaskServer/controllers/manage_task_server_controller.dart +++ b/lib/app/modules/manageTaskServer/controllers/manage_task_server_controller.dart @@ -24,7 +24,9 @@ class ManageTaskServerController extends GetxController { late RxString alias; Server? server; Credentials? credentials; + String? trust; final TextEditingController taskrcContentController = TextEditingController(); + RxBool isTaskDServerActive = true.obs; RxBool hideKey = true.obs; @@ -37,13 +39,12 @@ class ManageTaskServerController extends GetxController { alias = RxString(splashController.profilesMap[profile.value] ?? ''); var contents = rc.Taskrc(storage.home.home).readTaskrc(); if (contents != null) { - server = Taskrc.fromString(contents).server; - credentials = Taskrc.fromString(contents).credentials; - } - if (contents != null) { - server = Taskrc.fromString(contents).server; - credentials = Taskrc.fromString(contents).credentials; + final taskrc = Taskrc.fromString(contents); + server = taskrc.server; + credentials = taskrc.credentials; + trust = taskrc.trust; // ⬅️ ADD THIS } + configureCredentialString(); update(); } @@ -53,8 +54,7 @@ class ManageTaskServerController extends GetxController { var contents = await rootBundle.loadString('assets/.taskrc'); rc.Taskrc(storage.home.home).addTaskrc(contents); var taskrc = Taskrc.fromString(contents); - server = taskrc.server; - credentials = taskrc.credentials; + trust = taskrc.trust; for (var entry in { 'taskd.certificate': '.task/first_last.cert.pem', 'taskd.key': '.task/first_last.key.pem', @@ -96,12 +96,12 @@ class ManageTaskServerController extends GetxController { // Check if the server and credentials are present in the Taskrc object if (taskrc.server != null && taskrc.credentials != null) { - // Update the server and credentials variables - server = taskrc.server; credentials = taskrc.credentials; + trust = taskrc.trust; // ⬅️ ADD THIS update(); + // Handle the case when server or credentials are missing in the Taskrc object Navigator.pop(context); @@ -162,8 +162,16 @@ class ManageTaskServerController extends GetxController { if (credentialsString!.value.isNotEmpty && server.toString().isNotEmpty) { //print(credentialsString.value); - taskrcContentController.text = - "taskd.server=$server\ntaskd.credentials=${credentials!.org}/${credentials!.user}/$key"; + var taskrcContent = + "taskd.server=$server\n" + "taskd.credentials=${credentials!.org}/${credentials!.user}/$key"; + + if (trust?.isNotEmpty == true) { + taskrcContent += "\ntaskd.trust=$trust"; // ⬅️ ADD THIS + } + + taskrcContentController.text = taskrcContent; + isTaskDServerActive.value = false; } diff --git a/lib/app/utils/add_task_dialogue/date_picker_input.dart b/lib/app/utils/add_task_dialogue/date_picker_input.dart index fe1d6f13..0a4c2b67 100644 --- a/lib/app/utils/add_task_dialogue/date_picker_input.dart +++ b/lib/app/utils/add_task_dialogue/date_picker_input.dart @@ -106,11 +106,36 @@ class _AddTaskDatePickerInputState extends State { firstDate: DateTime.now(), lastDate: DateTime(2101), ); + + // FIX: Check if date was selected before showing time picker + if (picked == null) { + return; // User canceled date picker, exit early + } + + // Only show time picker if date was selected final TimeOfDay? time = await showTimePicker( context: context, initialTime: TimeOfDay.now(), ); - if (picked == null || time == null) return; + + // If user cancels time picker, still set the date with default time + if (time == null) { + setState(() { + // Set date with end-of-day time (23:59) + _selectedDates[forIndex] = picked.add( + const Duration(hours: 23, minutes: 59), + ); + // Update the controller text + _controllers[forIndex].text = + dateToStringForAddTask(_selectedDates[forIndex]!); + }); + if (widget.onDateChanges != null) { + widget.onDateChanges!(_selectedDates); + } + return; + } + + // Both date and time selected setState(() { _selectedDates[forIndex] = picked.add(Duration(hours: time.hour, minutes: time.minute)); @@ -135,4 +160,4 @@ class _AddTaskDatePickerInputState extends State { } return null; } -} +} \ No newline at end of file diff --git a/lib/app/utils/taskserver/taskrc.dart b/lib/app/utils/taskserver/taskrc.dart index 36348b9a..67dd406b 100644 --- a/lib/app/utils/taskserver/taskrc.dart +++ b/lib/app/utils/taskserver/taskrc.dart @@ -7,6 +7,7 @@ class Taskrc { Taskrc({ this.server, this.credentials, + this.trust, // ignore: always_put_required_named_parameters_first required this.pemFilePaths, }); @@ -20,15 +21,20 @@ class Taskrc { factory Taskrc.fromMap(Map taskrc) { var server = taskrc['taskd.server']; var credentials = taskrc['taskd.credentials']; + var trust = taskrc['taskd.trust']; // ⬅️ ADD THIS LINE + return Taskrc( server: (server == null) ? null : Server.fromString(server), credentials: (credentials == null) ? null : Credentials.fromString(credentials), + trust: trust, // ⬅️ ADD THIS LINE pemFilePaths: PemFilePaths.fromTaskrc(taskrc), ); } + final Server? server; final Credentials? credentials; + final String? trust; final PemFilePaths pemFilePaths; }