From 245d9d990b3be339eae1ccb34c63b6354393fcb9 Mon Sep 17 00:00:00 2001 From: Chris Bobbe Date: Wed, 21 May 2025 14:54:41 -0700 Subject: [PATCH] msglist: Colorize channel icon in the app bar, following Figma The Figma: https://www.figma.com/design/1JTNtYo9memgW7vV6d0ygq/Zulip-Mobile?node-id=6089-28394&m=dev And while we're adding a test for it, also check that the chosen channel icon is the intended one. --- lib/widgets/message_list.dart | 13 ++++++++++-- test/widgets/message_list_test.dart | 31 +++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 2 deletions(-) diff --git a/lib/widgets/message_list.dart b/lib/widgets/message_list.dart index 3bc7d60363..2c24638f86 100644 --- a/lib/widgets/message_list.dart +++ b/lib/widgets/message_list.dart @@ -329,9 +329,18 @@ class MessageListAppBarTitle extends StatelessWidget { Widget _buildStreamRow(BuildContext context, { ZulipStream? stream, }) { + final store = PerAccountStoreWidget.of(context); final zulipLocalizations = ZulipLocalizations.of(context); + // A null [Icon.icon] makes a blank space. - final icon = stream != null ? iconDataForStream(stream) : null; + IconData? icon; + Color? iconColor; + if (stream != null) { + icon = iconDataForStream(stream); + iconColor = colorSwatchFor(context, store.subscriptions[stream.streamId]) + .iconOnBarBackground; + } + return Row( mainAxisSize: MainAxisSize.min, // TODO(design): The vertical alignment of the stream privacy icon is a bit ad hoc. @@ -339,7 +348,7 @@ class MessageListAppBarTitle extends StatelessWidget { // https://github.com/zulip/zulip-flutter/pull/219#discussion_r1281024746 crossAxisAlignment: CrossAxisAlignment.center, children: [ - Icon(size: 16, icon), + Icon(size: 16, color: iconColor, icon), const SizedBox(width: 4), Flexible(child: Text( stream?.name ?? zulipLocalizations.unknownChannelName)), diff --git a/test/widgets/message_list_test.dart b/test/widgets/message_list_test.dart index 606a01f420..69aa693706 100644 --- a/test/widgets/message_list_test.dart +++ b/test/widgets/message_list_test.dart @@ -19,6 +19,7 @@ import 'package:zulip/model/message_list.dart'; import 'package:zulip/model/narrow.dart'; import 'package:zulip/model/store.dart'; import 'package:zulip/model/typing_status.dart'; +import 'package:zulip/widgets/app_bar.dart'; import 'package:zulip/widgets/autocomplete.dart'; import 'package:zulip/widgets/color.dart'; import 'package:zulip/widgets/compose_box.dart'; @@ -211,6 +212,36 @@ void main() { channel.name, eg.defaultRealmEmptyTopicDisplayName); }); + void testChannelIconInChannelRow(IconData expectedIcon, { + required bool isWebPublic, + required bool inviteOnly, + }) { + final description = 'channel icon in channel row; ' + 'web-public: $isWebPublic, invite-only: $inviteOnly'; + testWidgets(description, (tester) async { + final color = 0xff95a5fd; + + final channel = eg.stream(isWebPublic: isWebPublic, inviteOnly: inviteOnly); + final subscription = eg.subscription(channel, color: color); + + await setupMessageListPage(tester, + narrow: ChannelNarrow(channel.streamId), + streams: [channel], + subscriptions: [subscription], + messages: [eg.streamMessage(stream: channel)]); + + final iconElement = tester.element(find.descendant( + of: find.byType(ZulipAppBar), + matching: find.byIcon(expectedIcon))); + + check(Theme.brightnessOf(iconElement)).equals(Brightness.light); + check(iconElement.widget as Icon).color.equals(Color(0xff5972fc)); + }); + } + testChannelIconInChannelRow(ZulipIcons.globe, isWebPublic: true, inviteOnly: false); + testChannelIconInChannelRow(ZulipIcons.lock, isWebPublic: false, inviteOnly: true); + testChannelIconInChannelRow(ZulipIcons.hash_sign, isWebPublic: false, inviteOnly: false); + testWidgets('has channel-feed action for topic narrows', (tester) async { final pushedRoutes = >[]; final navObserver = TestNavigatorObserver()