Skip to content

TF-4179 Display tag list in sidebar#4181

Merged
hoangdat merged 6 commits intofeatures/labelfrom
feature/tf-4179-display-tag-list-in-sidebar
Dec 9, 2025
Merged

TF-4179 Display tag list in sidebar#4181
hoangdat merged 6 commits intofeatures/labelfrom
feature/tf-4179-display-tag-list-in-sidebar

Conversation

@dab246
Copy link
Member

@dab246 dab246 commented Nov 25, 2025

Issue

#4179

Resolved

Screen.Recording.2025-11-25.at.18.52.19.mov

Summary by CodeRabbit

  • New Features
    • Added Labels section to the mailbox view with collapsible interface for better organization
    • Introduced label display items showing label names and icons
    • Added ability to expand and collapse the labels list
    • Added "Add new label" action button for creating new labels

✏️ Tip: You can customize this high-level summary in your review settings.

@github-actions
Copy link

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

@dab246 dab246 force-pushed the feature/tf-4171-display-tag-in-mailbox branch 2 times, most recently from beae897 to 0b6c177 Compare December 4, 2025 08:53
@hoangdat
Copy link
Member

hoangdat commented Dec 8, 2025

  • sort in side bar

@dab246 dab246 force-pushed the feature/tf-4179-display-tag-list-in-sidebar branch from 8b64b6e to 63e7d93 Compare December 8, 2025 09:12
@coderabbitai
Copy link

coderabbitai bot commented Dec 8, 2025

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Walkthrough

This pull request introduces a labels UI feature to the mailbox, adding new widgets for displaying and managing labels, state management for expand/collapse functionality, integration into the mailbox view, and corresponding localization strings and image assets.

Changes

Cohort / File(s) Summary
Image assets and localization
core/lib/presentation/resources/image_paths.dart, lib/l10n/intl_messages.arb, lib/main/localizations/app_localizations.dart
Added icTag image path getter; added "labels" and "newLabel" localization keys with corresponding message getters
Label state management
lib/features/labels/presentation/label_controller.dart, lib/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller.dart
Added labelListExpandMode reactive field and toggleLabelListState() method to label controller; added public isLabelCapabilitySupported getter to dashboard controller
Label display widgets
lib/features/mailbox/presentation/widgets/labels/label_icon_widget.dart, lib/features/mailbox/presentation/widgets/labels/label_name_widget.dart, lib/features/mailbox/presentation/widgets/labels/label_list_item.dart, lib/features/mailbox/presentation/widgets/labels/label_list_view.dart
Created four new stateless widgets: LabelIconWidget (renders SVG icon with optional color), LabelNameWidget (displays label name with conditional styling), LabelListItem (horizontal label item with icon and name), LabelListView (scrollable list of labels with adaptive padding)
Labels bar widget
lib/features/mailbox/presentation/widgets/labels/labels_bar_widget.dart
Added LabelsBarWidget (stateless) with label text, expand/collapse toggle button, and optional add-new-label action button; supports desktop and mobile layouts
Mailbox view integration
lib/features/mailbox/presentation/base_mailbox_view.dart
Added buildLabelsBar() and buildLabelsList() builder methods to render label UI components conditionally when capability is supported

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20–25 minutes

Key areas requiring attention:

  • Widget composition and styling consistency across LabelIconWidget, LabelNameWidget, LabelListItem, and LabelsBarWidget
  • State management correctness: verify labelListExpandMode reactive updates and toggleLabelListState() integration with the UI
  • Layout responsiveness for desktop vs. mobile in LabelsBarWidget and LabelListView
  • Integration points in base_mailbox_view.dart to ensure labels bar and list render correctly alongside folder UI
  • Verify proper usage of isLabelCapabilitySupported to conditionally show/hide label features

Poem

🏷️ A labels bar with icons so bright,
Expanding lists, collapsing just right,
With tapping and toggling, the UI takes flight—
New widgets assembled, the feature's just right! 🐰✨

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title 'TF-4179 Display tag list in sidebar' directly and specifically describes the main change—adding label/tag list UI to the sidebar, which aligns with the file modifications across label widgets, controller, and mailbox views.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

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.

@dab246 dab246 changed the base branch from feature/tf-4171-display-tag-in-mailbox to features/label December 8, 2025 09:12
@dab246
Copy link
Member Author

dab246 commented Dec 8, 2025

@coderabbitai help Please review this PR

@coderabbitai
Copy link

coderabbitai bot commented Dec 8, 2025

@dab246: I'll review the changes in this PR right away!

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link

@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: 1

🧹 Nitpick comments (3)
lib/features/labels/presentation/label_controller.dart (1)

8-41: Label expand/collapse state looks good; consider sorting labels once here

labelListExpandMode and toggleLabelListState() are a clean mirror of existing folder expand/collapse handling; no functional issues spotted.

Given the PR checklist note about “sort in side bar”, this controller is a good central place to normalize ordering so all label UIs stay consistent. For example, you could sort once on success:

@override
void handleSuccessViewState(Success success) {
  if (success is GetAllLabelSuccess) {
    final sorted = [...success.labels]
      ..sort((a, b) => a.safeDisplayName.toLowerCase().compareTo(
                        b.safeDisplayName.toLowerCase()));
    labels.value = sorted;
  } else {
    super.handleSuccessViewState(success);
  }
}

This keeps the view widgets simple and guarantees stable ordering regardless of server response order.

lib/features/mailbox/presentation/widgets/labels/label_icon_widget.dart (1)

1-36: Consider exposing an optional semantics label for accessibility

The widget is clean and focused. If you expect screen‑reader users to navigate labels via this icon, you might add an optional semanticsLabel and pass it to SvgPicture.asset so callers can describe the icon when needed.

 class LabelIconWidget extends StatelessWidget {
   final String icon;
   final double iconSize;
   final EdgeInsetsGeometry padding;
   final Color? color;
+  final String? semanticsLabel;

   const LabelIconWidget({
     super.key,
     required this.icon,
     this.iconSize = MailboxIconWidgetStyles.iconSize,
     this.padding = const EdgeInsetsDirectional.only(
       end: MailboxItemWidgetStyles.labelIconSpace,
     ),
     this.color,
+    this.semanticsLabel,
   });

   @override
   Widget build(BuildContext context) {
     return Padding(
       padding: padding,
       child: SvgPicture.asset(
         icon,
         width: iconSize,
         height: iconSize,
         colorFilter: color?.asFilter(),
+        semanticsLabel: semanticsLabel,
         fit: BoxFit.fill,
       ),
     );
   }
 }
lib/features/mailbox/presentation/widgets/labels/labels_bar_widget.dart (1)

1-101: Minor cleanups: lazy-build add button and cache localization / theme color

The bar logic and conditions (expand only when expandMode != null && countLabels > 0, show add icon only when onAddNewLabel != null) look good. A couple of small tweaks could improve clarity and consistency:

  1. Build the add‑new‑label icon only when onAddNewLabel is non‑null, instead of eagerly:
  2. Cache AppLocalizations.of(context) once.
  3. Optionally use a theme color instead of Colors.black for the expand icon to better respect theming (if consistent with the folders bar).
   @override
   Widget build(BuildContext context) {
-    Widget addNewLabelIcon = TMailButtonWidget.fromIcon(
-      icon: imagePaths.icAddNewFolder,
-      backgroundColor: Colors.transparent,
-      iconColor: AppColor.steelGrayA540,
-      iconSize: 20,
-      padding: const EdgeInsets.all(5),
-      tooltipMessage: AppLocalizations.of(context).newLabel,
-      onTapActionCallback: onAddNewLabel,
-    );
-
-    if (isDesktop) {
-      addNewLabelIcon = Transform(
-        transform: Matrix4.translationValues(8, 0, 0),
-        child: addNewLabelIcon,
-      );
-    }
+    final l10n = AppLocalizations.of(context);
+
+    Widget? addNewLabelIcon;
+    if (onAddNewLabel != null) {
+      addNewLabelIcon = TMailButtonWidget.fromIcon(
+        icon: imagePaths.icAddNewFolder,
+        backgroundColor: Colors.transparent,
+        iconColor: AppColor.steelGrayA540,
+        iconSize: 20,
+        padding: const EdgeInsets.all(5),
+        tooltipMessage: l10n.newLabel,
+        onTapActionCallback: onAddNewLabel,
+      );
+
+      if (isDesktop) {
+        addNewLabelIcon = Transform(
+          transform: Matrix4.translationValues(8, 0, 0),
+          child: addNewLabelIcon,
+        );
+      }
+    }

     final labelText = Text(
-      AppLocalizations.of(context).labels,
+      l10n.labels,
       style: labelStyle ?? ThemeUtils.textStyleInter700(),
       maxLines: 1,
       overflow: TextOverflow.ellipsis,
@@
                   TMailButtonWidget.fromIcon(
                     icon: expandMode!.getIcon(
                       imagePaths,
                       DirectionUtils.isDirectionRTLByLanguage(context),
                     ),
-                    iconColor: Colors.black,
+                    // Optionally use a themed color if desired:
+                    // iconColor: Theme.of(context).iconTheme.color,
+                    iconColor: Colors.black,
@@
           if (onAddNewLabel != null)
             addNewLabelIcon,
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f7fe987 and 63e7d93.

⛔ Files ignored due to path filters (1)
  • assets/images/ic_tag.svg is excluded by !**/*.svg
📒 Files selected for processing (11)
  • core/lib/presentation/resources/image_paths.dart (1 hunks)
  • lib/features/labels/presentation/label_controller.dart (3 hunks)
  • lib/features/mailbox/presentation/base_mailbox_view.dart (2 hunks)
  • lib/features/mailbox/presentation/widgets/labels/label_icon_widget.dart (1 hunks)
  • lib/features/mailbox/presentation/widgets/labels/label_list_item.dart (1 hunks)
  • lib/features/mailbox/presentation/widgets/labels/label_list_view.dart (1 hunks)
  • lib/features/mailbox/presentation/widgets/labels/label_name_widget.dart (1 hunks)
  • lib/features/mailbox/presentation/widgets/labels/labels_bar_widget.dart (1 hunks)
  • lib/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller.dart (1 hunks)
  • lib/l10n/intl_messages.arb (2 hunks)
  • lib/main/localizations/app_localizations.dart (1 hunks)
🔇 Additional comments (7)
core/lib/presentation/resources/image_paths.dart (1)

264-264: Ensure ic_tag.svg asset is wired correctly

icTag follows the existing image path pattern; just make sure ic_tag.svg actually exists under AssetsPaths.images and is declared in pubspec.yaml so it doesn’t fail at runtime.

lib/main/localizations/app_localizations.dart (1)

5440-5452: New localization keys follow existing pattern

labels and newLabel are added consistently with the rest of this file. Just ensure the corresponding ARB entries (and translations for supported locales) exist so these don’t fall back to English unexpectedly.

lib/features/mailbox/presentation/widgets/labels/label_name_widget.dart (1)

4-25: LabelNameWidget implementation looks solid

Single-line, ellipsized text with desktop/mobile styles wired via ThemeUtils is straightforward and consistent; no issues spotted.

lib/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller.dart (1)

883-894: Centralized label capability check is safe and clearer

Wrapping the label capability logic in isLabelCapabilitySupported and reusing it both in _setUpComponentsFromSession and the UI (sidebar) keeps the behavior consistent. The early return when accountId or sessionCurrent are null also prevents accidental calls before a session is established. This refactor looks good.

lib/features/mailbox/presentation/base_mailbox_view.dart (1)

20-21: Label bar + list integration into the sidebar looks coherent

Adding LabelsBarWidget and LabelListView after the folders section, both guarded by mailboxDashBoardController.isLabelCapabilitySupported, cleanly wires label UI into the existing mailbox column without impacting accounts that lack the capability.

Since buildLabelsList renders inside the outer SingleChildScrollView, just ensure LabelListView itself is non-scrollable (or uses shrinkWrap/NeverScrollableScrollPhysics) so you don’t end up with nested vertical scrolls fighting each other on smaller screens.

Also applies to: 338-394

lib/l10n/intl_messages.arb (1)

2-2: New localization keys are consistent with existing ARB structure

labels and newLabel entries (including @ metadata) follow the existing pattern and the JSON remains valid. Just ensure corresponding keys are added/translated in other locale ARB files, if any.

Also applies to: 5132-5144

lib/features/mailbox/presentation/widgets/labels/label_list_view.dart (1)

1-44: Label list rendering looks correct and idiomatic

Use of ListView.builder with PageStorageKey, shrinkWrap: true, and primary: false is appropriate for a sidebar‑style nested list, and the mobile/desktop padding split is clear. No issues from this snippet.

@dab246
Copy link
Member Author

dab246 commented Dec 9, 2025

  • sort in side bar

Added

sort-label.mov

@hoangdat hoangdat merged commit 5b62376 into features/label Dec 9, 2025
20 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants