Skip to content

Commit 0c85980

Browse files
committed
Merge remote-tracking branch 'pr/1560'
2 parents e03c069 + 9cd2972 commit 0c85980

40 files changed

+899
-269
lines changed

assets/l10n/app_en.arb

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1007,17 +1007,13 @@
10071007
"@noEarlierMessages": {
10081008
"description": "Text to show at the start of a message list if there are no earlier messages."
10091009
},
1010-
"mutedSender": "Muted sender",
1011-
"@mutedSender": {
1012-
"description": "Name for a muted user to display in message list."
1013-
},
1014-
"revealButtonLabel": "Reveal message for muted sender",
1010+
"revealButtonLabel": "Reveal message",
10151011
"@revealButtonLabel": {
10161012
"description": "Label for the button revealing hidden message from a muted sender in message list."
10171013
},
10181014
"mutedUser": "Muted user",
10191015
"@mutedUser": {
1020-
"description": "Name for a muted user to display all over the app."
1016+
"description": "Text to display in place of a muted user's name."
10211017
},
10221018
"scrollToBottomTooltip": "Scroll to bottom",
10231019
"@scrollToBottomTooltip": {

assets/l10n/app_pl.arb

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1089,10 +1089,6 @@
10891089
"@mutedSender": {
10901090
"description": "Name for a muted user to display in message list."
10911091
},
1092-
"revealButtonLabel": "Odsłoń wiadomość od wyciszonego użytkownika",
1093-
"@revealButtonLabel": {
1094-
"description": "Label for the button revealing hidden message from a muted sender in message list."
1095-
},
10961092
"mutedUser": "Wyciszony użytkownik",
10971093
"@mutedUser": {
10981094
"description": "Name for a muted user to display all over the app."

assets/l10n/app_ru.arb

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1081,10 +1081,6 @@
10811081
"@mutedSender": {
10821082
"description": "Name for a muted user to display in message list."
10831083
},
1084-
"revealButtonLabel": "Показать сообщение отключенного отправителя",
1085-
"@revealButtonLabel": {
1086-
"description": "Label for the button revealing hidden message from a muted sender in message list."
1087-
},
10881084
"mutedUser": "Отключенный пользователь",
10891085
"@mutedUser": {
10901086
"description": "Name for a muted user to display all over the app."

lib/generated/l10n/zulip_localizations.dart

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1503,19 +1503,13 @@ abstract class ZulipLocalizations {
15031503
/// **'No earlier messages'**
15041504
String get noEarlierMessages;
15051505

1506-
/// Name for a muted user to display in message list.
1507-
///
1508-
/// In en, this message translates to:
1509-
/// **'Muted sender'**
1510-
String get mutedSender;
1511-
15121506
/// Label for the button revealing hidden message from a muted sender in message list.
15131507
///
15141508
/// In en, this message translates to:
1515-
/// **'Reveal message for muted sender'**
1509+
/// **'Reveal message'**
15161510
String get revealButtonLabel;
15171511

1518-
/// Name for a muted user to display all over the app.
1512+
/// Text to display in place of a muted user's name.
15191513
///
15201514
/// In en, this message translates to:
15211515
/// **'Muted user'**

lib/generated/l10n/zulip_localizations_ar.dart

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -820,10 +820,7 @@ class ZulipLocalizationsAr extends ZulipLocalizations {
820820
String get noEarlierMessages => 'No earlier messages';
821821

822822
@override
823-
String get mutedSender => 'Muted sender';
824-
825-
@override
826-
String get revealButtonLabel => 'Reveal message for muted sender';
823+
String get revealButtonLabel => 'Reveal message';
827824

828825
@override
829826
String get mutedUser => 'Muted user';

lib/generated/l10n/zulip_localizations_de.dart

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -820,10 +820,7 @@ class ZulipLocalizationsDe extends ZulipLocalizations {
820820
String get noEarlierMessages => 'No earlier messages';
821821

822822
@override
823-
String get mutedSender => 'Muted sender';
824-
825-
@override
826-
String get revealButtonLabel => 'Reveal message for muted sender';
823+
String get revealButtonLabel => 'Reveal message';
827824

828825
@override
829826
String get mutedUser => 'Muted user';

lib/generated/l10n/zulip_localizations_en.dart

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -820,10 +820,7 @@ class ZulipLocalizationsEn extends ZulipLocalizations {
820820
String get noEarlierMessages => 'No earlier messages';
821821

822822
@override
823-
String get mutedSender => 'Muted sender';
824-
825-
@override
826-
String get revealButtonLabel => 'Reveal message for muted sender';
823+
String get revealButtonLabel => 'Reveal message';
827824

828825
@override
829826
String get mutedUser => 'Muted user';

lib/generated/l10n/zulip_localizations_it.dart

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -820,10 +820,7 @@ class ZulipLocalizationsIt extends ZulipLocalizations {
820820
String get noEarlierMessages => 'No earlier messages';
821821

822822
@override
823-
String get mutedSender => 'Muted sender';
824-
825-
@override
826-
String get revealButtonLabel => 'Reveal message for muted sender';
823+
String get revealButtonLabel => 'Reveal message';
827824

828825
@override
829826
String get mutedUser => 'Muted user';

lib/generated/l10n/zulip_localizations_ja.dart

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -820,10 +820,7 @@ class ZulipLocalizationsJa extends ZulipLocalizations {
820820
String get noEarlierMessages => 'No earlier messages';
821821

822822
@override
823-
String get mutedSender => 'Muted sender';
824-
825-
@override
826-
String get revealButtonLabel => 'Reveal message for muted sender';
823+
String get revealButtonLabel => 'Reveal message';
827824

828825
@override
829826
String get mutedUser => 'Muted user';

lib/generated/l10n/zulip_localizations_nb.dart

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -820,10 +820,7 @@ class ZulipLocalizationsNb extends ZulipLocalizations {
820820
String get noEarlierMessages => 'No earlier messages';
821821

822822
@override
823-
String get mutedSender => 'Muted sender';
824-
825-
@override
826-
String get revealButtonLabel => 'Reveal message for muted sender';
823+
String get revealButtonLabel => 'Reveal message';
827824

828825
@override
829826
String get mutedUser => 'Muted user';

lib/generated/l10n/zulip_localizations_pl.dart

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -833,10 +833,7 @@ class ZulipLocalizationsPl extends ZulipLocalizations {
833833
String get noEarlierMessages => 'Brak historii';
834834

835835
@override
836-
String get mutedSender => 'Wyciszony nadawca';
837-
838-
@override
839-
String get revealButtonLabel => 'Odsłoń wiadomość od wyciszonego użytkownika';
836+
String get revealButtonLabel => 'Reveal message';
840837

841838
@override
842839
String get mutedUser => 'Wyciszony użytkownik';

lib/generated/l10n/zulip_localizations_ru.dart

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -835,10 +835,7 @@ class ZulipLocalizationsRu extends ZulipLocalizations {
835835
String get noEarlierMessages => 'Предшествующих сообщений нет';
836836

837837
@override
838-
String get mutedSender => 'Отключенный отправитель';
839-
840-
@override
841-
String get revealButtonLabel => 'Показать сообщение отключенного отправителя';
838+
String get revealButtonLabel => 'Reveal message';
842839

843840
@override
844841
String get mutedUser => 'Отключенный пользователь';

lib/generated/l10n/zulip_localizations_sk.dart

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -822,10 +822,7 @@ class ZulipLocalizationsSk extends ZulipLocalizations {
822822
String get noEarlierMessages => 'No earlier messages';
823823

824824
@override
825-
String get mutedSender => 'Muted sender';
826-
827-
@override
828-
String get revealButtonLabel => 'Reveal message for muted sender';
825+
String get revealButtonLabel => 'Reveal message';
829826

830827
@override
831828
String get mutedUser => 'Muted user';

lib/generated/l10n/zulip_localizations_sl.dart

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -842,9 +842,6 @@ class ZulipLocalizationsSl extends ZulipLocalizations {
842842
@override
843843
String get noEarlierMessages => 'Ni starejših sporočil';
844844

845-
@override
846-
String get mutedSender => 'Utišan pošiljatelj';
847-
848845
@override
849846
String get revealButtonLabel => 'Prikaži sporočilo utišanega pošiljatelja';
850847

lib/generated/l10n/zulip_localizations_uk.dart

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -834,9 +834,6 @@ class ZulipLocalizationsUk extends ZulipLocalizations {
834834
@override
835835
String get noEarlierMessages => 'Немає попередніх повідомлень';
836836

837-
@override
838-
String get mutedSender => 'Заглушений відправник';
839-
840837
@override
841838
String get revealButtonLabel =>
842839
'Показати повідомлення заглушеного відправника';

lib/generated/l10n/zulip_localizations_zh.dart

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -820,10 +820,7 @@ class ZulipLocalizationsZh extends ZulipLocalizations {
820820
String get noEarlierMessages => 'No earlier messages';
821821

822822
@override
823-
String get mutedSender => 'Muted sender';
824-
825-
@override
826-
String get revealButtonLabel => 'Reveal message for muted sender';
823+
String get revealButtonLabel => 'Reveal message';
827824

828825
@override
829826
String get mutedUser => 'Muted user';
@@ -1621,9 +1618,6 @@ class ZulipLocalizationsZhHansCn extends ZulipLocalizationsZh {
16211618
@override
16221619
String get noEarlierMessages => '没有更早的消息了';
16231620

1624-
@override
1625-
String get mutedSender => '静音发送者';
1626-
16271621
@override
16281622
String get revealButtonLabel => '显示静音用户发送的消息';
16291623

lib/model/compose.dart

Lines changed: 30 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -130,14 +130,33 @@ String wrapWithBacktickFence({required String content, String? infoString}) {
130130
/// To omit the user ID part ("|13313") whenever the name part is unambiguous,
131131
/// pass the full UserStore. This means accepting a linear scan
132132
/// through all users; avoid it in performance-sensitive codepaths.
133+
///
134+
/// See also [userMentionFromMessage].
133135
String userMention(User user, {bool silent = false, UserStore? users}) {
134136
bool includeUserId = users == null
135137
|| users.allUsers.where((u) => u.fullName == user.fullName)
136138
.take(2).length == 2;
137-
138-
return '@${silent ? '_' : ''}**${user.fullName}${includeUserId ? '|${user.userId}' : ''}**';
139+
return _userMentionImpl(
140+
silent: silent,
141+
fullName: user.fullName,
142+
userId: includeUserId ? user.userId : null);
139143
}
140144

145+
/// An @-mention of an individual user, like @**Chris Bobbe|13313**,
146+
/// from sender data in a [Message].
147+
///
148+
/// The user ID part ("|13313") is always included.
149+
///
150+
/// See also [userMention].
151+
String userMentionFromMessage(Message message, {bool silent = false, required UserStore users}) =>
152+
_userMentionImpl(
153+
silent: silent,
154+
fullName: users.senderDisplayName(message, replaceIfMuted: false),
155+
userId: message.senderId);
156+
157+
String _userMentionImpl({required bool silent, required String fullName, int? userId}) =>
158+
'@${silent ? '_' : ''}**$fullName${userId != null ? '|$userId' : ''}**';
159+
141160
/// An @-mention of all the users in a conversation, like @**channel**.
142161
String wildcardMention(WildcardMentionOption wildcardOption, {
143162
required PerAccountStore store,
@@ -190,13 +209,11 @@ String quoteAndReplyPlaceholder(
190209
PerAccountStore store, {
191210
required Message message,
192211
}) {
193-
final sender = store.getUser(message.senderId);
194-
assert(sender != null); // TODO(#716): should use `store.senderDisplayName`
195212
final url = narrowLink(store,
196213
SendableNarrow.ofMessage(message, selfUserId: store.selfUserId),
197214
nearMessageId: message.id);
198-
// See note in [quoteAndReply] about asking `mention` to omit the |<id> part.
199-
return '${userMention(sender!, silent: true)} ${inlineLink('said', url)}: ' // TODO(#1285)
215+
return '${userMentionFromMessage(message, silent: true, users: store)} '
216+
'${inlineLink('said', url)}: ' // TODO(#1285)
200217
'*${zulipLocalizations.composeBoxLoadingMessage(message.id)}*\n';
201218
}
202219

@@ -212,14 +229,14 @@ String quoteAndReply(PerAccountStore store, {
212229
required Message message,
213230
required String rawContent,
214231
}) {
215-
final sender = store.getUser(message.senderId);
216-
assert(sender != null); // TODO(#716): should use `store.senderDisplayName`
217232
final url = narrowLink(store,
218233
SendableNarrow.ofMessage(message, selfUserId: store.selfUserId),
219234
nearMessageId: message.id);
220-
// Could ask `mention` to omit the |<id> part unless the mention is ambiguous…
221-
// but that would mean a linear scan through all users, and the extra noise
222-
// won't much matter with the already probably-long message link in there too.
223-
return '${userMention(sender!, silent: true)} ${inlineLink('said', url)}:\n' // TODO(#1285)
224-
'${wrapWithBacktickFence(content: rawContent, infoString: 'quote')}';
235+
// Could ask userMentionFromMessage to omit the |<id> part unless the mention
236+
// is ambiguous… but that would mean a linear scan through all users,
237+
// and the extra noise won't much matter with the already probably-long
238+
// message link in there too.
239+
return '${userMentionFromMessage(message, silent: true, users: store)} '
240+
'${inlineLink('said', url)}:\n' // TODO(#1285)
241+
'${wrapWithBacktickFence(content: rawContent, infoString: 'quote')}';
225242
}

lib/model/store.dart

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -675,10 +675,13 @@ class PerAccountStore extends PerAccountStoreBase with ChangeNotifier, EmojiStor
675675
return byDate.difference(dateJoined).inDays >= realmWaitingPeriodThreshold;
676676
}
677677

678-
/// The given user's real email address, if known, for displaying in the UI.
678+
/// The user's real email address, if known, for displaying in the UI.
679679
///
680-
/// Returns null if self-user isn't able to see [user]'s real email address.
681-
String? userDisplayEmail(User user) {
680+
/// Returns null if self-user isn't able to see the user's real email address,
681+
/// or if the user isn't actually a user we know about.
682+
String? userDisplayEmail(int userId) {
683+
final user = getUser(userId);
684+
if (user == null) return null;
682685
if (zulipFeatureLevel >= 163) { // TODO(server-7)
683686
// A non-null value means self-user has access to [user]'s real email,
684687
// while a null value means it doesn't have access to the email.

lib/model/user.dart

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -44,27 +44,40 @@ mixin UserStore on PerAccountStoreBase {
4444

4545
/// The name to show the given user as in the UI, even for unknown users.
4646
///
47-
/// This is the user's [User.fullName] if the user is known,
48-
/// and otherwise a translation of "(unknown user)".
47+
/// If the user is muted and [replaceIfMuted] is true (the default),
48+
/// this is [ZulipLocalizations.mutedUser].
49+
///
50+
/// Otherwise this is the user's [User.fullName] if the user is known,
51+
/// or (if unknown) [ZulipLocalizations.unknownUserName].
4952
///
5053
/// When a [Message] is available which the user sent,
5154
/// use [senderDisplayName] instead for a better-informed fallback.
52-
String userDisplayName(int userId) {
55+
String userDisplayName(int userId, {bool replaceIfMuted = true}) {
56+
if (replaceIfMuted && isUserMuted(userId)) {
57+
return GlobalLocalizations.zulipLocalizations.mutedUser;
58+
}
5359
return getUser(userId)?.fullName
5460
?? GlobalLocalizations.zulipLocalizations.unknownUserName;
5561
}
5662

5763
/// The name to show for the given message's sender in the UI.
5864
///
59-
/// If the user is known (see [getUser]), this is their current [User.fullName].
65+
/// If the sender is muted and [replaceIfMuted] is true (the default),
66+
/// this is [ZulipLocalizations.mutedUser].
67+
///
68+
/// Otherwise, if the user is known (see [getUser]),
69+
/// this is their current [User.fullName].
6070
/// If unknown, this uses the fallback value conveniently provided on the
6171
/// [Message] object itself, namely [Message.senderFullName].
6272
///
6373
/// For a user who isn't the sender of some known message,
6474
/// see [userDisplayName].
65-
String senderDisplayName(Message message) {
66-
return getUser(message.senderId)?.fullName
67-
?? message.senderFullName;
75+
String senderDisplayName(Message message, {bool replaceIfMuted = true}) {
76+
final senderId = message.senderId;
77+
if (replaceIfMuted && isUserMuted(senderId)) {
78+
return GlobalLocalizations.zulipLocalizations.mutedUser;
79+
}
80+
return getUser(senderId)?.fullName ?? message.senderFullName;
6881
}
6982

7083
/// Whether the user with [userId] is muted by the self-user.

lib/widgets/action_sheet.dart

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -589,6 +589,8 @@ void showMessageActionSheet({required BuildContext context, required Message mes
589589
final markAsUnreadSupported = store.zulipFeatureLevel >= 155; // TODO(server-6)
590590
final showMarkAsUnreadButton = markAsUnreadSupported && isMessageRead;
591591

592+
final isSenderMuted = store.isUserMuted(message.senderId);
593+
592594
final optionButtons = [
593595
if (popularEmojiLoaded)
594596
ReactionButtons(message: message, pageContext: pageContext),
@@ -597,6 +599,8 @@ void showMessageActionSheet({required BuildContext context, required Message mes
597599
QuoteAndReplyButton(message: message, pageContext: pageContext),
598600
if (showMarkAsUnreadButton)
599601
MarkAsUnreadButton(message: message, pageContext: pageContext),
602+
if (isSenderMuted)
603+
UnrevealMutedMessageButton(message: message, pageContext: pageContext),
600604
CopyMessageTextButton(message: message, pageContext: pageContext),
601605
CopyMessageLinkButton(message: message, pageContext: pageContext),
602606
ShareButton(message: message, pageContext: pageContext),
@@ -902,6 +906,27 @@ class MarkAsUnreadButton extends MessageActionSheetMenuItemButton {
902906
}
903907
}
904908

909+
class UnrevealMutedMessageButton extends MessageActionSheetMenuItemButton {
910+
UnrevealMutedMessageButton({
911+
super.key,
912+
required super.message,
913+
required super.pageContext,
914+
});
915+
916+
@override
917+
IconData get icon => ZulipIcons.eye_off;
918+
919+
@override
920+
String label(ZulipLocalizations zulipLocalizations) {
921+
return zulipLocalizations.actionSheetOptionHideMutedMessage;
922+
}
923+
924+
@override
925+
void onPressed() {
926+
findMessageListPage().unrevealMutedMessage(message.id);
927+
}
928+
}
929+
905930
class CopyMessageTextButton extends MessageActionSheetMenuItemButton {
906931
CopyMessageTextButton({super.key, required super.message, required super.pageContext});
907932

0 commit comments

Comments
 (0)