Skip to content

Commit 00d7712

Browse files
committed
recent-dms: Show user status emoji in recent DMs page
Status emojis are only shown for self-1:1 and 1:1 conversation items. They're ignored for group conversations as that's what the Web does.
1 parent 3590d82 commit 00d7712

File tree

2 files changed

+103
-4
lines changed

2 files changed

+103
-4
lines changed

lib/widgets/recent_dm_conversations.dart

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -146,16 +146,31 @@ class RecentDmConversationsItem extends StatelessWidget {
146146
const SizedBox(width: 8),
147147
Expanded(child: Padding(
148148
padding: const EdgeInsets.symmetric(vertical: 4),
149-
child: Text(
149+
child: Text.rich(
150+
TextSpan(
151+
children: [
152+
TextSpan(text: title),
153+
...(switch (narrow.otherRecipientIds) {
154+
// self-DM
155+
[] => [UserStatusEmoji.asWidgetSpan(userId: store.selfUserId,
156+
size: 17, notoColorEmojiTextSize: 14.1)],
157+
// 1:1-DM
158+
[final otherUserId] =>
159+
[UserStatusEmoji.asWidgetSpan(userId: otherUserId,
160+
size: 17, notoColorEmojiTextSize: 14.1)],
161+
// group-DM - show nothing
162+
[...] => [],
163+
}),
164+
]
165+
),
150166
style: TextStyle(
151167
fontSize: 17,
152168
height: (20 / 17),
153169
// TODO(design) check if this is the right variable
154170
color: designVariables.labelMenuButton,
155171
),
156172
maxLines: 2,
157-
overflow: TextOverflow.ellipsis,
158-
title))),
173+
overflow: TextOverflow.ellipsis))),
159174
const SizedBox(width: 12),
160175
unreadCount > 0
161176
? Padding(padding: const EdgeInsetsDirectional.only(end: 16),

test/widgets/recent_dm_conversations_test.dart

Lines changed: 85 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,10 @@ import 'package:flutter_checks/flutter_checks.dart';
55
import 'package:flutter_test/flutter_test.dart';
66
import 'package:zulip/api/model/events.dart';
77
import 'package:zulip/api/model/model.dart';
8+
import 'package:zulip/basic.dart';
89
import 'package:zulip/model/narrow.dart';
910
import 'package:zulip/widgets/content.dart';
11+
import 'package:zulip/widgets/emoji.dart';
1012
import 'package:zulip/widgets/home.dart';
1113
import 'package:zulip/widgets/icons.dart';
1214
import 'package:zulip/widgets/message_list.dart';
@@ -28,6 +30,7 @@ Future<void> setupPage(WidgetTester tester, {
2830
required List<DmMessage> dmMessages,
2931
required List<User> users,
3032
List<int>? mutedUserIds,
33+
List<(int userId, UserStatusChange change)>? userStatuses,
3134
NavigatorObserver? navigatorObserver,
3235
String? newNameForSelfUser,
3336
}) async {
@@ -44,6 +47,8 @@ Future<void> setupPage(WidgetTester tester, {
4447
await store.setMutedUsers(mutedUserIds);
4548
}
4649

50+
await store.changeUserStatuses(userStatuses ?? []);
51+
4752
await store.addMessages(dmMessages);
4853

4954
if (newNameForSelfUser != null) {
@@ -176,7 +181,7 @@ void main() {
176181
// TODO(#232): syntax like `check(find(…), findsOneWidget)`
177182
final widget = tester.widget(find.descendant(
178183
of: find.byType(RecentDmConversationsItem),
179-
matching: find.text(expectedText),
184+
matching: find.textContaining(expectedText),
180185
));
181186
if (expectedLines != null) {
182187
final renderObject = tester.renderObject<RenderParagraph>(find.byWidget(widget));
@@ -186,6 +191,16 @@ void main() {
186191
}
187192
}
188193

194+
void checkStatusEmoji({required bool isPresent}) {
195+
final statusEmojiFinder = find.ancestor(of: find.byType(UnicodeEmojiWidget),
196+
matching: find.byType(UserStatusEmoji));
197+
final itemFinder = find.descendant(
198+
of: find.byType(RecentDmConversationsItem),
199+
matching: statusEmojiFinder,
200+
);
201+
check(itemFinder).findsExactly(isPresent ? 1 : 0);
202+
}
203+
189204
Future<void> markMessageAsRead(WidgetTester tester, Message message) async {
190205
final store = await testBinding.globalStore.perAccount(eg.selfAccount.id);
191206
await store.handleEvent(UpdateMessageFlagsAddEvent(
@@ -231,6 +246,28 @@ void main() {
231246
checkTitle(tester, name, 2);
232247
});
233248

249+
testWidgets('status emoji is set -> emoji is displayed', (tester) async {
250+
final message = eg.dmMessage(from: eg.selfUser, to: []);
251+
await setupPage(tester, dmMessages: [message], users: [],
252+
userStatuses: [
253+
(
254+
eg.selfUser.userId,
255+
UserStatusChange(
256+
text: OptionSome('Busy'),
257+
emoji: OptionSome(StatusEmoji(emojiName: 'working_on_it',
258+
emojiCode: '1f6e0', reactionType: ReactionType.unicodeEmoji)))
259+
),
260+
]);
261+
checkStatusEmoji(isPresent: true);
262+
});
263+
264+
testWidgets('status emoji is not set -> emoji is not displayed', (tester) async {
265+
final message = eg.dmMessage(from: eg.selfUser, to: []);
266+
await setupPage(tester, dmMessages: [message], users: [],
267+
userStatuses: []);
268+
checkStatusEmoji(isPresent: false);
269+
});
270+
234271
testWidgets('unread counts', (tester) async {
235272
final message = eg.dmMessage(from: eg.selfUser, to: []);
236273
await setupPage(tester, users: [], dmMessages: [message]);
@@ -291,6 +328,30 @@ void main() {
291328
checkTitle(tester, user.fullName, 2);
292329
});
293330

331+
testWidgets('status emoji is set -> emoji is displayed', (tester) async {
332+
final user = eg.user();
333+
final message = eg.dmMessage(from: eg.selfUser, to: [user]);
334+
await setupPage(tester, users: [user], dmMessages: [message],
335+
userStatuses: [
336+
(
337+
user.userId,
338+
UserStatusChange(
339+
text: OptionSome('Busy'),
340+
emoji: OptionSome(StatusEmoji(emojiName: 'working_on_it',
341+
emojiCode: '1f6e0', reactionType: ReactionType.unicodeEmoji)))
342+
),
343+
]);
344+
checkStatusEmoji(isPresent: true);
345+
});
346+
347+
testWidgets('status emoji is not set -> emoji is not displayed', (tester) async {
348+
final user = eg.user();
349+
final message = eg.dmMessage(from: eg.selfUser, to: [user]);
350+
await setupPage(tester, users: [user], dmMessages: [message],
351+
userStatuses: []);
352+
checkStatusEmoji(isPresent: false);
353+
});
354+
294355
testWidgets('unread counts', (tester) async {
295356
final message = eg.dmMessage(from: eg.otherUser, to: [eg.selfUser]);
296357
await setupPage(tester, users: [], dmMessages: [message]);
@@ -379,6 +440,29 @@ void main() {
379440
checkTitle(tester, users.map((u) => u.fullName).join(', '), 2);
380441
});
381442

443+
testWidgets('status emojis are set -> emoji are not displayed', (tester) async {
444+
final users = usersList(3);
445+
final message = eg.dmMessage(from: eg.selfUser, to: users);
446+
await setupPage(tester, users: users, dmMessages: [message],
447+
userStatuses: [
448+
(
449+
users.first.userId,
450+
UserStatusChange(
451+
text: OptionSome('Busy'),
452+
emoji: OptionSome(StatusEmoji(emojiName: 'working_on_it',
453+
emojiCode: '1f6e0', reactionType: ReactionType.unicodeEmoji)))
454+
),
455+
(
456+
users.last.userId,
457+
UserStatusChange(
458+
text: OptionSome('In a meeting'),
459+
emoji: OptionSome(StatusEmoji(emojiName: 'calendar',
460+
emojiCode: '1f4c5', reactionType: ReactionType.unicodeEmoji)))
461+
),
462+
]);
463+
checkStatusEmoji(isPresent: false);
464+
});
465+
382466
testWidgets('unread counts', (tester) async {
383467
final message = eg.dmMessage(from: eg.thirdUser, to: [eg.selfUser, eg.otherUser]);
384468
await setupPage(tester, users: [], dmMessages: [message]);

0 commit comments

Comments
 (0)