diff --git a/CHANGES.md b/CHANGES.md index 2bf7453632..ef31216264 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -5,7 +5,7 @@ Features ✨: - Improvements 🙌: - - + - New wording for notice when current user is the sender Bugfix 🐛: - Switch theme is not fully taken into account without restarting the app diff --git a/matrix-sdk-android/src/main/res/values/strings.xml b/matrix-sdk-android/src/main/res/values/strings.xml index 69907e5835..1010d5fe48 100644 --- a/matrix-sdk-android/src/main/res/values/strings.xml +++ b/matrix-sdk-android/src/main/res/values/strings.xml @@ -2,53 +2,85 @@ %1$s: %2$s %1$s sent an image. + You sent an image. %1$s sent a sticker. + You sent a sticker. %s\'s invitation + Your invitation %1$s created the room + You created the room %1$s invited %2$s + You invited %1$s %1$s invited you %1$s joined the room + You joined the room %1$s left the room + You left the room %1$s rejected the invitation + You rejected the invitation %1$s kicked %2$s + You kicked %1$s %1$s unbanned %2$s + You unbanned %1$s %1$s banned %2$s + You banned %1$s %1$s withdrew %2$s\'s invitation + You withdrew %1$s\'s invitation %1$s changed their avatar + You changed your avatar %1$s set their display name to %2$s + You set your display name to %1$s %1$s changed their display name from %2$s to %3$s + You changed your display name from %1$s to %2$s %1$s removed their display name (%2$s) + You removed your display name (%1$s) %1$s changed the topic to: %2$s + You changed the topic to: %1$s %1$s changed the room name to: %2$s + You changed the room name to: %1$s %s placed a video call. + You placed a video call. %s placed a voice call. + You placed a voice call. %s answered the call. + You answered the call. %s ended the call. + You ended the call. %1$s made future room history visible to %2$s + You made future room history visible to %1$s all room members, from the point they are invited. all room members, from the point they joined. all room members. anyone. unknown (%s). %1$s turned on end-to-end encryption (%2$s) + You turned on end-to-end encryption (%1$s) %s upgraded this room. + You upgraded this room. %1$s requested a VoIP conference + You requested a VoIP conference VoIP conference started VoIP conference finished (avatar was changed too) %1$s removed the room name + You removed the room name %1$s removed the room topic + You removed the room topic Message removed Message removed by %1$s Message removed [reason: %1$s] Message removed by %1$s [reason: %2$s] %1$s updated their profile %2$s + You updated your profile %1$s %1$s sent an invitation to %2$s to join the room + You sent an invitation to %1$s to join the room %1$s revoked the invitation for %2$s to join the room + You revoked the invitation for %1$s to join the room %1$s accepted the invitation for %2$s + You accepted the invitation for %1$s ** Unable to decrypt: %s ** The sender\'s device has not sent us the keys for this message. @@ -245,39 +277,68 @@ Clear sending queue %1$s\'s invitation. Reason: %2$s + Your invitation. Reason: %1$s %1$s invited %2$s. Reason: %3$s + You invited %1$s. Reason: %2$s %1$s invited you. Reason: %2$s %1$s joined the room. Reason: %2$s + You joined the room. Reason: %1$s %1$s left the room. Reason: %2$s + You left the room. Reason: %1$s %1$s rejected the invitation. Reason: %2$s + You rejected the invitation. Reason: %1$s %1$s kicked %2$s. Reason: %3$s + You kicked %1$s. Reason: %2$s %1$s unbanned %2$s. Reason: %3$s + You unbanned %1$s. Reason: %2$s %1$s banned %2$s. Reason: %3$s + You banned %1$s. Reason: %2$s %1$s sent an invitation to %2$s to join the room. Reason: %3$s + You sent an invitation to %1$s to join the room. Reason: %2$s %1$s revoked the invitation for %2$s to join the room. Reason: %3$s + You revoked the invitation for %1$s to join the room. Reason: %2$s %1$s accepted the invitation for %2$s. Reason: %3$s + You accepted the invitation for %1$s. Reason: %2$s %1$s withdrew %2$s\'s invitation. Reason: %3$s + You withdrew %1$s\'s invitation. Reason: %2$s %1$s added %2$s as an address for this room. %1$s added %2$s as addresses for this room. + + You added %1$s as an address for this room. + You added %1$s as addresses for this room. + + %1$s removed %2$s as an address for this room. %1$s removed %3$s as addresses for this room. + + You removed %1$s as an address for this room. + You removed %2$s as addresses for this room. + + %1$s added %2$s and removed %3$s as addresses for this room. + You added %1$s and removed %2$s as addresses for this room. "%1$s set the main address for this room to %2$s." + "You set the main address for this room to %1$s." "%1$s removed the main address for this room." + "You removed the main address for this room." "%1$s has allowed guests to join the room." + "You have allowed guests to join the room." "%1$s has prevented guests from joining the room." + "You have prevented guests from joining the room." %1$s turned on end-to-end encryption. + You turned on end-to-end encryption. %1$s turned on end-to-end encryption (unrecognised algorithm %2$s). + You turned on end-to-end encryption (unrecognised algorithm %1$s). %s is requesting to verify your key, but your client does not support in-chat key verification. You will need to use legacy key verification to verify keys. diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/factory/MergedHeaderItemFactory.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/factory/MergedHeaderItemFactory.kt index 419fd673d1..6616025110 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/factory/MergedHeaderItemFactory.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/factory/MergedHeaderItemFactory.kt @@ -22,6 +22,7 @@ import im.vector.matrix.android.api.session.room.model.create.RoomCreateContent import im.vector.matrix.android.api.session.room.timeline.TimelineEvent import im.vector.matrix.android.internal.crypto.MXCRYPTO_ALGORITHM_MEGOLM import im.vector.matrix.android.internal.crypto.model.event.EncryptionEventContent +import im.vector.riotx.core.di.ActiveSessionHolder import im.vector.riotx.core.extensions.prevOrNull import im.vector.riotx.features.home.AvatarRenderer import im.vector.riotx.features.home.room.detail.timeline.TimelineEventController @@ -38,7 +39,8 @@ import im.vector.riotx.features.home.room.detail.timeline.item.MergedRoomCreatio import javax.inject.Inject class MergedHeaderItemFactory @Inject constructor(private val avatarRenderer: AvatarRenderer, - private val avatarSizeProvider: AvatarSizeProvider) { + private val avatarSizeProvider: AvatarSizeProvider, + private val activeSessionHolder: ActiveSessionHolder) { private val collapsedEventIds = linkedSetOf() private val mergeItemCollapseStates = HashMap() @@ -188,7 +190,8 @@ class MergedHeaderItemFactory @Inject constructor(private val avatarRenderer: Av }, hasEncryptionEvent = hasEncryption, isEncryptionAlgorithmSecure = encryptionAlgorithm == MXCRYPTO_ALGORITHM_MEGOLM, - readReceiptsCallback = callback + readReceiptsCallback = callback, + currentUserId = activeSessionHolder.getSafeActiveSession()?.myUserId ?: "" ) MergedRoomCreationItem_() .id(mergeId) diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/format/NoticeEventFormatter.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/format/NoticeEventFormatter.kt index cab5b30190..eff5444a91 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/format/NoticeEventFormatter.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/format/NoticeEventFormatter.kt @@ -45,6 +45,8 @@ import javax.inject.Inject class NoticeEventFormatter @Inject constructor(private val sessionHolder: ActiveSessionHolder, private val sp: StringProvider) { + private fun Event.isSentByCurrentUser() = senderId != null && senderId == sessionHolder.getSafeActiveSession()?.myUserId + fun format(timelineEvent: TimelineEvent): CharSequence? { return when (val type = timelineEvent.root.getClearType()) { EventType.STATE_ROOM_JOIN_RULES -> formatJoinRulesEvent(timelineEvent.root, timelineEvent.senderInfo.disambiguatedDisplayName) @@ -57,7 +59,7 @@ class NoticeEventFormatter @Inject constructor(private val sessionHolder: Active EventType.STATE_ROOM_HISTORY_VISIBILITY -> formatRoomHistoryVisibilityEvent(timelineEvent.root, timelineEvent.senderInfo.disambiguatedDisplayName) EventType.STATE_ROOM_GUEST_ACCESS -> formatRoomGuestAccessEvent(timelineEvent.root, timelineEvent.senderInfo.disambiguatedDisplayName) EventType.STATE_ROOM_ENCRYPTION -> formatRoomEncryptionEvent(timelineEvent.root, timelineEvent.senderInfo.disambiguatedDisplayName) - EventType.STATE_ROOM_TOMBSTONE -> formatRoomTombstoneEvent(timelineEvent.senderInfo.disambiguatedDisplayName) + EventType.STATE_ROOM_TOMBSTONE -> formatRoomTombstoneEvent(timelineEvent.root, timelineEvent.senderInfo.disambiguatedDisplayName) EventType.CALL_INVITE, EventType.CALL_HANGUP, EventType.CALL_ANSWER -> formatCallEvent(type, timelineEvent.root, timelineEvent.senderInfo.disambiguatedDisplayName) @@ -88,7 +90,7 @@ class NoticeEventFormatter @Inject constructor(private val sessionHolder: Active EventType.CALL_INVITE, EventType.CALL_HANGUP, EventType.CALL_ANSWER -> formatCallEvent(type, event, senderName) - EventType.STATE_ROOM_TOMBSTONE -> formatRoomTombstoneEvent(senderName) + EventType.STATE_ROOM_TOMBSTONE -> formatRoomTombstoneEvent(event, senderName) else -> { Timber.v("Type $type not handled by this formatter") null @@ -103,28 +105,54 @@ class NoticeEventFormatter @Inject constructor(private val sessionHolder: Active private fun formatRoomCreateEvent(event: Event): CharSequence? { return event.getClearContent().toModel() ?.takeIf { it.creator.isNullOrBlank().not() } - ?.let { sp.getString(R.string.notice_room_created, it.creator) } + ?.let { + if (event.isSentByCurrentUser()) { + sp.getString(R.string.notice_room_created_by_you) + } else { + sp.getString(R.string.notice_room_created, it.creator) + } + } } private fun formatRoomNameEvent(event: Event, senderName: String?): CharSequence? { val content = event.getClearContent().toModel() ?: return null return if (content.name.isNullOrBlank()) { - sp.getString(R.string.notice_room_name_removed, senderName) + if (event.isSentByCurrentUser()) { + sp.getString(R.string.notice_room_name_removed_by_you) + } else { + sp.getString(R.string.notice_room_name_removed, senderName) + } } else { - sp.getString(R.string.notice_room_name_changed, senderName, content.name) + if (event.isSentByCurrentUser()) { + sp.getString(R.string.notice_room_name_changed_by_you, content.name) + } else { + sp.getString(R.string.notice_room_name_changed, senderName, content.name) + } } } - private fun formatRoomTombstoneEvent(senderName: String?): CharSequence? { - return sp.getString(R.string.notice_room_update, senderName) + private fun formatRoomTombstoneEvent(event: Event, senderName: String?): CharSequence? { + return if (event.isSentByCurrentUser()) { + sp.getString(R.string.notice_room_update_by_you) + } else { + sp.getString(R.string.notice_room_update, senderName) + } } private fun formatRoomTopicEvent(event: Event, senderName: String?): CharSequence? { val content = event.getClearContent().toModel() ?: return null return if (content.topic.isNullOrEmpty()) { - sp.getString(R.string.notice_room_topic_removed, senderName) + if (event.isSentByCurrentUser()) { + sp.getString(R.string.notice_room_topic_removed_by_you) + } else { + sp.getString(R.string.notice_room_topic_removed, senderName) + } } else { - sp.getString(R.string.notice_room_topic_changed, senderName, content.topic) + if (event.isSentByCurrentUser()) { + sp.getString(R.string.notice_room_topic_changed_by_you, content.topic) + } else { + sp.getString(R.string.notice_room_topic_changed, senderName, content.topic) + } } } @@ -137,7 +165,11 @@ class NoticeEventFormatter @Inject constructor(private val sessionHolder: Active RoomHistoryVisibility.JOINED -> sp.getString(R.string.notice_room_visibility_joined) RoomHistoryVisibility.WORLD_READABLE -> sp.getString(R.string.notice_room_visibility_world_readable) } - return sp.getString(R.string.notice_made_future_room_visibility, senderName, formattedVisibility) + return if (event.isSentByCurrentUser()) { + sp.getString(R.string.notice_made_future_room_visibility_by_you, formattedVisibility) + } else { + sp.getString(R.string.notice_made_future_room_visibility, senderName, formattedVisibility) + } } private fun formatCallEvent(type: String, event: Event, senderName: String?): CharSequence? { @@ -146,13 +178,31 @@ class NoticeEventFormatter @Inject constructor(private val sessionHolder: Active val content = event.getClearContent().toModel() ?: return null val isVideoCall = content.offer.sdp == CallInviteContent.Offer.SDP_VIDEO return if (isVideoCall) { - sp.getString(R.string.notice_placed_video_call, senderName) + if (event.isSentByCurrentUser()) { + sp.getString(R.string.notice_placed_video_call_by_you) + } else { + sp.getString(R.string.notice_placed_video_call, senderName) + } } else { - sp.getString(R.string.notice_placed_voice_call, senderName) + if (event.isSentByCurrentUser()) { + sp.getString(R.string.notice_placed_voice_call_by_you) + } else { + sp.getString(R.string.notice_placed_voice_call, senderName) + } } } - EventType.CALL_ANSWER -> sp.getString(R.string.notice_answered_call, senderName) - EventType.CALL_HANGUP -> sp.getString(R.string.notice_ended_call, senderName) + EventType.CALL_ANSWER -> + if (event.isSentByCurrentUser()) { + sp.getString(R.string.notice_answered_call_by_you) + } else { + sp.getString(R.string.notice_answered_call, senderName) + } + EventType.CALL_HANGUP -> + if (event.isSentByCurrentUser()) { + sp.getString(R.string.notice_ended_call_by_you) + } else { + sp.getString(R.string.notice_ended_call, senderName) + } else -> null } } @@ -175,15 +225,29 @@ class NoticeEventFormatter @Inject constructor(private val sessionHolder: Active val addedAliases = eventContent?.aliases.orEmpty() - prevEventContent?.aliases.orEmpty() val removedAliases = prevEventContent?.aliases.orEmpty() - eventContent?.aliases.orEmpty() - return if (addedAliases.isNotEmpty() && removedAliases.isNotEmpty()) { - sp.getString(R.string.notice_room_aliases_added_and_removed, senderName, addedAliases.joinToString(), removedAliases.joinToString()) - } else if (addedAliases.isNotEmpty()) { - sp.getQuantityString(R.plurals.notice_room_aliases_added, addedAliases.size, senderName, addedAliases.joinToString()) - } else if (removedAliases.isNotEmpty()) { - sp.getQuantityString(R.plurals.notice_room_aliases_removed, removedAliases.size, senderName, removedAliases.joinToString()) - } else { - Timber.w("Alias event without any change...") - null + return when { + addedAliases.isNotEmpty() && removedAliases.isNotEmpty() -> + if (event.isSentByCurrentUser()) { + sp.getString(R.string.notice_room_aliases_added_and_removed_by_you, addedAliases.joinToString(), removedAliases.joinToString()) + } else { + sp.getString(R.string.notice_room_aliases_added_and_removed, senderName, addedAliases.joinToString(), removedAliases.joinToString()) + } + addedAliases.isNotEmpty() -> + if (event.isSentByCurrentUser()) { + sp.getQuantityString(R.plurals.notice_room_aliases_added_by_you, addedAliases.size, addedAliases.joinToString()) + } else { + sp.getQuantityString(R.plurals.notice_room_aliases_added, addedAliases.size, senderName, addedAliases.joinToString()) + } + removedAliases.isNotEmpty() -> + if (event.isSentByCurrentUser()) { + sp.getQuantityString(R.plurals.notice_room_aliases_removed_by_you, removedAliases.size, removedAliases.joinToString()) + } else { + sp.getQuantityString(R.plurals.notice_room_aliases_removed, removedAliases.size, senderName, removedAliases.joinToString()) + } + else -> { + Timber.w("Alias event without any change...") + null + } } } @@ -192,25 +256,54 @@ class NoticeEventFormatter @Inject constructor(private val sessionHolder: Active val canonicalAlias = eventContent?.canonicalAlias return canonicalAlias ?.takeIf { it.isNotBlank() } - ?.let { sp.getString(R.string.notice_room_canonical_alias_set, senderName, it) } - ?: sp.getString(R.string.notice_room_canonical_alias_unset, senderName) + ?.let { + if (event.isSentByCurrentUser()) { + sp.getString(R.string.notice_room_canonical_alias_set_by_you, it) + } else { + sp.getString(R.string.notice_room_canonical_alias_set, senderName, it) + } + } + ?: if (event.isSentByCurrentUser()) { + sp.getString(R.string.notice_room_canonical_alias_unset_by_you) + } else { + sp.getString(R.string.notice_room_canonical_alias_unset, senderName) + } } private fun formatRoomGuestAccessEvent(event: Event, senderName: String?): String? { val eventContent: RoomGuestAccessContent? = event.getClearContent().toModel() return when (eventContent?.guestAccess) { - GuestAccess.CanJoin -> sp.getString(R.string.notice_room_guest_access_can_join, senderName) - GuestAccess.Forbidden -> sp.getString(R.string.notice_room_guest_access_forbidden, senderName) + GuestAccess.CanJoin -> + if (event.isSentByCurrentUser()) { + sp.getString(R.string.notice_room_guest_access_can_join_by_you) + } else { + sp.getString(R.string.notice_room_guest_access_can_join, senderName) + } + GuestAccess.Forbidden -> + if (event.isSentByCurrentUser()) { + sp.getString(R.string.notice_room_guest_access_forbidden_by_you) + } else { + sp.getString(R.string.notice_room_guest_access_forbidden, senderName) + } else -> null } } private fun formatRoomEncryptionEvent(event: Event, senderName: String?): CharSequence? { val content = event.content.toModel() ?: return null - return if (content.algorithm == MXCRYPTO_ALGORITHM_MEGOLM) { - sp.getString(R.string.notice_end_to_end_ok, senderName) - } else { - sp.getString(R.string.notice_end_to_end_unknown_algorithm, senderName, content.algorithm) + return when (content.algorithm) { + MXCRYPTO_ALGORITHM_MEGOLM -> + if (event.isSentByCurrentUser()) { + sp.getString(R.string.notice_end_to_end_ok_by_you) + } else { + sp.getString(R.string.notice_end_to_end_ok, senderName) + } + else -> + if (event.isSentByCurrentUser()) { + sp.getString(R.string.notice_end_to_end_unknown_algorithm_by_you, content.algorithm) + } else { + sp.getString(R.string.notice_end_to_end_unknown_algorithm, senderName, content.algorithm) + } } } @@ -220,11 +313,23 @@ class NoticeEventFormatter @Inject constructor(private val sessionHolder: Active if (eventContent?.displayName != prevEventContent?.displayName) { val displayNameText = when { prevEventContent?.displayName.isNullOrEmpty() -> - sp.getString(R.string.notice_display_name_set, event.senderId, eventContent?.displayName) + if (event.isSentByCurrentUser()) { + sp.getString(R.string.notice_display_name_set_by_you, eventContent?.displayName) + } else { + sp.getString(R.string.notice_display_name_set, event.senderId, eventContent?.displayName) + } eventContent?.displayName.isNullOrEmpty() -> - sp.getString(R.string.notice_display_name_removed, event.senderId, prevEventContent?.displayName) + if (event.isSentByCurrentUser()) { + sp.getString(R.string.notice_display_name_removed_by_you, prevEventContent?.displayName) + } else { + sp.getString(R.string.notice_display_name_removed, event.senderId, prevEventContent?.displayName) + } else -> - sp.getString(R.string.notice_display_name_changed_from, event.senderId, prevEventContent?.displayName, eventContent?.displayName) + if (event.isSentByCurrentUser()) { + sp.getString(R.string.notice_display_name_changed_from_by_you, prevEventContent?.displayName, eventContent?.displayName) + } else { + sp.getString(R.string.notice_display_name_changed_from, event.senderId, prevEventContent?.displayName, eventContent?.displayName) + } } displayText.append(displayNameText) } @@ -234,13 +339,21 @@ class NoticeEventFormatter @Inject constructor(private val sessionHolder: Active displayText.append(" ") sp.getString(R.string.notice_avatar_changed_too) } else { - sp.getString(R.string.notice_avatar_url_changed, senderName) + if (event.isSentByCurrentUser()) { + sp.getString(R.string.notice_avatar_url_changed_by_you) + } else { + sp.getString(R.string.notice_avatar_url_changed, senderName) + } } displayText.append(displayAvatarText) } if (displayText.isEmpty()) { displayText.append( - sp.getString(R.string.notice_member_no_changes, senderName) + if (event.isSentByCurrentUser()) { + sp.getString(R.string.notice_member_no_changes_by_you) + } else { + sp.getString(R.string.notice_member_no_changes, senderName) + } ) } return displayText.toString() @@ -257,62 +370,133 @@ class NoticeEventFormatter @Inject constructor(private val sessionHolder: Active val userWhoHasAccepted = eventContent.thirdPartyInvite?.signed?.mxid ?: event.stateKey val threePidDisplayName = eventContent.thirdPartyInvite?.displayName ?: "" eventContent.safeReason?.let { reason -> - sp.getString(R.string.notice_room_third_party_registered_invite_with_reason, userWhoHasAccepted, threePidDisplayName, reason) - } ?: sp.getString(R.string.notice_room_third_party_registered_invite, userWhoHasAccepted, threePidDisplayName) + if (event.isSentByCurrentUser()) { + sp.getString(R.string.notice_room_third_party_registered_invite_with_reason_by_you, threePidDisplayName, reason) + } else { + sp.getString(R.string.notice_room_third_party_registered_invite_with_reason, userWhoHasAccepted, threePidDisplayName, reason) + } + } ?: if (event.isSentByCurrentUser()) { + sp.getString(R.string.notice_room_third_party_registered_invite_by_you, threePidDisplayName) + } else { + sp.getString(R.string.notice_room_third_party_registered_invite, userWhoHasAccepted, threePidDisplayName) + } } event.stateKey == selfUserId -> eventContent.safeReason?.let { reason -> sp.getString(R.string.notice_room_invite_you_with_reason, senderDisplayName, reason) } ?: sp.getString(R.string.notice_room_invite_you, senderDisplayName) event.stateKey.isNullOrEmpty() -> - eventContent.safeReason?.let { reason -> - sp.getString(R.string.notice_room_invite_no_invitee_with_reason, senderDisplayName, reason) - } ?: sp.getString(R.string.notice_room_invite_no_invitee, senderDisplayName) + if (event.isSentByCurrentUser()) { + eventContent.safeReason?.let { reason -> + sp.getString(R.string.notice_room_invite_no_invitee_with_reason_by_you, reason) + } ?: sp.getString(R.string.notice_room_invite_no_invitee_by_you) + } else { + eventContent.safeReason?.let { reason -> + sp.getString(R.string.notice_room_invite_no_invitee_with_reason, senderDisplayName, reason) + } ?: sp.getString(R.string.notice_room_invite_no_invitee, senderDisplayName) + } else -> - eventContent.safeReason?.let { reason -> - sp.getString(R.string.notice_room_invite_with_reason, senderDisplayName, targetDisplayName, reason) - } ?: sp.getString(R.string.notice_room_invite, senderDisplayName, targetDisplayName) + if (event.isSentByCurrentUser()) { + eventContent.safeReason?.let { reason -> + sp.getString(R.string.notice_room_invite_with_reason_by_you, targetDisplayName, reason) + } ?: sp.getString(R.string.notice_room_invite_by_you, targetDisplayName) + } else { + eventContent.safeReason?.let { reason -> + sp.getString(R.string.notice_room_invite_with_reason, senderDisplayName, targetDisplayName, reason) + } ?: sp.getString(R.string.notice_room_invite, senderDisplayName, targetDisplayName) + } } } Membership.JOIN -> - eventContent.safeReason?.let { reason -> - sp.getString(R.string.notice_room_join_with_reason, senderDisplayName, reason) - } ?: sp.getString(R.string.notice_room_join, senderDisplayName) + if (event.isSentByCurrentUser()) { + eventContent.safeReason?.let { reason -> + sp.getString(R.string.notice_room_join_with_reason_by_you, reason) + } ?: sp.getString(R.string.notice_room_join_by_you) + } else { + eventContent.safeReason?.let { reason -> + sp.getString(R.string.notice_room_join_with_reason, senderDisplayName, reason) + } ?: sp.getString(R.string.notice_room_join, senderDisplayName) + } Membership.LEAVE -> // 2 cases here: this member may have left voluntarily or they may have been "left" by someone else ie. kicked if (event.senderId == event.stateKey) { - if (prevEventContent?.membership == Membership.INVITE) { - eventContent.safeReason?.let { reason -> - sp.getString(R.string.notice_room_reject_with_reason, senderDisplayName, reason) - } ?: sp.getString(R.string.notice_room_reject, senderDisplayName) - } else { - eventContent.safeReason?.let { reason -> - sp.getString(R.string.notice_room_leave_with_reason, senderDisplayName, reason) - } ?: sp.getString(R.string.notice_room_leave, senderDisplayName) + when (prevEventContent?.membership) { + Membership.INVITE -> + if (event.isSentByCurrentUser()) { + eventContent.safeReason?.let { reason -> + sp.getString(R.string.notice_room_reject_with_reason_by_you, reason) + } ?: sp.getString(R.string.notice_room_reject_by_you) + } else { + eventContent.safeReason?.let { reason -> + sp.getString(R.string.notice_room_reject_with_reason, senderDisplayName, reason) + } ?: sp.getString(R.string.notice_room_reject, senderDisplayName) + } + else -> + if (event.isSentByCurrentUser()) { + eventContent.safeReason?.let { reason -> + sp.getString(R.string.notice_room_leave_with_reason_by_you, reason) + } ?: sp.getString(R.string.notice_room_leave_by_you) + } else { + eventContent.safeReason?.let { reason -> + sp.getString(R.string.notice_room_leave_with_reason, senderDisplayName, reason) + } ?: sp.getString(R.string.notice_room_leave, senderDisplayName) + } } - } else if (prevEventContent?.membership == Membership.INVITE) { + } else { + when (prevEventContent?.membership) { + Membership.INVITE -> + if (event.isSentByCurrentUser()) { + eventContent.safeReason?.let { reason -> + sp.getString(R.string.notice_room_withdraw_with_reason_by_you, targetDisplayName, reason) + } ?: sp.getString(R.string.notice_room_withdraw_by_you, targetDisplayName) + } else { + eventContent.safeReason?.let { reason -> + sp.getString(R.string.notice_room_withdraw_with_reason, senderDisplayName, targetDisplayName, reason) + } ?: sp.getString(R.string.notice_room_withdraw, senderDisplayName, targetDisplayName) + } + Membership.JOIN -> + if (event.isSentByCurrentUser()) { + eventContent.safeReason?.let { reason -> + sp.getString(R.string.notice_room_kick_with_reason_by_you, targetDisplayName, reason) + } ?: sp.getString(R.string.notice_room_kick_by_you, targetDisplayName) + } else { + eventContent.safeReason?.let { reason -> + sp.getString(R.string.notice_room_kick_with_reason, senderDisplayName, targetDisplayName, reason) + } ?: sp.getString(R.string.notice_room_kick, senderDisplayName, targetDisplayName) + } + Membership.BAN -> + if (event.isSentByCurrentUser()) { + eventContent.safeReason?.let { reason -> + sp.getString(R.string.notice_room_unban_with_reason_by_you, targetDisplayName, reason) + } ?: sp.getString(R.string.notice_room_unban_by_you, targetDisplayName) + } else { + eventContent.safeReason?.let { reason -> + sp.getString(R.string.notice_room_unban_with_reason, senderDisplayName, targetDisplayName, reason) + } ?: sp.getString(R.string.notice_room_unban, senderDisplayName, targetDisplayName) + } + else -> null + } + } + Membership.BAN -> + if (event.isSentByCurrentUser()) { + eventContent.safeReason?.let { + sp.getString(R.string.notice_room_ban_with_reason_by_you, targetDisplayName, it) + } ?: sp.getString(R.string.notice_room_ban_by_you, targetDisplayName) + } else { + eventContent.safeReason?.let { + sp.getString(R.string.notice_room_ban_with_reason, senderDisplayName, targetDisplayName, it) + } ?: sp.getString(R.string.notice_room_ban, senderDisplayName, targetDisplayName) + } + Membership.KNOCK -> + if (event.isSentByCurrentUser()) { eventContent.safeReason?.let { reason -> - sp.getString(R.string.notice_room_withdraw_with_reason, senderDisplayName, targetDisplayName, reason) - } ?: sp.getString(R.string.notice_room_withdraw, senderDisplayName, targetDisplayName) - } else if (prevEventContent?.membership == Membership.JOIN) { + sp.getString(R.string.notice_room_kick_with_reason_by_you, targetDisplayName, reason) + } ?: sp.getString(R.string.notice_room_kick_by_you, targetDisplayName) + } else { eventContent.safeReason?.let { reason -> sp.getString(R.string.notice_room_kick_with_reason, senderDisplayName, targetDisplayName, reason) } ?: sp.getString(R.string.notice_room_kick, senderDisplayName, targetDisplayName) - } else if (prevEventContent?.membership == Membership.BAN) { - eventContent.safeReason?.let { reason -> - sp.getString(R.string.notice_room_unban_with_reason, senderDisplayName, targetDisplayName, reason) - } ?: sp.getString(R.string.notice_room_unban, senderDisplayName, targetDisplayName) - } else { - null } - Membership.BAN -> - eventContent.safeReason?.let { - sp.getString(R.string.notice_room_ban_with_reason, senderDisplayName, targetDisplayName, it) - } ?: sp.getString(R.string.notice_room_ban, senderDisplayName, targetDisplayName) - Membership.KNOCK -> - eventContent.safeReason?.let { reason -> - sp.getString(R.string.notice_room_kick_with_reason, senderDisplayName, targetDisplayName, reason) - } ?: sp.getString(R.string.notice_room_kick, senderDisplayName, targetDisplayName) else -> null } } @@ -320,8 +504,18 @@ class NoticeEventFormatter @Inject constructor(private val sessionHolder: Active private fun formatJoinRulesEvent(event: Event, senderName: String?): CharSequence? { val content = event.getClearContent().toModel() ?: return null return when (content.joinRules) { - RoomJoinRules.INVITE -> sp.getString(R.string.room_join_rules_invite, senderName) - RoomJoinRules.PUBLIC -> sp.getString(R.string.room_join_rules_public, senderName) + RoomJoinRules.INVITE -> + if (event.isSentByCurrentUser()) { + sp.getString(R.string.room_join_rules_invite_by_you) + } else { + sp.getString(R.string.room_join_rules_invite, senderName) + } + RoomJoinRules.PUBLIC -> + if (event.isSentByCurrentUser()) { + sp.getString(R.string.room_join_rules_public_by_you) + } else { + sp.getString(R.string.room_join_rules_public, senderName) + } else -> null } } diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/item/MergedRoomCreationItem.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/item/MergedRoomCreationItem.kt index 3985b3856b..cf044f8a37 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/item/MergedRoomCreationItem.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/item/MergedRoomCreationItem.kt @@ -46,8 +46,12 @@ abstract class MergedRoomCreationItem : BasedMergedItem Unit, - val hasEncryptionEvent : Boolean, + val currentUserId: String, + val hasEncryptionEvent: Boolean, val isEncryptionAlgorithmSecure: Boolean ) : BasedMergedItem.Attributes } diff --git a/vector/src/main/res/values/strings.xml b/vector/src/main/res/values/strings.xml index 36521e897e..60b74570ba 100644 --- a/vector/src/main/res/values/strings.xml +++ b/vector/src/main/res/values/strings.xml @@ -1823,6 +1823,7 @@ Not all features in Riot are implemented in RiotX yet. Main missing (and coming "Settings" "Leave the room" "%1$s made no changes" + "You made no changes" Sends the given message as a spoiler Spoiler Type keywords to find a reaction. @@ -1833,7 +1834,9 @@ Not all features in Riot are implemented in RiotX yet. Main missing (and coming %1$s made the room public to whoever knows the link. + You made the room public to whoever knows the link. %1$s made the room invite only. + You made the room invite only. Unread messages Liberate your communication @@ -2302,6 +2305,7 @@ Not all features in Riot are implemented in RiotX yet. Main missing (and coming The encryption used by this room is not supported %s created and configured the room. + You created and configured the room. Almost there! Is the other device showing the same shield? Almost there! Waiting for confirmation…