From 18beef14cfd77979e21860aa529b62ca109f334b Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 4 Dec 2019 18:33:23 +0100 Subject: [PATCH 01/12] "ban" event are not rendered correctly (#716) --- CHANGES.md | 1 + .../api/session/room/model/RoomMember.kt | 1 + .../src/main/res/values/strings_RiotX.xml | 2 +- .../timeline/format/NoticeEventFormatter.kt | 27 +++++++------------ 4 files changed, 12 insertions(+), 19 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 7e386e01945..0b0cf05a666 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -45,6 +45,7 @@ Bugfix 🐛: - Fix emoji filtering not working - Fix issue of closing Realm in another thread (#725) - Attempt to properly cancel the crypto module when user signs out (#724) + - "ban" event are not rendered correctly (#716) Changes in RiotX 0.8.0 (2019-11-19) =================================================== diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/RoomMember.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/RoomMember.kt index aa73727685a..2d96cef43d6 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/RoomMember.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/RoomMember.kt @@ -26,6 +26,7 @@ import im.vector.matrix.android.api.session.events.model.UnsignedData @JsonClass(generateAdapter = true) data class RoomMember( @Json(name = "membership") val membership: Membership, + @Json(name = "reason") val reason: String?, @Json(name = "displayname") val displayName: String? = null, @Json(name = "avatar_url") val avatarUrl: String? = null, @Json(name = "is_direct") val isDirect: Boolean = false, diff --git a/matrix-sdk-android/src/main/res/values/strings_RiotX.xml b/matrix-sdk-android/src/main/res/values/strings_RiotX.xml index a588bb36fd6..7972e63e5ac 100644 --- a/matrix-sdk-android/src/main/res/values/strings_RiotX.xml +++ b/matrix-sdk-android/src/main/res/values/strings_RiotX.xml @@ -2,7 +2,7 @@ - + %1$s banned %2$s. Reason: %3$s There is no network connection right now 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 a3910664a2a..701d58eb2f1 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 @@ -19,14 +19,7 @@ package im.vector.riotx.features.home.room.detail.timeline.format import im.vector.matrix.android.api.session.events.model.Event import im.vector.matrix.android.api.session.events.model.EventType import im.vector.matrix.android.api.session.events.model.toModel -import im.vector.matrix.android.api.session.room.model.Membership -import im.vector.matrix.android.api.session.room.model.RoomHistoryVisibility -import im.vector.matrix.android.api.session.room.model.RoomHistoryVisibilityContent -import im.vector.matrix.android.api.session.room.model.RoomJoinRules -import im.vector.matrix.android.api.session.room.model.RoomJoinRulesContent -import im.vector.matrix.android.api.session.room.model.RoomMember -import im.vector.matrix.android.api.session.room.model.RoomNameContent -import im.vector.matrix.android.api.session.room.model.RoomTopicContent +import im.vector.matrix.android.api.session.room.model.* import im.vector.matrix.android.api.session.room.model.call.CallInviteContent import im.vector.matrix.android.api.session.room.timeline.TimelineEvent import im.vector.riotx.R @@ -104,8 +97,7 @@ class NoticeEventFormatter @Inject constructor(private val sessionHolder: Active } private fun formatRoomHistoryVisibilityEvent(event: Event, senderName: String?): CharSequence? { - val historyVisibility = event.getClearContent().toModel()?.historyVisibility - ?: return null + val historyVisibility = event.getClearContent().toModel()?.historyVisibility ?: return null val formattedVisibility = when (historyVisibility) { RoomHistoryVisibility.SHARED -> stringProvider.getString(R.string.notice_room_visibility_shared) @@ -154,8 +146,7 @@ class NoticeEventFormatter @Inject constructor(private val sessionHolder: Active eventContent?.displayName.isNullOrEmpty() -> stringProvider.getString(R.string.notice_display_name_removed, event.senderId, prevEventContent?.displayName) else -> - stringProvider.getString(R.string.notice_display_name_changed_from, - event.senderId, prevEventContent?.displayName, eventContent?.displayName) + stringProvider.getString(R.string.notice_display_name_changed_from, event.senderId, prevEventContent?.displayName, eventContent?.displayName) } displayText.append(displayNameText) } @@ -179,16 +170,14 @@ class NoticeEventFormatter @Inject constructor(private val sessionHolder: Active private fun buildMembershipNotice(event: Event, senderName: String?, eventContent: RoomMember?, prevEventContent: RoomMember?): String? { val senderDisplayName = senderName ?: event.senderId - val targetDisplayName = eventContent?.displayName ?: prevEventContent?.displayName ?: "" + val targetDisplayName = eventContent?.displayName ?: prevEventContent?.displayName ?: event.stateKey ?: "" return when { Membership.INVITE == eventContent?.membership -> { val selfUserId = sessionHolder.getSafeActiveSession()?.myUserId when { eventContent.thirdPartyInvite != null -> { - val userWhoHasAccepted = eventContent.thirdPartyInvite?.signed?.mxid - ?: event.stateKey - stringProvider.getString(R.string.notice_room_third_party_registered_invite, - userWhoHasAccepted, eventContent.thirdPartyInvite?.displayName) + val userWhoHasAccepted = eventContent.thirdPartyInvite?.signed?.mxid ?: event.stateKey + stringProvider.getString(R.string.notice_room_third_party_registered_invite, userWhoHasAccepted, eventContent.thirdPartyInvite?.displayName) } event.stateKey == selfUserId -> stringProvider.getString(R.string.notice_room_invite_you, senderDisplayName) @@ -218,7 +207,9 @@ class NoticeEventFormatter @Inject constructor(private val sessionHolder: Active null } Membership.BAN == eventContent?.membership -> - stringProvider.getString(R.string.notice_room_ban, senderDisplayName, targetDisplayName) + eventContent.reason?.takeIf { it.isNotBlank() } + ?.let { reason -> stringProvider.getString(R.string.notice_room_ban_with_reason, senderDisplayName, targetDisplayName, reason) } + ?: stringProvider.getString(R.string.notice_room_ban, senderDisplayName, targetDisplayName) Membership.KNOCK == eventContent?.membership -> stringProvider.getString(R.string.notice_room_kick, senderDisplayName, targetDisplayName) else -> null From d28700e2bf08b6097678209c3d3314457daa1796 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 4 Dec 2019 18:51:56 +0100 Subject: [PATCH 02/12] Add reason for all membership events (https://github.com/matrix-org/matrix-doc/pull/2367) --- CHANGES.md | 1 + .../api/session/room/model/RoomMember.kt | 5 +- .../src/main/res/values/strings_RiotX.xml | 13 +++++- .../timeline/format/NoticeEventFormatter.kt | 46 ++++++++++++++----- 4 files changed, 51 insertions(+), 14 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 0b0cf05a666..0b8ecbba7a4 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -39,6 +39,7 @@ Improvements 🙌: Other changes: - Fix a small grammatical error when an empty room list is shown. + - Add reason for all membership events (https://github.com/matrix-org/matrix-doc/pull/2367) Bugfix 🐛: - Do not show long click help if only invitation are displayed diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/RoomMember.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/RoomMember.kt index 2d96cef43d6..e28ba90b526 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/RoomMember.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/RoomMember.kt @@ -32,4 +32,7 @@ data class RoomMember( @Json(name = "is_direct") val isDirect: Boolean = false, @Json(name = "third_party_invite") val thirdPartyInvite: Invite? = null, @Json(name = "unsigned") val unsignedData: UnsignedData? = null -) +) { + val safeReason + get() = reason?.takeIf { it.isNotBlank() } +} diff --git a/matrix-sdk-android/src/main/res/values/strings_RiotX.xml b/matrix-sdk-android/src/main/res/values/strings_RiotX.xml index 7972e63e5ac..a22533c6d13 100644 --- a/matrix-sdk-android/src/main/res/values/strings_RiotX.xml +++ b/matrix-sdk-android/src/main/res/values/strings_RiotX.xml @@ -2,8 +2,19 @@ + %1$s\'s invitation. Reason: %2$s + %1$s invited %2$s. Reason: %3$s + %1$s invited you. Reason: %2$s + %1$s joined. Reason: %2$s + %1$s left. Reason: %2$s + %1$s rejected the invitation. Reason: %2$s + %1$s kicked %2$s. Reason: %3$s + %1$s unbanned %2$s. Reason: %3$s %1$s banned %2$s. Reason: %3$s - + %1$s sent an invitation to %2$s to join the room. Reason: %3$s + %1$s revoked the invitation for %2$s to join the room. Reason: %3$s + %1$s accepted the invitation for %2$s. Reason: %3$s + %1$s withdrew %2$s\'s invitation. Reason: %3$s There is no network connection right now \ No newline at end of file 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 701d58eb2f1..07d240171e6 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 @@ -177,41 +177,63 @@ class NoticeEventFormatter @Inject constructor(private val sessionHolder: Active when { eventContent.thirdPartyInvite != null -> { val userWhoHasAccepted = eventContent.thirdPartyInvite?.signed?.mxid ?: event.stateKey - stringProvider.getString(R.string.notice_room_third_party_registered_invite, userWhoHasAccepted, eventContent.thirdPartyInvite?.displayName) + eventContent.safeReason + ?.let { reason -> stringProvider.getString(R.string.notice_room_third_party_registered_invite_with_reason, userWhoHasAccepted, eventContent.thirdPartyInvite?.displayName, reason) } + ?: stringProvider.getString(R.string.notice_room_third_party_registered_invite, userWhoHasAccepted, eventContent.thirdPartyInvite?.displayName) } event.stateKey == selfUserId -> - stringProvider.getString(R.string.notice_room_invite_you, senderDisplayName) + eventContent.safeReason + ?.let { reason -> stringProvider.getString(R.string.notice_room_invite_you_with_reason, senderDisplayName, reason) } + ?: stringProvider.getString(R.string.notice_room_invite_you, senderDisplayName) event.stateKey.isNullOrEmpty() -> - stringProvider.getString(R.string.notice_room_invite_no_invitee, senderDisplayName) + eventContent.safeReason + ?.let { reason -> stringProvider.getString(R.string.notice_room_invite_no_invitee_with_reason, senderDisplayName, reason) } + ?: stringProvider.getString(R.string.notice_room_invite_no_invitee, senderDisplayName) else -> - stringProvider.getString(R.string.notice_room_invite, senderDisplayName, targetDisplayName) + eventContent.safeReason + ?.let { reason -> stringProvider.getString(R.string.notice_room_invite, senderDisplayName, targetDisplayName, reason) } + ?: stringProvider.getString(R.string.notice_room_invite, senderDisplayName, targetDisplayName) } } Membership.JOIN == eventContent?.membership -> - stringProvider.getString(R.string.notice_room_join, senderDisplayName) + eventContent.safeReason + ?.let { reason -> stringProvider.getString(R.string.notice_room_join_with_reason, senderDisplayName, reason) } + ?: stringProvider.getString(R.string.notice_room_join, senderDisplayName) Membership.LEAVE == eventContent?.membership -> // 2 cases here: this member may have left voluntarily or they may have been "left" by someone else ie. kicked return if (event.senderId == event.stateKey) { if (prevEventContent?.membership == Membership.INVITE) { - stringProvider.getString(R.string.notice_room_reject, senderDisplayName) + eventContent.safeReason + ?.let { reason -> stringProvider.getString(R.string.notice_room_reject_with_reason, senderDisplayName, reason) } + ?: stringProvider.getString(R.string.notice_room_reject, senderDisplayName) } else { - stringProvider.getString(R.string.notice_room_leave, senderDisplayName) + eventContent.safeReason + ?.let { reason -> stringProvider.getString(R.string.notice_room_leave_with_reason, senderDisplayName, reason) } + ?: stringProvider.getString(R.string.notice_room_leave, senderDisplayName) } } else if (prevEventContent?.membership == Membership.INVITE) { - stringProvider.getString(R.string.notice_room_withdraw, senderDisplayName, targetDisplayName) + eventContent.safeReason + ?.let { reason -> stringProvider.getString(R.string.notice_room_withdraw_with_reason, senderDisplayName, targetDisplayName, reason) } + ?: stringProvider.getString(R.string.notice_room_withdraw, senderDisplayName, targetDisplayName) } else if (prevEventContent?.membership == Membership.JOIN) { - stringProvider.getString(R.string.notice_room_kick, senderDisplayName, targetDisplayName) + eventContent.safeReason + ?.let { reason -> stringProvider.getString(R.string.notice_room_kick_with_reason, senderDisplayName, targetDisplayName, reason) } + ?: stringProvider.getString(R.string.notice_room_kick, senderDisplayName, targetDisplayName) } else if (prevEventContent?.membership == Membership.BAN) { - stringProvider.getString(R.string.notice_room_unban, senderDisplayName, targetDisplayName) + eventContent.safeReason + ?.let { reason -> stringProvider.getString(R.string.notice_room_unban_with_reason, senderDisplayName, targetDisplayName, reason) } + ?: stringProvider.getString(R.string.notice_room_unban, senderDisplayName, targetDisplayName) } else { null } Membership.BAN == eventContent?.membership -> - eventContent.reason?.takeIf { it.isNotBlank() } + eventContent.safeReason ?.let { reason -> stringProvider.getString(R.string.notice_room_ban_with_reason, senderDisplayName, targetDisplayName, reason) } ?: stringProvider.getString(R.string.notice_room_ban, senderDisplayName, targetDisplayName) Membership.KNOCK == eventContent?.membership -> - stringProvider.getString(R.string.notice_room_kick, senderDisplayName, targetDisplayName) + eventContent.safeReason + ?.let { reason -> stringProvider.getString(R.string.notice_room_kick_with_reason, senderDisplayName, targetDisplayName, reason) } + ?: stringProvider.getString(R.string.notice_room_kick, senderDisplayName, targetDisplayName) else -> null } } From 872b14373b575f631cce3948ed75b283bd1fe24e Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 4 Dec 2019 19:02:16 +0100 Subject: [PATCH 03/12] Better code --- .../timeline/format/NoticeEventFormatter.kt | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) 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 07d240171e6..11d9d8bd0c6 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 @@ -171,8 +171,8 @@ class NoticeEventFormatter @Inject constructor(private val sessionHolder: Active private fun buildMembershipNotice(event: Event, senderName: String?, eventContent: RoomMember?, prevEventContent: RoomMember?): String? { val senderDisplayName = senderName ?: event.senderId val targetDisplayName = eventContent?.displayName ?: prevEventContent?.displayName ?: event.stateKey ?: "" - return when { - Membership.INVITE == eventContent?.membership -> { + return when (eventContent?.membership) { + Membership.INVITE -> { val selfUserId = sessionHolder.getSafeActiveSession()?.myUserId when { eventContent.thirdPartyInvite != null -> { @@ -195,13 +195,13 @@ class NoticeEventFormatter @Inject constructor(private val sessionHolder: Active ?: stringProvider.getString(R.string.notice_room_invite, senderDisplayName, targetDisplayName) } } - Membership.JOIN == eventContent?.membership -> + Membership.JOIN -> eventContent.safeReason ?.let { reason -> stringProvider.getString(R.string.notice_room_join_with_reason, senderDisplayName, reason) } ?: stringProvider.getString(R.string.notice_room_join, senderDisplayName) - Membership.LEAVE == eventContent?.membership -> + Membership.LEAVE -> // 2 cases here: this member may have left voluntarily or they may have been "left" by someone else ie. kicked - return if (event.senderId == event.stateKey) { + if (event.senderId == event.stateKey) { if (prevEventContent?.membership == Membership.INVITE) { eventContent.safeReason ?.let { reason -> stringProvider.getString(R.string.notice_room_reject_with_reason, senderDisplayName, reason) } @@ -226,15 +226,15 @@ class NoticeEventFormatter @Inject constructor(private val sessionHolder: Active } else { null } - Membership.BAN == eventContent?.membership -> + Membership.BAN -> eventContent.safeReason ?.let { reason -> stringProvider.getString(R.string.notice_room_ban_with_reason, senderDisplayName, targetDisplayName, reason) } ?: stringProvider.getString(R.string.notice_room_ban, senderDisplayName, targetDisplayName) - Membership.KNOCK == eventContent?.membership -> + Membership.KNOCK -> eventContent.safeReason ?.let { reason -> stringProvider.getString(R.string.notice_room_kick_with_reason, senderDisplayName, targetDisplayName, reason) } ?: stringProvider.getString(R.string.notice_room_kick, senderDisplayName, targetDisplayName) - else -> null + else -> null } } From b9efc9f4bdfc34bcbd1d164eea495b24d3e20fcc Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 4 Dec 2019 19:05:57 +0100 Subject: [PATCH 04/12] Ensure user will never see 'null' in a String --- .../room/detail/timeline/format/NoticeEventFormatter.kt | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) 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 11d9d8bd0c6..979104110ef 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 @@ -169,7 +169,7 @@ class NoticeEventFormatter @Inject constructor(private val sessionHolder: Active } private fun buildMembershipNotice(event: Event, senderName: String?, eventContent: RoomMember?, prevEventContent: RoomMember?): String? { - val senderDisplayName = senderName ?: event.senderId + val senderDisplayName = senderName ?: event.senderId ?: "" val targetDisplayName = eventContent?.displayName ?: prevEventContent?.displayName ?: event.stateKey ?: "" return when (eventContent?.membership) { Membership.INVITE -> { @@ -177,9 +177,10 @@ class NoticeEventFormatter @Inject constructor(private val sessionHolder: Active when { eventContent.thirdPartyInvite != null -> { val userWhoHasAccepted = eventContent.thirdPartyInvite?.signed?.mxid ?: event.stateKey + val threePidDisplayName = eventContent.thirdPartyInvite?.displayName ?: "" eventContent.safeReason - ?.let { reason -> stringProvider.getString(R.string.notice_room_third_party_registered_invite_with_reason, userWhoHasAccepted, eventContent.thirdPartyInvite?.displayName, reason) } - ?: stringProvider.getString(R.string.notice_room_third_party_registered_invite, userWhoHasAccepted, eventContent.thirdPartyInvite?.displayName) + ?.let { reason -> stringProvider.getString(R.string.notice_room_third_party_registered_invite_with_reason, userWhoHasAccepted, threePidDisplayName, reason) } + ?: stringProvider.getString(R.string.notice_room_third_party_registered_invite, userWhoHasAccepted, threePidDisplayName) } event.stateKey == selfUserId -> eventContent.safeReason From e0e778909dd46b05d68c12dab585a429365a503d Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 4 Dec 2019 19:09:10 +0100 Subject: [PATCH 05/12] Better formatting --- .../timeline/format/NoticeEventFormatter.kt | 61 +++++++++++-------- 1 file changed, 36 insertions(+), 25 deletions(-) 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 979104110ef..8f2f8857752 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 @@ -178,63 +178,74 @@ class NoticeEventFormatter @Inject constructor(private val sessionHolder: Active eventContent.thirdPartyInvite != null -> { val userWhoHasAccepted = eventContent.thirdPartyInvite?.signed?.mxid ?: event.stateKey val threePidDisplayName = eventContent.thirdPartyInvite?.displayName ?: "" - eventContent.safeReason - ?.let { reason -> stringProvider.getString(R.string.notice_room_third_party_registered_invite_with_reason, userWhoHasAccepted, threePidDisplayName, reason) } + eventContent.safeReason?.let { reason -> + stringProvider.getString(R.string.notice_room_third_party_registered_invite_with_reason, userWhoHasAccepted, threePidDisplayName, reason) + } ?: stringProvider.getString(R.string.notice_room_third_party_registered_invite, userWhoHasAccepted, threePidDisplayName) } event.stateKey == selfUserId -> - eventContent.safeReason - ?.let { reason -> stringProvider.getString(R.string.notice_room_invite_you_with_reason, senderDisplayName, reason) } + eventContent.safeReason?.let { reason -> + stringProvider.getString(R.string.notice_room_invite_you_with_reason, senderDisplayName, reason) + } ?: stringProvider.getString(R.string.notice_room_invite_you, senderDisplayName) event.stateKey.isNullOrEmpty() -> - eventContent.safeReason - ?.let { reason -> stringProvider.getString(R.string.notice_room_invite_no_invitee_with_reason, senderDisplayName, reason) } + eventContent.safeReason?.let { reason -> + stringProvider.getString(R.string.notice_room_invite_no_invitee_with_reason, senderDisplayName, reason) + } ?: stringProvider.getString(R.string.notice_room_invite_no_invitee, senderDisplayName) else -> - eventContent.safeReason - ?.let { reason -> stringProvider.getString(R.string.notice_room_invite, senderDisplayName, targetDisplayName, reason) } + eventContent.safeReason?.let { reason -> + stringProvider.getString(R.string.notice_room_invite, senderDisplayName, targetDisplayName, reason) + } ?: stringProvider.getString(R.string.notice_room_invite, senderDisplayName, targetDisplayName) } } Membership.JOIN -> - eventContent.safeReason - ?.let { reason -> stringProvider.getString(R.string.notice_room_join_with_reason, senderDisplayName, reason) } + eventContent.safeReason?.let { reason -> + stringProvider.getString(R.string.notice_room_join_with_reason, senderDisplayName, reason) + } ?: stringProvider.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 -> stringProvider.getString(R.string.notice_room_reject_with_reason, senderDisplayName, reason) } + eventContent.safeReason?.let { reason -> + stringProvider.getString(R.string.notice_room_reject_with_reason, senderDisplayName, reason) + } ?: stringProvider.getString(R.string.notice_room_reject, senderDisplayName) } else { - eventContent.safeReason - ?.let { reason -> stringProvider.getString(R.string.notice_room_leave_with_reason, senderDisplayName, reason) } + eventContent.safeReason?.let { reason -> + stringProvider.getString(R.string.notice_room_leave_with_reason, senderDisplayName, reason) + } ?: stringProvider.getString(R.string.notice_room_leave, senderDisplayName) } } else if (prevEventContent?.membership == Membership.INVITE) { - eventContent.safeReason - ?.let { reason -> stringProvider.getString(R.string.notice_room_withdraw_with_reason, senderDisplayName, targetDisplayName, reason) } + eventContent.safeReason?.let { reason -> + stringProvider.getString(R.string.notice_room_withdraw_with_reason, senderDisplayName, targetDisplayName, reason) + } ?: stringProvider.getString(R.string.notice_room_withdraw, senderDisplayName, targetDisplayName) } else if (prevEventContent?.membership == Membership.JOIN) { - eventContent.safeReason - ?.let { reason -> stringProvider.getString(R.string.notice_room_kick_with_reason, senderDisplayName, targetDisplayName, reason) } + eventContent.safeReason?.let { reason -> + stringProvider.getString(R.string.notice_room_kick_with_reason, senderDisplayName, targetDisplayName, reason) + } ?: stringProvider.getString(R.string.notice_room_kick, senderDisplayName, targetDisplayName) } else if (prevEventContent?.membership == Membership.BAN) { - eventContent.safeReason - ?.let { reason -> stringProvider.getString(R.string.notice_room_unban_with_reason, senderDisplayName, targetDisplayName, reason) } + eventContent.safeReason?.let { reason -> + stringProvider.getString(R.string.notice_room_unban_with_reason, senderDisplayName, targetDisplayName, reason) + } ?: stringProvider.getString(R.string.notice_room_unban, senderDisplayName, targetDisplayName) } else { null } Membership.BAN -> - eventContent.safeReason - ?.let { reason -> stringProvider.getString(R.string.notice_room_ban_with_reason, senderDisplayName, targetDisplayName, reason) } + eventContent.safeReason?.let { reason -> + stringProvider.getString(R.string.notice_room_ban_with_reason, senderDisplayName, targetDisplayName, reason) + } ?: stringProvider.getString(R.string.notice_room_ban, senderDisplayName, targetDisplayName) Membership.KNOCK -> - eventContent.safeReason - ?.let { reason -> stringProvider.getString(R.string.notice_room_kick_with_reason, senderDisplayName, targetDisplayName, reason) } - ?: stringProvider.getString(R.string.notice_room_kick, senderDisplayName, targetDisplayName) + eventContent.safeReason?.let { reason -> + stringProvider.getString(R.string.notice_room_kick_with_reason, senderDisplayName, targetDisplayName, reason) + } ?: stringProvider.getString(R.string.notice_room_kick, senderDisplayName, targetDisplayName) else -> null } } From 415511f3e08b5e8849e96c27e691d4e017fef59c Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 4 Dec 2019 19:17:23 +0100 Subject: [PATCH 06/12] Shortened lines --- .../timeline/format/NoticeEventFormatter.kt | 106 ++++++++---------- 1 file changed, 48 insertions(+), 58 deletions(-) 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 8f2f8857752..8cdb93a99d6 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 @@ -29,7 +29,7 @@ import timber.log.Timber import javax.inject.Inject class NoticeEventFormatter @Inject constructor(private val sessionHolder: ActiveSessionHolder, - private val stringProvider: StringProvider) { + private val sp: StringProvider) { fun format(timelineEvent: TimelineEvent): CharSequence? { return when (val type = timelineEvent.root.getClearType()) { @@ -77,22 +77,22 @@ class NoticeEventFormatter @Inject constructor(private val sessionHolder: Active private fun formatRoomNameEvent(event: Event, senderName: String?): CharSequence? { val content = event.getClearContent().toModel() ?: return null return if (content.name.isNullOrBlank()) { - stringProvider.getString(R.string.notice_room_name_removed, senderName) + sp.getString(R.string.notice_room_name_removed, senderName) } else { - stringProvider.getString(R.string.notice_room_name_changed, senderName, content.name) + sp.getString(R.string.notice_room_name_changed, senderName, content.name) } } private fun formatRoomTombstoneEvent(senderName: String?): CharSequence? { - return stringProvider.getString(R.string.notice_room_update, senderName) + return 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()) { - stringProvider.getString(R.string.notice_room_topic_removed, senderName) + sp.getString(R.string.notice_room_topic_removed, senderName) } else { - stringProvider.getString(R.string.notice_room_topic_changed, senderName, content.topic) + sp.getString(R.string.notice_room_topic_changed, senderName, content.topic) } } @@ -100,12 +100,12 @@ class NoticeEventFormatter @Inject constructor(private val sessionHolder: Active val historyVisibility = event.getClearContent().toModel()?.historyVisibility ?: return null val formattedVisibility = when (historyVisibility) { - RoomHistoryVisibility.SHARED -> stringProvider.getString(R.string.notice_room_visibility_shared) - RoomHistoryVisibility.INVITED -> stringProvider.getString(R.string.notice_room_visibility_invited) - RoomHistoryVisibility.JOINED -> stringProvider.getString(R.string.notice_room_visibility_joined) - RoomHistoryVisibility.WORLD_READABLE -> stringProvider.getString(R.string.notice_room_visibility_world_readable) + RoomHistoryVisibility.SHARED -> sp.getString(R.string.notice_room_visibility_shared) + RoomHistoryVisibility.INVITED -> sp.getString(R.string.notice_room_visibility_invited) + RoomHistoryVisibility.JOINED -> sp.getString(R.string.notice_room_visibility_joined) + RoomHistoryVisibility.WORLD_READABLE -> sp.getString(R.string.notice_room_visibility_world_readable) } - return stringProvider.getString(R.string.notice_made_future_room_visibility, senderName, formattedVisibility) + return sp.getString(R.string.notice_made_future_room_visibility, senderName, formattedVisibility) } private fun formatCallEvent(event: Event, senderName: String?): CharSequence? { @@ -114,13 +114,13 @@ 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) { - stringProvider.getString(R.string.notice_placed_video_call, senderName) + sp.getString(R.string.notice_placed_video_call, senderName) } else { - stringProvider.getString(R.string.notice_placed_voice_call, senderName) + sp.getString(R.string.notice_placed_voice_call, senderName) } } - EventType.CALL_ANSWER == event.type -> stringProvider.getString(R.string.notice_answered_call, senderName) - EventType.CALL_HANGUP == event.type -> stringProvider.getString(R.string.notice_ended_call, senderName) + EventType.CALL_ANSWER == event.type -> sp.getString(R.string.notice_answered_call, senderName) + EventType.CALL_HANGUP == event.type -> sp.getString(R.string.notice_ended_call, senderName) else -> null } } @@ -142,11 +142,11 @@ class NoticeEventFormatter @Inject constructor(private val sessionHolder: Active if (eventContent?.displayName != prevEventContent?.displayName) { val displayNameText = when { prevEventContent?.displayName.isNullOrEmpty() -> - stringProvider.getString(R.string.notice_display_name_set, event.senderId, eventContent?.displayName) + sp.getString(R.string.notice_display_name_set, event.senderId, eventContent?.displayName) eventContent?.displayName.isNullOrEmpty() -> - stringProvider.getString(R.string.notice_display_name_removed, event.senderId, prevEventContent?.displayName) + sp.getString(R.string.notice_display_name_removed, event.senderId, prevEventContent?.displayName) else -> - stringProvider.getString(R.string.notice_display_name_changed_from, event.senderId, prevEventContent?.displayName, eventContent?.displayName) + sp.getString(R.string.notice_display_name_changed_from, event.senderId, prevEventContent?.displayName, eventContent?.displayName) } displayText.append(displayNameText) } @@ -154,15 +154,15 @@ class NoticeEventFormatter @Inject constructor(private val sessionHolder: Active if (eventContent?.avatarUrl != prevEventContent?.avatarUrl) { val displayAvatarText = if (displayText.isNotEmpty()) { displayText.append(" ") - stringProvider.getString(R.string.notice_avatar_changed_too) + sp.getString(R.string.notice_avatar_changed_too) } else { - stringProvider.getString(R.string.notice_avatar_url_changed, senderName) + sp.getString(R.string.notice_avatar_url_changed, senderName) } displayText.append(displayAvatarText) } if (displayText.isEmpty()) { displayText.append( - stringProvider.getString(R.string.notice_member_no_changes, senderName) + sp.getString(R.string.notice_member_no_changes, senderName) ) } return displayText.toString() @@ -179,73 +179,63 @@ 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 -> - stringProvider.getString(R.string.notice_room_third_party_registered_invite_with_reason, userWhoHasAccepted, threePidDisplayName, reason) - } - ?: stringProvider.getString(R.string.notice_room_third_party_registered_invite, userWhoHasAccepted, threePidDisplayName) + 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) } event.stateKey == selfUserId -> eventContent.safeReason?.let { reason -> - stringProvider.getString(R.string.notice_room_invite_you_with_reason, senderDisplayName, reason) - } - ?: stringProvider.getString(R.string.notice_room_invite_you, senderDisplayName) + 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 -> - stringProvider.getString(R.string.notice_room_invite_no_invitee_with_reason, senderDisplayName, reason) - } - ?: stringProvider.getString(R.string.notice_room_invite_no_invitee, senderDisplayName) + 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 -> - stringProvider.getString(R.string.notice_room_invite, senderDisplayName, targetDisplayName, reason) - } - ?: stringProvider.getString(R.string.notice_room_invite, senderDisplayName, targetDisplayName) + sp.getString(R.string.notice_room_invite, senderDisplayName, targetDisplayName, reason) + } ?: sp.getString(R.string.notice_room_invite, senderDisplayName, targetDisplayName) } } Membership.JOIN -> eventContent.safeReason?.let { reason -> - stringProvider.getString(R.string.notice_room_join_with_reason, senderDisplayName, reason) + sp.getString(R.string.notice_room_join_with_reason, senderDisplayName, reason) } - ?: stringProvider.getString(R.string.notice_room_join, senderDisplayName) + ?: 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 -> - stringProvider.getString(R.string.notice_room_reject_with_reason, senderDisplayName, reason) - } - ?: stringProvider.getString(R.string.notice_room_reject, senderDisplayName) + sp.getString(R.string.notice_room_reject_with_reason, senderDisplayName, reason) + } ?: sp.getString(R.string.notice_room_reject, senderDisplayName) } else { eventContent.safeReason?.let { reason -> - stringProvider.getString(R.string.notice_room_leave_with_reason, senderDisplayName, reason) - } - ?: stringProvider.getString(R.string.notice_room_leave, senderDisplayName) + 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) { eventContent.safeReason?.let { reason -> - stringProvider.getString(R.string.notice_room_withdraw_with_reason, senderDisplayName, targetDisplayName, reason) - } - ?: stringProvider.getString(R.string.notice_room_withdraw, senderDisplayName, targetDisplayName) + 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) { eventContent.safeReason?.let { reason -> - stringProvider.getString(R.string.notice_room_kick_with_reason, senderDisplayName, targetDisplayName, reason) - } - ?: stringProvider.getString(R.string.notice_room_kick, senderDisplayName, targetDisplayName) + 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 -> - stringProvider.getString(R.string.notice_room_unban_with_reason, senderDisplayName, targetDisplayName, reason) - } - ?: stringProvider.getString(R.string.notice_room_unban, senderDisplayName, targetDisplayName) + 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 { reason -> - stringProvider.getString(R.string.notice_room_ban_with_reason, senderDisplayName, targetDisplayName, reason) - } - ?: stringProvider.getString(R.string.notice_room_ban, senderDisplayName, targetDisplayName) + 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 -> - stringProvider.getString(R.string.notice_room_kick_with_reason, senderDisplayName, targetDisplayName, reason) - } ?: stringProvider.getString(R.string.notice_room_kick, senderDisplayName, targetDisplayName) + sp.getString(R.string.notice_room_kick_with_reason, senderDisplayName, targetDisplayName, reason) + } ?: sp.getString(R.string.notice_room_kick, senderDisplayName, targetDisplayName) else -> null } } @@ -253,8 +243,8 @@ 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 -> stringProvider.getString(R.string.room_join_rules_invite, senderName) - RoomJoinRules.PUBLIC -> stringProvider.getString(R.string.room_join_rules_public, senderName) + RoomJoinRules.INVITE -> sp.getString(R.string.room_join_rules_invite, senderName) + RoomJoinRules.PUBLIC -> sp.getString(R.string.room_join_rules_public, senderName) else -> null } } From 03d51281a2fc43ba7852ded0b5d732b2b5cfdaba Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 4 Dec 2019 19:18:35 +0100 Subject: [PATCH 07/12] Mistake --- .../home/room/detail/timeline/format/NoticeEventFormatter.kt | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) 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 8cdb93a99d6..75100e6c038 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 @@ -192,15 +192,14 @@ class NoticeEventFormatter @Inject constructor(private val sessionHolder: Active } ?: sp.getString(R.string.notice_room_invite_no_invitee, senderDisplayName) else -> eventContent.safeReason?.let { reason -> - sp.getString(R.string.notice_room_invite, senderDisplayName, targetDisplayName, 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) + } ?: 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) { From 57354cbd69f77612ed1da48590647b1272aea0a4 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 4 Dec 2019 20:11:19 +0100 Subject: [PATCH 08/12] Add reason to slash commands --- .../main/java/im/vector/matrix/rx/RxRoom.kt | 4 +- .../java/im/vector/matrix/rx/RxSession.kt | 4 +- .../api/session/room/RoomDirectoryService.kt | 2 +- .../android/api/session/room/RoomService.kt | 2 + .../session/room/members/MembershipService.kt | 6 +- .../room/DefaultRoomDirectoryService.kt | 4 +- .../session/room/DefaultRoomService.kt | 4 +- .../android/internal/session/room/RoomAPI.kt | 4 +- .../membership/DefaultMembershipService.kt | 12 +-- .../room/membership/joining/InviteBody.kt | 3 +- .../room/membership/joining/InviteTask.kt | 5 +- .../room/membership/joining/JoinRoomTask.kt | 3 +- .../room/membership/leaving/LeaveRoomTask.kt | 5 +- .../vector/riotx/features/command/Command.kt | 8 +- .../riotx/features/command/CommandParser.kt | 76 +++++++++++++------ .../riotx/features/command/ParsedCommand.kt | 12 +-- .../home/room/detail/RoomDetailViewModel.kt | 8 +- .../home/room/list/RoomListViewModel.kt | 6 +- .../NotificationBroadcastReceiver.kt | 4 +- .../roomdirectory/RoomDirectoryViewModel.kt | 2 +- .../roompreview/RoomPreviewViewModel.kt | 2 +- 21 files changed, 107 insertions(+), 69 deletions(-) diff --git a/matrix-sdk-android-rx/src/main/java/im/vector/matrix/rx/RxRoom.kt b/matrix-sdk-android-rx/src/main/java/im/vector/matrix/rx/RxRoom.kt index 6793d6249d6..96f2de9cdca 100644 --- a/matrix-sdk-android-rx/src/main/java/im/vector/matrix/rx/RxRoom.kt +++ b/matrix-sdk-android-rx/src/main/java/im/vector/matrix/rx/RxRoom.kt @@ -57,8 +57,8 @@ class RxRoom(private val room: Room) { room.loadRoomMembersIfNeeded(MatrixCallbackSingle(it)).toSingle(it) } - fun joinRoom(viaServers: List = emptyList()): Single = Single.create { - room.join(viaServers, MatrixCallbackSingle(it)).toSingle(it) + fun joinRoom(reason: String?, viaServers: List = emptyList()): Single = Single.create { + room.join(reason, viaServers, MatrixCallbackSingle(it)).toSingle(it) } fun liveEventReadReceipts(eventId: String): Observable> { diff --git a/matrix-sdk-android-rx/src/main/java/im/vector/matrix/rx/RxSession.kt b/matrix-sdk-android-rx/src/main/java/im/vector/matrix/rx/RxSession.kt index 1964d05a1b9..1ef1c8cadb8 100644 --- a/matrix-sdk-android-rx/src/main/java/im/vector/matrix/rx/RxSession.kt +++ b/matrix-sdk-android-rx/src/main/java/im/vector/matrix/rx/RxSession.kt @@ -76,8 +76,8 @@ class RxSession(private val session: Session) { session.searchUsersDirectory(search, limit, excludedUserIds, MatrixCallbackSingle(it)).toSingle(it) } - fun joinRoom(roomId: String, viaServers: List = emptyList()): Single = Single.create { - session.joinRoom(roomId, viaServers, MatrixCallbackSingle(it)).toSingle(it) + fun joinRoom(roomId: String, reason: String?, viaServers: List = emptyList()): Single = Single.create { + session.joinRoom(roomId, reason, viaServers, MatrixCallbackSingle(it)).toSingle(it) } } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/RoomDirectoryService.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/RoomDirectoryService.kt index 930320d9766..8d03c70efad 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/RoomDirectoryService.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/RoomDirectoryService.kt @@ -35,7 +35,7 @@ interface RoomDirectoryService { /** * Join a room by id */ - fun joinRoom(roomId: String, callback: MatrixCallback): Cancelable + fun joinRoom(roomId: String, reason: String?, callback: MatrixCallback): Cancelable /** * Fetches the overall metadata about protocols supported by the homeserver. diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/RoomService.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/RoomService.kt index 2dbb580a4fe..71a9a8e4fa0 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/RoomService.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/RoomService.kt @@ -35,9 +35,11 @@ interface RoomService { /** * Join a room by id * @param roomId the roomId of the room to join + * @param reason optional reason for joining the room * @param viaServers the servers to attempt to join the room through. One of the servers must be participating in the room. */ fun joinRoom(roomId: String, + reason: String?, viaServers: List = emptyList(), callback: MatrixCallback): Cancelable diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/members/MembershipService.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/members/MembershipService.kt index 8d60bee9da8..0f487880b71 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/members/MembershipService.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/members/MembershipService.kt @@ -52,16 +52,16 @@ interface MembershipService { /** * Invite a user in the room */ - fun invite(userId: String, callback: MatrixCallback): Cancelable + fun invite(userId: String, reason: String?, callback: MatrixCallback): Cancelable /** * Join the room, or accept an invitation. */ - fun join(viaServers: List = emptyList(), callback: MatrixCallback): Cancelable + fun join(reason: String?, viaServers: List = emptyList(), callback: MatrixCallback): Cancelable /** * Leave the room, or reject an invitation. */ - fun leave(callback: MatrixCallback): Cancelable + fun leave(reason: String?, callback: MatrixCallback): Cancelable } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/DefaultRoomDirectoryService.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/DefaultRoomDirectoryService.kt index 4251a66304f..711e2bd97ce 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/DefaultRoomDirectoryService.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/DefaultRoomDirectoryService.kt @@ -44,9 +44,9 @@ internal class DefaultRoomDirectoryService @Inject constructor(private val getPu .executeBy(taskExecutor) } - override fun joinRoom(roomId: String, callback: MatrixCallback): Cancelable { + override fun joinRoom(roomId: String, reason: String?, callback: MatrixCallback): Cancelable { return joinRoomTask - .configureWith(JoinRoomTask.Params(roomId)) { + .configureWith(JoinRoomTask.Params(roomId, reason)) { this.callback = callback } .executeBy(taskExecutor) diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/DefaultRoomService.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/DefaultRoomService.kt index be2a588510f..22caf76eaf7 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/DefaultRoomService.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/DefaultRoomService.kt @@ -96,9 +96,9 @@ internal class DefaultRoomService @Inject constructor(private val monarchy: Mona .executeBy(taskExecutor) } - override fun joinRoom(roomId: String, viaServers: List, callback: MatrixCallback): Cancelable { + override fun joinRoom(roomId: String, reason: String?, viaServers: List, callback: MatrixCallback): Cancelable { return joinRoomTask - .configureWith(JoinRoomTask.Params(roomId, viaServers)) { + .configureWith(JoinRoomTask.Params(roomId, reason, viaServers)) { this.callback = callback } .executeBy(taskExecutor) diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/RoomAPI.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/RoomAPI.kt index 797dbed31c9..40164d16978 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/RoomAPI.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/RoomAPI.kt @@ -217,7 +217,7 @@ internal interface RoomAPI { @POST(NetworkConstants.URI_API_PREFIX_PATH_R0 + "rooms/{roomId}/join") fun join(@Path("roomId") roomId: String, @Query("server_name") viaServers: List, - @Body params: Map): Call + @Body params: Map): Call /** * Leave the given room. @@ -227,7 +227,7 @@ internal interface RoomAPI { */ @POST(NetworkConstants.URI_API_PREFIX_PATH_R0 + "rooms/{roomId}/leave") fun leave(@Path("roomId") roomId: String, - @Body params: Map): Call + @Body params: Map): Call /** * Strips all information out of an event which isn't critical to the integrity of the server-side representation of the room. diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/membership/DefaultMembershipService.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/membership/DefaultMembershipService.kt index 3490fed30f0..00c1c2c4ca5 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/membership/DefaultMembershipService.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/membership/DefaultMembershipService.kt @@ -83,8 +83,8 @@ internal class DefaultMembershipService @AssistedInject constructor(@Assisted pr return result } - override fun invite(userId: String, callback: MatrixCallback): Cancelable { - val params = InviteTask.Params(roomId, userId) + override fun invite(userId: String, reason: String?, callback: MatrixCallback): Cancelable { + val params = InviteTask.Params(roomId, userId, reason) return inviteTask .configureWith(params) { this.callback = callback @@ -92,8 +92,8 @@ internal class DefaultMembershipService @AssistedInject constructor(@Assisted pr .executeBy(taskExecutor) } - override fun join(viaServers: List, callback: MatrixCallback): Cancelable { - val params = JoinRoomTask.Params(roomId, viaServers) + override fun join(reason: String?, viaServers: List, callback: MatrixCallback): Cancelable { + val params = JoinRoomTask.Params(roomId, reason, viaServers) return joinTask .configureWith(params) { this.callback = callback @@ -101,8 +101,8 @@ internal class DefaultMembershipService @AssistedInject constructor(@Assisted pr .executeBy(taskExecutor) } - override fun leave(callback: MatrixCallback): Cancelable { - val params = LeaveRoomTask.Params(roomId) + override fun leave(reason: String?, callback: MatrixCallback): Cancelable { + val params = LeaveRoomTask.Params(roomId, reason) return leaveRoomTask .configureWith(params) { this.callback = callback diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/membership/joining/InviteBody.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/membership/joining/InviteBody.kt index 4529a17ab80..2d721971985 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/membership/joining/InviteBody.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/membership/joining/InviteBody.kt @@ -21,5 +21,6 @@ import com.squareup.moshi.JsonClass @JsonClass(generateAdapter = true) data class InviteBody( - @Json(name = "user_id") val userId: String + @Json(name = "user_id") val userId: String, + @Json(name = "reason") val reason: String? ) diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/membership/joining/InviteTask.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/membership/joining/InviteTask.kt index a41e8d3ca39..6bc453a0f3c 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/membership/joining/InviteTask.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/membership/joining/InviteTask.kt @@ -24,7 +24,8 @@ import javax.inject.Inject internal interface InviteTask : Task { data class Params( val roomId: String, - val userId: String + val userId: String, + val reason: String? ) } @@ -32,7 +33,7 @@ internal class DefaultInviteTask @Inject constructor(private val roomAPI: RoomAP override suspend fun execute(params: InviteTask.Params) { return executeRequest { - val body = InviteBody(params.userId) + val body = InviteBody(params.userId, params.reason) apiCall = roomAPI.invite(params.roomId, body) } } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/membership/joining/JoinRoomTask.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/membership/joining/JoinRoomTask.kt index 2555d802098..7304c09d579 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/membership/joining/JoinRoomTask.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/membership/joining/JoinRoomTask.kt @@ -32,6 +32,7 @@ import javax.inject.Inject internal interface JoinRoomTask : Task { data class Params( val roomId: String, + val reason: String?, val viaServers: List = emptyList() ) } @@ -43,7 +44,7 @@ internal class DefaultJoinRoomTask @Inject constructor(private val roomAPI: Room override suspend fun execute(params: JoinRoomTask.Params) { executeRequest { - apiCall = roomAPI.join(params.roomId, params.viaServers, HashMap()) + apiCall = roomAPI.join(params.roomId, params.viaServers, mapOf("reason" to params.reason)) } val roomId = params.roomId // Wait for room to come back from the sync (but it can maybe be in the DB is the sync response is received before) diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/membership/leaving/LeaveRoomTask.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/membership/leaving/LeaveRoomTask.kt index be9a421e956..01198c47de6 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/membership/leaving/LeaveRoomTask.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/membership/leaving/LeaveRoomTask.kt @@ -23,7 +23,8 @@ import javax.inject.Inject internal interface LeaveRoomTask : Task { data class Params( - val roomId: String + val roomId: String, + val reason: String? ) } @@ -31,7 +32,7 @@ internal class DefaultLeaveRoomTask @Inject constructor(private val roomAPI: Roo override suspend fun execute(params: LeaveRoomTask.Params) { return executeRequest { - apiCall = roomAPI.leave(params.roomId, HashMap()) + apiCall = roomAPI.leave(params.roomId, mapOf("reason" to params.reason)) } } } diff --git a/vector/src/main/java/im/vector/riotx/features/command/Command.kt b/vector/src/main/java/im/vector/riotx/features/command/Command.kt index 7d745b925b1..9b3ecb3be5b 100644 --- a/vector/src/main/java/im/vector/riotx/features/command/Command.kt +++ b/vector/src/main/java/im/vector/riotx/features/command/Command.kt @@ -27,12 +27,12 @@ import im.vector.riotx.R enum class Command(val command: String, val parameters: String, @StringRes val description: Int) { EMOTE("/me", "", R.string.command_description_emote), BAN_USER("/ban", " [reason]", R.string.command_description_ban_user), - UNBAN_USER("/unban", "", R.string.command_description_unban_user), + UNBAN_USER("/unban", " [reason]", R.string.command_description_unban_user), SET_USER_POWER_LEVEL("/op", " []", R.string.command_description_op_user), RESET_USER_POWER_LEVEL("/deop", "", R.string.command_description_deop_user), - INVITE("/invite", "", R.string.command_description_invite_user), - JOIN_ROOM("/join", "", R.string.command_description_join_room), - PART("/part", "", R.string.command_description_part_room), + INVITE("/invite", " [reason]", R.string.command_description_invite_user), + JOIN_ROOM("/join", " [reason]", R.string.command_description_join_room), + PART("/part", " [reason]", R.string.command_description_part_room), TOPIC("/topic", "", R.string.command_description_topic), KICK_USER("/kick", " [reason]", R.string.command_description_kick_user), CHANGE_DISPLAY_NAME("/nick", "", R.string.command_description_nick), diff --git a/vector/src/main/java/im/vector/riotx/features/command/CommandParser.kt b/vector/src/main/java/im/vector/riotx/features/command/CommandParser.kt index bc451f8e844..bdcaa4d9b83 100644 --- a/vector/src/main/java/im/vector/riotx/features/command/CommandParser.kt +++ b/vector/src/main/java/im/vector/riotx/features/command/CommandParser.kt @@ -81,29 +81,52 @@ object CommandParser { ParsedCommand.SendEmote(message) } Command.JOIN_ROOM.command -> { - val roomAlias = textMessage.substring(Command.JOIN_ROOM.command.length).trim() - - if (roomAlias.isNotEmpty()) { - ParsedCommand.JoinRoom(roomAlias) + if (messageParts.size >= 2) { + val roomAlias = messageParts[1] + + if (roomAlias.isNotEmpty()) { + ParsedCommand.JoinRoom( + roomAlias, + textMessage.substring(Command.JOIN_ROOM.command.length + 1 + roomAlias.length) + .trim() + .takeIf { it.isNotBlank() } + ) + } else { + ParsedCommand.ErrorSyntax(Command.JOIN_ROOM) + } } else { ParsedCommand.ErrorSyntax(Command.JOIN_ROOM) } } Command.PART.command -> { - val roomAlias = textMessage.substring(Command.PART.command.length).trim() - - if (roomAlias.isNotEmpty()) { - ParsedCommand.PartRoom(roomAlias) + if (messageParts.size >= 2) { + val roomAlias = messageParts[1] + + if (roomAlias.isNotEmpty()) { + ParsedCommand.PartRoom( + roomAlias, + textMessage.substring(Command.PART.command.length + 1 + roomAlias.length) + .trim() + .takeIf { it.isNotBlank() } + ) + } else { + ParsedCommand.ErrorSyntax(Command.PART) + } } else { ParsedCommand.ErrorSyntax(Command.PART) } } Command.INVITE.command -> { - if (messageParts.size == 2) { + if (messageParts.size >= 2) { val userId = messageParts[1] if (MatrixPatterns.isUserId(userId)) { - ParsedCommand.Invite(userId) + ParsedCommand.Invite( + userId, + textMessage.substring(Command.INVITE.command.length + 1 + userId.length) + .trim() + .takeIf { it.isNotBlank() } + ) } else { ParsedCommand.ErrorSyntax(Command.INVITE) } @@ -114,12 +137,14 @@ object CommandParser { Command.KICK_USER.command -> { if (messageParts.size >= 2) { val userId = messageParts[1] - if (MatrixPatterns.isUserId(userId)) { - val reason = textMessage.substring(Command.KICK_USER.command.length - + 1 - + userId.length).trim() - ParsedCommand.KickUser(userId, reason) + if (MatrixPatterns.isUserId(userId)) { + ParsedCommand.KickUser( + userId, + textMessage.substring(Command.KICK_USER.command.length + 1 + userId.length) + .trim() + .takeIf { it.isNotBlank() } + ) } else { ParsedCommand.ErrorSyntax(Command.KICK_USER) } @@ -130,12 +155,14 @@ object CommandParser { Command.BAN_USER.command -> { if (messageParts.size >= 2) { val userId = messageParts[1] - if (MatrixPatterns.isUserId(userId)) { - val reason = textMessage.substring(Command.BAN_USER.command.length - + 1 - + userId.length).trim() - ParsedCommand.BanUser(userId, reason) + if (MatrixPatterns.isUserId(userId)) { + ParsedCommand.BanUser( + userId, + textMessage.substring(Command.BAN_USER.command.length + 1 + userId.length) + .trim() + .takeIf { it.isNotBlank() } + ) } else { ParsedCommand.ErrorSyntax(Command.BAN_USER) } @@ -144,11 +171,16 @@ object CommandParser { } } Command.UNBAN_USER.command -> { - if (messageParts.size == 2) { + if (messageParts.size >= 2) { val userId = messageParts[1] if (MatrixPatterns.isUserId(userId)) { - ParsedCommand.UnbanUser(userId) + ParsedCommand.UnbanUser( + userId, + textMessage.substring(Command.UNBAN_USER.command.length + 1 + userId.length) + .trim() + .takeIf { it.isNotBlank() } + ) } else { ParsedCommand.ErrorSyntax(Command.UNBAN_USER) } diff --git a/vector/src/main/java/im/vector/riotx/features/command/ParsedCommand.kt b/vector/src/main/java/im/vector/riotx/features/command/ParsedCommand.kt index 89438c8a9dd..dd7c0c7e865 100644 --- a/vector/src/main/java/im/vector/riotx/features/command/ParsedCommand.kt +++ b/vector/src/main/java/im/vector/riotx/features/command/ParsedCommand.kt @@ -34,14 +34,14 @@ sealed class ParsedCommand { // Valid commands: class SendEmote(val message: CharSequence) : ParsedCommand() - class BanUser(val userId: String, val reason: String) : ParsedCommand() - class UnbanUser(val userId: String) : ParsedCommand() + class BanUser(val userId: String, val reason: String?) : ParsedCommand() + class UnbanUser(val userId: String, val reason: String?) : ParsedCommand() class SetUserPowerLevel(val userId: String, val powerLevel: Int) : ParsedCommand() - class Invite(val userId: String) : ParsedCommand() - class JoinRoom(val roomAlias: String) : ParsedCommand() - class PartRoom(val roomAlias: String) : ParsedCommand() + class Invite(val userId: String, val reason: String?) : ParsedCommand() + class JoinRoom(val roomAlias: String, val reason: String?) : ParsedCommand() + class PartRoom(val roomAlias: String, val reason: String?) : ParsedCommand() class ChangeTopic(val topic: String) : ParsedCommand() - class KickUser(val userId: String, val reason: String) : ParsedCommand() + class KickUser(val userId: String, val reason: String?) : ParsedCommand() class ChangeDisplayName(val displayName: String) : ParsedCommand() class SetMarkdown(val enable: Boolean) : ParsedCommand() object ClearScalarToken : ParsedCommand() diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailViewModel.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailViewModel.kt index d0bff31f790..abdcc46f6a9 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailViewModel.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailViewModel.kt @@ -266,7 +266,7 @@ class RoomDetailViewModel @AssistedInject constructor(@Assisted initialState: Ro } } session.rx() - .joinRoom(roomId, viaServer) + .joinRoom(roomId, null, viaServer) .map { roomId } .execute { copy(tombstoneEventHandling = it) @@ -487,7 +487,7 @@ class RoomDetailViewModel @AssistedInject constructor(@Assisted initialState: Ro private fun handleInviteSlashCommand(invite: ParsedCommand.Invite) { _sendMessageResultLiveData.postLiveEvent(SendMessageResult.SlashCommandHandled()) - room.invite(invite.userId, object : MatrixCallback { + room.invite(invite.userId, invite.reason, object : MatrixCallback { override fun onSuccess(data: Unit) { _sendMessageResultLiveData.postLiveEvent(SendMessageResult.SlashCommandResultOk) } @@ -553,11 +553,11 @@ class RoomDetailViewModel @AssistedInject constructor(@Assisted initialState: Ro } private fun handleRejectInvite() { - room.leave(object : MatrixCallback {}) + room.leave(null, object : MatrixCallback {}) } private fun handleAcceptInvite() { - room.join(callback = object : MatrixCallback {}) + room.join(null, callback = object : MatrixCallback {}) } private fun handleEditAction(action: RoomDetailAction.EnterEditMode) { diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/list/RoomListViewModel.kt b/vector/src/main/java/im/vector/riotx/features/home/room/list/RoomListViewModel.kt index e5924d9f2a6..8e9e76099de 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/list/RoomListViewModel.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/list/RoomListViewModel.kt @@ -123,7 +123,7 @@ class RoomListViewModel @Inject constructor(initialState: RoomListViewState, ) } - session.getRoom(roomId)?.join(emptyList(), object : MatrixCallback { + session.getRoom(roomId)?.join(null, emptyList(), object : MatrixCallback { override fun onSuccess(data: Unit) { // We do not update the joiningRoomsIds here, because, the room is not joined yet regarding the sync data. // Instead, we wait for the room to be joined @@ -158,7 +158,7 @@ class RoomListViewModel @Inject constructor(initialState: RoomListViewState, ) } - session.getRoom(roomId)?.leave(object : MatrixCallback { + session.getRoom(roomId)?.leave(null, object : MatrixCallback { override fun onSuccess(data: Unit) { // We do not update the rejectingRoomsIds here, because, the room is not rejected yet regarding the sync data. // Instead, we wait for the room to be rejected @@ -197,7 +197,7 @@ class RoomListViewModel @Inject constructor(initialState: RoomListViewState, } private fun handleLeaveRoom(action: RoomListAction.LeaveRoom) { - session.getRoom(action.roomId)?.leave(object : MatrixCallback { + session.getRoom(action.roomId)?.leave(null, object : MatrixCallback { override fun onFailure(failure: Throwable) { _viewEvents.post(RoomListViewEvents.Failure(failure)) } diff --git a/vector/src/main/java/im/vector/riotx/features/notifications/NotificationBroadcastReceiver.kt b/vector/src/main/java/im/vector/riotx/features/notifications/NotificationBroadcastReceiver.kt index 63cd1c5ce6d..447137d2632 100644 --- a/vector/src/main/java/im/vector/riotx/features/notifications/NotificationBroadcastReceiver.kt +++ b/vector/src/main/java/im/vector/riotx/features/notifications/NotificationBroadcastReceiver.kt @@ -74,14 +74,14 @@ class NotificationBroadcastReceiver : BroadcastReceiver() { private fun handleJoinRoom(roomId: String) { activeSessionHolder.getSafeActiveSession()?.let { session -> session.getRoom(roomId) - ?.join(emptyList(), object : MatrixCallback {}) + ?.join(null, emptyList(), object : MatrixCallback {}) } } private fun handleRejectRoom(roomId: String) { activeSessionHolder.getSafeActiveSession()?.let { session -> session.getRoom(roomId) - ?.leave(object : MatrixCallback {}) + ?.leave(null, object : MatrixCallback {}) } } diff --git a/vector/src/main/java/im/vector/riotx/features/roomdirectory/RoomDirectoryViewModel.kt b/vector/src/main/java/im/vector/riotx/features/roomdirectory/RoomDirectoryViewModel.kt index 685e1aa2829..3f8b6883ab6 100644 --- a/vector/src/main/java/im/vector/riotx/features/roomdirectory/RoomDirectoryViewModel.kt +++ b/vector/src/main/java/im/vector/riotx/features/roomdirectory/RoomDirectoryViewModel.kt @@ -214,7 +214,7 @@ class RoomDirectoryViewModel @AssistedInject constructor(@Assisted initialState: ) } - session.joinRoom(action.roomId, emptyList(), object : MatrixCallback { + session.joinRoom(action.roomId, null, emptyList(), object : MatrixCallback { override fun onSuccess(data: Unit) { // We do not update the joiningRoomsIds here, because, the room is not joined yet regarding the sync data. // Instead, we wait for the room to be joined diff --git a/vector/src/main/java/im/vector/riotx/features/roomdirectory/roompreview/RoomPreviewViewModel.kt b/vector/src/main/java/im/vector/riotx/features/roomdirectory/roompreview/RoomPreviewViewModel.kt index 9ffb64556f2..42659b2b20d 100644 --- a/vector/src/main/java/im/vector/riotx/features/roomdirectory/roompreview/RoomPreviewViewModel.kt +++ b/vector/src/main/java/im/vector/riotx/features/roomdirectory/roompreview/RoomPreviewViewModel.kt @@ -97,7 +97,7 @@ class RoomPreviewViewModel @AssistedInject constructor(@Assisted initialState: R ) } - session.joinRoom(state.roomId, emptyList(), object : MatrixCallback { + session.joinRoom(state.roomId, null, emptyList(), object : MatrixCallback { override fun onSuccess(data: Unit) { // We do not update the joiningRoomsIds here, because, the room is not joined yet regarding the sync data. // Instead, we wait for the room to be joined From 411afb0bf3efe65ccf15bafbf1287b14a6c02279 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 4 Dec 2019 20:12:55 +0100 Subject: [PATCH 09/12] Add shortcut for command length --- .../java/im/vector/riotx/features/command/Command.kt | 3 +++ .../vector/riotx/features/command/CommandParser.kt | 12 ++++++------ .../features/home/room/detail/RoomDetailFragment.kt | 2 +- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/vector/src/main/java/im/vector/riotx/features/command/Command.kt b/vector/src/main/java/im/vector/riotx/features/command/Command.kt index 9b3ecb3be5b..8b72ffa4a6e 100644 --- a/vector/src/main/java/im/vector/riotx/features/command/Command.kt +++ b/vector/src/main/java/im/vector/riotx/features/command/Command.kt @@ -39,4 +39,7 @@ enum class Command(val command: String, val parameters: String, @StringRes val d MARKDOWN("/markdown", "", R.string.command_description_markdown), CLEAR_SCALAR_TOKEN("/clear_scalar_token", "", R.string.command_description_clear_scalar_token), SPOILER("/spoiler", "", R.string.command_description_spoiler); + + val length + get() = command.length + 1 } diff --git a/vector/src/main/java/im/vector/riotx/features/command/CommandParser.kt b/vector/src/main/java/im/vector/riotx/features/command/CommandParser.kt index bdcaa4d9b83..359f2c1f138 100644 --- a/vector/src/main/java/im/vector/riotx/features/command/CommandParser.kt +++ b/vector/src/main/java/im/vector/riotx/features/command/CommandParser.kt @@ -87,7 +87,7 @@ object CommandParser { if (roomAlias.isNotEmpty()) { ParsedCommand.JoinRoom( roomAlias, - textMessage.substring(Command.JOIN_ROOM.command.length + 1 + roomAlias.length) + textMessage.substring(Command.JOIN_ROOM.length + roomAlias.length) .trim() .takeIf { it.isNotBlank() } ) @@ -105,7 +105,7 @@ object CommandParser { if (roomAlias.isNotEmpty()) { ParsedCommand.PartRoom( roomAlias, - textMessage.substring(Command.PART.command.length + 1 + roomAlias.length) + textMessage.substring(Command.PART.length + roomAlias.length) .trim() .takeIf { it.isNotBlank() } ) @@ -123,7 +123,7 @@ object CommandParser { if (MatrixPatterns.isUserId(userId)) { ParsedCommand.Invite( userId, - textMessage.substring(Command.INVITE.command.length + 1 + userId.length) + textMessage.substring(Command.INVITE.length + userId.length) .trim() .takeIf { it.isNotBlank() } ) @@ -141,7 +141,7 @@ object CommandParser { if (MatrixPatterns.isUserId(userId)) { ParsedCommand.KickUser( userId, - textMessage.substring(Command.KICK_USER.command.length + 1 + userId.length) + textMessage.substring(Command.KICK_USER.length + userId.length) .trim() .takeIf { it.isNotBlank() } ) @@ -159,7 +159,7 @@ object CommandParser { if (MatrixPatterns.isUserId(userId)) { ParsedCommand.BanUser( userId, - textMessage.substring(Command.BAN_USER.command.length + 1 + userId.length) + textMessage.substring(Command.BAN_USER.length + userId.length) .trim() .takeIf { it.isNotBlank() } ) @@ -177,7 +177,7 @@ object CommandParser { if (MatrixPatterns.isUserId(userId)) { ParsedCommand.UnbanUser( userId, - textMessage.substring(Command.UNBAN_USER.command.length + 1 + userId.length) + textMessage.substring(Command.UNBAN_USER.length + userId.length) .trim() .takeIf { it.isNotBlank() } ) diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailFragment.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailFragment.kt index d50b0c9f68e..19ba1a85ce2 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailFragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailFragment.kt @@ -1181,7 +1181,7 @@ class RoomDetailFragment @Inject constructor( && userId == session.myUserId) { // Empty composer, current user: start an emote composerLayout.composerEditText.setText(Command.EMOTE.command + " ") - composerLayout.composerEditText.setSelection(Command.EMOTE.command.length + 1) + composerLayout.composerEditText.setSelection(Command.EMOTE.length) } else { val roomMember = roomDetailViewModel.getMember(userId) // TODO move logic outside of fragment From 6d82ac7c5968ca608e6be35bb78f2f037c930346 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 4 Dec 2019 20:22:04 +0100 Subject: [PATCH 10/12] Add default param values --- .../src/main/java/im/vector/matrix/rx/RxRoom.kt | 3 ++- .../src/main/java/im/vector/matrix/rx/RxSession.kt | 4 +++- .../android/api/session/room/RoomDirectoryService.kt | 8 ++++++-- .../matrix/android/api/session/room/RoomService.kt | 8 +++++--- .../api/session/room/members/MembershipService.kt | 11 ++++++++--- .../features/home/room/detail/RoomDetailViewModel.kt | 9 +++++---- .../features/home/room/list/RoomListViewModel.kt | 2 +- .../notifications/NotificationBroadcastReceiver.kt | 4 ++-- .../features/roomdirectory/RoomDirectoryViewModel.kt | 2 +- .../roomdirectory/roompreview/RoomPreviewViewModel.kt | 2 +- 10 files changed, 34 insertions(+), 19 deletions(-) diff --git a/matrix-sdk-android-rx/src/main/java/im/vector/matrix/rx/RxRoom.kt b/matrix-sdk-android-rx/src/main/java/im/vector/matrix/rx/RxRoom.kt index 96f2de9cdca..bc0a8661175 100644 --- a/matrix-sdk-android-rx/src/main/java/im/vector/matrix/rx/RxRoom.kt +++ b/matrix-sdk-android-rx/src/main/java/im/vector/matrix/rx/RxRoom.kt @@ -57,7 +57,8 @@ class RxRoom(private val room: Room) { room.loadRoomMembersIfNeeded(MatrixCallbackSingle(it)).toSingle(it) } - fun joinRoom(reason: String?, viaServers: List = emptyList()): Single = Single.create { + fun joinRoom(reason: String? = null, + viaServers: List = emptyList()): Single = Single.create { room.join(reason, viaServers, MatrixCallbackSingle(it)).toSingle(it) } diff --git a/matrix-sdk-android-rx/src/main/java/im/vector/matrix/rx/RxSession.kt b/matrix-sdk-android-rx/src/main/java/im/vector/matrix/rx/RxSession.kt index 1ef1c8cadb8..5a42dbb8049 100644 --- a/matrix-sdk-android-rx/src/main/java/im/vector/matrix/rx/RxSession.kt +++ b/matrix-sdk-android-rx/src/main/java/im/vector/matrix/rx/RxSession.kt @@ -76,7 +76,9 @@ class RxSession(private val session: Session) { session.searchUsersDirectory(search, limit, excludedUserIds, MatrixCallbackSingle(it)).toSingle(it) } - fun joinRoom(roomId: String, reason: String?, viaServers: List = emptyList()): Single = Single.create { + fun joinRoom(roomId: String, + reason: String? = null, + viaServers: List = emptyList()): Single = Single.create { session.joinRoom(roomId, reason, viaServers, MatrixCallbackSingle(it)).toSingle(it) } } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/RoomDirectoryService.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/RoomDirectoryService.kt index 8d03c70efad..c0e413f83b3 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/RoomDirectoryService.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/RoomDirectoryService.kt @@ -30,12 +30,16 @@ interface RoomDirectoryService { /** * Get rooms from directory */ - fun getPublicRooms(server: String?, publicRoomsParams: PublicRoomsParams, callback: MatrixCallback): Cancelable + fun getPublicRooms(server: String?, + publicRoomsParams: PublicRoomsParams, + callback: MatrixCallback): Cancelable /** * Join a room by id */ - fun joinRoom(roomId: String, reason: String?, callback: MatrixCallback): Cancelable + fun joinRoom(roomId: String, + reason: String? = null, + callback: MatrixCallback): Cancelable /** * Fetches the overall metadata about protocols supported by the homeserver. diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/RoomService.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/RoomService.kt index 71a9a8e4fa0..98abce5898d 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/RoomService.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/RoomService.kt @@ -30,7 +30,8 @@ interface RoomService { /** * Create a room asynchronously */ - fun createRoom(createRoomParams: CreateRoomParams, callback: MatrixCallback): Cancelable + fun createRoom(createRoomParams: CreateRoomParams, + callback: MatrixCallback): Cancelable /** * Join a room by id @@ -39,7 +40,7 @@ interface RoomService { * @param viaServers the servers to attempt to join the room through. One of the servers must be participating in the room. */ fun joinRoom(roomId: String, - reason: String?, + reason: String? = null, viaServers: List = emptyList(), callback: MatrixCallback): Cancelable @@ -71,5 +72,6 @@ interface RoomService { /** * Mark all rooms as read */ - fun markAllAsRead(roomIds: List, callback: MatrixCallback): Cancelable + fun markAllAsRead(roomIds: List, + callback: MatrixCallback): Cancelable } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/members/MembershipService.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/members/MembershipService.kt index 0f487880b71..b750c5347e5 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/members/MembershipService.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/members/MembershipService.kt @@ -52,16 +52,21 @@ interface MembershipService { /** * Invite a user in the room */ - fun invite(userId: String, reason: String?, callback: MatrixCallback): Cancelable + fun invite(userId: String, + reason: String? = null, + callback: MatrixCallback): Cancelable /** * Join the room, or accept an invitation. */ - fun join(reason: String?, viaServers: List = emptyList(), callback: MatrixCallback): Cancelable + fun join(reason: String? = null, + viaServers: List = emptyList(), + callback: MatrixCallback): Cancelable /** * Leave the room, or reject an invitation. */ - fun leave(reason: String?, callback: MatrixCallback): Cancelable + fun leave(reason: String? = null, + callback: MatrixCallback): Cancelable } diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailViewModel.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailViewModel.kt index abdcc46f6a9..00a31db455a 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailViewModel.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailViewModel.kt @@ -200,9 +200,10 @@ class RoomDetailViewModel @AssistedInject constructor(@Assisted initialState: Ro invisibleEventsObservable.accept(action) } - fun getMember(userId: String) : RoomMember? { - return room.getRoomMember(userId) + fun getMember(userId: String): RoomMember? { + return room.getRoomMember(userId) } + /** * Convert a send mode to a draft and save the draft */ @@ -266,7 +267,7 @@ class RoomDetailViewModel @AssistedInject constructor(@Assisted initialState: Ro } } session.rx() - .joinRoom(roomId, null, viaServer) + .joinRoom(roomId, viaServers = viaServer) .map { roomId } .execute { copy(tombstoneEventHandling = it) @@ -557,7 +558,7 @@ class RoomDetailViewModel @AssistedInject constructor(@Assisted initialState: Ro } private fun handleAcceptInvite() { - room.join(null, callback = object : MatrixCallback {}) + room.join(callback = object : MatrixCallback {}) } private fun handleEditAction(action: RoomDetailAction.EnterEditMode) { diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/list/RoomListViewModel.kt b/vector/src/main/java/im/vector/riotx/features/home/room/list/RoomListViewModel.kt index 8e9e76099de..a9ea8317235 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/list/RoomListViewModel.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/list/RoomListViewModel.kt @@ -123,7 +123,7 @@ class RoomListViewModel @Inject constructor(initialState: RoomListViewState, ) } - session.getRoom(roomId)?.join(null, emptyList(), object : MatrixCallback { + session.getRoom(roomId)?.join(callback = object : MatrixCallback { override fun onSuccess(data: Unit) { // We do not update the joiningRoomsIds here, because, the room is not joined yet regarding the sync data. // Instead, we wait for the room to be joined diff --git a/vector/src/main/java/im/vector/riotx/features/notifications/NotificationBroadcastReceiver.kt b/vector/src/main/java/im/vector/riotx/features/notifications/NotificationBroadcastReceiver.kt index 447137d2632..c9dc131b42f 100644 --- a/vector/src/main/java/im/vector/riotx/features/notifications/NotificationBroadcastReceiver.kt +++ b/vector/src/main/java/im/vector/riotx/features/notifications/NotificationBroadcastReceiver.kt @@ -74,14 +74,14 @@ class NotificationBroadcastReceiver : BroadcastReceiver() { private fun handleJoinRoom(roomId: String) { activeSessionHolder.getSafeActiveSession()?.let { session -> session.getRoom(roomId) - ?.join(null, emptyList(), object : MatrixCallback {}) + ?.join(callback = object : MatrixCallback {}) } } private fun handleRejectRoom(roomId: String) { activeSessionHolder.getSafeActiveSession()?.let { session -> session.getRoom(roomId) - ?.leave(null, object : MatrixCallback {}) + ?.leave(callback = object : MatrixCallback {}) } } diff --git a/vector/src/main/java/im/vector/riotx/features/roomdirectory/RoomDirectoryViewModel.kt b/vector/src/main/java/im/vector/riotx/features/roomdirectory/RoomDirectoryViewModel.kt index 3f8b6883ab6..d89f0e2b99a 100644 --- a/vector/src/main/java/im/vector/riotx/features/roomdirectory/RoomDirectoryViewModel.kt +++ b/vector/src/main/java/im/vector/riotx/features/roomdirectory/RoomDirectoryViewModel.kt @@ -214,7 +214,7 @@ class RoomDirectoryViewModel @AssistedInject constructor(@Assisted initialState: ) } - session.joinRoom(action.roomId, null, emptyList(), object : MatrixCallback { + session.joinRoom(action.roomId, callback = object : MatrixCallback { override fun onSuccess(data: Unit) { // We do not update the joiningRoomsIds here, because, the room is not joined yet regarding the sync data. // Instead, we wait for the room to be joined diff --git a/vector/src/main/java/im/vector/riotx/features/roomdirectory/roompreview/RoomPreviewViewModel.kt b/vector/src/main/java/im/vector/riotx/features/roomdirectory/roompreview/RoomPreviewViewModel.kt index 42659b2b20d..54c86537d23 100644 --- a/vector/src/main/java/im/vector/riotx/features/roomdirectory/roompreview/RoomPreviewViewModel.kt +++ b/vector/src/main/java/im/vector/riotx/features/roomdirectory/roompreview/RoomPreviewViewModel.kt @@ -97,7 +97,7 @@ class RoomPreviewViewModel @AssistedInject constructor(@Assisted initialState: R ) } - session.joinRoom(state.roomId, null, emptyList(), object : MatrixCallback { + session.joinRoom(state.roomId, callback = object : MatrixCallback { override fun onSuccess(data: Unit) { // We do not update the joiningRoomsIds here, because, the room is not joined yet regarding the sync data. // Instead, we wait for the room to be joined From 2f26f4b8bb46648bb86d58c45f6e2c652a0df611 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 5 Dec 2019 09:26:14 +0100 Subject: [PATCH 11/12] Add default value (fix test compilation issue) --- .../vector/matrix/android/api/session/room/model/RoomMember.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/RoomMember.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/RoomMember.kt index e28ba90b526..6a4d8e3c94a 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/RoomMember.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/RoomMember.kt @@ -26,7 +26,7 @@ import im.vector.matrix.android.api.session.events.model.UnsignedData @JsonClass(generateAdapter = true) data class RoomMember( @Json(name = "membership") val membership: Membership, - @Json(name = "reason") val reason: String?, + @Json(name = "reason") val reason: String? = null, @Json(name = "displayname") val displayName: String? = null, @Json(name = "avatar_url") val avatarUrl: String? = null, @Json(name = "is_direct") val isDirect: Boolean = false, From ac75fe12bfa0c770db13226672dd8f6177c3ba09 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 5 Dec 2019 09:53:18 +0100 Subject: [PATCH 12/12] Will be merged for next release --- CHANGES.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 0b8ecbba7a4..60950d9d876 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -8,7 +8,7 @@ Improvements 🙌: - Other changes: - - + - Add reason for all membership events (https://github.com/matrix-org/matrix-doc/pull/2367) Bugfix 🐛: - When automardown is ON, pills are sent as MD in body (#739) @@ -17,7 +17,7 @@ Translations 🗣: - Build 🧱: - - + - "ban" event are not rendered correctly (#716) Changes in RiotX 0.9.1 (2019-12-05) =================================================== @@ -39,14 +39,12 @@ Improvements 🙌: Other changes: - Fix a small grammatical error when an empty room list is shown. - - Add reason for all membership events (https://github.com/matrix-org/matrix-doc/pull/2367) Bugfix 🐛: - Do not show long click help if only invitation are displayed - Fix emoji filtering not working - Fix issue of closing Realm in another thread (#725) - Attempt to properly cancel the crypto module when user signs out (#724) - - "ban" event are not rendered correctly (#716) Changes in RiotX 0.8.0 (2019-11-19) ===================================================