Skip to content

TF-4479 Clear trash subfolders with Riverpod state management#4576

Open
dab246 wants to merge 10 commits into
masterfrom
enhancement/tf-4479-remove-trash-sub-folders-r3
Open

TF-4479 Clear trash subfolders with Riverpod state management#4576
dab246 wants to merge 10 commits into
masterfrom
enhancement/tf-4479-remove-trash-sub-folders-r3

Conversation

@dab246

@dab246 dab246 commented Jun 2, 2026

Copy link
Copy Markdown
Member

Issue

#4479

Summary

  • Add DeleteTrashSubfoldersNotifier (@riverpod, sealed state hierarchy) to handle async deletion of trash subfolders
  • Add MailboxProviderListenerWidget at mailbox view scope to listen to notifier state (toast + refresh)
  • Wire action to context menu, long-press, and empty-trash banner (thread view + dashboard web)
  • Add l10n strings for success / partial-success / failure outcomes
  • Add unit tests for DeleteTrashSubfoldersNotifier

Summary by CodeRabbit

Release Notes

  • New Features

    • Enhanced trash folder clearing with support for removing nested subfolders
    • Improved confirmation dialogs for trash operations with better visual feedback
    • Added progress tracking during folder cleanup operations
    • Localized messages for subfolder deletion outcomes (success, partial, failure)
  • Bug Fixes

    • Fixed trash banner visibility to correctly detect folder contents including subfolders
    • Improved handling of partial folder deletion scenarios

@coderabbitai

coderabbitai Bot commented Jun 2, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 30fa6a80-2215-4197-827d-799249c7bc6b

📥 Commits

Reviewing files that changed from the base of the PR and between e3cc31d and cf6f0a6.

📒 Files selected for processing (36)
  • lib/features/base/base_controller.dart
  • lib/features/base/mixin/mailbox_action_handler_mixin.dart
  • lib/features/base/urgent_exception_handler.dart
  • lib/features/mailbox/data/repository/mailbox_repository_impl.dart
  • lib/features/mailbox/presentation/model/mailbox_node.dart
  • lib/features/mailbox/presentation/widgets/label_mailbox_item_widget.dart
  • lib/features/mailbox/presentation/widgets/trailing_mailbox_item_widget.dart
  • lib/features/mailbox_dashboard/domain/state/empty_folder_state.dart
  • lib/features/mailbox_dashboard/presentation/bindings/mailbox_dashboard_bindings.dart
  • lib/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller.dart
  • lib/features/mailbox_dashboard/presentation/delegates/dashboard_provider_listener_delegate.dart
  • lib/features/mailbox_dashboard/presentation/delegates/empty_folder_provider_listener_delegate.dart
  • lib/features/mailbox_dashboard/presentation/dialogs/empty_trash_confirmation_dialog.dart
  • lib/features/mailbox_dashboard/presentation/extensions/delete_emails_in_mailbox_extension.dart
  • lib/features/mailbox_dashboard/presentation/extensions/map_mailbox_by_id_extension.dart
  • lib/features/mailbox_dashboard/presentation/mailbox_dashboard_view.dart
  • lib/features/mailbox_dashboard/presentation/mailbox_dashboard_view_web.dart
  • lib/features/mailbox_dashboard/presentation/model/empty_folder_request.dart
  • lib/features/mailbox_dashboard/presentation/providers/empty_folder_provider.dart
  • lib/features/mailbox_dashboard/presentation/riverpod_widgets/mailbox_dashboard_provider_listener_widget.dart
  • lib/features/mailbox_dashboard/presentation/strategies/empty_folder_strategy.dart
  • lib/features/mailbox_dashboard/presentation/strategies/empty_folder_tag.dart
  • lib/features/mailbox_dashboard/presentation/strategies/trash_folder_strategy.dart
  • lib/features/mailbox_dashboard/presentation/widgets/empty_trash_banner_widget.dart
  • lib/features/thread/presentation/thread_view.dart
  • lib/l10n/intl_messages.arb
  • lib/main/localizations/app_localizations.dart
  • lib/main/providers/app_toast_provider.dart
  • model/lib/extensions/presentation_mailbox_extension.dart
  • test/features/mailbox/repository/mailbox_respository_test.dart
  • test/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller_test.dart
  • test/features/mailbox_dashboard/presentation/providers/empty_trash_notifier_test.dart
  • test/features/mailbox_dashboard/presentation/strategies/trash_folder_strategy_test.dart
  • test/features/mailbox_dashboard/presentation/view/mailbox_dashboard_view_widget_test.dart
  • test/features/search/verify_before_time_in_search_email_filter_test.dart
  • test/fixtures/widget_fixtures.dart
💤 Files with no reviewable changes (1)
  • test/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller_test.dart
✅ Files skipped from review due to trivial changes (2)
  • lib/features/mailbox_dashboard/presentation/extensions/map_mailbox_by_id_extension.dart
  • lib/features/mailbox_dashboard/presentation/strategies/empty_folder_tag.dart
🚧 Files skipped from review as they are similar to previous changes (27)
  • test/fixtures/widget_fixtures.dart
  • lib/features/base/mixin/mailbox_action_handler_mixin.dart
  • lib/features/base/urgent_exception_handler.dart
  • lib/features/mailbox/presentation/widgets/label_mailbox_item_widget.dart
  • model/lib/extensions/presentation_mailbox_extension.dart
  • lib/features/mailbox_dashboard/presentation/model/empty_folder_request.dart
  • lib/features/mailbox/presentation/model/mailbox_node.dart
  • lib/features/mailbox/presentation/widgets/trailing_mailbox_item_widget.dart
  • lib/features/base/base_controller.dart
  • lib/features/mailbox_dashboard/presentation/mailbox_dashboard_view.dart
  • test/features/mailbox/repository/mailbox_respository_test.dart
  • lib/features/mailbox_dashboard/presentation/widgets/empty_trash_banner_widget.dart
  • lib/features/mailbox/data/repository/mailbox_repository_impl.dart
  • lib/features/mailbox_dashboard/presentation/extensions/delete_emails_in_mailbox_extension.dart
  • lib/features/mailbox_dashboard/presentation/delegates/dashboard_provider_listener_delegate.dart
  • lib/features/mailbox_dashboard/domain/state/empty_folder_state.dart
  • lib/features/mailbox_dashboard/presentation/strategies/trash_folder_strategy.dart
  • lib/main/localizations/app_localizations.dart
  • lib/features/mailbox_dashboard/presentation/bindings/mailbox_dashboard_bindings.dart
  • lib/l10n/intl_messages.arb
  • test/features/mailbox_dashboard/presentation/providers/empty_trash_notifier_test.dart
  • test/features/mailbox_dashboard/presentation/strategies/trash_folder_strategy_test.dart
  • lib/features/mailbox_dashboard/presentation/strategies/empty_folder_strategy.dart
  • lib/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller.dart
  • lib/features/mailbox_dashboard/presentation/delegates/empty_folder_provider_listener_delegate.dart
  • test/features/search/verify_before_time_in_search_email_filter_test.dart
  • lib/features/mailbox_dashboard/presentation/providers/empty_folder_provider.dart

Walkthrough

This PR refactors trash folder emptying from synchronous controller execution to an asynchronous stream-based provider pattern. It introduces an UrgentExceptionHandler interface for exception routing, defines domain states and a strategy pattern for extensible folder clearing, implements provider-based state management with delegate coordination for UI updates, and updates mailbox visibility logic to consider subfolders. The changes include new Riverpod providers and notifiers for two-phase empty-folder operations (email clearing plus subfolder deletion), responsive UI components for confirmation and progress, localization support for subfolder deletion outcomes, and comprehensive test coverage.

Possibly related PRs

  • linagora/tmail-flutter#4429: Updates to MailboxActionHandlerMixin.emptyTrashAction to use the refactored dashboardController.emptyTrashFolderAction with the new trashMailbox: parameter signature introduced here.
  • linagora/tmail-flutter#2519: The new empty-trash flow relies on DeleteMultipleMailboxInteractor for subfolder deletion coordination, which was updated in that PR.

Suggested reviewers

  • hoangdat
  • jbrnzl
  • 9clg6
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main objective: implementing clearing trash subfolders with Riverpod state management.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch enhancement/tf-4479-remove-trash-sub-folders-r3

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.

codescene-delta-analysis[bot]

This comment was marked as outdated.

Comment thread lib/features/mailbox/presentation/widgets/mailbox_provider_listener_widget.dart Outdated
@hoangdat

hoangdat commented Jun 2, 2026

Copy link
Copy Markdown
Member

How about to completely move all the logic of clear trash into a specific provider?

@dab246

dab246 commented Jun 2, 2026

Copy link
Copy Markdown
Member Author

How about to completely move all the logic of clear trash into a specific provider?

The execution logic is already fully contained in EmptyTrashNotifier. What remains in the widget are UI-only side effects: showing toasts (which require BuildContext) and dispatching GetX actions (which require the controller). These responsibilities cannot live in a pure Riverpod provider. The current separation, business logic in the provider and UI reactions in the widget, is both intentional and the correct architectural boundary.

codescene-delta-analysis[bot]

This comment was marked as outdated.

codescene-delta-analysis[bot]

This comment was marked as outdated.

@github-actions

github-actions Bot commented Jun 2, 2026

Copy link
Copy Markdown

This PR has been deployed to https://linagora.github.io/tmail-flutter/4576.

codescene-delta-analysis[bot]

This comment was marked as outdated.

@dab246 dab246 force-pushed the enhancement/tf-4479-remove-trash-sub-folders-r3 branch from 88b255d to cced3ce Compare June 3, 2026 03:50
codescene-delta-analysis[bot]

This comment was marked as outdated.

Comment thread lib/features/mailbox_dashboard/presentation/providers/empty_trash_provider.dart Outdated
Comment thread lib/features/mailbox/presentation/widgets/mailbox_provider_listener_widget.dart Outdated
@dab246 dab246 marked this pull request as ready for review June 3, 2026 09:36
@dab246 dab246 requested a review from hoangdat June 3, 2026 09:37
codescene-delta-analysis[bot]

This comment was marked as outdated.

codescene-delta-analysis[bot]

This comment was marked as outdated.

@dab246 dab246 requested a review from hoangdat June 4, 2026 10:05

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Caution

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

⚠️ Outside diff range comments (1)
lib/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller.dart (1)

1891-1893: ⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

Resolve the selected team trash before falling back to personal trash.

This branch only accepts selectedMailbox when isTrash == true. But the same controller enables the empty-trash flow for isTrashTeamMailbox on Lines 2417-2430, and DeleteActionType.all reaches this method without passing trashMailbox on Line 1875. From a team-trash screen, this can fall through to mapDefaultMailboxIdByRole[roleTrash] and purge the personal trash instead of the selected team trash.

Proposed fix
-    final trashFolder = trashMailbox
-        ?? (selectedMailbox.value?.isTrash == true ? selectedMailbox.value : null)
+    final trashFolder = trashMailbox
+        ?? ((selectedMailbox.value?.isTrash == true ||
+                (selectedMailbox.value?.isTrashTeamMailbox == true &&
+                    selectedMailbox.value?.myRights?.mayRemoveItems == true))
+            ? selectedMailbox.value
+            : null)
         ?? mapMailboxById[mapDefaultMailboxIdByRole[PresentationMailbox.roleTrash]];
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@lib/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller.dart`
around lines 1891 - 1893, The current fallback for trashFolder ignores selected
team trash and can pick the personal trash; update the selection logic so
selectedMailbox is accepted when it's either a personal trash or a team trash.
Concretely, change the conditional around selectedMailbox in the expression that
builds trashFolder (the code referencing trashMailbox, selectedMailbox, isTrash,
isTrashTeamMailbox, mapMailboxById and
mapDefaultMailboxIdByRole[PresentationMailbox.roleTrash]) to treat
selectedMailbox.value as valid when selectedMailbox.value?.isTrash == true ||
selectedMailbox.value?.isTrashTeamMailbox == true so team-trash screens resolve
to the selected team trash before falling back to the default personal trash.
🧹 Nitpick comments (1)
test/features/mailbox/repository/mailbox_respository_test.dart (1)

289-301: ⚡ Quick win

Strengthen this test to validate non-empty error passthrough.

The setup at Line 293-294 returns an empty network error map, so Line 300 only proves “empty stays empty.” It doesn’t validate the stated behavior (“original error map is returned”) when the map is non-empty.

Proposed test tightening
     test(
       'SHOULD return the original error map \n'
       'WHEN local cache update throws',
     () async {
-      when(mailboxDataSource.deleteMultipleMailbox(sessionFixture, accountIdFixture, [mailboxIdA]))
-        .thenAnswer((_) async => {});
+      final networkErrors = {
+        mailboxIdB.id: SetError(ErrorType('serverFail')),
+      };
+      when(mailboxDataSource.deleteMultipleMailbox(sessionFixture, accountIdFixture, [mailboxIdA, mailboxIdB]))
+        .thenAnswer((_) async => networkErrors);
       when(mailboxCacheDataSourceImpl.update(accountIdFixture, userNameFixture, destroyed: anyNamed('destroyed')))
         .thenThrow(Exception('cache error'));
 
-      final result = await mailboxRepository.deleteMultipleMailbox(sessionFixture, accountIdFixture, [mailboxIdA]);
+      final result = await mailboxRepository.deleteMultipleMailbox(sessionFixture, accountIdFixture, [mailboxIdA, mailboxIdB]);
 
-      expect(result, isEmpty);
+      expect(result, same(networkErrors));
+      verify(mailboxCacheDataSourceImpl.update(
+        accountIdFixture,
+        userNameFixture,
+        destroyed: [mailboxIdA],
+      )).called(1);
     });
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@test/features/mailbox/repository/mailbox_respository_test.dart` around lines
289 - 301, The test currently stubs mailboxDataSource.deleteMultipleMailbox to
return an empty map so it only proves emptiness is preserved; change the stub
for mailboxDataSource.deleteMultipleMailbox (used by
mailboxRepository.deleteMultipleMailbox) to return a non-empty error map (e.g.
{'someError': 'details'}) and keep mailboxCacheDataSourceImpl.update throwing
Exception('cache error'), then assert that the result from
mailboxRepository.deleteMultipleMailbox equals that same non-empty error map to
verify proper passthrough; reference the mailboxRepository.deleteMultipleMailbox
call and the stubs for mailboxDataSource.deleteMultipleMailbox and
mailboxCacheDataSourceImpl.update when making this change.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In
`@lib/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller.dart`:
- Around line 1891-1893: The current fallback for trashFolder ignores selected
team trash and can pick the personal trash; update the selection logic so
selectedMailbox is accepted when it's either a personal trash or a team trash.
Concretely, change the conditional around selectedMailbox in the expression that
builds trashFolder (the code referencing trashMailbox, selectedMailbox, isTrash,
isTrashTeamMailbox, mapMailboxById and
mapDefaultMailboxIdByRole[PresentationMailbox.roleTrash]) to treat
selectedMailbox.value as valid when selectedMailbox.value?.isTrash == true ||
selectedMailbox.value?.isTrashTeamMailbox == true so team-trash screens resolve
to the selected team trash before falling back to the default personal trash.

---

Nitpick comments:
In `@test/features/mailbox/repository/mailbox_respository_test.dart`:
- Around line 289-301: The test currently stubs
mailboxDataSource.deleteMultipleMailbox to return an empty map so it only proves
emptiness is preserved; change the stub for
mailboxDataSource.deleteMultipleMailbox (used by
mailboxRepository.deleteMultipleMailbox) to return a non-empty error map (e.g.
{'someError': 'details'}) and keep mailboxCacheDataSourceImpl.update throwing
Exception('cache error'), then assert that the result from
mailboxRepository.deleteMultipleMailbox equals that same non-empty error map to
verify proper passthrough; reference the mailboxRepository.deleteMultipleMailbox
call and the stubs for mailboxDataSource.deleteMultipleMailbox and
mailboxCacheDataSourceImpl.update when making this change.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 2fa8f2f0-ee0f-4474-9a67-51ff4bbb57b5

📥 Commits

Reviewing files that changed from the base of the PR and between 06d87d2 and 7ddeeb9.

📒 Files selected for processing (8)
  • lib/features/mailbox/data/repository/mailbox_repository_impl.dart
  • lib/features/mailbox_dashboard/domain/state/empty_folder_state.dart
  • lib/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller.dart
  • lib/features/mailbox_dashboard/presentation/delegates/dashboard_provider_listener_delegate.dart
  • lib/features/mailbox_dashboard/presentation/delegates/empty_folder_provider_listener_delegate.dart
  • lib/features/mailbox_dashboard/presentation/providers/empty_folder_provider.dart
  • lib/features/mailbox_dashboard/presentation/riverpod_widgets/mailbox_dashboard_provider_listener_widget.dart
  • test/features/mailbox/repository/mailbox_respository_test.dart
🚧 Files skipped from review as they are similar to previous changes (2)
  • lib/features/mailbox_dashboard/presentation/delegates/dashboard_provider_listener_delegate.dart
  • lib/features/mailbox_dashboard/presentation/delegates/empty_folder_provider_listener_delegate.dart

@dab246

dab246 commented Jun 4, 2026

Copy link
Copy Markdown
Member Author

⚠️ Outside diff range comments (1)

lib/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller.dart (1)> 1891-1893: ⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

Resolve the selected team trash before falling back to personal trash.
This branch only accepts selectedMailbox when isTrash == true. But the same controller enables the empty-trash flow for isTrashTeamMailbox on Lines 2417-2430, and DeleteActionType.all reaches this method without passing trashMailbox on Line 1875. From a team-trash screen, this can fall through to mapDefaultMailboxIdByRole[roleTrash] and purge the personal trash instead of the selected team trash.

🧹 Nitpick comments (1)

test/features/mailbox/repository/mailbox_respository_test.dart (1)> 289-301: ⚡ Quick win

Strengthen this test to validate non-empty error passthrough.
The setup at Line 293-294 returns an empty network error map, so Line 300 only proves “empty stays empty.” It doesn’t validate the stated behavior (“original error map is returned”) when the map is non-empty.

Fixed

codescene-delta-analysis[bot]

This comment was marked as outdated.

codescene-delta-analysis[bot]

This comment was marked as outdated.

tddang-linagora
tddang-linagora previously approved these changes Jun 5, 2026
@hoangdat

hoangdat commented Jun 5, 2026

Copy link
Copy Markdown
Member

hi @jbrnzl @C. it is in better shape, can you take a look and give us the feedback. Thank you

@@ -0,0 +1,7 @@
import 'package:core/presentation/state/failure.dart';

abstract class UrgentExceptionHandler {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

IMO, it is not in use, why not create a separate instance for it and use directly with EmptyFolderProviderListenerDelegate?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

It's still in use. It's used in the listener, and Riverpod uses it via GetX binding.

import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/delegates/dashboard_provider_listener_delegate.dart';

class MailboxDashboardProviderListenerWidget extends ConsumerStatefulWidget {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

with the idea of delegate, in the future controller will use as a place to keep the data, variable, ...?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

No. The controller will all be moved to Riverpod later.

BuildContext context, {
required SubfoldersDeleteStatus subfoldersStatus,
}) {
final appToast = getBinding<AppToast>();

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

how about we should minimize using getBinding to use riverpod more?
create AppToast with riverpod the use it here? wdyt?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

AppToast is independent of any classes. Therefore, we can convert it to RiverPod for use. Fixed

import 'package:tmail_ui_user/main/routes/route_navigation.dart';

extension ExecuteEmptyTrashExtension on MailboxDashBoardController {
List<MailboxId> childMailboxIds(PresentationMailbox parent) => mapMailboxById

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

should move it as a extension of Map, no need to make extension of controller bigger.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

reasonable, fixed

.map((m) => m.id)
.toList();

void requestEmptyTrash(

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

why need to define as a method in extension? we should find the way to reduce extension as much as possible.

how about to separate it as a dialog and have the callback? we can eliminate this extension?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

reasonable, fixed

codescene-delta-analysis[bot]

This comment was marked as outdated.

Base automatically changed from feat/riverpod-3-upgrade to master June 10, 2026 12:25
@hoangdat hoangdat dismissed tddang-linagora’s stale review June 10, 2026 12:25

The base branch was changed.

@dab246 dab246 force-pushed the enhancement/tf-4479-remove-trash-sub-folders-r3 branch from 034ee22 to cf6f0a6 Compare June 11, 2026 08:59

@codescene-delta-analysis codescene-delta-analysis Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Code Health Improved (4 files improve in Code Health)

Gates Failed
Prevent hotspot decline (1 hotspot with Lines of Code in a Single File)

Our agent can fix these. Install it.

Gates Passed
2 Quality Gates Passed

Reason for failure
Prevent hotspot decline Violations Code Health Impact
app_localizations.dart 1 rule in this hotspot 8.55 → 8.03 Suppress

See analysis details in CodeScene

View Improvements
File Code Health Impact Categories Improved
mailbox_dashboard_controller.dart 6.66 → 6.68 Lines of Declarations in a Single File, Low Cohesion, Complex Method
mailbox_dashboard_view_web.dart 6.75 → 6.78 Overall Code Complexity
mailbox_dashboard_controller_test.dart 9.00 → 9.00 Large Method
mailbox_dashboard_view_widget_test.dart 9.38 → 9.38 Large Method

Absence of Expected Change Pattern

  • tmail-flutter/lib/features/mailbox/data/repository/mailbox_repository_impl.dart is usually changed with: tmail-flutter/lib/features/mailbox/data/datasource_impl/mailbox_cache_datasource_impl.dart, tmail-flutter/lib/features/mailbox/data/datasource_impl/mailbox_datasource_impl.dart, tmail-flutter/lib/features/mailbox/data/datasource/mailbox_datasource.dart

Quality Gate Profile: The Bare Minimum
Install CodeScene MCP: safeguard and uplift AI-generated code. Catch issues early with our IDE extension and CLI tool.

@chibenwa

Copy link
Copy Markdown
Member

Why app_localizations.dart goes down in code quality ?

I saw this in a couple of code scene PRs and it gets me curious...

@dab246

dab246 commented Jun 12, 2026

Copy link
Copy Markdown
Member Author

Why app_localizations.dart goes down in code quality ?

I saw this in a couple of code scene PRs and it gets me curious...

I think we discussed this in a previous PR, perhaps you've forgotten (#4553 (comment)). Basically, it's because app_localizations.dart is the only file containing declarations for all Strings in the app, so the number of lines of code in this file is currently exceeding the Code Scene limit, leading to the error Lines of code in a single file.

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.

4 participants