diff --git a/lib/app/models/data.dart b/lib/app/models/data.dart index 3fe5c66c..d99e42de 100644 --- a/lib/app/models/data.dart +++ b/lib/app/models/data.dart @@ -61,7 +61,7 @@ class Data { List _completedData() { var data = _allData().where( - (task) => task.status == 'completed' || task.status == 'deleted'); + (task) => task.status == 'completed'); return [ for (var task in data) task.rebuild((b) => b..id = 0), ]; @@ -69,7 +69,7 @@ class Data { List completedData() { var data = _allData().where( - (task) => task.status == 'completed' || task.status == 'deleted'); + (task) => task.status == 'completed'); return data .toList() .asMap() @@ -85,8 +85,19 @@ class Data { ]; } + List deletedData() { + var data = _allData().where( + (task) => task.status == 'deleted'); + return data + .toList() + .asMap() + .entries + .map((entry) => entry.value.rebuild((b) => b..id = entry.key + 1)) + .toList(); + } + List allData() { - var data = pendingData()..addAll(_completedData()); + var data = pendingData()..addAll(_completedData())..addAll(deletedData()); return data; } diff --git a/lib/app/models/filters.dart b/lib/app/models/filters.dart index a2296246..524208a4 100644 --- a/lib/app/models/filters.dart +++ b/lib/app/models/filters.dart @@ -4,6 +4,7 @@ class Filters { const Filters({ required this.pendingFilter, required this.waitingFilter, + required this.deletedFilter, required this.togglePendingFilter, required this.toggleWaitingFilter, required this.tagFilters, @@ -14,8 +15,11 @@ class Filters { final bool pendingFilter; final bool waitingFilter; + final bool deletedFilter; + final void Function() togglePendingFilter; final void Function() toggleWaitingFilter; + 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 a7b6d353..e3fd4eb7 100644 --- a/lib/app/modules/home/controllers/home_controller.dart +++ b/lib/app/modules/home/controllers/home_controller.dart @@ -49,6 +49,8 @@ class HomeController extends GetxController { late Storage storage; final RxBool pendingFilter = false.obs; final RxBool waitingFilter = false.obs; + final RxBool deletedFilter = false.obs; + final RxString projectFilter = ''.obs; final RxBool tagUnion = false.obs; final RxString selectedSort = ''.obs; @@ -95,6 +97,7 @@ class HomeController extends GetxController { everAll([ pendingFilter, waitingFilter, + deletedFilter, projectFilter, tagUnion, selectedSort, @@ -210,92 +213,98 @@ class HomeController extends GetxController { } void _profileSet() { - pendingFilter.value = Query(storage.tabs.tab()).getPendingFilter(); - if (!Query(storage.tabs.tab()).getWaitingFilter()) { - waitingFilter.value = Query(storage.tabs.tab()).getWaitingFilter(); - } else { - Query(storage.tabs.tab()).toggleWaitingFilter(); - waitingFilter.value = Query(storage.tabs.tab()).getWaitingFilter(); - } + final bool isPending = Query(storage.tabs.tab()).getPendingFilter(); + + pendingFilter.value = isPending; + deletedFilter.value = false; + waitingFilter.value = Query(storage.tabs.tab()).getWaitingFilter(); + projectFilter.value = Query(storage.tabs.tab()).projectFilter(); tagUnion.value = Query(storage.tabs.tab()).tagUnion(); selectedSort.value = Query(storage.tabs.tab()).getSelectedSort(); - selectedTags.addAll(Query(storage.tabs.tab()).getSelectedTags()); + selectedTags.assignAll(Query(storage.tabs.tab()).getSelectedTags()); _refreshTasks(); pendingTags.value = _pendingTags(); projects.value = _projects(); + if (searchVisible.value) { toggleSearch(); } } void _refreshTasks() { + List baseTasks; + if (pendingFilter.value) { - queriedTasks.value = storage.data - .pendingData() - .where((task) => task.status == 'pending') - .toList(); + baseTasks = storage.data.pendingData(); + } else if (deletedFilter.value) { + baseTasks = storage.data.deletedData(); } else { - queriedTasks.value = storage.data.completedData(); + baseTasks = storage.data.completedData(); } + queriedTasks.assignAll(baseTasks); + if (waitingFilter.value) { - var currentTime = DateTime.now(); - queriedTasks.value = queriedTasks - .where((task) => task.wait != null && task.wait!.isAfter(currentTime)) - .toList(); + final now = DateTime.now(); + queriedTasks.value = queriedTasks.where((task) { + return task.wait != null && task.wait!.isAfter(now); + }).toList(); } if (projectFilter.value.isNotEmpty) { queriedTasks.value = queriedTasks.where((task) { - if (task.project == null) { - return false; - } else { - return task.project!.startsWith(projectFilter.value); - } + return task.project?.startsWith(projectFilter.value) ?? false; }).toList(); } queriedTasks.value = queriedTasks.where((task) { - var tags = task.tags?.toSet() ?? {}; + final tags = task.tags?.toSet() ?? {}; + + if (selectedTags.isEmpty) return true; + if (tagUnion.value) { - if (selectedTags.isEmpty) { - return true; - } - return selectedTags.any((tag) => (tag.startsWith('+')) - ? tags.contains(tag.substring(1)) - : !tags.contains(tag.substring(1))); + return selectedTags.any((tag) { + final clean = tag.substring(1); + return tag.startsWith('+') + ? tags.contains(clean) + : !tags.contains(clean); + }); } else { - return selectedTags.every((tag) => (tag.startsWith('+')) - ? tags.contains(tag.substring(1)) - : !tags.contains(tag.substring(1))); + return selectedTags.every((tag) { + final clean = tag.substring(1); + return tag.startsWith('+') + ? tags.contains(clean) + : !tags.contains(clean); + }); } }).toList(); - var sortColumn = - selectedSort.value.substring(0, selectedSort.value.length - 1); - var ascending = selectedSort.value.endsWith('+'); - queriedTasks.sort((a, b) { - int result; - if (sortColumn == 'id') { - result = a.id!.compareTo(b.id!); - } else { - result = compareTasks(sortColumn)(a, b); - } - return ascending ? result : -result; - }); + if (selectedSort.value.isNotEmpty) { + final column = + selectedSort.value.substring(0, selectedSort.value.length - 1); + final ascending = selectedSort.value.endsWith('+'); + + queriedTasks.sort((a, b) { + final result = column == 'id' + ? a.id!.compareTo(b.id!) + : compareTasks(column)(a, b); + return ascending ? result : -result; + }); + } searchedTasks.assignAll(queriedTasks); - var searchTerm = searchController.text; - if (searchVisible.value) { - searchedTasks.value = searchedTasks - .where((task) => - task.description.contains(searchTerm) || - (task.annotations?.asList() ?? []).any( - (annotation) => annotation.description.contains(searchTerm))) - .toList(); + if (searchVisible.value && searchController.text.isNotEmpty) { + final term = searchController.text.toLowerCase(); + searchedTasks.value = searchedTasks.where((task) { + return task.description.toLowerCase().contains(term) || + (task.annotations?.asList() ?? []).any( + (a) => a.description.toLowerCase().contains(term), + ); + }).toList(); } + pendingTags.value = _pendingTags(); projects.value = _projects(); } @@ -374,6 +383,23 @@ class HomeController extends GetxController { _refreshTasks(); } + void toggleStatusFilter() { + if (pendingFilter.value) { + // Pending → Completed + pendingFilter.value = false; + deletedFilter.value = false; + } else if (!pendingFilter.value && !deletedFilter.value) { + // Completed → Deleted + deletedFilter.value = true; + } else { + // Deleted → Pending + pendingFilter.value = true; + deletedFilter.value = false; + } + + _refreshTasks(); + } + Task getTask(String uuid) { return storage.data.getTask(uuid); } @@ -611,6 +637,7 @@ class HomeController extends GetxController { var filters = Filters( pendingFilter: pendingFilter.value, waitingFilter: waitingFilter.value, + deletedFilter: deletedFilter.value, togglePendingFilter: togglePendingFilter, toggleWaitingFilter: toggleWaitingFilter, projects: projects, 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..a08e55a3 100644 --- a/lib/app/modules/home/views/filter_drawer_home_page.dart +++ b/lib/app/modules/home/views/filter_drawer_home_page.dart @@ -80,44 +80,50 @@ class FilterDrawer extends StatelessWidget { border: Border.all(color: TaskWarriorColors.borderColor), ), child: ListTile( - contentPadding: const EdgeInsets.only( - left: 8, - ), + contentPadding: const EdgeInsets.only(left: 8), + onTap: + homeController.toggleStatusFilter, title: RichText( key: homeController.statusKey, maxLines: 2, text: TextSpan( - children: [ + children: [ TextSpan( - text: - '${SentenceManager(currentLanguage: homeController.selectedLanguage.value).sentences.filterDrawerStatus} : ', - style: TextStyle( - fontFamily: FontFamily.poppins, - fontSize: TaskWarriorFonts.fontSizeMedium, - color: tColors.primaryTextColor, - )), + text: + '${SentenceManager(currentLanguage: homeController.selectedLanguage.value).sentences.filterDrawerStatus} : ', + style: TextStyle( + fontFamily: FontFamily.poppins, + fontSize: TaskWarriorFonts.fontSizeMedium, + color: tColors.primaryTextColor, + ), + ), TextSpan( - text: filters.pendingFilter - ? SentenceManager( - currentLanguage: homeController - .selectedLanguage.value) - .sentences - .filterDrawerPending - : SentenceManager( - currentLanguage: homeController - .selectedLanguage.value) - .sentences - .filterDrawerCompleted, - style: TextStyle( - fontFamily: FontFamily.poppins, - fontSize: TaskWarriorFonts.fontSizeMedium, - color: tColors.primaryTextColor, - )), + text: filters.deletedFilter + ? SentenceManager( + currentLanguage: + homeController.selectedLanguage.value) + .sentences + .filterDrawerDeleted + : filters.pendingFilter + ? SentenceManager( + currentLanguage: homeController + .selectedLanguage.value) + .sentences + .filterDrawerPending + : SentenceManager( + currentLanguage: homeController + .selectedLanguage.value) + .sentences + .filterDrawerCompleted, + style: TextStyle( + fontFamily: FontFamily.poppins, + fontSize: TaskWarriorFonts.fontSizeMedium, + color: tColors.primaryTextColor, + ), + ), ], ), ), - onTap: filters.togglePendingFilter, - textColor: tColors.primaryTextColor, ), ), const Divider( diff --git a/lib/app/utils/language/bengali_sentences.dart b/lib/app/utils/language/bengali_sentences.dart index 997f695b..5858d188 100644 --- a/lib/app/utils/language/bengali_sentences.dart +++ b/lib/app/utils/language/bengali_sentences.dart @@ -127,6 +127,8 @@ class BengaliSentences extends Sentences { @override String get filterDrawerCompleted => 'সম্পন্ন'; @override + String get filterDrawerDeleted => 'মুছে ফেলা হয়েছে'; + @override String get filterDrawerFilterTagBy => 'ট্যাগ দ্বারা ফিল্টার করুন'; @override String get filterDrawerAND => 'এবং'; diff --git a/lib/app/utils/language/english_sentences.dart b/lib/app/utils/language/english_sentences.dart index efddd0c0..a622df96 100644 --- a/lib/app/utils/language/english_sentences.dart +++ b/lib/app/utils/language/english_sentences.dart @@ -140,6 +140,8 @@ class EnglishSentences extends Sentences { @override String get filterDrawerCompleted => 'Completed'; @override + String get filterDrawerDeleted => 'Deleted'; + @override String get filterDrawerFilterTagBy => 'Filter Tag By'; @override String get filterDrawerAND => 'AND'; diff --git a/lib/app/utils/language/french_sentences.dart b/lib/app/utils/language/french_sentences.dart index 8f6ac18f..7d5b6cfb 100644 --- a/lib/app/utils/language/french_sentences.dart +++ b/lib/app/utils/language/french_sentences.dart @@ -126,6 +126,8 @@ class FrenchSentences extends Sentences { @override String get filterDrawerCompleted => 'Complété'; @override + String get filterDrawerDeleted => 'Supprimé'; + @override String get filterDrawerFilterTagBy => 'Filtrer par tag'; @override String get filterDrawerAND => 'et'; diff --git a/lib/app/utils/language/hindi_sentences.dart b/lib/app/utils/language/hindi_sentences.dart index 64da4f91..6227ffeb 100644 --- a/lib/app/utils/language/hindi_sentences.dart +++ b/lib/app/utils/language/hindi_sentences.dart @@ -140,6 +140,8 @@ class HindiSentences extends Sentences { @override String get filterDrawerCompleted => 'पूर्ण'; @override + String get filterDrawerDeleted => 'हटाए गए'; + @override String get filterDrawerFilterTagBy => 'टैग से फ़िल्टर करें'; @override String get filterDrawerAND => 'और'; diff --git a/lib/app/utils/language/marathi_sentences.dart b/lib/app/utils/language/marathi_sentences.dart index 12c2c45e..60b9a83d 100644 --- a/lib/app/utils/language/marathi_sentences.dart +++ b/lib/app/utils/language/marathi_sentences.dart @@ -127,6 +127,8 @@ class MarathiSentences extends Sentences { @override String get filterDrawerCompleted => 'पूर्ण'; @override + String get filterDrawerDeleted => 'काढून टाकलेले'; + @override String get filterDrawerFilterTagBy => 'टॅगवर फिल्टर करा'; @override String get filterDrawerAND => 'आणि'; diff --git a/lib/app/utils/language/sentences.dart b/lib/app/utils/language/sentences.dart index 4de41df3..58afd8cb 100644 --- a/lib/app/utils/language/sentences.dart +++ b/lib/app/utils/language/sentences.dart @@ -84,6 +84,7 @@ abstract class Sentences { String get filterDrawerShowWaiting; String get filterDrawerPending; String get filterDrawerCompleted; + String get filterDrawerDeleted; String get filterDrawerFilterTagBy; String get filterDrawerAND; String get filterDrawerOR; diff --git a/lib/app/utils/language/spanish_sentences.dart b/lib/app/utils/language/spanish_sentences.dart index 4281e103..00e6935a 100644 --- a/lib/app/utils/language/spanish_sentences.dart +++ b/lib/app/utils/language/spanish_sentences.dart @@ -128,6 +128,8 @@ class SpanishSentences extends Sentences { @override String get filterDrawerCompleted => 'Completado'; @override + String get filterDrawerDeleted => 'Eliminado'; + @override String get filterDrawerFilterTagBy => 'Filtrar por etiqueta'; @override String get filterDrawerAND => 'y'; diff --git a/lib/app/utils/taskfunctions/query.dart b/lib/app/utils/taskfunctions/query.dart index 3040830c..44c24062 100644 --- a/lib/app/utils/taskfunctions/query.dart +++ b/lib/app/utils/taskfunctions/query.dart @@ -9,6 +9,7 @@ class Query { File get _selectedSort => File('${_queryStorage.path}/selectedSort'); File get _pendingFilter => File('${_queryStorage.path}/pendingFilter'); File get _waitingFilter => File('${_queryStorage.path}/waitingFilter'); + File get _deletedFilter => File('${_queryStorage.path}/deletedFilter'); File get _projectFilter => File('${_queryStorage.path}/projectFilter'); File get _tagUnion => File('${_queryStorage.path}/tagUnion'); File get _selectedTags => File('${_queryStorage.path}/selectedTags'); @@ -59,6 +60,15 @@ class Query { return json.decode(_waitingFilter.readAsStringSync()); } + bool getDeletedFilter() { + if (!_deletedFilter.existsSync()) { + _deletedFilter + ..createSync(recursive: true) + ..writeAsStringSync('false'); + } + return json.decode(_deletedFilter.readAsStringSync()); + } + void toggleProjectFilter(String project) { _projectFilter.writeAsStringSync( (project == projectFilter()) ? '' : project, @@ -107,6 +117,8 @@ class Query { ..createSync(recursive: true) ..writeAsStringSync(json.encode([])); } - return (json.decode(_selectedTags.readAsStringSync()) as List).cast().toSet(); + return (json.decode(_selectedTags.readAsStringSync()) as List) + .cast() + .toSet(); } } diff --git a/test/models/filters_test.dart b/test/models/filters_test.dart index 8d577349..be225d5f 100644 --- a/test/models/filters_test.dart +++ b/test/models/filters_test.dart @@ -7,6 +7,7 @@ void main() { late Filters filters; late bool pendingFilter; late bool waitingFilter; + late bool deletedFilter; late String projectFilter; late bool tagUnion; late Map tags; @@ -14,6 +15,7 @@ void main() { setUp(() { pendingFilter = false; waitingFilter = false; + deletedFilter = false; projectFilter = 'TestProject'; tagUnion = false; tags = { @@ -24,6 +26,7 @@ void main() { filters = Filters( pendingFilter: pendingFilter, waitingFilter: waitingFilter, + deletedFilter: deletedFilter, togglePendingFilter: () { pendingFilter = !pendingFilter; }, diff --git a/test/utils/language/bengali_sentences_test.dart b/test/utils/language/bengali_sentences_test.dart index 413c587c..7972ac7e 100644 --- a/test/utils/language/bengali_sentences_test.dart +++ b/test/utils/language/bengali_sentences_test.dart @@ -72,6 +72,7 @@ void main() { expect(bengali.filterDrawerShowWaiting, 'অপেক্ষা প্রদর্শন করুন'); expect(bengali.filterDrawerPending, 'মুলতুবি'); expect(bengali.filterDrawerCompleted, 'সম্পন্ন'); + expect(bengali.filterDrawerDeleted, 'মুছে ফেলা হয়েছে'); expect(bengali.filterDrawerFilterTagBy, 'ট্যাগ দ্বারা ফিল্টার করুন'); expect(bengali.filterDrawerAND, 'এবং'); expect(bengali.filterDrawerOR, 'অথবা'); diff --git a/test/utils/language/english_sentences_test.dart b/test/utils/language/english_sentences_test.dart index a2e14071..d1656f47 100644 --- a/test/utils/language/english_sentences_test.dart +++ b/test/utils/language/english_sentences_test.dart @@ -71,6 +71,7 @@ void main() { expect(english.filterDrawerShowWaiting, 'Show Waiting'); expect(english.filterDrawerPending, 'Pending'); expect(english.filterDrawerCompleted, 'Completed'); + expect(english.filterDrawerDeleted, 'Deleted'); expect(english.filterDrawerFilterTagBy, 'Filter Tag By'); expect(english.filterDrawerAND, 'AND'); expect(english.filterDrawerOR, 'OR'); diff --git a/test/utils/language/french_sentences_test.dart b/test/utils/language/french_sentences_test.dart index 023647ac..1559fde0 100644 --- a/test/utils/language/french_sentences_test.dart +++ b/test/utils/language/french_sentences_test.dart @@ -73,6 +73,7 @@ void main() { expect(french.filterDrawerShowWaiting, 'Afficher les en attente'); expect(french.filterDrawerPending, 'En attente'); expect(french.filterDrawerCompleted, 'Complété'); + expect(french.filterDrawerDeleted, 'Supprimé'); expect(french.filterDrawerFilterTagBy, 'Filtrer par tag'); expect(french.filterDrawerAND, 'et'); expect(french.filterDrawerOR, 'ou'); diff --git a/test/utils/language/hindi_sentences_test.dart b/test/utils/language/hindi_sentences_test.dart index 45c41702..9c309cd4 100644 --- a/test/utils/language/hindi_sentences_test.dart +++ b/test/utils/language/hindi_sentences_test.dart @@ -73,6 +73,7 @@ void main() { expect(hindi.filterDrawerShowWaiting, 'इंतजार दिखाएं'); expect(hindi.filterDrawerPending, 'अपूर्ण'); expect(hindi.filterDrawerCompleted, 'पूर्ण'); + expect(hindi.filterDrawerDeleted, 'हटाए गए'); expect(hindi.filterDrawerFilterTagBy, 'टैग से फ़िल्टर करें'); expect(hindi.filterDrawerAND, 'और'); expect(hindi.filterDrawerOR, 'या'); diff --git a/test/utils/language/marathi_sentences_test.dart b/test/utils/language/marathi_sentences_test.dart index 57e8104c..50806c1d 100644 --- a/test/utils/language/marathi_sentences_test.dart +++ b/test/utils/language/marathi_sentences_test.dart @@ -72,6 +72,7 @@ void main() { expect(marathi.filterDrawerShowWaiting, 'वाट दाखवा'); expect(marathi.filterDrawerPending, 'प्रलंबित'); expect(marathi.filterDrawerCompleted, 'पूर्ण'); + expect(marathi.filterDrawerDeleted, 'काढून टाकलेले'); expect(marathi.filterDrawerFilterTagBy, 'टॅगवर फिल्टर करा'); expect(marathi.filterDrawerAND, 'आणि'); expect(marathi.filterDrawerOR, 'किंवा'); diff --git a/test/utils/language/sentences_test.dart b/test/utils/language/sentences_test.dart index 7c073bdf..2b88216c 100644 --- a/test/utils/language/sentences_test.dart +++ b/test/utils/language/sentences_test.dart @@ -84,6 +84,7 @@ void main() { expect(sentences.filterDrawerShowWaiting, isA()); expect(sentences.filterDrawerPending, isA()); expect(sentences.filterDrawerCompleted, isA()); + expect(sentences.filterDrawerDeleted, isA()); expect(sentences.filterDrawerFilterTagBy, isA()); expect(sentences.filterDrawerAND, isA()); expect(sentences.filterDrawerOR, isA()); diff --git a/test/utils/language/spanish_sentences_test.dart b/test/utils/language/spanish_sentences_test.dart index f51722c4..674e431b 100644 --- a/test/utils/language/spanish_sentences_test.dart +++ b/test/utils/language/spanish_sentences_test.dart @@ -74,6 +74,7 @@ void main() { expect(spanish.filterDrawerShowWaiting, 'Mostrar pendientes'); expect(spanish.filterDrawerPending, 'Pendiente'); expect(spanish.filterDrawerCompleted, 'Completado'); + expect(spanish.filterDrawerDeleted, 'Eliminado'); expect(spanish.filterDrawerFilterTagBy, 'Filtrar por etiqueta'); expect(spanish.filterDrawerAND, 'y'); expect(spanish.filterDrawerOR, 'o');