Skip to content

Commit 17ebb00

Browse files
committed
msglist: Add stream icon to recipient headers
Fixes: zulip#220
1 parent 22e7a35 commit 17ebb00

File tree

2 files changed

+61
-2
lines changed

2 files changed

+61
-2
lines changed

lib/widgets/message_list.dart

+12-2
Original file line numberDiff line numberDiff line change
@@ -555,16 +555,19 @@ class StreamMessageRecipientHeader extends StatelessWidget {
555555
final subscription = store.subscriptions[message.streamId];
556556
final Color backgroundColor;
557557
final Color contrastingColor;
558+
final Color iconColor;
558559
if (subscription != null) {
559560
final swatch = subscription.colorSwatch();
560561
backgroundColor = swatch.barBackground;
561562
contrastingColor =
562563
(ThemeData.estimateBrightnessForColor(swatch.barBackground) == Brightness.dark)
563564
? Colors.white
564565
: Colors.black;
566+
iconColor = swatch.iconOnBarBackground;
565567
} else {
566568
backgroundColor = _kFallbackStreamColor;
567569
contrastingColor = Colors.black;
570+
iconColor = Colors.black;
568571
}
569572
final textStyle = TextStyle(
570573
color: contrastingColor,
@@ -588,8 +591,15 @@ class StreamMessageRecipientHeader extends StatelessWidget {
588591
child: Row(
589592
crossAxisAlignment: CrossAxisAlignment.center,
590593
children: [
591-
const SizedBox(width: 16),
592-
// TODO globe/lock icons for web-public and private streams
594+
Padding(
595+
// Figma specifies 5px horizontal spacing but 6px matches
596+
// more accurately what we see in Figma.
597+
// Bottom padding added here to shift icon up to
598+
// match alignment with text visually.
599+
padding: const EdgeInsets.only(left: 6, right: 6, bottom: 3),
600+
child: Icon(size: 18, color: iconColor,
601+
// A null [Icon.icon] makes a blank space.
602+
(stream != null) ? iconDataForStream(stream) : null)),
593603
Padding(
594604
padding: const EdgeInsets.symmetric(vertical: 11),
595605
child: Text(streamName,

test/widgets/message_list_test.dart

+49
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import 'package:zulip/model/localizations.dart';
1414
import 'package:zulip/model/narrow.dart';
1515
import 'package:zulip/model/store.dart';
1616
import 'package:zulip/widgets/content.dart';
17+
import 'package:zulip/widgets/icons.dart';
1718
import 'package:zulip/widgets/message_list.dart';
1819
import 'package:zulip/widgets/sticky_header.dart';
1920
import 'package:zulip/widgets/store.dart';
@@ -249,6 +250,54 @@ void main() {
249250
matching: find.byType(ColoredBox),
250251
))).color.equals(swatch.barBackground);
251252
});
253+
254+
testWidgets('color of stream icon', (tester) async {
255+
final stream = eg.stream(isWebPublic: true);
256+
final subscription = eg.subscription(stream, color: Colors.red.value);
257+
final swatch = subscription.colorSwatch();
258+
await setupMessageListPage(tester,
259+
messages: [eg.streamMessage(stream: subscription)],
260+
subscriptions: [subscription]);
261+
await tester.pump();
262+
check(tester.widget<Icon>(find.byIcon(ZulipIcons.globe)))
263+
.color.equals(swatch.iconOnBarBackground);
264+
});
265+
266+
testWidgets('normal streams show hash icon', (tester) async {
267+
final stream = eg.stream(isWebPublic: false, inviteOnly: false);
268+
await setupMessageListPage(tester,
269+
messages: [eg.streamMessage(stream: stream)],
270+
streams: [stream]);
271+
await tester.pump();
272+
check(find.descendant(
273+
of: find.byType(StreamMessageRecipientHeader),
274+
matching: find.byIcon(ZulipIcons.hash_sign),
275+
).evaluate()).length.equals(1);
276+
});
277+
278+
testWidgets('public streams show globe icon', (tester) async {
279+
final stream = eg.stream(isWebPublic: true);
280+
await setupMessageListPage(tester,
281+
messages: [eg.streamMessage(stream: stream)],
282+
streams: [stream]);
283+
await tester.pump();
284+
check(find.descendant(
285+
of: find.byType(StreamMessageRecipientHeader),
286+
matching: find.byIcon(ZulipIcons.globe),
287+
).evaluate()).length.equals(1);
288+
});
289+
290+
testWidgets('private streams show lock icon', (tester) async {
291+
final stream = eg.stream(inviteOnly: true);
292+
await setupMessageListPage(tester,
293+
messages: [eg.streamMessage(stream: stream)],
294+
streams: [stream]);
295+
await tester.pump();
296+
check(find.descendant(
297+
of: find.byType(StreamMessageRecipientHeader),
298+
matching: find.byIcon(ZulipIcons.lock),
299+
).evaluate()).length.equals(1);
300+
});
252301
});
253302

254303
testWidgets('show stream name from message when stream unknown', (tester) async {

0 commit comments

Comments
 (0)