From 1edf40ee0274a9d414b52d97d9e819d1c16d95cf Mon Sep 17 00:00:00 2001 From: Soumyajyoti Date: Sun, 19 Jan 2025 11:09:48 +0530 Subject: [PATCH 1/2] Addition to fixing Due Date Error & Enhancing the Task Widget --- .../controllers/detail_route_controller.dart | 7 +- .../detailRoute/views/detail_route_view.dart | 218 ++++++++++-------- .../detailRoute/views/tags_widget.dart | 149 ++++++++++-- .../detailRoute/views/urgency_widget.dart | 71 ++++++ .../home/views/add_task_bottom_sheet.dart | 69 +++--- 5 files changed, 366 insertions(+), 148 deletions(-) create mode 100644 lib/app/modules/detailRoute/views/urgency_widget.dart diff --git a/lib/app/modules/detailRoute/controllers/detail_route_controller.dart b/lib/app/modules/detailRoute/controllers/detail_route_controller.dart index 3bc12109..473d909e 100644 --- a/lib/app/modules/detailRoute/controllers/detail_route_controller.dart +++ b/lib/app/modules/detailRoute/controllers/detail_route_controller.dart @@ -34,7 +34,7 @@ class DetailRouteController extends GetxController { void setAttribute(String name, dynamic newValue) { modify.set(name, newValue); onEdit.value = true; - if(name == 'start'){ + if (name == 'start') { debugPrint('Start Value Changed to $newValue'); startValue.value = newValue; } @@ -101,9 +101,12 @@ class DetailRouteController extends GetxController { final GlobalKey dueKey = GlobalKey(); final GlobalKey untilKey = GlobalKey(); - final GlobalKey waitKey = GlobalKey(); final GlobalKey priorityKey = GlobalKey(); + final GlobalKey modifiedKey = GlobalKey(); + final GlobalKey startKey = GlobalKey(); + final GlobalKey endKey = GlobalKey(); + final GlobalKey entryKey = GlobalKey(); void initDetailsPageTour() { tutorialCoachMark = TutorialCoachMark( diff --git a/lib/app/modules/detailRoute/views/detail_route_view.dart b/lib/app/modules/detailRoute/views/detail_route_view.dart index 478da44f..1e236abb 100644 --- a/lib/app/modules/detailRoute/views/detail_route_view.dart +++ b/lib/app/modules/detailRoute/views/detail_route_view.dart @@ -10,6 +10,7 @@ import 'package:taskwarrior/app/modules/detailRoute/views/description_widget.dar import 'package:taskwarrior/app/modules/detailRoute/views/priority_widget.dart'; import 'package:taskwarrior/app/modules/detailRoute/views/status_widget.dart'; import 'package:taskwarrior/app/modules/detailRoute/views/tags_widget.dart'; +import 'package:taskwarrior/app/modules/detailRoute/views/urgency_widget.dart'; import 'package:taskwarrior/app/utils/constants/constants.dart'; import 'package:taskwarrior/app/utils/gen/fonts.gen.dart'; import 'package:taskwarrior/app/utils/language/sentence_manager.dart'; @@ -118,19 +119,19 @@ class DetailRouteView extends GetView { const EdgeInsets.symmetric(vertical: 4, horizontal: 2), children: [ for (var entry in { - 'description': controller.descriptionValue.value, - 'status': controller.statusValue.value, - 'entry': controller.entryValue.value, - 'modified': controller.modifiedValue.value, - 'start': controller.startValue.value, - 'end': controller.endValue.value, - 'due': controller.dueValue.value, - 'wait': controller.waitValue.value, - 'until': controller.untilValue.value, - 'priority': controller.priorityValue?.value, - 'project': controller.projectValue?.value, - 'tags': controller.tagsValue?.value, - 'urgency': controller.urgencyValue.value, + 'Task Name': controller.descriptionValue.value, + 'Status': controller.statusValue.value, + 'Due Date': controller.dueValue.value, + 'Priority': controller.priorityValue?.value, + 'Urgency': controller.urgencyValue.value, + 'Tags': controller.tagsValue?.value, + 'Project': controller.projectValue?.value, + 'Entry': controller.entryValue.value, + 'Modified': controller.modifiedValue.value, + 'Start': controller.startValue.value, + 'End': controller.endValue.value, + 'Wait': controller.waitValue.value, + 'Until': controller.untilValue.value, }.entries) AttributeWidget( name: entry.key, @@ -140,6 +141,9 @@ class DetailRouteView extends GetView { waitKey: controller.waitKey, dueKey: controller.dueKey, untilKey: controller.untilKey, + modifiedKey: controller.modifiedKey, + endKey: controller.endKey, + entryKey: controller.entryKey, priorityKey: controller.priorityKey, ), ], @@ -233,6 +237,9 @@ class AttributeWidget extends StatelessWidget { required this.callback, required this.waitKey, required this.dueKey, + required this.entryKey, + required this.modifiedKey, + required this.endKey, required this.priorityKey, required this.untilKey, super.key, @@ -243,6 +250,9 @@ class AttributeWidget extends StatelessWidget { final void Function(dynamic) callback; final GlobalKey waitKey; final GlobalKey dueKey; + final GlobalKey entryKey; + final GlobalKey modifiedKey; + final GlobalKey endKey; final GlobalKey untilKey; final GlobalKey priorityKey; @@ -253,59 +263,85 @@ class AttributeWidget extends StatelessWidget { : ((value is BuiltList) ? (value).toBuilder() : value); switch (name) { - case 'description': + case 'Task Name': return DescriptionWidget( name: name, value: localValue, callback: callback, ); - case 'status': + case 'Urgency': + return UrgencyWidget( + name: name, + value: localValue, + callback: callback, + ); + case 'Status': return StatusWidget( name: name, value: localValue, callback: callback, ); - case 'start': + case 'Start': + return StartWidget( + name: name, + value: localValue, + callback: callback, + ); + case 'End': return StartWidget( name: name, value: localValue, callback: callback, ); - case 'due': + case 'Modified': + return DateTimeWidget( + name: name, + value: localValue, + callback: callback, + globalKey: modifiedKey, + ); + case 'Entry': + return DateTimeWidget( + name: name, + value: localValue, + callback: callback, + globalKey: entryKey, + ); + case 'Due Date': return DateTimeWidget( name: name, value: localValue, callback: callback, globalKey: dueKey, ); - case 'wait': + case 'Wait': return DateTimeWidget( name: name, value: localValue, callback: callback, globalKey: waitKey, ); - case 'until': + case 'Until': return DateTimeWidget( name: name, value: localValue, callback: callback, globalKey: untilKey, ); - case 'priority': + case 'Priority': return PriorityWidget( name: name, value: localValue, callback: callback, globalKey: priorityKey, ); - case 'project': + case 'Project': return ProjectWidget( name: name, value: localValue, callback: callback, ); - case 'tags': + case 'Tags': return TagsWidget( name: name, value: localValue, @@ -349,73 +385,73 @@ class AttributeWidget extends StatelessWidget { } } -class TagsWidget extends StatelessWidget { - const TagsWidget({ - required this.name, - required this.value, - required this.callback, - super.key, - }); +// class TagsWidget extends StatelessWidget { +// const TagsWidget({ +// required this.name, +// required this.value, +// required this.callback, +// super.key, +// }); - final String name; - final dynamic value; - final void Function(dynamic) callback; - @override - Widget build(BuildContext context) { - return Card( - color: AppSettings.isDarkMode - ? TaskWarriorColors.ksecondaryBackgroundColor - : TaskWarriorColors.kLightSecondaryBackgroundColor, - child: ListTile( - textColor: AppSettings.isDarkMode - ? TaskWarriorColors.kprimaryTextColor - : TaskWarriorColors.ksecondaryTextColor, - title: SingleChildScrollView( - scrollDirection: Axis.horizontal, - child: Row( - children: [ - RichText( - text: TextSpan( - children: [ - TextSpan( - text: '$name:'.padRight(13), - style: TextStyle( - fontFamily: FontFamily.poppins, - fontSize: TaskWarriorFonts.fontSizeMedium, - color: AppSettings.isDarkMode - ? TaskWarriorColors.white - : TaskWarriorColors.black, - ) - // style: GoogleFonts.poppins( - // fontWeight: TaskWarriorFonts.bold, - // fontSize: TaskWarriorFonts.fontSizeMedium, - // color: AppSettings.isDarkMode - // ? TaskWarriorColors.white - // : TaskWarriorColors.black, - // ), - ), - TextSpan( - text: - '${(value as ListBuilder?)?.build() ?? 'not selected'}', - style: TextStyle( - color: AppSettings.isDarkMode - ? TaskWarriorColors.white - : TaskWarriorColors.black, - ), - ), - ], - ), - ), - ], - ), - ), - onTap: () => Get.to( - TagsRoute( - value: value, - callback: callback, - ), - ), - ), - ); - } -} +// final String name; +// final dynamic value; +// final void Function(dynamic) callback; +// @override +// Widget build(BuildContext context) { +// return Card( +// color: AppSettings.isDarkMode +// ? TaskWarriorColors.ksecondaryBackgroundColor +// : TaskWarriorColors.kLightSecondaryBackgroundColor, +// child: ListTile( +// textColor: AppSettings.isDarkMode +// ? TaskWarriorColors.kprimaryTextColor +// : TaskWarriorColors.ksecondaryTextColor, +// title: SingleChildScrollView( +// scrollDirection: Axis.horizontal, +// child: Row( +// children: [ +// RichText( +// text: TextSpan( +// children: [ +// TextSpan( +// text: '$name:'.padRight(13), +// style: TextStyle( +// fontFamily: FontFamily.poppins, +// fontSize: TaskWarriorFonts.fontSizeMedium, +// color: AppSettings.isDarkMode +// ? TaskWarriorColors.white +// : TaskWarriorColors.black, +// ) +// // style: GoogleFonts.poppins( +// // fontWeight: TaskWarriorFonts.bold, +// // fontSize: TaskWarriorFonts.fontSizeMedium, +// // color: AppSettings.isDarkMode +// // ? TaskWarriorColors.white +// // : TaskWarriorColors.black, +// // ), +// ), +// TextSpan( +// text: +// '${(value as ListBuilder?)?.build() ?? 'not selected'}', +// style: TextStyle( +// color: AppSettings.isDarkMode +// ? TaskWarriorColors.white +// : TaskWarriorColors.black, +// ), +// ), +// ], +// ), +// ), +// ], +// ), +// ), +// onTap: () => Get.to( +// () => TagsRoute( +// value: value, +// callback: callback, +// ), +// ), +// ), +// ); +// } +// } diff --git a/lib/app/modules/detailRoute/views/tags_widget.dart b/lib/app/modules/detailRoute/views/tags_widget.dart index c4906d59..3c75f10b 100644 --- a/lib/app/modules/detailRoute/views/tags_widget.dart +++ b/lib/app/modules/detailRoute/views/tags_widget.dart @@ -7,10 +7,8 @@ import 'package:google_fonts/google_fonts.dart'; import 'package:loggy/loggy.dart'; import 'package:taskwarrior/app/models/tag_meta_data.dart'; import 'package:taskwarrior/app/modules/home/controllers/home_controller.dart'; - import 'package:taskwarrior/app/utils/constants/constants.dart'; import 'package:taskwarrior/app/utils/constants/utilites.dart'; -import 'package:taskwarrior/app/utils/taskfunctions/validate.dart'; import 'package:taskwarrior/app/utils/app_settings/app_settings.dart'; class TagsWidget extends StatelessWidget { @@ -22,28 +20,49 @@ class TagsWidget extends StatelessWidget { }); final String name; - final dynamic value; - final void Function(dynamic) callback; + final ListBuilder? value; + final void Function(ListBuilder?) callback; @override Widget build(BuildContext context) { return Card( + color: AppSettings.isDarkMode + ? TaskWarriorColors.ksecondaryBackgroundColor + : TaskWarriorColors.kLightSecondaryBackgroundColor, child: ListTile( - tileColor: AppSettings.isDarkMode - ? const Color.fromARGB(255, 55, 54, 54) - : TaskWarriorColors.white, textColor: AppSettings.isDarkMode - ? TaskWarriorColors.white - : const Color.fromARGB(255, 48, 46, 46), - title: SingleChildScrollView( - scrollDirection: Axis.horizontal, - child: Row( - children: [ - Text( - '${'$name:'.padRight(13)}${(value as ListBuilder?)?.build()}', + ? TaskWarriorColors.kprimaryTextColor + : TaskWarriorColors.ksecondaryTextColor, + title: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + name, + style: TextStyle( + color: AppSettings.isDarkMode + ? TaskWarriorColors.kprimaryTextColor + : TaskWarriorColors.ksecondaryTextColor, ), - ], - ), + ), + Wrap( + spacing: 8.0, + runSpacing: 4.0, + children: value?.build().map((tag) { + return Chip( + label: Text(tag), + backgroundColor: AppSettings.isDarkMode + ? TaskWarriorColors.kprimaryBackgroundColor + : TaskWarriorColors.kLightPrimaryBackgroundColor, + labelStyle: TextStyle( + color: AppSettings.isDarkMode + ? TaskWarriorColors.kprimaryTextColor + : TaskWarriorColors.ksecondaryTextColor, + ), + ); + }).toList() ?? + [], + ), + ], ), onTap: () => Navigator.push( context, @@ -75,7 +94,6 @@ class TagsRouteState extends State { void _addTag(String tag) { if (tag.isNotEmpty) { - // Add this condition to ensure the tag is not empty if (draftTags == null) { draftTags = ListBuilder([tag]); } else { @@ -97,6 +115,13 @@ class TagsRouteState extends State { setState(() {}); } + void _editTag(String oldTag, String newTag) { + if (newTag.isNotEmpty && !newTag.contains(" ")) { + _removeTag(oldTag); + _addTag(newTag); + } + } + @override void initState() { super.initState(); @@ -144,7 +169,7 @@ class TagsRouteState extends State { for (var tag in draftTags!.build()) FilterChip( backgroundColor: TaskWarriorColors.lightGrey, - onSelected: (_) => _removeTag(tag), + onSelected: (_) => _showEditTagDialog(tag), label: Text( '+$tag ${_pendingTags?[tag]?.frequency ?? 0}', ), @@ -230,7 +255,6 @@ class TagsRouteState extends State { actions: [ TextButton( onPressed: () { - // Navigator.of(context).pop(); Get.back(); }, child: Text( @@ -248,7 +272,6 @@ class TagsRouteState extends State { try { validateTaskTags(controller.text); _addTag(controller.text); - // Navigator.of(context).pop(); Get.back(); } on FormatException catch (e, trace) { logError(e, trace); @@ -272,4 +295,88 @@ class TagsRouteState extends State { ), ); } + + void _showEditTagDialog(String oldTag) { + final formKey = GlobalKey(); + var controller = TextEditingController(text: oldTag); + showDialog( + context: context, + builder: (context) => Utils.showAlertDialog( + scrollable: true, + title: Text( + 'Edit tag', + style: TextStyle( + color: AppSettings.isDarkMode + ? TaskWarriorColors.white + : TaskWarriorColors.black, + ), + ), + content: Form( + key: formKey, + child: TextFormField( + style: TextStyle( + color: AppSettings.isDarkMode + ? TaskWarriorColors.white + : TaskWarriorColors.black, + ), + validator: (value) { + if (value != null) { + if (value.isNotEmpty && value.contains(" ")) { + return "Tags cannot contain spaces"; + } + } + return null; + }, + autofocus: true, + controller: controller, + ), + ), + actions: [ + TextButton( + onPressed: () { + Get.back(); + }, + child: Text( + 'Cancel', + style: TextStyle( + color: AppSettings.isDarkMode + ? TaskWarriorColors.white + : TaskWarriorColors.black, + ), + ), + ), + ElevatedButton( + onPressed: () { + if (formKey.currentState!.validate()) { + try { + validateTaskTags(controller.text); + _editTag(oldTag, controller.text); + Get.back(); + } on FormatException catch (e, trace) { + logError(e, trace); + } + } + }, + child: Text( + 'Submit', + style: TextStyle( + color: AppSettings.isDarkMode + ? TaskWarriorColors.black + : TaskWarriorColors.black, + ), + ), + ), + ], + ), + ); + } +} + +void validateTaskTags(String tag) { + if (tag.isEmpty) { + throw const FormatException("Tag cannot be empty"); + } + if (tag.contains(" ")) { + throw const FormatException("Tags cannot contain spaces"); + } } diff --git a/lib/app/modules/detailRoute/views/urgency_widget.dart b/lib/app/modules/detailRoute/views/urgency_widget.dart new file mode 100644 index 00000000..a75f8374 --- /dev/null +++ b/lib/app/modules/detailRoute/views/urgency_widget.dart @@ -0,0 +1,71 @@ +import 'package:flutter/material.dart'; +import 'package:google_fonts/google_fonts.dart'; +import 'package:taskwarrior/app/utils/constants/constants.dart'; +import 'package:taskwarrior/app/utils/app_settings/app_settings.dart'; + +class UrgencyWidget extends StatelessWidget { + const UrgencyWidget( + {required this.name, + required this.value, + required this.callback, + super.key}); + + final String name; + final double value; + final void Function(double?) callback; + + @override + Widget build(BuildContext context) { + return Card( + color: AppSettings.isDarkMode + ? const Color.fromARGB(255, 57, 57, 57) + : Colors.white, + child: ListTile( + textColor: AppSettings.isDarkMode + ? Colors.white + : const Color.fromARGB(255, 48, 46, 46), + title: SingleChildScrollView( + scrollDirection: Axis.horizontal, + child: Row( + children: [ + RichText( + text: TextSpan( + children: [ + TextSpan( + text: '$name:'.padRight(13), + style: GoogleFonts.poppins( + fontWeight: TaskWarriorFonts.bold, + fontSize: TaskWarriorFonts.fontSizeMedium, + color: AppSettings.isDarkMode + ? Colors.white + : Colors.black, + ), + ), + TextSpan( + text: value.toString(), + style: GoogleFonts.poppins( + fontSize: TaskWarriorFonts.fontSizeMedium, + color: AppSettings.isDarkMode + ? Colors.white + : Colors.black, + ), + ), + ], + ), + ), + ], + ), + ), + onTap: () { + if (value >= 2.0) { + callback(1.0); + } else if (value >= 1.0) { + callback(0.0); + } else { + callback(2.0); + } + }, + ), + ); + } +} diff --git a/lib/app/modules/home/views/add_task_bottom_sheet.dart b/lib/app/modules/home/views/add_task_bottom_sheet.dart index 9e08077e..3f12565a 100644 --- a/lib/app/modules/home/views/add_task_bottom_sheet.dart +++ b/lib/app/modules/home/views/add_task_bottom_sheet.dart @@ -205,7 +205,7 @@ class AddTaskBottomSheet extends StatelessWidget { currentLanguage: homeController.selectedLanguage.value) .sentences - .addTaskTitle, + .addTaskSelectDueDate, hintStyle: homeController.inThePast.value ? TextStyle(color: TaskWarriorColors.red) : TextStyle( @@ -355,10 +355,7 @@ class AddTaskBottomSheet extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.center, children: [ Text( - "${SentenceManager( - currentLanguage: homeController.selectedLanguage.value) - .sentences - .addTaskPriority} :", + "${SentenceManager(currentLanguage: homeController.selectedLanguage.value).sentences.addTaskPriority} :", style: GoogleFonts.poppins( fontWeight: TaskWarriorFonts.bold, color: AppSettings.isDarkMode @@ -367,16 +364,19 @@ class AddTaskBottomSheet extends StatelessWidget { ), textAlign: TextAlign.left, ), - const SizedBox(width: 2,), + const SizedBox( + width: 2, + ), Obx( () => Row( children: [ - for(int i=0;i tags = trimmedString.split(" "); - for(tag in tags){ - if(checkTagIfExists(tag)) { + for (tag in tags) { + if (checkTagIfExists(tag)) { removeTag(tag); } homeController.tags.add(tag); @@ -554,9 +553,11 @@ class AddTaskBottomSheet extends StatelessWidget { homeController.tagcontroller.text = ''; } } - bool checkTagIfExists(String tag){ + + bool checkTagIfExists(String tag) { return homeController.tags.contains(tag); } + void removeTag(String tag) { homeController.tags.remove(tag); } From 77fe4bc14afa5b2b3e13285afe83d18341d1406e Mon Sep 17 00:00:00 2001 From: Soumyajyoti Date: Sun, 19 Jan 2025 15:36:27 +0530 Subject: [PATCH 2/2] Fixes and Enhancements in the Navigation Bar --- .../modules/home/views/home_page_body.dart | 232 ++++++----- lib/app/modules/home/views/nav_drawer.dart | 376 ++++++++++-------- 2 files changed, 353 insertions(+), 255 deletions(-) diff --git a/lib/app/modules/home/views/home_page_body.dart b/lib/app/modules/home/views/home_page_body.dart index 5f1a3700..f6ac986d 100644 --- a/lib/app/modules/home/views/home_page_body.dart +++ b/lib/app/modules/home/views/home_page_body.dart @@ -1,14 +1,11 @@ import 'package:double_back_to_close_app/double_back_to_close_app.dart'; import 'package:flutter/material.dart'; - import 'package:get/get.dart'; import 'package:taskwarrior/app/modules/home/views/show_tasks.dart'; - import 'package:taskwarrior/app/modules/home/views/tasks_builder.dart'; import 'package:taskwarrior/app/utils/constants/palette.dart'; import 'package:taskwarrior/app/utils/constants/taskwarrior_colors.dart'; import 'package:taskwarrior/app/utils/app_settings/app_settings.dart'; - import '../controllers/home_controller.dart'; class HomePageBody extends StatelessWidget { @@ -19,106 +16,145 @@ class HomePageBody extends StatelessWidget { Widget build(BuildContext context) { controller.initInAppTour(); controller.showInAppTour(context); - return DoubleBackToCloseApp( - snackBar: const SnackBar(content: Text('Tap back again to exit')), - child: Container( - color: AppSettings.isDarkMode - ? Palette.kToDark.shade200 - : TaskWarriorColors.white, - child: Padding( - padding: const EdgeInsets.only(left: 8.0, right: 8.0), - child: Obx( - () => Column( - children: [ - if (controller.searchVisible.value) - Container( - margin: const EdgeInsets.symmetric( - horizontal: 10, vertical: 10), - child: SearchBar( - backgroundColor: WidgetStateProperty.all( - (TaskWarriorColors.kLightPrimaryBackgroundColor)), - surfaceTintColor: WidgetStateProperty.all( - (TaskWarriorColors.kLightPrimaryBackgroundColor)), - controller: controller.searchController, - // shape:, - onChanged: (value) { - controller.search(value); - }, - - shape: WidgetStateProperty.resolveWith( - (Set states) { - if (states.contains(WidgetState.focused)) { - return RoundedRectangleBorder( - borderRadius: BorderRadius.circular(12.0), - side: BorderSide( - color: TaskWarriorColors.black, - width: 2.0, - ), - ); - } else { - return RoundedRectangleBorder( - borderRadius: BorderRadius.circular(12.0), - side: BorderSide( - color: TaskWarriorColors.black, - width: 1.5, - ), - ); - } - }, + return Scaffold( + drawer: Drawer( + // Add your drawer content here + child: ListView( + padding: EdgeInsets.zero, + children: const [ + DrawerHeader( + decoration: BoxDecoration( + color: Colors.blue, + ), + child: Text( + 'Drawer Header', + style: TextStyle( + color: Colors.white, + fontSize: 24, + ), + ), + ), + ListTile( + leading: Icon(Icons.message), + title: Text('Messages'), + ), + ListTile( + leading: Icon(Icons.account_circle), + title: Text('Profile'), + ), + ListTile( + leading: Icon(Icons.settings), + title: Text('Settings'), + ), + ], + ), + ), + body: GestureDetector( + onHorizontalDragEnd: (details) { + if (details.primaryVelocity! > 0) { + Scaffold.of(context).openDrawer(); + } + }, + child: DoubleBackToCloseApp( + snackBar: const SnackBar(content: Text('Tap back again to exit')), + child: Container( + color: AppSettings.isDarkMode + ? Palette.kToDark.shade200 + : TaskWarriorColors.white, + child: Padding( + padding: const EdgeInsets.only(left: 8.0, right: 8.0), + child: Obx( + () => Column( + children: [ + if (controller.searchVisible.value) + Container( + margin: const EdgeInsets.symmetric( + horizontal: 10, vertical: 10), + child: SearchBar( + backgroundColor: WidgetStateProperty.all( + (TaskWarriorColors.kLightPrimaryBackgroundColor)), + surfaceTintColor: WidgetStateProperty.all( + (TaskWarriorColors.kLightPrimaryBackgroundColor)), + controller: controller.searchController, + onChanged: (value) { + controller.search(value); + }, + shape: + WidgetStateProperty.resolveWith( + (Set states) { + if (states.contains(WidgetState.focused)) { + return RoundedRectangleBorder( + borderRadius: BorderRadius.circular(12.0), + side: BorderSide( + color: TaskWarriorColors.black, + width: 2.0, + ), + ); + } else { + return RoundedRectangleBorder( + borderRadius: BorderRadius.circular(12.0), + side: BorderSide( + color: TaskWarriorColors.black, + width: 1.5, + ), + ); + } + }, + ), + leading: const Icon(Icons.search_rounded), + trailing: [ + (controller.searchController.text.isNotEmpty) + ? IconButton( + key: GlobalKey(), + icon: Icon(Icons.cancel, + color: TaskWarriorColors.black), + onPressed: () { + controller.searchController.clear(); + controller.search( + controller.searchController.text); + }, + ) + : const SizedBox( + width: 0, + height: 0, + ) + ], + hintText: 'Search', + ), ), - leading: const Icon(Icons.search_rounded), - trailing: [ - (controller.searchController.text.isNotEmpty) - ? IconButton( - key: GlobalKey(), - icon: Icon(Icons.cancel, - color: TaskWarriorColors.black), - onPressed: () { - controller.searchController.clear(); - controller - .search(controller.searchController.text); - }, - ) - : const SizedBox( - width: 0, - height: 0, - ) - ], - - hintText: 'Search', - ), - ), - Visibility( - visible: !controller.taskchampion.value, - child: Expanded( - child: Scrollbar( - child: Obx( - () => TasksBuilder( - // darkmode: AppSettings.isDarkMode, - useDelayTask: controller.useDelayTask.value, - taskData: controller.searchedTasks, - pendingFilter: controller.pendingFilter.value, - waitingFilter: controller.waitingFilter.value, - searchVisible: controller.searchVisible.value, - selectedLanguage: controller.selectedLanguage.value, - scrollController: controller.scrollController, - showbtn: controller.showbtn.value, + Visibility( + visible: !controller.taskchampion.value, + child: Expanded( + child: Scrollbar( + child: Obx( + () => TasksBuilder( + useDelayTask: controller.useDelayTask.value, + taskData: controller.searchedTasks, + pendingFilter: controller.pendingFilter.value, + waitingFilter: controller.waitingFilter.value, + searchVisible: controller.searchVisible.value, + selectedLanguage: + controller.selectedLanguage.value, + scrollController: controller.scrollController, + showbtn: controller.showbtn.value, + ), + ), ), ), ), - ), + Visibility( + visible: controller.taskchampion.value, + child: Expanded( + child: Scrollbar( + child: TaskViewBuilder( + pendingFilter: controller.pendingFilter.value, + selectedSort: controller.selectedSort.value, + project: controller.projectFilter.value, + ), + ))) + ], ), - Visibility( - visible: controller.taskchampion.value, - child: Expanded( - child: Scrollbar( - child: TaskViewBuilder( - pendingFilter: controller.pendingFilter.value, - selectedSort: controller.selectedSort.value, - project: controller.projectFilter.value, - ), - ))) - ], + ), ), ), ), diff --git a/lib/app/modules/home/views/nav_drawer.dart b/lib/app/modules/home/views/nav_drawer.dart index 0a3d36dc..96c53ac4 100644 --- a/lib/app/modules/home/views/nav_drawer.dart +++ b/lib/app/modules/home/views/nav_drawer.dart @@ -24,76 +24,87 @@ class NavDrawer extends StatelessWidget { backgroundColor: AppSettings.isDarkMode ? TaskWarriorColors.kprimaryBackgroundColor : TaskWarriorColors.kLightPrimaryBackgroundColor, - surfaceTintColor: AppSettings.isDarkMode - ? TaskWarriorColors.kprimaryBackgroundColor - : TaskWarriorColors.kLightPrimaryBackgroundColor, child: Container( color: AppSettings.isDarkMode ? TaskWarriorColors.kprimaryBackgroundColor : TaskWarriorColors.kLightPrimaryBackgroundColor, - child: ListView( - padding: EdgeInsets.zero, + child: Column( children: [ - Container( + _buildHeader(context), + Expanded(child: _buildMenuItems(context)), + _buildExitButton(context), + ], + ), + ), + ); + } + + Widget _buildHeader(BuildContext context) { + return Container( + color: AppSettings.isDarkMode + ? TaskWarriorColors.kprimaryBackgroundColor + : TaskWarriorColors.kLightPrimaryBackgroundColor, + padding: const EdgeInsets.only(top: 50, left: 15, right: 10), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + SentenceManager( + currentLanguage: homeController.selectedLanguage.value) + .sentences + .homePageMenu, + style: TextStyle( + fontSize: TaskWarriorFonts.fontSizeExtraLarge, + fontWeight: TaskWarriorFonts.bold, color: AppSettings.isDarkMode - ? TaskWarriorColors.kprimaryBackgroundColor - : TaskWarriorColors.kLightPrimaryBackgroundColor, - padding: const EdgeInsets.only(top: 50, left: 15, right: 10), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text( - SentenceManager( - currentLanguage: - homeController.selectedLanguage.value) - .sentences - .homePageMenu, - style: TextStyle( - fontSize: TaskWarriorFonts.fontSizeExtraLarge, - fontWeight: TaskWarriorFonts.bold, - color: AppSettings.isDarkMode - ? TaskWarriorColors.white - : TaskWarriorColors.black, - ), - ), - Padding( - padding: const EdgeInsets.only(right: 10), - child: ThemeSwitcherClipper( - isDarkMode: AppSettings.isDarkMode, - onTap: (bool newMode) async { - AppSettings.isDarkMode = newMode; - await SelectedTheme.saveMode(AppSettings.isDarkMode); - // Get.back(); - homeController.initLanguageAndDarkMode(); - }, - child: Icon( - AppSettings.isDarkMode - ? Icons.dark_mode - : Icons.light_mode, - color: AppSettings.isDarkMode - ? TaskWarriorColors.white - : TaskWarriorColors.black, - size: 15, - ), - ), - ), - ], - ), + ? TaskWarriorColors.white + : TaskWarriorColors.black, ), - Container( - color: AppSettings.isDarkMode - ? TaskWarriorColors.kprimaryBackgroundColor - : TaskWarriorColors.kLightPrimaryBackgroundColor, - height: Get.height * 0.03, + ), + Padding( + padding: const EdgeInsets.only(right: 10), + child: AnimatedSwitcher( + duration: const Duration(milliseconds: 300), + transitionBuilder: (Widget child, Animation animation) { + return ScaleTransition(scale: animation, child: child); + }, + child: IconButton( + key: ValueKey(AppSettings.isDarkMode), + icon: Icon( + AppSettings.isDarkMode ? Icons.dark_mode : Icons.light_mode, + color: AppSettings.isDarkMode + ? TaskWarriorColors.white + : TaskWarriorColors.black, + ), + onPressed: () async { + AppSettings.isDarkMode = !AppSettings.isDarkMode; + await SelectedTheme.saveMode(AppSettings.isDarkMode); + homeController.initLanguageAndDarkMode(); + }, + ), ), - Visibility( - visible: homeController.taskchampion.value, - child: NavDrawerMenuItem( + ), + ], + ), + ); + } + + Widget _buildMenuItems(BuildContext context) { + return ListView( + padding: EdgeInsets.zero, + children: [ + SizedBox(height: Get.height * 0.03), + Visibility( + visible: homeController.taskchampion.value, + child: Column( + children: [ + NavDrawerMenuItem( icon: Icons.task_alt, text: SentenceManager( currentLanguage: homeController.selectedLanguage.value, ).sentences.ccsyncCredentials, onTap: () { + Navigator.of(context).pop(); // Close the drawer Navigator.of(context).push( MaterialPageRoute( builder: (context) => ManageTaskChampionCreds(), @@ -101,130 +112,109 @@ class NavDrawer extends StatelessWidget { ); }, ), - ), - Visibility( - visible: homeController.taskchampion.value, - child: NavDrawerMenuItem( - icon: Icons.delete, - text: SentenceManager( - currentLanguage: homeController.selectedLanguage.value, - ).sentences.deleteTaskTitle, - onTap: () { - showDialog( - context: context, - builder: (BuildContext context) { - return Utils.showAlertDialog( - title: Text( - SentenceManager( - currentLanguage: - homeController.selectedLanguage.value, - ).sentences.deleteTaskConfirmation, - style: TextStyle( - color: AppSettings.isDarkMode - ? TaskWarriorColors.white - : TaskWarriorColors.black, - ), - ), - content: Text( - SentenceManager( - currentLanguage: - homeController.selectedLanguage.value, - ).sentences.deleteTaskWarning, - style: TextStyle( - color: AppSettings.isDarkMode - ? TaskWarriorColors.white - : TaskWarriorColors.black, - ), - ), - actions: [ - TextButton( - child: Text( - 'Cancel', - style: TextStyle( - color: AppSettings.isDarkMode - ? TaskWarriorColors.white - : TaskWarriorColors.black, - ), - ), - onPressed: () { - Navigator.of(context).pop(); // Close the dialog - }, - ), - TextButton( - child: Text( - 'Confirm', - style: TextStyle( - color: AppSettings.isDarkMode - ? TaskWarriorColors.white - : TaskWarriorColors.black, - ), - ), - onPressed: () { - homeController.deleteAllTasksInDB(); - Navigator.of(context).pop(); // Close the dialog - }, - ), - ], - ); - }, - ); - }), - ), - Visibility( - visible: !homeController.taskchampion.value, - child: Obx( - () => NavDrawerMenuItem( + Divider(color: Colors.grey.shade700), + ], + ), + ), + Visibility( + visible: homeController.taskchampion.value, + child: Column( + children: [ + NavDrawerMenuItem( + icon: Icons.delete, + text: SentenceManager( + currentLanguage: homeController.selectedLanguage.value, + ).sentences.deleteTaskTitle, + onTap: () { + Navigator.of(context).pop(); // Close the drawer + _showDeleteConfirmationDialog(context); + }, + ), + Divider(color: Colors.grey.shade700), + ], + ), + ), + Visibility( + visible: !homeController.taskchampion.value, + child: Obx( + () => Column( + children: [ + NavDrawerMenuItem( icon: Icons.person_rounded, text: SentenceManager( currentLanguage: homeController.selectedLanguage.value, ).sentences.navDrawerProfile, onTap: () { + Navigator.of(context).pop(); // Close the drawer Get.toNamed(Routes.PROFILE); }, ), - ), + Divider(color: Colors.grey.shade700), + ], ), - Visibility( - visible: !homeController.taskchampion.value, - child: Obx( - () => NavDrawerMenuItem( + ), + ), + Visibility( + visible: !homeController.taskchampion.value, + child: Obx( + () => Column( + children: [ + NavDrawerMenuItem( icon: Icons.summarize, text: SentenceManager( currentLanguage: homeController.selectedLanguage.value, ).sentences.navDrawerReports, onTap: () { + Navigator.of(context).pop(); // Close the drawer Get.toNamed(Routes.REPORTS); }, ), - ), + Divider(color: Colors.grey.shade700), + ], ), - Visibility( - visible: homeController.taskchampion.value, - child: Obx( - () => NavDrawerMenuItem( + ), + ), + Visibility( + visible: homeController.taskchampion.value, + child: Obx( + () => Column( + children: [ + NavDrawerMenuItem( icon: Icons.summarize, text: SentenceManager( currentLanguage: homeController.selectedLanguage.value, ).sentences.navDrawerReports, onTap: () { + Navigator.of(context).pop(); // Close the drawer Get.to(() => ReportsHomeTaskc()); }, ), - ), + Divider(color: Colors.grey.shade700), + ], ), - Obx( - () => NavDrawerMenuItem( + ), + ), + Obx( + () => Column( + children: [ + NavDrawerMenuItem( icon: Icons.info, text: SentenceManager( currentLanguage: homeController.selectedLanguage.value, ).sentences.navDrawerAbout, onTap: () { + Navigator.of(context).pop(); // Close the drawer Get.toNamed(Routes.ABOUT); }, ), - ), - Obx( - () => NavDrawerMenuItem( + Divider(color: Colors.grey.shade700), + ], + ), + ), + Obx( + () => Column( + children: [ + NavDrawerMenuItem( icon: Icons.settings, text: SentenceManager( currentLanguage: homeController.selectedLanguage.value, @@ -241,24 +231,96 @@ class NavDrawer extends StatelessWidget { homeController.change24hr.value = prefs.getBool('24hourformate') ?? false; + Navigator.of(context).pop(); // Close the drawer Get.toNamed(Routes.SETTINGS); }, ), + Divider(color: Colors.grey.shade700), + ], + ), + ), + ], + ); + } + + Widget _buildExitButton(BuildContext context) { + return Obx( + () => Column( + children: [ + Divider(color: Colors.grey.shade700), + NavDrawerMenuItem( + icon: Icons.exit_to_app, + text: SentenceManager( + currentLanguage: homeController.selectedLanguage.value, + ).sentences.navDrawerExit, + onTap: () { + Navigator.of(context).pop(); // Close the drawer + _showExitConfirmationDialog(context); + }, + ), + ], + ), + ); + } + + Future _showDeleteConfirmationDialog(BuildContext context) async { + return showDialog( + context: context, + builder: (BuildContext context) { + return Utils.showAlertDialog( + title: Text( + SentenceManager( + currentLanguage: homeController.selectedLanguage.value) + .sentences + .deleteTaskConfirmation, + style: TextStyle( + color: AppSettings.isDarkMode + ? TaskWarriorColors.white + : TaskWarriorColors.black, ), - Obx( - () => NavDrawerMenuItem( - icon: Icons.exit_to_app, - text: SentenceManager( - currentLanguage: homeController.selectedLanguage.value, - ).sentences.navDrawerExit, - onTap: () { - _showExitConfirmationDialog(context); - }, + ), + content: Text( + SentenceManager( + currentLanguage: homeController.selectedLanguage.value) + .sentences + .deleteTaskWarning, + style: TextStyle( + color: AppSettings.isDarkMode + ? TaskWarriorColors.white + : TaskWarriorColors.black, + ), + ), + actions: [ + TextButton( + child: Text( + 'Cancel', + style: TextStyle( + color: AppSettings.isDarkMode + ? TaskWarriorColors.white + : TaskWarriorColors.black, + ), + ), + onPressed: () { + Navigator.of(context).pop(); // Close the dialog + }, + ), + TextButton( + child: Text( + 'Confirm', + style: TextStyle( + color: AppSettings.isDarkMode + ? TaskWarriorColors.white + : TaskWarriorColors.black, + ), ), + onPressed: () { + homeController.deleteAllTasksInDB(); + Navigator.of(context).pop(); // Close the dialog + }, ), ], - ), - ), + ); + }, ); }