Skip to content

Commit c99bd22

Browse files
sm-sayedignprice
authored andcommitted
new-dm: Show user status emoji
1 parent 395eb91 commit c99bd22

File tree

2 files changed

+103
-28
lines changed

2 files changed

+103
-28
lines changed

lib/widgets/new_dm_sheet.dart

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -317,6 +317,8 @@ class _SelectedUserChip extends StatelessWidget {
317317
fontSize: 16,
318318
height: 16 / 16,
319319
color: designVariables.labelMenuButton)))),
320+
UserStatusEmoji(userId: userId, size: 16,
321+
padding: EdgeInsetsDirectional.only(end: 4)),
320322
])));
321323
}
322324
}
@@ -415,7 +417,11 @@ class _NewDmUserListItem extends StatelessWidget {
415417
Avatar(userId: userId, size: 32, borderRadius: 3),
416418
SizedBox(width: 8),
417419
Expanded(
418-
child: Text(store.userDisplayName(userId),
420+
child: Text.rich(
421+
TextSpan(text: store.userDisplayName(userId), children: [
422+
UserStatusEmoji.asWidgetSpan(userId: userId, fontSize: 17,
423+
textScaler: MediaQuery.textScalerOf(context)),
424+
]),
419425
style: TextStyle(
420426
fontSize: 17,
421427
height: 19 / 17,

test/widgets/new_dm_sheet_test.dart

Lines changed: 96 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ import 'package:flutter/material.dart';
33
import 'package:flutter_checks/flutter_checks.dart';
44
import 'package:flutter_test/flutter_test.dart';
55
import 'package:zulip/api/model/model.dart';
6+
import 'package:zulip/basic.dart';
7+
import 'package:zulip/model/store.dart';
68
import 'package:zulip/widgets/app_bar.dart';
79
import 'package:zulip/widgets/compose_box.dart';
810
import 'package:zulip/widgets/content.dart';
@@ -17,8 +19,11 @@ import '../flutter_checks.dart';
1719
import '../model/binding.dart';
1820
import '../model/test_store.dart';
1921
import '../test_navigation.dart';
22+
import 'finders.dart';
2023
import 'test_app.dart';
2124

25+
late PerAccountStore store;
26+
2227
Future<void> setupSheet(WidgetTester tester, {
2328
required List<User> users,
2429
List<int>? mutedUserIds,
@@ -30,7 +35,7 @@ Future<void> setupSheet(WidgetTester tester, {
3035
..onPushed = (route, _) => lastPushedRoute = route;
3136

3237
await testBinding.globalStore.add(eg.selfAccount, eg.initialSnapshot());
33-
final store = await testBinding.globalStore.perAccount(eg.selfAccount.id);
38+
store = await testBinding.globalStore.perAccount(eg.selfAccount.id);
3439
await store.addUsers(users);
3540
if (mutedUserIds != null) {
3641
await store.setMutedUsers(mutedUserIds);
@@ -65,7 +70,8 @@ void main() {
6570
}
6671

6772
Finder findUserTile(User user) =>
68-
find.widgetWithText(InkWell, user.fullName).first;
73+
find.ancestor(of: findText(user.fullName, includePlaceholders: false),
74+
matching: find.byType(InkWell)).first;
6975

7076
Finder findUserChip(User user) {
7177
final findAvatar = find.byWidgetPredicate((widget) =>
@@ -120,23 +126,23 @@ void main() {
120126

121127
testWidgets('shows all non-muted users initially', (tester) async {
122128
await setupSheet(tester, users: testUsers, mutedUserIds: [mutedUser.userId]);
123-
check(find.text('Alice Anderson')).findsOne();
124-
check(find.text('Bob Brown')).findsOne();
125-
check(find.text('Charlie Carter')).findsOne();
129+
check(findText(includePlaceholders: false, 'Alice Anderson')).findsOne();
130+
check(findText(includePlaceholders: false, 'Bob Brown')).findsOne();
131+
check(findText(includePlaceholders: false, 'Charlie Carter')).findsOne();
126132

127133
check(find.byIcon(ZulipIcons.check_circle_unchecked)).findsExactly(3);
128134
check(find.byIcon(ZulipIcons.check_circle_checked)).findsNothing();
129-
check(find.text('Someone Muted')).findsNothing();
130-
check(find.text('Muted user')).findsNothing();
135+
check(findText(includePlaceholders: false, 'Someone Muted')).findsNothing();
136+
check(findText(includePlaceholders: false, 'Muted user')).findsNothing();
131137
});
132138

133139
testWidgets('shows filtered users based on search', (tester) async {
134140
await setupSheet(tester, users: testUsers);
135141
await tester.enterText(find.byType(TextField), 'Alice');
136142
await tester.pump();
137-
check(find.text('Alice Anderson')).findsOne();
138-
check(find.text('Charlie Carter')).findsNothing();
139-
check(find.text('Bob Brown')).findsNothing();
143+
check(findText(includePlaceholders: false, 'Alice Anderson')).findsOne();
144+
check(findText(includePlaceholders: false, 'Charlie Carter')).findsNothing();
145+
check(findText(includePlaceholders: false, 'Bob Brown')).findsNothing();
140146
});
141147

142148
// TODO test sorting by recent-DMs
@@ -146,43 +152,43 @@ void main() {
146152
await setupSheet(tester, users: testUsers);
147153
await tester.enterText(find.byType(TextField), 'alice');
148154
await tester.pump();
149-
check(find.text('Alice Anderson')).findsOne();
155+
check(findText(includePlaceholders: false, 'Alice Anderson')).findsOne();
150156

151157
await tester.enterText(find.byType(TextField), 'ALICE');
152158
await tester.pump();
153-
check(find.text('Alice Anderson')).findsOne();
159+
check(findText(includePlaceholders: false, 'Alice Anderson')).findsOne();
154160
});
155161

156162
testWidgets('partial name and last name search handling', (tester) async {
157163
await setupSheet(tester, users: testUsers);
158164

159165
await tester.enterText(find.byType(TextField), 'Ali');
160166
await tester.pump();
161-
check(find.text('Alice Anderson')).findsOne();
162-
check(find.text('Bob Brown')).findsNothing();
163-
check(find.text('Charlie Carter')).findsNothing();
167+
check(findText(includePlaceholders: false, 'Alice Anderson')).findsOne();
168+
check(findText(includePlaceholders: false, 'Bob Brown')).findsNothing();
169+
check(findText(includePlaceholders: false, 'Charlie Carter')).findsNothing();
164170

165171
await tester.enterText(find.byType(TextField), 'Anderson');
166172
await tester.pump();
167-
check(find.text('Alice Anderson')).findsOne();
168-
check(find.text('Charlie Carter')).findsNothing();
169-
check(find.text('Bob Brown')).findsNothing();
173+
check(findText(includePlaceholders: false, 'Alice Anderson')).findsOne();
174+
check(findText(includePlaceholders: false, 'Charlie Carter')).findsNothing();
175+
check(findText(includePlaceholders: false, 'Bob Brown')).findsNothing();
170176

171177
await tester.enterText(find.byType(TextField), 'son');
172178
await tester.pump();
173-
check(find.text('Alice Anderson')).findsOne();
174-
check(find.text('Charlie Carter')).findsNothing();
175-
check(find.text('Bob Brown')).findsNothing();
179+
check(findText(includePlaceholders: false, 'Alice Anderson')).findsOne();
180+
check(findText(includePlaceholders: false, 'Charlie Carter')).findsNothing();
181+
check(findText(includePlaceholders: false, 'Bob Brown')).findsNothing();
176182
});
177183

178184
testWidgets('shows empty state when no users match', (tester) async {
179185
await setupSheet(tester, users: testUsers);
180186
await tester.enterText(find.byType(TextField), 'Zebra');
181187
await tester.pump();
182-
check(find.text('No users found')).findsOne();
183-
check(find.text('Alice Anderson')).findsNothing();
184-
check(find.text('Bob Brown')).findsNothing();
185-
check(find.text('Charlie Carter')).findsNothing();
188+
check(findText(includePlaceholders: false, 'No users found')).findsOne();
189+
check(findText(includePlaceholders: false, 'Alice Anderson')).findsNothing();
190+
check(findText(includePlaceholders: false, 'Bob Brown')).findsNothing();
191+
check(findText(includePlaceholders: false, 'Charlie Carter')).findsNothing();
186192
});
187193

188194
testWidgets('search text clears when user is selected', (tester) async {
@@ -252,7 +258,7 @@ void main() {
252258
await tester.tap(findUserTile(eg.selfUser));
253259
await tester.pump();
254260
checkUserSelected(tester, eg.selfUser, true);
255-
check(find.text(eg.selfUser.fullName)).findsExactly(2);
261+
check(findText(includePlaceholders: false, eg.selfUser.fullName)).findsExactly(2);
256262

257263
await tester.tap(findUserTile(otherUser));
258264
await tester.pump();
@@ -264,7 +270,7 @@ void main() {
264270
final otherUser = eg.user(fullName: 'Other User');
265271
await setupSheet(tester, users: [eg.selfUser, otherUser]);
266272

267-
check(find.text(eg.selfUser.fullName)).findsOne();
273+
check(findText(includePlaceholders: false, eg.selfUser.fullName)).findsOne();
268274

269275
await tester.tap(findUserTile(otherUser));
270276
await tester.pump();
@@ -285,6 +291,69 @@ void main() {
285291
});
286292
});
287293

294+
group('User status', () {
295+
void checkFindsTileStatusEmoji(WidgetTester tester, User user, Finder emojiFinder) {
296+
final statusEmojiFinder = find.ancestor(of: emojiFinder,
297+
matching: find.byType(UserStatusEmoji));
298+
final tileStatusEmojiFinder = find.descendant(of: findUserTile(user),
299+
matching: statusEmojiFinder);
300+
check(tester.widget<UserStatusEmoji>(tileStatusEmojiFinder)
301+
.neverAnimate).isTrue();
302+
check(tileStatusEmojiFinder).findsOne();
303+
}
304+
305+
void checkFindsChipStatusEmoji(WidgetTester tester, User user, Finder emojiFinder) {
306+
final statusEmojiFinder = find.ancestor(of: emojiFinder,
307+
matching: find.byType(UserStatusEmoji));
308+
final chipStatusEmojiFinder = find.descendant(of: findUserChip(user),
309+
matching: statusEmojiFinder);
310+
check(tester.widget<UserStatusEmoji>(chipStatusEmojiFinder)
311+
.neverAnimate).isTrue();
312+
check(chipStatusEmojiFinder).findsOne();
313+
}
314+
315+
testWidgets('emoji & text are set -> emoji is displayed, text is not', (tester) async {
316+
final user = eg.user();
317+
await setupSheet(tester, users: [user]);
318+
await store.changeUserStatus(user.userId, UserStatusChange(
319+
text: OptionSome('Busy'),
320+
emoji: OptionSome(StatusEmoji(emojiName: 'working_on_it',
321+
emojiCode: '1f6e0', reactionType: ReactionType.unicodeEmoji))));
322+
await tester.pump();
323+
324+
checkFindsTileStatusEmoji(tester, user, find.text('\u{1f6e0}'));
325+
check(findUserChip(user)).findsNothing();
326+
check(find.textContaining('Busy')).findsNothing();
327+
328+
await tester.tap(findUserTile(user));
329+
await tester.pump();
330+
331+
checkFindsTileStatusEmoji(tester, user, find.text('\u{1f6e0}'));
332+
check(findUserChip(user)).findsOne();
333+
checkFindsChipStatusEmoji(tester, user, find.text('\u{1f6e0}'));
334+
check(find.textContaining('Busy')).findsNothing();
335+
});
336+
337+
testWidgets('emoji is not set, text is set -> text is not displayed', (tester) async {
338+
final user = eg.user();
339+
await setupSheet(tester, users: [user]);
340+
await store.changeUserStatus(user.userId, UserStatusChange(
341+
text: OptionSome('Busy'), emoji: OptionNone()));
342+
await tester.pump();
343+
344+
check(findUserTile(user)).findsOne();
345+
check(findUserChip(user)).findsNothing();
346+
check(find.textContaining('Busy')).findsNothing();
347+
348+
await tester.tap(findUserTile(user));
349+
await tester.pump();
350+
351+
check(findUserTile(user)).findsOne();
352+
check(findUserChip(user)).findsOne();
353+
check(find.textContaining('Busy')).findsNothing();
354+
});
355+
});
356+
288357
group('navigation to DM Narrow', () {
289358
Future<void> runAndCheck(WidgetTester tester, {
290359
required List<User> users,

0 commit comments

Comments
 (0)