Skip to content

Commit 463b938

Browse files
committed
msglist: Show user status emoji
1 parent 02a2898 commit 463b938

File tree

2 files changed

+80
-0
lines changed

2 files changed

+80
-0
lines changed

lib/widgets/message_list.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1943,6 +1943,8 @@ class SenderRow extends StatelessWidget {
19431943
: designVariables.title,
19441944
).merge(weightVariableTextStyle(context, wght: 600)),
19451945
overflow: TextOverflow.ellipsis)),
1946+
UserStatusEmoji(userId: message.senderId, size: 18,
1947+
padding: const EdgeInsetsDirectional.only(start: 5.0)),
19461948
if (sender?.isBot ?? false) ...[
19471949
const SizedBox(width: 5),
19481950
Icon(

test/widgets/message_list_test.dart

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import 'package:zulip/api/model/model.dart';
1414
import 'package:zulip/api/model/narrow.dart';
1515
import 'package:zulip/api/route/channels.dart';
1616
import 'package:zulip/api/route/messages.dart';
17+
import 'package:zulip/basic.dart';
1718
import 'package:zulip/model/actions.dart';
1819
import 'package:zulip/model/localizations.dart';
1920
import 'package:zulip/model/message.dart';
@@ -26,6 +27,7 @@ import 'package:zulip/widgets/autocomplete.dart';
2627
import 'package:zulip/widgets/color.dart';
2728
import 'package:zulip/widgets/compose_box.dart';
2829
import 'package:zulip/widgets/content.dart';
30+
import 'package:zulip/widgets/emoji.dart';
2931
import 'package:zulip/widgets/icons.dart';
3032
import 'package:zulip/widgets/message_list.dart';
3133
import 'package:zulip/widgets/page.dart';
@@ -50,6 +52,22 @@ import 'message_list_checks.dart';
5052
import 'page_checks.dart';
5153
import 'test_app.dart';
5254

55+
/// Finder for [UserStatusEmoji] widget.
56+
///
57+
/// Use [type] to specify the exact emoji child widget. It can be either
58+
/// [UnicodeEmojiWidget] or [ImageEmojiWidget].
59+
Finder findStatusEmoji(Type type) {
60+
assert(type == UnicodeEmojiWidget || type == ImageEmojiWidget);
61+
return find.ancestor(
62+
of: find.byType(type),
63+
matching: find.byType(UserStatusEmoji));
64+
}
65+
66+
void checkUserStatusEmoji(Finder emojiFinder, {required bool isAnimated}) {
67+
check((emojiFinder
68+
.evaluate().first.widget as UserStatusEmoji).neverAnimate).equals(!isAnimated);
69+
}
70+
5371
void main() {
5472
TestZulipBinding.ensureInitialized();
5573
MessageListPage.debugEnableMarkReadOnScroll = false;
@@ -66,6 +84,7 @@ void main() {
6684
List<ZulipStream>? streams,
6785
List<User>? users,
6886
List<int>? mutedUserIds,
87+
List<(int userId, UserStatusChange change)>? userStatuses,
6988
List<Subscription>? subscriptions,
7089
UnreadMessagesSnapshot? unreadMsgs,
7190
int? zulipFeatureLevel,
@@ -91,6 +110,7 @@ void main() {
91110
if (mutedUserIds != null) {
92111
await store.setMutedUsers(mutedUserIds);
93112
}
113+
await store.changeUserStatuses(userStatuses ?? []);
94114
if (fetchResult != null) {
95115
assert(foundOldest && messageCount == null && messages == null);
96116
} else {
@@ -1755,6 +1775,64 @@ void main() {
17551775
debugNetworkImageHttpClientProvider = null;
17561776
});
17571777

1778+
group('User status emoji', () {
1779+
void checkStatusEmoji(User user, Type type, {required bool isPresent}) {
1780+
final nameFinder = find.text(user.fullName);
1781+
final statusEmojiFinder = findStatusEmoji(type);
1782+
1783+
check(nameFinder).findsOne();
1784+
check(statusEmojiFinder).findsExactly(isPresent ? 1 : 0);
1785+
if (isPresent) {
1786+
checkUserStatusEmoji(statusEmojiFinder, isAnimated: false);
1787+
}
1788+
1789+
final senderRowFinder = find.ancestor(of: nameFinder,
1790+
matching: find.ancestor(of: statusEmojiFinder,
1791+
matching: find.byType(Row)));
1792+
isPresent
1793+
? check(senderRowFinder).findsAny()
1794+
: check(senderRowFinder).findsNothing();
1795+
}
1796+
1797+
final user1 = eg.user(userId: 1,
1798+
fullName: 'User with a very very very long name to check if emoji is still visible');
1799+
final user2 = eg.user(userId: 2, fullName: 'User 2');
1800+
1801+
testWidgets('status emoji is set -> emoji is displayed', (tester) async {
1802+
await setupMessageListPage(tester,
1803+
users: [user1, user2],
1804+
messages: [eg.streamMessage(sender: user1), eg.streamMessage(sender: user2)],
1805+
userStatuses: [
1806+
(
1807+
user1.userId,
1808+
UserStatusChange(
1809+
text: OptionSome('Busy'),
1810+
emoji: OptionSome(StatusEmoji(emojiName: 'working_on_it',
1811+
emojiCode: '1f6e0', reactionType: ReactionType.unicodeEmoji)))
1812+
),
1813+
(
1814+
user2.userId,
1815+
UserStatusChange(
1816+
text: OptionSome('Coding'),
1817+
emoji: OptionSome(StatusEmoji(emojiName: 'zulip',
1818+
emojiCode: 'zulip', reactionType: ReactionType.zulipExtraEmoji)))
1819+
),
1820+
],
1821+
);
1822+
checkStatusEmoji(user1, UnicodeEmojiWidget, isPresent: true);
1823+
checkStatusEmoji(user2, ImageEmojiWidget, isPresent: true);
1824+
});
1825+
1826+
testWidgets('status emoji is not set -> emoji is not displayed', (tester) async {
1827+
await setupMessageListPage(tester,
1828+
users: [user1],
1829+
messages: [eg.streamMessage(sender: user1)],
1830+
userStatuses: [],
1831+
);
1832+
checkStatusEmoji(user1, UnicodeEmojiWidget, isPresent: false);
1833+
});
1834+
});
1835+
17581836
group('Muted sender', () {
17591837
void checkMessage(Message message, {required bool expectIsMuted}) {
17601838
final mutedLabel = 'Muted user';

0 commit comments

Comments
 (0)