TF-4179 Display tag list in sidebar#4181
Conversation
|
This PR has been deployed to https://linagora.github.io/tmail-flutter/4181. |
beae897 to
0b6c177
Compare
|
8b64b6e to
63e7d93
Compare
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the You can disable this status message by setting the WalkthroughThis 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
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20–25 minutes Key areas requiring attention:
Poem
Pre-merge checks and finishing touches✅ Passed checks (3 passed)
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. Comment |
|
@coderabbitai help Please review this PR |
|
@dab246: I'll review the changes in this PR right away! ✅ Actions performedReview triggered.
|
There was a problem hiding this comment.
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
labelListExpandModeandtoggleLabelListState()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 accessibilityThe widget is clean and focused. If you expect screen‑reader users to navigate labels via this icon, you might add an optional
semanticsLabeland pass it toSvgPicture.assetso 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 colorThe bar logic and conditions (expand only when
expandMode != null && countLabels > 0, show add icon only whenonAddNewLabel != null) look good. A couple of small tweaks could improve clarity and consistency:
- Build the add‑new‑label icon only when
onAddNewLabelis non‑null, instead of eagerly:- Cache
AppLocalizations.of(context)once.- Optionally use a theme color instead of
Colors.blackfor 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
⛔ Files ignored due to path filters (1)
assets/images/ic_tag.svgis 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: Ensureic_tag.svgasset is wired correctly
icTagfollows the existing image path pattern; just make sureic_tag.svgactually exists underAssetsPaths.imagesand is declared inpubspec.yamlso it doesn’t fail at runtime.lib/main/localizations/app_localizations.dart (1)
5440-5452: New localization keys follow existing pattern
labelsandnewLabelare 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:LabelNameWidgetimplementation looks solidSingle-line, ellipsized text with desktop/mobile styles wired via
ThemeUtilsis 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 clearerWrapping the label capability logic in
isLabelCapabilitySupportedand reusing it both in_setUpComponentsFromSessionand the UI (sidebar) keeps the behavior consistent. The early return whenaccountIdorsessionCurrentare 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 coherentAdding
LabelsBarWidgetandLabelListViewafter the folders section, both guarded bymailboxDashBoardController.isLabelCapabilitySupported, cleanly wires label UI into the existing mailbox column without impacting accounts that lack the capability.Since
buildLabelsListrenders inside the outerSingleChildScrollView, just ensureLabelListViewitself is non-scrollable (or usesshrinkWrap/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
labelsandnewLabelentries (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 idiomaticUse of
ListView.builderwithPageStorageKey,shrinkWrap: true, andprimary: falseis appropriate for a sidebar‑style nested list, and the mobile/desktop padding split is clear. No issues from this snippet.
Added sort-label.mov |
Issue
#4179
Resolved
Screen.Recording.2025-11-25.at.18.52.19.mov
Summary by CodeRabbit
✏️ Tip: You can customize this high-level summary in your review settings.