Skip to content

Fix/hide waiting tasks#607

Open
Apprentice2907 wants to merge 15 commits intoCCExtractor:mainfrom
Apprentice2907:fix/hide-waiting-tasks
Open

Fix/hide waiting tasks#607
Apprentice2907 wants to merge 15 commits intoCCExtractor:mainfrom
Apprentice2907:fix/hide-waiting-tasks

Conversation

@Apprentice2907
Copy link
Copy Markdown
Contributor

@Apprentice2907 Apprentice2907 commented Feb 27, 2026

Description

Waiting tasks (tasks with a future wait date or status == 'waiting')
are now hidden from the default Pending view, matching taskwarrior CLI
behavior. The waiting filter toggle now correctly shows only waiting tasks.

Fixes #592

Screenshots

Checklist

  • Tests have been added or updated to cover the changes
  • Documentation has been updated to reflect the changes
  • Code follows the established coding style guidelines
  • All tests are passing

Summary by CodeRabbit

Release Notes

  • New Features

    • Added "Completed" and "Deleted" task status filters for improved task organization and visibility
    • Introduced "Hide Blocked Tasks" feature to reduce visual clutter in your task lists
    • Added interactive task dependency picker for managing and viewing task relationships
    • Implemented "Follow System Language" option for automatic app localization based on system settings
  • Chores

    • Enhanced localization framework with improved system locale detection

@SGI-CAPP-AT2
Copy link
Copy Markdown
Collaborator

Has commits from multiple different PRs

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 28, 2026

📝 Walkthrough

Walkthrough

This PR refactors and expands the filter system to support completed and deleted task filtering, introduces task dependency management with an interactive picker, implements system language following capability with proper localization configuration, and adds trust field support for task server configuration.

Changes

Cohort / File(s) Summary
Filter Model Restructuring
lib/app/models/tag_filters.dart, lib/app/services/tag_filter.dart
Moved TagFilterMetadata and TagFilters from services to models cohort, simplifying service code and establishing a dedicated model layer for filter types.
Filters API Expansion
lib/app/models/filters.dart, test/models/filters_test.dart
Extended Filters class with three new filter state fields (completedFilter, deletedFilter, hideBlocked) and corresponding toggle callbacks; updated test fixtures accordingly.
Home Controller Logic Updates
lib/app/modules/home/controllers/home_controller.dart
Added new observable filter states (hideBlocked, completedFilter, deletedFilter), rewrote task refresh filtering logic to prioritize deleted/completed/pending states with conditional hide-blocked behavior, introduced task server banner support, imported sentence manager for UI text.
Filter Drawer UI
lib/app/modules/home/views/filter_drawer_home_page.dart
Updated status filter display logic with priority chain (Deleted → Completed → Pending), replaced waiting toggle with deleted toggle, added new "Hide Blocked Tasks" switch section with divider.
Task List and Details Enhancements
lib/app/modules/home/views/tasks_builder.dart, lib/app/modules/taskc_details/views/taskc_details_view.dart, lib/app/modules/taskc_details/controllers/taskc_details_controller.dart
Updated task slidability logic to include waiting filter, added dependency detail section with interactive picker dialog, refactored depends field initialization.
Task Data Model
lib/app/v3/champion/models/task_for_replica.dart
Added new depends field (list of dependency UUIDs) with full constructor, JSON serialization, and copyWith support.
Language System & Localization
lib/app/utils/language/supported_language.dart, lib/app/utils/app_settings/app_settings.dart, lib/app/utils/app_settings/selected_language.dart, lib/app/modules/settings/controllers/settings_controller.dart, lib/app/modules/settings/views/settings_page_select_the_language_trailing.dart, lib/main.dart, pubspec.yaml
Introduced SupportedLanguage.system enum value enabling "Follow System Language" option; refactored language persistence to clear preferences for system mode, added locale getter, updated app localization configuration with delegates and supported locales.
Task Server Configuration
lib/app/modules/manageTaskServer/controllers/manage_task_server_controller.dart, lib/app/utils/taskserver/taskrc.dart
Added optional trust field to taskrc model and controller, wired through constructor, serialization, and configuration parsing.
Filter Initialization & Query
lib/app/utils/taskfunctions/query.dart
Changed default initialization values for pending and waiting filters from 'true' to 'false' so filters are disabled by default until explicitly toggled.
Minor Formatting
lib/app/utils/add_task_dialogue/date_picker_input.dart
Removed trailing newline for consistency.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Poem

🐰 Filters bloom in splendid array,
Dependencies now linked to stay,
System language heeds the call,
Blocked tasks hidden, none left tall!
Trust flows through the taskrc stream,
Refactored logic makes us beam!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Out of Scope Changes check ⚠️ Warning The PR contains numerous changes unrelated to hiding waiting tasks including new filters (deleted, completed), dependency picker, language system selection, taskd.trust field, and UI overhauls. Separate out-of-scope changes into dedicated PRs. Keep this PR focused solely on hiding waiting tasks and treating pending/waiting as separate entities.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Fix/hide waiting tasks' directly reflects the main change—hiding waiting tasks from the default Pending view to match taskwarrior CLI behavior.
Description check ✅ Passed The PR description covers the key change (hiding waiting tasks) and links to the relevant issue #592. While not all checklist items are completed, the core required sections are present and adequately filled.
Linked Issues check ✅ Passed Changes successfully implement issue #592 requirements: waiting tasks are hidden from default Pending view and treated as separate entities with independent filter toggle.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 9

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (3)
lib/app/modules/home/views/tasks_builder.dart (1)

184-206: ⚠️ Potential issue | 🟠 Major

Preserve the original status in the undo flow.

Line 184 now routes waiting tasks through the same swipe path as pending tasks, but saveChanges() still restores 'pending' unconditionally. Undoing a swipe on a task whose real status was waiting will bring it back with the wrong status.

Possible fix
- void setStatus(BuildContext context, String newValue, String id) {
+ void setStatus(
+   BuildContext context,
+   String newValue,
+   String id,
+   String originalStatus,
+ ) {
    var storageWidget = Get.find<HomeController>();
    Modify modify = Modify(
      getTask: storageWidget.getTask,
      mergeTask: storageWidget.mergeTask,
      uuid: id,
    );
    modify.set('status', newValue);
-   saveChanges(context, modify, id, newValue);
+   saveChanges(context, modify, id, originalStatus);
  }

- void saveChanges(
-     BuildContext context, Modify modify, String id, String newValue) async {
+ void saveChanges(
+     BuildContext context, Modify modify, String id, String originalStatus) async {
    ...
        onPressed: () {
-         undoChanges(context, id, 'pending');
+         undoChanges(context, id, originalStatus);
        },
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@lib/app/modules/home/views/tasks_builder.dart` around lines 184 - 206,
Capture the task's original status before you call setStatus in the
SlidableAction onPressed and pass that original value into the undo/save flow
instead of hardcoding 'pending'; e.g., read task.status (or task.state) into a
local originalStatus, call setStatus(...), then ensure saveChanges()/undo
restores originalStatus (not the literal 'pending') so waiting tasks are
returned to 'waiting' when undone. Use the existing symbols setStatus,
saveChanges, and task.status/task.uuid to locate and update the logic.
lib/app/utils/taskfunctions/query.dart (1)

38-45: ⚠️ Potential issue | 🟠 Major

Handle the upgrade path for legacy filter defaults.

These getters only change first-run initialization. Users who already have pendingFilter / waitingFilter files created with the old true defaults will keep those values, so HomeController._refreshTasks() never reaches the new "hide waiting tasks by default" branch until they manually reset filters. This needs a one-time migration or an explicit "unset vs user-chosen" state.

Also applies to: 53-60

lib/app/v3/champion/models/task_for_replica.dart (1)

122-138: ⚠️ Potential issue | 🟠 Major

operator== and hashCode do not include depends and project fields.

The depends field (and also project) are excluded from equality comparison and hash computation. This violates the Dart contract that objects that are equal must have the same hash code, and could cause subtle bugs when using TaskForReplica in Set, Map, or with List.contains().

Proposed fix
   `@override`
   bool operator ==(Object other) {
     if (identical(this, other)) return true;
     return other is TaskForReplica &&
         other.modified == modified &&
         other.due == due &&
         other.start == start &&
         other.wait == wait &&
         other.status == status &&
         other.description == description &&
         _listEquals(other.tags, tags) &&
         other.uuid == uuid &&
-        other.priority == priority;
+        other.priority == priority &&
+        other.project == project &&
+        _listEquals(other.depends, depends);
   }

   `@override`
-  int get hashCode => Object.hash(modified, due, status, description, uuid,
-      priority, tags == null ? 0 : tags.hashCode, start, wait);
+  int get hashCode => Object.hash(
+      modified,
+      due,
+      status,
+      description,
+      uuid,
+      priority,
+      tags == null ? 0 : tags.hashCode,
+      start,
+      wait,
+      project,
+      depends == null ? 0 : depends.hashCode,
+    );
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@lib/app/v3/champion/models/task_for_replica.dart` around lines 122 - 138, The
equality and hash computation for TaskForReplica omit the depends and project
fields, breaking equality/hashCode consistency; update operator== (in the
TaskForReplica class) to compare depends (using the same list comparison helper
_listEquals if depends is a list) and project alongside the existing fields, and
update int get hashCode to include depends and project (include a null-safe hash
for depends similar to tags and incorporate project into Object.hash) so equal
objects produce identical hashCodes.
🧹 Nitpick comments (7)
test/models/filters_test.dart (1)

71-119: Add assertions for the new filter states.

This update wires completedFilter and deletedFilter into the fixture, but the suite still never checks their initial values or toggle callbacks. A couple of focused tests here would lock down the expanded Filters API and make regressions in this PR's filter behavior harder to reintroduce.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@test/models/filters_test.dart` around lines 71 - 119, Add tests asserting the
initial values and toggle behavior for the newly wired completedFilter and
deletedFilter: check filters.completedFilter and filters.deletedFilter initial
states (e.g., expect(..., isFalse/isTrue as appropriate), call
filters.toggleCompletedFilter() and assert the completedFilter changed, then
call it again and assert it reverted; do the same for
filters.toggleDeletedFilter(); reference the Filters instance and its properties
completedFilter, deletedFilter and methods toggleCompletedFilter,
toggleDeletedFilter to locate where to add the assertions in the existing tests.
lib/main.dart (1)

5-5: Remove development comments before merging.

Comments like // ADD THIS and // ADD THESE 3 PROPERTIES appear to be development reminders and should be removed for cleaner production code.

Also applies to: 70-71

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@lib/main.dart` at line 5, Remove development reminder comments such as "//
ADD THIS" in the import line for flutter_localizations (import
'package:flutter_localizations/flutter_localizations.dart') and any other inline
notes like "// ADD THESE 3 PROPERTIES" found around lines ~70-71; open
lib/main.dart, locate the import and the commented reminders and delete those
comment fragments so only production-ready code and necessary comments remain,
then run a quick build/lint to ensure no leftover TODO/dev comments remain.
lib/app/utils/language/supported_language.dart (2)

77-82: toLocale() returns English when called on SupportedLanguage.system, which may not match user expectations.

When this == SupportedLanguage.system, this method returns Locale('en') unconditionally rather than resolving the actual system language. While the current call site in settings_controller.dart correctly uses getSystemLanguage().toLocale(), calling SupportedLanguage.system.toLocale() directly would yield incorrect results.

Consider either:

  1. Throwing an UnsupportedError for the system case to enforce proper usage, or
  2. Delegating to getSystemLanguage().toLocale() for consistency.
Option 1: Enforce proper usage by throwing
  Locale toLocale() {
-   if (this == SupportedLanguage.system || languageCode.isEmpty) {
-     return const Locale('en');
+   if (this == SupportedLanguage.system) {
+     throw UnsupportedError(
+       'Cannot convert system to Locale directly; use getSystemLanguage().toLocale()',
+     );
+   }
+   if (languageCode.isEmpty) {
+     return const Locale('en');
    }
    return Locale(languageCode);
  }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@lib/app/utils/language/supported_language.dart` around lines 77 - 82, The
toLocale() method on SupportedLanguage currently returns Locale('en') for
SupportedLanguage.system; change it to either (a) throw an UnsupportedError when
this == SupportedLanguage.system (e.g., in toLocale() throw
UnsupportedError('toLocale() must not be called on SupportedLanguage.system; use
getSystemLanguage() instead')) to enforce correct usage, or (b) resolve the
actual system language by delegating to getSystemLanguage().toLocale() when this
== SupportedLanguage.system so SupportedLanguage.system.toLocale() returns the
real system locale; update the implementation of SupportedLanguage.toLocale()
accordingly and keep the rest of the codepaths (e.g., callers that already call
getSystemLanguage().toLocale()) unchanged.

36-38: Unreachable default case.

All SupportedLanguage enum values are explicitly handled in the switch, making the default branch dead code. Removing it enables compile-time exhaustiveness checks if a new language is added later.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@lib/app/utils/language/supported_language.dart` around lines 36 - 38, The
switch over the SupportedLanguage enum currently includes a default branch which
is unreachable; remove the default case in the switch so the compiler can
enforce exhaustiveness when new SupportedLanguage values are added, and ensure
every SupportedLanguage case in the switch (the branches returning the language
string) remains present so the function still returns a value for all enum
members.
lib/app/modules/home/views/filter_drawer_home_page.dart (1)

196-200: Duplicate dividers.

There are two consecutive Divider widgets (lines 196 and 198-200), which creates unnecessary spacing.

Proposed fix
             ),
-              const Divider(color: Color.fromARGB(0, 48, 46, 46)),
-              
               const Divider(
                 color: Color.fromARGB(0, 48, 46, 46),
               ),
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@lib/app/modules/home/views/filter_drawer_home_page.dart` around lines 196 -
200, Two consecutive Divider widgets with identical color (Color.fromARGB(0, 48,
46, 46)) are duplicated in the widget tree; remove the redundant Divider so only
a single Divider remains (inside the build of the filter drawer widget in
filter_drawer_home_page.dart) to eliminate extra spacing and keep layout
consistent, then run formatter/analysis to ensure no trailing commas or style
issues.
lib/app/modules/home/controllers/home_controller.dart (2)

750-751: Remove leftover development comment.

The comment "REPLACE this entire Filters() instantiation:" appears to be a leftover from development that should be removed before merging.

-    // REPLACE this entire Filters() instantiation:
     var filters = Filters(
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@lib/app/modules/home/controllers/home_controller.dart` around lines 750 -
751, Remove the leftover development comment "REPLACE this entire Filters()
instantiation:" from the home controller; locate the Filters() instantiation in
HomeController (or the Filters constructor call near the UI/filter setup) and
delete that stray comment so only the actual Filters() code and surrounding
logic remain, ensuring no other functional code is altered.

600-635: Consider cancelling the auto-dismiss timer on manual dismissal.

The 5-second Future.delayed timer continues running even after the user manually dismisses the banner. While hideCurrentMaterialBanner() is idempotent, if another banner is shown in the meantime, the timer could inadvertently hide it.

Optional: Use a cancellable timer
Timer? _bannerDismissTimer;

void showTaskServerNotConfiguredBanner(BuildContext context) {
  if (taskServerBannerShown.value) return;
  
  taskServerBannerShown.value = true;
  final messenger = ScaffoldMessenger.of(context);
  
  messenger.clearMaterialBanners();
  
  void dismissBanner() {
    _bannerDismissTimer?.cancel();
    messenger.hideCurrentMaterialBanner();
    taskServerBannerShown.value = false;
  }
  
  messenger.showMaterialBanner(
    MaterialBanner(
      content: Text(sentences.homePageTaskWarriorNotConfigured),
      actions: [
        TextButton(
          onPressed: () {
            dismissBanner();
            Get.toNamed(Routes.MANAGE_TASK_SERVER);
          },
          child: Text(sentences.homePageSetup),
        ),
        TextButton(
          onPressed: dismissBanner,
          child: const Text('Dismiss'),
        ),
      ],
    ),
  );
  
  _bannerDismissTimer = Timer(const Duration(seconds: 5), dismissBanner);
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@lib/app/modules/home/controllers/home_controller.dart` around lines 600 -
635, The Future.delayed in showTaskServerNotConfiguredBanner keeps running after
manual dismiss and can hide a subsequently shown banner; change this to use a
cancellable Timer (e.g., a top-level or class field Timer? _bannerDismissTimer),
create a single dismissBanner() helper that calls _bannerDismissTimer?.cancel(),
messenger.hideCurrentMaterialBanner(), and sets taskServerBannerShown.value =
false, call dismissBanner() from both action handlers, and replace
Future.delayed(...) with _bannerDismissTimer = Timer(const Duration(seconds: 5),
dismissBanner); ensure you reference showTaskServerNotConfiguredBanner,
taskServerBannerShown, messenger.hideCurrentMaterialBanner, and replace
Future.delayed with Timer usage.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@lib/app/modules/home/controllers/home_controller.dart`:
- Around line 259-298: The _refreshTasks method's filter order is wrong:
waitingFilter is applied after hideBlocked and replaces queriedTasks, causing
hideBlocked to be ignored for waiting views; fix by capturing DateTime.now()
once at method start (assign to currentTime), then move the waitingFilter branch
into the main if-else chain alongside
deletedFilter/completedFilter/pendingFilter so it produces queriedTasks from
storage.data.pendingData() like the others, or if waiting should ignore
hideBlocked explicitly apply hideBlocked only for the non-waiting branches; also
remove or update the misleading "Rest of the method stays the same..." comment
so it reflects the new flow (references: _refreshTasks, waitingFilter,
hideBlocked, queriedTasks, storage.data.pendingData(),
storage.data.completedData()).

In `@lib/app/modules/home/views/filter_drawer_home_page.dart`:
- Around line 100-112: Replace the hardcoded English labels with localized
sentences from SentenceManager: where the ternary uses 'Deleted' (the expression
referencing filters.deletedFilter / filters.completedFilter) switch it to
SentenceManager(currentLanguage:
homeController.selectedLanguage.value).sentences.filterDrawerDeleted; likewise
replace 'Show Deleted' and 'Hide Blocked Tasks' with
SentenceManager(...).sentences.filterDrawerShowDeleted and
SentenceManager(...).sentences.filterDrawerHideBlockedTasks respectively
(consistent with how filterDrawerCompleted/filterDrawerPending are used) and add
those keys to SentenceManager if they do not already exist.
- Around line 151-167: The UI is missing a "Show Waiting" toggle: add a row
identical to the existing "Show Deleted" entry but using the localized string
key filterDrawerShowWaiting for the label and binding the Switch to the waiting
filter state and toggle methods (use filters.waitingFilter for value and call
filters.toggleWaitingFilter() in onChanged). Match the existing Text style
(FontFamily.poppins, TaskWarriorFonts.fontSizeMedium, tColors.primaryTextColor)
and place the new toggle alongside the other filter switches in the same
container so users can control waiting-task visibility.

In
`@lib/app/modules/manageTaskServer/controllers/manage_task_server_controller.dart`:
- Around line 56-57: The fixture loader setConfigurationFromFixtureForDebugging
currently parses Taskrc and only assigns trust (taskrc.trust), leaving
controller fields server and credentials stale; update the same method to also
refresh server and credentials from the parsed Taskrc (e.g., assign server =
taskrc.server and credentials = taskrc.credentials or map equivalent fields) so
controller state stays in sync with the fixture; locate the assignments in
setConfigurationFromFixtureForDebugging and ensure all relevant controller
properties (trust, server, credentials) are updated from Taskrc.

In
`@lib/app/modules/settings/views/settings_page_select_the_language_trailing.dart`:
- Around line 47-48: The literal 'Follow System Language' returned for
SupportedLanguage.system should be replaced with the app's localized string;
update the switch/case that maps SupportedLanguage to a label (the code
returning that literal) to call the project's localization accessor (e.g.
AppLocalizations.of(context).followSystemLanguage or
context.l10n.followSystemLanguage) instead of the hard-coded English text,
ensuring you obtain a BuildContext where this mapping function is called or pass
context into it.

In `@lib/app/modules/taskc_details/controllers/taskc_details_controller.dart`:
- Around line 507-553: The dependency picker mutates depends and sets hasChanges
but those changes are never persisted; update the save paths so the edited
depends list is written back: when calling saveEditedTaskInDB(...) ensure the
TaskForC instance passed includes the updated depends, and when building the
TaskForReplica in saveTask() set its depends field from the controller's depends
list (or propagate depends into whatever object is saved); modify the
saveEditedTaskInDB callsite and the TaskForReplica construction to copy the
current depends list so selected dependencies are persisted.
- Around line 524-533: The code is force-unwrapping nullable TaskForC.uuid
(t.uuid!) inside the CheckboxListTile which can throw; update the list building
to skip tasks with null UUIDs (e.g., add .where((t) => t.uuid != null) to the
chain) or otherwise use a safe non-null key (e.g., use a stable fallback like
t.hashCode or t.id if available) and replace t.uuid! with the safe value; ensure
references to depends.contains(...) and depends.add(...) use the same non-null
identifier so no forced unwrapping occurs (check symbols: allTasks, initialTask,
depends, t.uuid, CheckboxListTile).

In `@lib/app/utils/app_settings/selected_language.dart`:
- Around line 26-28: The clearSelectedLanguage method is missing its closing
brace and the class lacks a blank line before the final closing brace; add the
missing closing brace to terminate the static Future clearSelectedLanguage()
async { ... } method (which uses _preferences?.remove('_selectedLanguage')),
ensure the method body is properly closed, and insert a single blank line before
the class's closing brace to match file formatting.

In `@lib/main.dart`:
- Around line 72-79: The supportedLocales list in main.dart is missing the
German and Urdu entries defined in SupportedLanguage, causing locale fallback
for those selections; update the supportedLocales constant (the list referenced
by supportedLocales) to include Locale('de') and Locale('ur') so it matches the
SupportedLanguage enum in lib/app/utils/language/supported_language.dart and
ensure any related locale resolution logic uses those entries.

---

Outside diff comments:
In `@lib/app/modules/home/views/tasks_builder.dart`:
- Around line 184-206: Capture the task's original status before you call
setStatus in the SlidableAction onPressed and pass that original value into the
undo/save flow instead of hardcoding 'pending'; e.g., read task.status (or
task.state) into a local originalStatus, call setStatus(...), then ensure
saveChanges()/undo restores originalStatus (not the literal 'pending') so
waiting tasks are returned to 'waiting' when undone. Use the existing symbols
setStatus, saveChanges, and task.status/task.uuid to locate and update the
logic.

In `@lib/app/v3/champion/models/task_for_replica.dart`:
- Around line 122-138: The equality and hash computation for TaskForReplica omit
the depends and project fields, breaking equality/hashCode consistency; update
operator== (in the TaskForReplica class) to compare depends (using the same list
comparison helper _listEquals if depends is a list) and project alongside the
existing fields, and update int get hashCode to include depends and project
(include a null-safe hash for depends similar to tags and incorporate project
into Object.hash) so equal objects produce identical hashCodes.

---

Nitpick comments:
In `@lib/app/modules/home/controllers/home_controller.dart`:
- Around line 750-751: Remove the leftover development comment "REPLACE this
entire Filters() instantiation:" from the home controller; locate the Filters()
instantiation in HomeController (or the Filters constructor call near the
UI/filter setup) and delete that stray comment so only the actual Filters() code
and surrounding logic remain, ensuring no other functional code is altered.
- Around line 600-635: The Future.delayed in showTaskServerNotConfiguredBanner
keeps running after manual dismiss and can hide a subsequently shown banner;
change this to use a cancellable Timer (e.g., a top-level or class field Timer?
_bannerDismissTimer), create a single dismissBanner() helper that calls
_bannerDismissTimer?.cancel(), messenger.hideCurrentMaterialBanner(), and sets
taskServerBannerShown.value = false, call dismissBanner() from both action
handlers, and replace Future.delayed(...) with _bannerDismissTimer = Timer(const
Duration(seconds: 5), dismissBanner); ensure you reference
showTaskServerNotConfiguredBanner, taskServerBannerShown,
messenger.hideCurrentMaterialBanner, and replace Future.delayed with Timer
usage.

In `@lib/app/modules/home/views/filter_drawer_home_page.dart`:
- Around line 196-200: Two consecutive Divider widgets with identical color
(Color.fromARGB(0, 48, 46, 46)) are duplicated in the widget tree; remove the
redundant Divider so only a single Divider remains (inside the build of the
filter drawer widget in filter_drawer_home_page.dart) to eliminate extra spacing
and keep layout consistent, then run formatter/analysis to ensure no trailing
commas or style issues.

In `@lib/app/utils/language/supported_language.dart`:
- Around line 77-82: The toLocale() method on SupportedLanguage currently
returns Locale('en') for SupportedLanguage.system; change it to either (a) throw
an UnsupportedError when this == SupportedLanguage.system (e.g., in toLocale()
throw UnsupportedError('toLocale() must not be called on
SupportedLanguage.system; use getSystemLanguage() instead')) to enforce correct
usage, or (b) resolve the actual system language by delegating to
getSystemLanguage().toLocale() when this == SupportedLanguage.system so
SupportedLanguage.system.toLocale() returns the real system locale; update the
implementation of SupportedLanguage.toLocale() accordingly and keep the rest of
the codepaths (e.g., callers that already call getSystemLanguage().toLocale())
unchanged.
- Around line 36-38: The switch over the SupportedLanguage enum currently
includes a default branch which is unreachable; remove the default case in the
switch so the compiler can enforce exhaustiveness when new SupportedLanguage
values are added, and ensure every SupportedLanguage case in the switch (the
branches returning the language string) remains present so the function still
returns a value for all enum members.

In `@lib/main.dart`:
- Line 5: Remove development reminder comments such as "// ADD THIS" in the
import line for flutter_localizations (import
'package:flutter_localizations/flutter_localizations.dart') and any other inline
notes like "// ADD THESE 3 PROPERTIES" found around lines ~70-71; open
lib/main.dart, locate the import and the commented reminders and delete those
comment fragments so only production-ready code and necessary comments remain,
then run a quick build/lint to ensure no leftover TODO/dev comments remain.

In `@test/models/filters_test.dart`:
- Around line 71-119: Add tests asserting the initial values and toggle behavior
for the newly wired completedFilter and deletedFilter: check
filters.completedFilter and filters.deletedFilter initial states (e.g.,
expect(..., isFalse/isTrue as appropriate), call filters.toggleCompletedFilter()
and assert the completedFilter changed, then call it again and assert it
reverted; do the same for filters.toggleDeletedFilter(); reference the Filters
instance and its properties completedFilter, deletedFilter and methods
toggleCompletedFilter, toggleDeletedFilter to locate where to add the assertions
in the existing tests.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 43f67d64-f25a-4800-8ae4-a944aac807be

📥 Commits

Reviewing files that changed from the base of the PR and between f058b4a and 54f2a24.

📒 Files selected for processing (21)
  • lib/app/models/filters.dart
  • lib/app/models/tag_filters.dart
  • lib/app/modules/home/controllers/home_controller.dart
  • lib/app/modules/home/views/filter_drawer_home_page.dart
  • lib/app/modules/home/views/tasks_builder.dart
  • lib/app/modules/manageTaskServer/controllers/manage_task_server_controller.dart
  • lib/app/modules/settings/controllers/settings_controller.dart
  • lib/app/modules/settings/views/settings_page_select_the_language_trailing.dart
  • lib/app/modules/taskc_details/controllers/taskc_details_controller.dart
  • lib/app/modules/taskc_details/views/taskc_details_view.dart
  • lib/app/services/tag_filter.dart
  • lib/app/utils/add_task_dialogue/date_picker_input.dart
  • lib/app/utils/app_settings/app_settings.dart
  • lib/app/utils/app_settings/selected_language.dart
  • lib/app/utils/language/supported_language.dart
  • lib/app/utils/taskfunctions/query.dart
  • lib/app/utils/taskserver/taskrc.dart
  • lib/app/v3/champion/models/task_for_replica.dart
  • lib/main.dart
  • pubspec.yaml
  • test/models/filters_test.dart

Comment on lines 259 to +298
void _refreshTasks() {
if (pendingFilter.value) {

if (deletedFilter.value) {
queriedTasks.value = storage.data
.completedData()
.where((task) => task.status == 'deleted')
.toList();
} else if (completedFilter.value) {
queriedTasks.value = storage.data
.completedData()
.where((task) => task.status == 'completed')
.toList();
} else if (pendingFilter.value) {
queriedTasks.value = storage.data
.pendingData()
.where((task) => task.status == 'pending')
.toList();
} else {
queriedTasks.value = storage.data.completedData();
var currentTime = DateTime.now();
queriedTasks.value = storage.data.pendingData().where((task) =>
task.status != 'waiting' &&
!(task.wait != null && task.wait!.isAfter(currentTime))
).toList();
}

if (waitingFilter.value) {
var currentTime = DateTime.now();
if (hideBlocked.value) {
queriedTasks.value = queriedTasks
.where((task) => task.wait != null && task.wait!.isAfter(currentTime))
.where((task) => task.depends == null || task.depends!.isEmpty)
.toList();
}


// Rest of the method stays the same...
if (waitingFilter.value) {
var currentTime = DateTime.now();
queriedTasks.value = storage.data.pendingData().where((task) =>
task.status == 'waiting' ||
(task.wait != null && task.wait!.isAfter(currentTime))
).toList();
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Filter logic structure is confusing and potentially incorrect.

The waitingFilter check (lines 292-298) sits outside the main if-else chain and runs after hideBlocked filtering. This means when waitingFilter is enabled, it completely replaces queriedTasks with a fresh query, ignoring the hideBlocked filter that was just applied.

If this is intentional (waiting tasks should ignore blocked filtering), the code flow would be clearer with waitingFilter inside the main if-else chain. If unintentional, blocked tasks would incorrectly appear when viewing waiting tasks.

Additionally:

  • Line 291's comment "Rest of the method stays the same..." is misleading since the waitingFilter code that follows is new logic.
  • DateTime.now() is called twice (lines 277 and 293); consider capturing it once at the method start.
Suggested refactor to clarify intent
 void _refreshTasks() {
-    
+    var currentTime = DateTime.now();
+
     if (deletedFilter.value) {
       queriedTasks.value = storage.data
           .completedData()
           .where((task) => task.status == 'deleted')
           .toList();
     } else if (completedFilter.value) {
       queriedTasks.value = storage.data
           .completedData()
           .where((task) => task.status == 'completed')
           .toList();
+    } else if (waitingFilter.value) {
+      queriedTasks.value = storage.data.pendingData().where((task) =>
+        task.status == 'waiting' ||
+        (task.wait != null && task.wait!.isAfter(currentTime))
+      ).toList();
     } else if (pendingFilter.value) {
       queriedTasks.value = storage.data
           .pendingData()
           .where((task) => task.status == 'pending')
           .toList();
     } else {
-      var currentTime = DateTime.now();
       queriedTasks.value = storage.data.pendingData().where((task) =>
         task.status != 'waiting' &&
         !(task.wait != null && task.wait!.isAfter(currentTime))
       ).toList();
     }

     if (hideBlocked.value) {
       queriedTasks.value = queriedTasks
           .where((task) => task.depends == null || task.depends!.isEmpty)
           .toList();
     }
-
-    // Rest of the method stays the same...
-    if (waitingFilter.value) {
-      var currentTime = DateTime.now();
-      queriedTasks.value = storage.data.pendingData().where((task) =>
-        task.status == 'waiting' ||
-        (task.wait != null && task.wait!.isAfter(currentTime))
-      ).toList();
-    }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@lib/app/modules/home/controllers/home_controller.dart` around lines 259 -
298, The _refreshTasks method's filter order is wrong: waitingFilter is applied
after hideBlocked and replaces queriedTasks, causing hideBlocked to be ignored
for waiting views; fix by capturing DateTime.now() once at method start (assign
to currentTime), then move the waitingFilter branch into the main if-else chain
alongside deletedFilter/completedFilter/pendingFilter so it produces
queriedTasks from storage.data.pendingData() like the others, or if waiting
should ignore hideBlocked explicitly apply hideBlocked only for the non-waiting
branches; also remove or update the misleading "Rest of the method stays the
same..." comment so it reflects the new flow (references: _refreshTasks,
waitingFilter, hideBlocked, queriedTasks, storage.data.pendingData(),
storage.data.completedData()).

Comment on lines +100 to +112
text: filters.deletedFilter
? 'Deleted'
: filters.completedFilter
? SentenceManager(
currentLanguage:
homeController.selectedLanguage.value)
.sentences
.filterDrawerCompleted
: SentenceManager(
currentLanguage:
homeController.selectedLanguage.value)
.sentences
.filterDrawerPending,
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Hardcoded English strings break internationalization.

Several UI strings are hardcoded in English instead of using SentenceManager:

  • Line 101: 'Deleted'
  • Line 152: 'Show Deleted'
  • Line 181: 'Hide Blocked Tasks'

Other strings in this file correctly use SentenceManager for localization consistency.

Example fix pattern
-                          text: filters.deletedFilter
-                              ? 'Deleted'
+                          text: filters.deletedFilter
+                              ? SentenceManager(
+                                      currentLanguage:
+                                          homeController.selectedLanguage.value)
+                                  .sentences
+                                  .filterDrawerDeleted

Also applies to: 151-158, 180-187

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@lib/app/modules/home/views/filter_drawer_home_page.dart` around lines 100 -
112, Replace the hardcoded English labels with localized sentences from
SentenceManager: where the ternary uses 'Deleted' (the expression referencing
filters.deletedFilter / filters.completedFilter) switch it to
SentenceManager(currentLanguage:
homeController.selectedLanguage.value).sentences.filterDrawerDeleted; likewise
replace 'Show Deleted' and 'Hide Blocked Tasks' with
SentenceManager(...).sentences.filterDrawerShowDeleted and
SentenceManager(...).sentences.filterDrawerHideBlockedTasks respectively
(consistent with how filterDrawerCompleted/filterDrawerPending are used) and add
those keys to SentenceManager if they do not already exist.

Comment on lines 151 to 167
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(),
),
],
),
),
),
),
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Search for waitingFilter toggle usage in the codebase
rg -n "waitingFilter|toggleWaitingFilter|Show.*Waiting" --type=dart -g '!test/**'

Repository: CCExtractor/taskwarrior-flutter

Length of output: 3549


🏁 Script executed:

cat -n lib/app/modules/home/views/filter_drawer_home_page.dart

Repository: CCExtractor/taskwarrior-flutter

Length of output: 26400


Add "Show Waiting" toggle to filter drawer — feature exists but is not accessible in the UI.

The waiting filter infrastructure exists in the codebase (controller, models, persistence), with language strings already defined (filterDrawerShowWaiting), but the UI toggle is absent from the filter drawer. Users have no way to control waiting task visibility through the filter interface, despite the feature being functional in the backend.

Add a "Show Waiting" switch alongside the other filter toggles to expose this functionality to users.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@lib/app/modules/home/views/filter_drawer_home_page.dart` around lines 151 -
167, The UI is missing a "Show Waiting" toggle: add a row identical to the
existing "Show Deleted" entry but using the localized string key
filterDrawerShowWaiting for the label and binding the Switch to the waiting
filter state and toggle methods (use filters.waitingFilter for value and call
filters.toggleWaitingFilter() in onChanged). Match the existing Text style
(FontFamily.poppins, TaskWarriorFonts.fontSizeMedium, tColors.primaryTextColor)
and place the new toggle alongside the other filter switches in the same
container so users can control waiting-task visibility.

Comment on lines 56 to +57
var taskrc = Taskrc.fromString(contents);
server = taskrc.server;
credentials = taskrc.credentials;
trust = taskrc.trust;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Fixture load updates only trust, leaving controller state partially stale.

At Line 57, setConfigurationFromFixtureForDebugging() refreshes trust but not server/credentials from the same parsed Taskrc. That can desync in-memory state from the fixture file.

Proposed fix
       var taskrc = Taskrc.fromString(contents);
+      server = taskrc.server;
+      credentials = taskrc.credentials;
       trust = taskrc.trust;
+      configureCredentialString();
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@lib/app/modules/manageTaskServer/controllers/manage_task_server_controller.dart`
around lines 56 - 57, The fixture loader setConfigurationFromFixtureForDebugging
currently parses Taskrc and only assigns trust (taskrc.trust), leaving
controller fields server and credentials stale; update the same method to also
refresh server and credentials from the parsed Taskrc (e.g., assign server =
taskrc.server and credentials = taskrc.credentials or map equivalent fields) so
controller state stays in sync with the fixture; locate the assignments in
setConfigurationFromFixtureForDebugging and ensure all relevant controller
properties (trust, server, credentials) are updated from Taskrc.

Comment on lines +47 to +48
case SupportedLanguage.system:
return 'Follow System Language';
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Localize the new system-language label.

Follow System Language bypasses the app's translation layer, so this new option will stay in English even when the rest of Settings is localized.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@lib/app/modules/settings/views/settings_page_select_the_language_trailing.dart`
around lines 47 - 48, The literal 'Follow System Language' returned for
SupportedLanguage.system should be replaced with the app's localized string;
update the switch/case that maps SupportedLanguage to a label (the code
returning that literal) to call the project's localization accessor (e.g.
AppLocalizations.of(context).followSystemLanguage or
context.l10n.followSystemLanguage) instead of the hard-coded English text,
ensuring you obtain a BuildContext where this mapping function is called or pass
context into it.

Comment on lines +507 to +553
Future<void> showDependencyPicker() async {
// Get all pending tasks except current
final allTasks = await taskDatabase.fetchTasksFromDatabase();
final BuildContext context = Get.context!;
TaskwarriorColorTheme tColors =
Theme.of(context).extension<TaskwarriorColorTheme>()!;

await Get.dialog(
AlertDialog(
backgroundColor: tColors.secondaryBackgroundColor,
title: Text('Select Dependencies', style: TextStyle(color: tColors.primaryTextColor)),
content: StatefulBuilder(
builder: (context, setState) {
return SizedBox(
width: double.maxFinite,
child: ListView(
shrinkWrap: true,
children: allTasks
.where((t) => t.uuid != initialTask.uuid && t.status == 'pending')
.map((t) => CheckboxListTile(
title: Text(t.description, style: TextStyle(color: tColors.primaryTextColor)),
value: depends.contains(t.uuid),
onChanged: (checked) {
setState(() {
if (checked == true) {
depends.add(t.uuid!);
} else {
depends.remove(t.uuid);
}
hasChanges.value = true;
});
},
))
.toList(),
),
);
},
),
actions: [
TextButton(
onPressed: () => Get.back(),
child: Text('Done', style: TextStyle(color: tColors.primaryTextColor)),
),
],
),
);
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Dependency edits are never persisted.

This dialog mutates depends and flips hasChanges, but neither save path writes that list back out: saveEditedTaskInDB(...) is still called without depends for TaskForC, and the TaskForReplica built in saveTask() never sets depends. Users can select dependencies, tap save, and silently lose the change.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@lib/app/modules/taskc_details/controllers/taskc_details_controller.dart`
around lines 507 - 553, The dependency picker mutates depends and sets
hasChanges but those changes are never persisted; update the save paths so the
edited depends list is written back: when calling saveEditedTaskInDB(...) ensure
the TaskForC instance passed includes the updated depends, and when building the
TaskForReplica in saveTask() set its depends field from the controller's depends
list (or propagate depends into whatever object is saved); modify the
saveEditedTaskInDB callsite and the TaskForReplica construction to copy the
current depends list so selected dependencies are persisted.

Comment on lines +524 to +533
children: allTasks
.where((t) => t.uuid != initialTask.uuid && t.status == 'pending')
.map((t) => CheckboxListTile(
title: Text(t.description, style: TextStyle(color: tColors.primaryTextColor)),
value: depends.contains(t.uuid),
onChanged: (checked) {
setState(() {
if (checked == true) {
depends.add(t.uuid!);
} else {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Don't force-unwrap nullable task UUIDs here.

TaskForC.uuid is nullable, so selecting a pending task without a UUID will throw at t.uuid!. Either filter those rows out before building the list or use a non-null fallback identifier.

Minimal guard
children: allTasks
-    .where((t) => t.uuid != initialTask.uuid && t.status == 'pending')
+    .where((t) => t.uuid != null && t.uuid != initialTask.uuid && t.status == 'pending')
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
children: allTasks
.where((t) => t.uuid != initialTask.uuid && t.status == 'pending')
.map((t) => CheckboxListTile(
title: Text(t.description, style: TextStyle(color: tColors.primaryTextColor)),
value: depends.contains(t.uuid),
onChanged: (checked) {
setState(() {
if (checked == true) {
depends.add(t.uuid!);
} else {
children: allTasks
.where((t) => t.uuid != null && t.uuid != initialTask.uuid && t.status == 'pending')
.map((t) => CheckboxListTile(
title: Text(t.description, style: TextStyle(color: tColors.primaryTextColor)),
value: depends.contains(t.uuid),
onChanged: (checked) {
setState(() {
if (checked == true) {
depends.add(t.uuid!);
} else {
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@lib/app/modules/taskc_details/controllers/taskc_details_controller.dart`
around lines 524 - 533, The code is force-unwrapping nullable TaskForC.uuid
(t.uuid!) inside the CheckboxListTile which can throw; update the list building
to skip tasks with null UUIDs (e.g., add .where((t) => t.uuid != null) to the
chain) or otherwise use a safe non-null key (e.g., use a stable fallback like
t.hashCode or t.id if available) and replace t.uuid! with the safe value; ensure
references to depends.contains(...) and depends.add(...) use the same non-null
identifier so no forced unwrapping occurs (check symbols: allTasks, initialTask,
depends, t.uuid, CheckboxListTile).

Comment on lines +26 to +28
static Future clearSelectedLanguage() async {
await _preferences?.remove('_selectedLanguage');
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Missing closing brace/newline formatting.

The clearSelectedLanguage method is missing a closing brace for the method body, and there's no blank line before the class closing brace.

Proposed fix
   static Future clearSelectedLanguage() async {
     await _preferences?.remove('_selectedLanguage');
+  }
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
static Future clearSelectedLanguage() async {
await _preferences?.remove('_selectedLanguage');
}
static Future clearSelectedLanguage() async {
await _preferences?.remove('_selectedLanguage');
}
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@lib/app/utils/app_settings/selected_language.dart` around lines 26 - 28, The
clearSelectedLanguage method is missing its closing brace and the class lacks a
blank line before the final closing brace; add the missing closing brace to
terminate the static Future clearSelectedLanguage() async { ... } method (which
uses _preferences?.remove('_selectedLanguage')), ensure the method body is
properly closed, and insert a single blank line before the class's closing brace
to match file formatting.

Comment on lines +72 to +79
supportedLocales: const [
Locale('en'),
Locale('hi'),
Locale('mr'),
Locale('fr'),
Locale('es'),
Locale('bn'),
],
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Missing locales: de (German) and ur (Urdu) are defined in SupportedLanguage but not in supportedLocales.

The SupportedLanguage enum in lib/app/utils/language/supported_language.dart includes german ('de') and urdu ('ur'), but they're absent from supportedLocales. This mismatch will cause Flutter to fall back to the default locale when a user selects German or Urdu, potentially resulting in unexpected behavior.

Proposed fix
       supportedLocales: const [
         Locale('en'),
         Locale('hi'),
         Locale('mr'),
         Locale('fr'),
         Locale('es'),
         Locale('bn'),
+        Locale('de'),
+        Locale('ur'),
       ],
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@lib/main.dart` around lines 72 - 79, The supportedLocales list in main.dart
is missing the German and Urdu entries defined in SupportedLanguage, causing
locale fallback for those selections; update the supportedLocales constant (the
list referenced by supportedLocales) to include Locale('de') and Locale('ur') so
it matches the SupportedLanguage enum in
lib/app/utils/language/supported_language.dart and ensure any related locale
resolution logic uses those entries.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Hide waiting tasks

2 participants