Render events m.room.encryption and m.room.guest_access in the timeline

This commit is contained in:
Benoit Marty 2020-01-10 18:15:34 +01:00
parent 0dbca829ea
commit 550908fa70
8 changed files with 68 additions and 82 deletions

View file

@ -5,7 +5,7 @@ Features ✨:
-
Improvements 🙌:
-
- Render events m.room.encryption and m.room.guest_access in the timeline
Other changes:
-

View file

@ -91,7 +91,8 @@ object EventType {
STATE_ROOM_CANONICAL_ALIAS,
STATE_ROOM_HISTORY_VISIBILITY,
STATE_ROOM_RELATED_GROUPS,
STATE_ROOM_PINNED_EVENT
STATE_ROOM_PINNED_EVENT,
STATE_ROOM_ENCRYPTION
)
fun isStateEvent(type: String): Boolean {

View file

@ -0,0 +1,37 @@
/*
* Copyright 2019 New Vector Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package im.vector.matrix.android.api.session.room.model
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
/**
* Class representing the EventType.STATE_ROOM_GUEST_ACCESS state event content
* Ref: https://matrix.org/docs/spec/client_server/latest#m-room-guest-access
*/
@JsonClass(generateAdapter = true)
data class RoomGuestAccessContent(
// Required. Whether guests can join the room. One of: ["can_join", "forbidden"]
@Json(name = "guest_access") val guestAccess: GuestAccess? = null
)
enum class GuestAccess(val value: String) {
@Json(name = "can_join")
CanJoin("can_join"),
@Json(name = "forbidden")
Forbidden("forbidden")
}

View file

@ -272,4 +272,7 @@
<string name="notice_room_canonical_alias_set">"%1$s set the main address for this room to %2$s."</string>
<string name="notice_room_canonical_alias_unset">"%1$s removed the main address for this room."</string>
<string name="notice_room_guest_access_can_join">"%1$s has allowed guests to join the room."</string>
<string name="notice_room_guest_access_forbidden">"%1$s has prevented guests from joining the room."</string>
</resources>

View file

@ -1,75 +0,0 @@
/*
* Copyright 2019 New Vector Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package im.vector.riotx.features.home.room.detail.timeline.factory
import android.view.View
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.timeline.TimelineEvent
import im.vector.matrix.android.internal.crypto.model.event.EncryptionEventContent
import im.vector.riotx.R
import im.vector.riotx.core.resources.StringProvider
import im.vector.riotx.features.home.AvatarRenderer
import im.vector.riotx.features.home.room.detail.timeline.TimelineEventController
import im.vector.riotx.features.home.room.detail.timeline.helper.AvatarSizeProvider
import im.vector.riotx.features.home.room.detail.timeline.item.MessageInformationData
import im.vector.riotx.features.home.room.detail.timeline.item.NoticeItem
import im.vector.riotx.features.home.room.detail.timeline.item.NoticeItem_
import javax.inject.Inject
class EncryptionItemFactory @Inject constructor(private val stringProvider: StringProvider,
private val avatarRenderer: AvatarRenderer,
private val avatarSizeProvider: AvatarSizeProvider) {
fun create(event: TimelineEvent,
highlight: Boolean,
callback: TimelineEventController.Callback?): NoticeItem? {
val text = buildNoticeText(event.root, event.getDisambiguatedDisplayName()) ?: return null
val informationData = MessageInformationData(
eventId = event.root.eventId ?: "?",
senderId = event.root.senderId ?: "",
sendState = event.root.sendState,
avatarUrl = event.senderAvatar,
memberName = event.getDisambiguatedDisplayName(),
showInformation = false
)
val attributes = NoticeItem.Attributes(
avatarRenderer = avatarRenderer,
informationData = informationData,
noticeText = text,
itemLongClickListener = View.OnLongClickListener { view ->
callback?.onEventLongClicked(informationData, null, view) ?: false
},
readReceiptsCallback = callback
)
return NoticeItem_()
.leftGuideline(avatarSizeProvider.leftGuideline)
.highlighted(highlight)
.attributes(attributes)
}
private fun buildNoticeText(event: Event, senderName: String?): CharSequence? {
return when {
EventType.STATE_ROOM_ENCRYPTION == event.getClearType() -> {
val content = event.content.toModel<EncryptionEventContent>() ?: return null
stringProvider.getString(R.string.notice_end_to_end, senderName, content.algorithm)
}
else -> null
}
}
}

View file

@ -24,11 +24,12 @@ import im.vector.riotx.features.home.room.detail.timeline.TimelineEventControlle
import timber.log.Timber
import javax.inject.Inject
class TimelineItemFactory @Inject constructor(private val messageItemFactory: MessageItemFactory,
private val encryptedItemFactory: EncryptedItemFactory,
private val noticeItemFactory: NoticeItemFactory,
private val defaultItemFactory: DefaultItemFactory,
private val roomCreateItemFactory: RoomCreateItemFactory) {
class TimelineItemFactory @Inject constructor(
private val messageItemFactory: MessageItemFactory,
private val encryptedItemFactory: EncryptedItemFactory,
private val noticeItemFactory: NoticeItemFactory,
private val defaultItemFactory: DefaultItemFactory,
private val roomCreateItemFactory: RoomCreateItemFactory) {
fun create(event: TimelineEvent,
nextEvent: TimelineEvent?,
@ -49,6 +50,7 @@ class TimelineItemFactory @Inject constructor(private val messageItemFactory: Me
EventType.STATE_ROOM_CANONICAL_ALIAS,
EventType.STATE_ROOM_JOIN_RULES,
EventType.STATE_ROOM_HISTORY_VISIBILITY,
EventType.STATE_ROOM_GUEST_ACCESS,
EventType.CALL_INVITE,
EventType.CALL_HANGUP,
EventType.CALL_ANSWER,

View file

@ -22,6 +22,7 @@ import im.vector.matrix.android.api.session.events.model.toModel
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.matrix.android.internal.crypto.model.event.EncryptionEventContent
import im.vector.riotx.R
import im.vector.riotx.core.di.ActiveSessionHolder
import im.vector.riotx.core.resources.StringProvider
@ -40,6 +41,8 @@ class NoticeEventFormatter @Inject constructor(private val sessionHolder: Active
EventType.STATE_ROOM_ALIASES -> formatRoomAliasesEvent(timelineEvent.root, timelineEvent.getDisambiguatedDisplayName())
EventType.STATE_ROOM_CANONICAL_ALIAS -> formatRoomCanonicalAliasEvent(timelineEvent.root, timelineEvent.getDisambiguatedDisplayName())
EventType.STATE_ROOM_HISTORY_VISIBILITY -> formatRoomHistoryVisibilityEvent(timelineEvent.root, timelineEvent.getDisambiguatedDisplayName())
EventType.STATE_ROOM_GUEST_ACCESS -> formatRoomGuestAccessEvent(timelineEvent.root, timelineEvent.getDisambiguatedDisplayName())
EventType.STATE_ROOM_ENCRYPTION -> formatRoomEncryptionEvent(timelineEvent.root, timelineEvent.getDisambiguatedDisplayName())
EventType.STATE_ROOM_TOMBSTONE -> formatRoomTombstoneEvent(timelineEvent.getDisambiguatedDisplayName())
EventType.CALL_INVITE,
EventType.CALL_HANGUP,
@ -166,6 +169,20 @@ class NoticeEventFormatter @Inject constructor(private val sessionHolder: Active
?: 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)
else -> null
}
}
private fun formatRoomEncryptionEvent(event: Event, senderName: String?): CharSequence? {
val content = event.content.toModel<EncryptionEventContent>() ?: return null
return sp.getString(R.string.notice_end_to_end, senderName, content.algorithm)
}
private fun buildProfileNotice(event: Event, senderName: String?, eventContent: RoomMemberContent?, prevEventContent: RoomMemberContent?): String {
val displayText = StringBuilder()
// Check display name has been changed

View file

@ -35,6 +35,7 @@ object TimelineDisplayableEvents {
EventType.CALL_ANSWER,
EventType.ENCRYPTED,
EventType.STATE_ROOM_ENCRYPTION,
EventType.STATE_ROOM_GUEST_ACCESS,
EventType.STATE_ROOM_THIRD_PARTY_INVITE,
EventType.STICKER,
EventType.STATE_ROOM_CREATE,