diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/session/room/timeline/PollAggregationTest.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/session/room/timeline/PollAggregationTest.kt index a37d2ce015..a52e3cd7c7 100644 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/session/room/timeline/PollAggregationTest.kt +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/session/room/timeline/PollAggregationTest.kt @@ -66,7 +66,7 @@ class PollAggregationTest : InstrumentedTest { val aliceEventsListener = object : Timeline.Listener { override fun onTimelineUpdated(snapshot: List) { - snapshot.firstOrNull { it.root.getClearType() in EventType.POLL_START }?.let { pollEvent -> + snapshot.firstOrNull { it.root.getClearType() in EventType.POLL_START.values }?.let { pollEvent -> val pollEventId = pollEvent.eventId val pollContent = pollEvent.root.content?.toModel() val pollSummary = pollEvent.annotations?.pollResponseSummary diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/events/model/Event.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/events/model/Event.kt index 1e32437727..40ce6ecb5c 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/events/model/Event.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/events/model/Event.kt @@ -26,10 +26,8 @@ import org.matrix.android.sdk.api.session.crypto.model.OlmDecryptionResult import org.matrix.android.sdk.api.session.events.model.content.EncryptedEventContent import org.matrix.android.sdk.api.session.room.model.Membership import org.matrix.android.sdk.api.session.room.model.RoomMemberContent -import org.matrix.android.sdk.api.session.room.model.message.MessageBeaconLocationDataContent import org.matrix.android.sdk.api.session.room.model.message.MessageContent import org.matrix.android.sdk.api.session.room.model.message.MessagePollContent -import org.matrix.android.sdk.api.session.room.model.message.MessageStickerContent import org.matrix.android.sdk.api.session.room.model.message.MessageType import org.matrix.android.sdk.api.session.room.model.message.asMessageAudioEvent import org.matrix.android.sdk.api.session.room.model.relation.RelationDefaultContent @@ -390,24 +388,18 @@ fun Event.isLocationMessage(): Boolean { } } -fun Event.isPoll(): Boolean = getClearType() in EventType.POLL_START || getClearType() in EventType.POLL_END +fun Event.isPoll(): Boolean = getClearType() in EventType.POLL_START.values || getClearType() in EventType.POLL_END.values fun Event.isSticker(): Boolean = getClearType() == EventType.STICKER -fun Event.isLiveLocation(): Boolean = getClearType() in EventType.STATE_ROOM_BEACON_INFO +fun Event.isLiveLocation(): Boolean = getClearType() in EventType.STATE_ROOM_BEACON_INFO.values fun Event.getRelationContent(): RelationDefaultContent? { return if (isEncrypted()) { content.toModel()?.relatesTo } else { - content.toModel()?.relatesTo ?: run { - // Special cases when there is only a local msgtype for some event types - when (getClearType()) { - EventType.STICKER -> getClearContent().toModel()?.relatesTo - in EventType.BEACON_LOCATION_DATA -> getClearContent().toModel()?.relatesTo - else -> getClearContent()?.get("m.relates_to")?.toContent().toModel() - } - } + content.toModel()?.relatesTo + ?: getClearContent()?.get("m.relates_to")?.toContent().toModel() // Special cases when there is only a local msgtype for some event types } } @@ -451,7 +443,7 @@ fun Event.getPollContent(): MessagePollContent? { } fun Event.supportsNotification() = - this.getClearType() in EventType.MESSAGE + EventType.POLL_START + EventType.STATE_ROOM_BEACON_INFO + this.getClearType() in EventType.MESSAGE + EventType.POLL_START.values + EventType.STATE_ROOM_BEACON_INFO.values fun Event.isContentReportable() = - this.getClearType() in EventType.MESSAGE + EventType.STATE_ROOM_BEACON_INFO + this.getClearType() in EventType.MESSAGE + EventType.STATE_ROOM_BEACON_INFO.values diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/events/model/EventType.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/events/model/EventType.kt index 3ad4f3a87f..e5c14afa90 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/events/model/EventType.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/events/model/EventType.kt @@ -49,11 +49,10 @@ object EventType { const val STATE_ROOM_JOIN_RULES = "m.room.join_rules" const val STATE_ROOM_GUEST_ACCESS = "m.room.guest_access" const val STATE_ROOM_POWER_LEVELS = "m.room.power_levels" - val STATE_ROOM_BEACON_INFO = listOf("org.matrix.msc3672.beacon_info", "m.beacon_info") - val BEACON_LOCATION_DATA = listOf("org.matrix.msc3672.beacon", "m.beacon") + val STATE_ROOM_BEACON_INFO = StableUnstableId(stable = "m.beacon_info", unstable = "org.matrix.msc3672.beacon_info") + val BEACON_LOCATION_DATA = StableUnstableId(stable = "m.beacon", unstable = "org.matrix.msc3672.beacon") const val STATE_SPACE_CHILD = "m.space.child" - const val STATE_SPACE_PARENT = "m.space.parent" /** @@ -81,8 +80,7 @@ object EventType { const val CALL_NEGOTIATE = "m.call.negotiate" const val CALL_REJECT = "m.call.reject" const val CALL_HANGUP = "m.call.hangup" - const val CALL_ASSERTED_IDENTITY = "m.call.asserted_identity" - const val CALL_ASSERTED_IDENTITY_PREFIX = "org.matrix.call.asserted_identity" + val CALL_ASSERTED_IDENTITY = StableUnstableId(stable = "m.call.asserted_identity", unstable = "org.matrix.call.asserted_identity") // This type is not processed by the client, just sent to the server const val CALL_REPLACES = "m.call.replaces" @@ -90,10 +88,7 @@ object EventType { // Key share events const val ROOM_KEY_REQUEST = "m.room_key_request" const val FORWARDED_ROOM_KEY = "m.forwarded_room_key" - val ROOM_KEY_WITHHELD = StableUnstableId( - stable = "m.room_key.withheld", - unstable = "org.matrix.room_key.withheld" - ) + val ROOM_KEY_WITHHELD = StableUnstableId(stable = "m.room_key.withheld", unstable = "org.matrix.room_key.withheld") const val REQUEST_SECRET = "m.secret.request" const val SEND_SECRET = "m.secret.send" @@ -111,9 +106,9 @@ object EventType { const val REACTION = "m.reaction" // Poll - val POLL_START = listOf("org.matrix.msc3381.poll.start", "m.poll.start") - val POLL_RESPONSE = listOf("org.matrix.msc3381.poll.response", "m.poll.response") - val POLL_END = listOf("org.matrix.msc3381.poll.end", "m.poll.end") + val POLL_START = StableUnstableId(stable = "m.poll.start", unstable = "org.matrix.msc3381.poll.start") + val POLL_RESPONSE = StableUnstableId(stable = "m.poll.response", unstable = "org.matrix.msc3381.poll.response") + val POLL_END = StableUnstableId(stable = "m.poll.end", unstable = "org.matrix.msc3381.poll.end") // Unwedging internal const val DUMMY = "m.dummy" diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/message/MessageStickerContent.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/message/MessageStickerContent.kt index f8c1c0d798..627ce53df6 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/message/MessageStickerContent.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/message/MessageStickerContent.kt @@ -34,7 +34,7 @@ data class MessageStickerContent( * Required. A textual representation of the image. This could be the alt text of the image, the filename of the image, * or some kind of content description for accessibility e.g. 'image attachment'. */ - @Json(name = "body") override val body: String, + @Json(name = "body") override val body: String = "", /** * Metadata about the image referred to in url. diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/summary/RoomSummaryConstants.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/summary/RoomSummaryConstants.kt index 8f214e0f89..634e71c43b 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/summary/RoomSummaryConstants.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/summary/RoomSummaryConstants.kt @@ -33,5 +33,7 @@ object RoomSummaryConstants { EventType.ENCRYPTED, EventType.STICKER, EventType.REACTION - ) + EventType.POLL_START + EventType.STATE_ROOM_BEACON_INFO + ) + + EventType.POLL_START.values + + EventType.STATE_ROOM_BEACON_INFO.values } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/timeline/TimelineEvent.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/timeline/TimelineEvent.kt index 6b4a0226a0..9053425a39 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/timeline/TimelineEvent.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/timeline/TimelineEvent.kt @@ -147,9 +147,9 @@ fun TimelineEvent.getLastMessageContent(): MessageContent? { // Polls/Beacon are not message contents like others as there is no msgtype subtype to discriminate moshi parsing // so toModel won't parse them correctly // It's discriminated on event type instead. Maybe it shouldn't be MessageContent at all to avoid confusion? - in EventType.POLL_START -> (getLastEditNewContent() ?: root.getClearContent()).toModel() - in EventType.STATE_ROOM_BEACON_INFO -> (getLastEditNewContent() ?: root.getClearContent()).toModel() - in EventType.BEACON_LOCATION_DATA -> (getLastEditNewContent() ?: root.getClearContent()).toModel() + in EventType.POLL_START.values -> (getLastEditNewContent() ?: root.getClearContent()).toModel() + in EventType.STATE_ROOM_BEACON_INFO.values -> (getLastEditNewContent() ?: root.getClearContent()).toModel() + in EventType.BEACON_LOCATION_DATA.values -> (getLastEditNewContent() ?: root.getClearContent()).toModel() else -> (getLastEditNewContent() ?: root.getClearContent()).toModel() } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/call/CallEventProcessor.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/call/CallEventProcessor.kt index 6a4abe9d34..b6ad7581fe 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/call/CallEventProcessor.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/call/CallEventProcessor.kt @@ -41,9 +41,8 @@ internal class CallEventProcessor @Inject constructor(private val callSignalingH EventType.CALL_INVITE, EventType.CALL_HANGUP, EventType.ENCRYPTED, - EventType.CALL_ASSERTED_IDENTITY, - EventType.CALL_ASSERTED_IDENTITY_PREFIX - ) + ) + + EventType.CALL_ASSERTED_IDENTITY.values private val eventsToPostProcess = mutableListOf() diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/call/CallSignalingHandler.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/call/CallSignalingHandler.kt index 48a9dfd3da..d824aaa51a 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/call/CallSignalingHandler.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/call/CallSignalingHandler.kt @@ -84,8 +84,7 @@ internal class CallSignalingHandler @Inject constructor( EventType.CALL_NEGOTIATE -> { handleCallNegotiateEvent(event) } - EventType.CALL_ASSERTED_IDENTITY, - EventType.CALL_ASSERTED_IDENTITY_PREFIX -> { + in EventType.CALL_ASSERTED_IDENTITY.values -> { handleCallAssertedIdentityEvent(event) } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/pushrules/ProcessEventForPushTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/pushrules/ProcessEventForPushTask.kt index 09d7d50ecb..9fe93d8262 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/pushrules/ProcessEventForPushTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/pushrules/ProcessEventForPushTask.kt @@ -56,8 +56,8 @@ internal class DefaultProcessEventForPushTask @Inject constructor( val allEvents = (newJoinEvents + inviteEvents).filter { event -> when (event.type) { - in EventType.POLL_START, - in EventType.STATE_ROOM_BEACON_INFO, + in EventType.POLL_START.values, + in EventType.STATE_ROOM_BEACON_INFO.values, EventType.MESSAGE, EventType.REDACTION, EventType.ENCRYPTED, diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/EventRelationsAggregationProcessor.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/EventRelationsAggregationProcessor.kt index 48e75821bd..be73309837 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/EventRelationsAggregationProcessor.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/EventRelationsAggregationProcessor.kt @@ -91,7 +91,12 @@ internal class EventRelationsAggregationProcessor @Inject constructor( EventType.KEY_VERIFICATION_READY, EventType.KEY_VERIFICATION_KEY, EventType.ENCRYPTED - ) + EventType.POLL_START + EventType.POLL_RESPONSE + EventType.POLL_END + EventType.STATE_ROOM_BEACON_INFO + EventType.BEACON_LOCATION_DATA + ) + + EventType.POLL_START.values + + EventType.POLL_RESPONSE.values + + EventType.POLL_END.values + + EventType.STATE_ROOM_BEACON_INFO.values + + EventType.BEACON_LOCATION_DATA.values override fun shouldProcess(eventId: String, eventType: String, insertType: EventInsertType): Boolean { return allowedTypes.contains(eventType) @@ -208,7 +213,7 @@ internal class EventRelationsAggregationProcessor @Inject constructor( } } } - in EventType.POLL_START -> { + in EventType.POLL_START.values -> { val content: MessagePollContent? = event.content.toModel() if (content?.relatesTo?.type == RelationType.REPLACE) { Timber.v("###REPLACE in room $roomId for event ${event.eventId}") @@ -216,26 +221,26 @@ internal class EventRelationsAggregationProcessor @Inject constructor( handleReplace(realm, event, roomId, isLocalEcho, content.relatesTo.eventId) } } - in EventType.POLL_RESPONSE -> { + in EventType.POLL_RESPONSE.values -> { event.content.toModel(catchError = true)?.let { sessionManager.getSessionComponent(sessionId)?.session()?.let { session -> pollAggregationProcessor.handlePollResponseEvent(session, realm, event) } } } - in EventType.POLL_END -> { + in EventType.POLL_END.values -> { sessionManager.getSessionComponent(sessionId)?.session()?.let { session -> getPowerLevelsHelper(event.roomId)?.let { pollAggregationProcessor.handlePollEndEvent(session, it, realm, event) } } } - in EventType.STATE_ROOM_BEACON_INFO -> { + in EventType.STATE_ROOM_BEACON_INFO.values -> { event.content.toModel(catchError = true)?.let { liveLocationAggregationProcessor.handleBeaconInfo(realm, event, it, roomId, isLocalEcho) } } - in EventType.BEACON_LOCATION_DATA -> { + in EventType.BEACON_LOCATION_DATA.values -> { handleBeaconLocationData(event, realm, roomId, isLocalEcho) } else -> Timber.v("UnHandled event ${event.eventId}") @@ -324,7 +329,7 @@ internal class EventRelationsAggregationProcessor @Inject constructor( } } - if (event.getClearType() in EventType.POLL_START) { + if (event.getClearType() in EventType.POLL_START.values) { pollAggregationProcessor.handlePollStartEvent(realm, event) } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/location/GetActiveBeaconInfoForUserTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/location/GetActiveBeaconInfoForUserTask.kt index a8d955af1d..ae7022a204 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/location/GetActiveBeaconInfoForUserTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/location/GetActiveBeaconInfoForUserTask.kt @@ -39,7 +39,7 @@ internal class DefaultGetActiveBeaconInfoForUserTask @Inject constructor( ) : GetActiveBeaconInfoForUserTask { override suspend fun execute(params: GetActiveBeaconInfoForUserTask.Params): Event? { - return EventType.STATE_ROOM_BEACON_INFO + return EventType.STATE_ROOM_BEACON_INFO.values .mapNotNull { stateEventDataSource.getStateEvent( roomId = params.roomId, diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/location/LiveLocationShareRedactionEventProcessor.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/location/LiveLocationShareRedactionEventProcessor.kt index 9041ef2677..dbdc5dc228 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/location/LiveLocationShareRedactionEventProcessor.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/location/LiveLocationShareRedactionEventProcessor.kt @@ -48,7 +48,7 @@ internal class LiveLocationShareRedactionEventProcessor @Inject constructor() : val redactedEvent = EventEntity.where(realm, eventId = event.redacts).findFirst() ?: return - if (redactedEvent.type in EventType.STATE_ROOM_BEACON_INFO) { + if (redactedEvent.type in EventType.STATE_ROOM_BEACON_INFO.values) { val liveSummary = LiveLocationShareAggregatedSummaryEntity.get(realm, eventId = redactedEvent.eventId) if (liveSummary != null) { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/location/StartLiveLocationShareTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/location/StartLiveLocationShareTask.kt index 781def1abe..13753115ac 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/location/StartLiveLocationShareTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/location/StartLiveLocationShareTask.kt @@ -46,7 +46,7 @@ internal class DefaultStartLiveLocationShareTask @Inject constructor( isLive = true, unstableTimestampMillis = clock.epochMillis() ).toContent() - val eventType = EventType.STATE_ROOM_BEACON_INFO.first() + val eventType = EventType.STATE_ROOM_BEACON_INFO.stable val sendStateTaskParams = SendStateTask.Params( roomId = params.roomId, stateKey = userId, diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/location/StopLiveLocationShareTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/location/StopLiveLocationShareTask.kt index da5fd76940..40f7aa2dd2 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/location/StopLiveLocationShareTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/location/StopLiveLocationShareTask.kt @@ -45,7 +45,7 @@ internal class DefaultStopLiveLocationShareTask @Inject constructor( val sendStateTaskParams = SendStateTask.Params( roomId = params.roomId, stateKey = stateKey, - eventType = EventType.STATE_ROOM_BEACON_INFO.first(), + eventType = EventType.STATE_ROOM_BEACON_INFO.stable, body = updatedContent ) return try { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/prune/RedactionEventProcessor.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/prune/RedactionEventProcessor.kt index 7968eabd30..0cff2c5a7c 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/prune/RedactionEventProcessor.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/prune/RedactionEventProcessor.kt @@ -61,45 +61,36 @@ internal class RedactionEventProcessor @Inject constructor() : EventInsertLivePr val isLocalEcho = LocalEcho.isLocalEchoId(redactionEvent.eventId ?: "") Timber.v("Redact event for ${redactionEvent.redacts} localEcho=$isLocalEcho") - val eventToPrune = EventEntity.where(realm, eventId = redactionEvent.redacts).findFirst() - ?: return + val eventToPrune = EventEntity.where(realm, eventId = redactionEvent.redacts).findFirst() ?: return val typeToPrune = eventToPrune.type val stateKey = eventToPrune.stateKey val allowedKeys = computeAllowedKeys(typeToPrune) - if (allowedKeys.isNotEmpty()) { - val prunedContent = ContentMapper.map(eventToPrune.content)?.filterKeys { key -> allowedKeys.contains(key) } - eventToPrune.content = ContentMapper.map(prunedContent) - } else { - when (typeToPrune) { - EventType.ENCRYPTED, - EventType.MESSAGE, - in EventType.STATE_ROOM_BEACON_INFO, - in EventType.BEACON_LOCATION_DATA, - in EventType.POLL_START -> { - Timber.d("REDACTION for message ${eventToPrune.eventId}") - val unsignedData = EventMapper.map(eventToPrune).unsignedData - ?: UnsignedData(null, null) + when { + allowedKeys.isNotEmpty() -> { + val prunedContent = ContentMapper.map(eventToPrune.content)?.filterKeys { key -> allowedKeys.contains(key) } + eventToPrune.content = ContentMapper.map(prunedContent) + } + canPruneEventType(typeToPrune) -> { + Timber.d("REDACTION for message ${eventToPrune.eventId}") + val unsignedData = EventMapper.map(eventToPrune).unsignedData ?: UnsignedData(null, null) - // was this event a m.replace + // was this event a m.replace // val contentModel = ContentMapper.map(eventToPrune.content)?.toModel() // if (RelationType.REPLACE == contentModel?.relatesTo?.type && contentModel.relatesTo?.eventId != null) { // eventRelationsAggregationUpdater.handleRedactionOfReplace(eventToPrune, contentModel.relatesTo!!.eventId!!, realm) // } - val modified = unsignedData.copy(redactedEvent = redactionEvent) - // Deleting the content of a thread message will result to delete the thread relation, however threads are now dynamic - // so there is not much of a problem - eventToPrune.content = ContentMapper.map(emptyMap()) - eventToPrune.unsignedData = MoshiProvider.providesMoshi().adapter(UnsignedData::class.java).toJson(modified) - eventToPrune.decryptionResultJson = null - eventToPrune.decryptionErrorCode = null + val modified = unsignedData.copy(redactedEvent = redactionEvent) + eventToPrune.content = ContentMapper.map(emptyMap()) + eventToPrune.unsignedData = MoshiProvider.providesMoshi().adapter(UnsignedData::class.java).toJson(modified) + eventToPrune.decryptionResultJson = null + eventToPrune.decryptionErrorCode = null - handleTimelineThreadSummaryIfNeeded(realm, eventToPrune, isLocalEcho) - } -// EventType.REACTION -> { -// eventRelationsAggregationUpdater.handleReactionRedact(eventToPrune, realm, userId) -// } + handleTimelineThreadSummaryIfNeeded(realm, eventToPrune, isLocalEcho) + } + else -> { + Timber.w("Not pruning event (type $typeToPrune)") } } if (typeToPrune == EventType.STATE_ROOM_MEMBER && stateKey != null) { @@ -167,4 +158,28 @@ internal class RedactionEventProcessor @Inject constructor() : EventInsertLivePr else -> emptyList() } } + + private fun canPruneEventType(eventType: String): Boolean { + return when { + EventType.isCallEvent(eventType) -> false + EventType.isVerificationEvent(eventType) -> false + eventType == EventType.STATE_ROOM_WIDGET_LEGACY || + eventType == EventType.STATE_ROOM_WIDGET || + eventType == EventType.STATE_ROOM_NAME || + eventType == EventType.STATE_ROOM_TOPIC || + eventType == EventType.STATE_ROOM_AVATAR || + eventType == EventType.STATE_ROOM_THIRD_PARTY_INVITE || + eventType == EventType.STATE_ROOM_GUEST_ACCESS || + eventType == EventType.STATE_SPACE_CHILD || + eventType == EventType.STATE_SPACE_PARENT || + eventType == EventType.STATE_ROOM_TOMBSTONE || + eventType == EventType.STATE_ROOM_HISTORY_VISIBILITY || + eventType == EventType.STATE_ROOM_RELATED_GROUPS || + eventType == EventType.STATE_ROOM_PINNED_EVENT || + eventType == EventType.STATE_ROOM_ENCRYPTION || + eventType == EventType.STATE_ROOM_SERVER_ACL || + eventType == EventType.REACTION -> false + else -> true + } + } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/LocalEchoEventFactory.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/LocalEchoEventFactory.kt index 55ba78c2a5..2f8be69473 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/LocalEchoEventFactory.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/LocalEchoEventFactory.kt @@ -181,7 +181,7 @@ internal class LocalEchoEventFactory @Inject constructor( originServerTs = dummyOriginServerTs(), senderId = userId, eventId = localId, - type = EventType.POLL_START.first(), + type = EventType.POLL_START.stable, content = newContent.toContent().plus(additionalContent.orEmpty()) ) } @@ -206,7 +206,7 @@ internal class LocalEchoEventFactory @Inject constructor( originServerTs = dummyOriginServerTs(), senderId = userId, eventId = localId, - type = EventType.POLL_RESPONSE.first(), + type = EventType.POLL_RESPONSE.stable, content = content.toContent().plus(additionalContent.orEmpty()), unsignedData = UnsignedData(age = null, transactionId = localId) ) @@ -226,7 +226,7 @@ internal class LocalEchoEventFactory @Inject constructor( originServerTs = dummyOriginServerTs(), senderId = userId, eventId = localId, - type = EventType.POLL_START.first(), + type = EventType.POLL_START.stable, content = content.toContent().plus(additionalContent.orEmpty()), unsignedData = UnsignedData(age = null, transactionId = localId) ) @@ -249,7 +249,7 @@ internal class LocalEchoEventFactory @Inject constructor( originServerTs = dummyOriginServerTs(), senderId = userId, eventId = localId, - type = EventType.POLL_END.first(), + type = EventType.POLL_END.stable, content = content.toContent().plus(additionalContent.orEmpty()), unsignedData = UnsignedData(age = null, transactionId = localId) ) @@ -300,7 +300,7 @@ internal class LocalEchoEventFactory @Inject constructor( originServerTs = dummyOriginServerTs(), senderId = userId, eventId = localId, - type = EventType.BEACON_LOCATION_DATA.first(), + type = EventType.BEACON_LOCATION_DATA.stable, content = content.toContent().plus(additionalContent.orEmpty()), unsignedData = UnsignedData(age = null, transactionId = localId) ) diff --git a/matrix-sdk-android/src/test/java/org/matrix/android/sdk/internal/session/room/aggregation/poll/PollEventsTestData.kt b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/internal/session/room/aggregation/poll/PollEventsTestData.kt index 129d49633e..bdd1fd9b0d 100644 --- a/matrix-sdk-android/src/test/java/org/matrix/android/sdk/internal/session/room/aggregation/poll/PollEventsTestData.kt +++ b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/internal/session/room/aggregation/poll/PollEventsTestData.kt @@ -87,7 +87,7 @@ object PollEventsTestData { ) internal val A_POLL_START_EVENT = Event( - type = EventType.POLL_START.first(), + type = EventType.POLL_START.stable, eventId = AN_EVENT_ID, originServerTs = 1652435922563, senderId = A_USER_ID_1, @@ -96,7 +96,7 @@ object PollEventsTestData { ) internal val A_POLL_RESPONSE_EVENT = Event( - type = EventType.POLL_RESPONSE.first(), + type = EventType.POLL_RESPONSE.stable, eventId = AN_EVENT_ID, originServerTs = 1652435922563, senderId = A_USER_ID_1, @@ -105,7 +105,7 @@ object PollEventsTestData { ) internal val A_POLL_END_EVENT = Event( - type = EventType.POLL_END.first(), + type = EventType.POLL_END.stable, eventId = AN_EVENT_ID, originServerTs = 1652435922563, senderId = A_USER_ID_1, diff --git a/matrix-sdk-android/src/test/java/org/matrix/android/sdk/internal/session/room/location/DefaultGetActiveBeaconInfoForUserTaskTest.kt b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/internal/session/room/location/DefaultGetActiveBeaconInfoForUserTaskTest.kt index d51ed77399..4a10795647 100644 --- a/matrix-sdk-android/src/test/java/org/matrix/android/sdk/internal/session/room/location/DefaultGetActiveBeaconInfoForUserTaskTest.kt +++ b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/internal/session/room/location/DefaultGetActiveBeaconInfoForUserTaskTest.kt @@ -69,7 +69,7 @@ class DefaultGetActiveBeaconInfoForUserTaskTest { result shouldBeEqualTo currentStateEvent fakeStateEventDataSource.verifyGetStateEvent( roomId = params.roomId, - eventType = EventType.STATE_ROOM_BEACON_INFO.first(), + eventType = EventType.STATE_ROOM_BEACON_INFO.stable, stateKey = QueryStringValue.Equals(A_USER_ID) ) } diff --git a/matrix-sdk-android/src/test/java/org/matrix/android/sdk/internal/session/room/location/DefaultStartLiveLocationShareTaskTest.kt b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/internal/session/room/location/DefaultStartLiveLocationShareTaskTest.kt index fdc411cc9d..a5c126cf72 100644 --- a/matrix-sdk-android/src/test/java/org/matrix/android/sdk/internal/session/room/location/DefaultStartLiveLocationShareTaskTest.kt +++ b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/internal/session/room/location/DefaultStartLiveLocationShareTaskTest.kt @@ -75,7 +75,7 @@ internal class DefaultStartLiveLocationShareTaskTest { val expectedParams = SendStateTask.Params( roomId = params.roomId, stateKey = A_USER_ID, - eventType = EventType.STATE_ROOM_BEACON_INFO.first(), + eventType = EventType.STATE_ROOM_BEACON_INFO.stable, body = expectedBeaconContent ) fakeSendStateTask.verifyExecuteRetry( diff --git a/matrix-sdk-android/src/test/java/org/matrix/android/sdk/internal/session/room/location/DefaultStopLiveLocationShareTaskTest.kt b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/internal/session/room/location/DefaultStopLiveLocationShareTaskTest.kt index 1abf179ccf..a7adadfc63 100644 --- a/matrix-sdk-android/src/test/java/org/matrix/android/sdk/internal/session/room/location/DefaultStopLiveLocationShareTaskTest.kt +++ b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/internal/session/room/location/DefaultStopLiveLocationShareTaskTest.kt @@ -79,7 +79,7 @@ class DefaultStopLiveLocationShareTaskTest { val expectedSendParams = SendStateTask.Params( roomId = params.roomId, stateKey = A_USER_ID, - eventType = EventType.STATE_ROOM_BEACON_INFO.first(), + eventType = EventType.STATE_ROOM_BEACON_INFO.stable, body = expectedBeaconContent ) fakeSendStateTask.verifyExecuteRetry( diff --git a/matrix-sdk-android/src/test/java/org/matrix/android/sdk/internal/session/room/location/LiveLocationShareRedactionEventProcessorTest.kt b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/internal/session/room/location/LiveLocationShareRedactionEventProcessorTest.kt index 24d9c30039..d6edb69d93 100644 --- a/matrix-sdk-android/src/test/java/org/matrix/android/sdk/internal/session/room/location/LiveLocationShareRedactionEventProcessorTest.kt +++ b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/internal/session/room/location/LiveLocationShareRedactionEventProcessorTest.kt @@ -79,7 +79,7 @@ class LiveLocationShareRedactionEventProcessorTest { @Test fun `given a redacted live location share event when processing it then related summaries are deleted from database`() = runTest { val event = Event(eventId = AN_EVENT_ID, redacts = A_REDACTED_EVENT_ID) - val redactedEventEntity = EventEntity(eventId = A_REDACTED_EVENT_ID, type = EventType.STATE_ROOM_BEACON_INFO.first()) + val redactedEventEntity = EventEntity(eventId = A_REDACTED_EVENT_ID, type = EventType.STATE_ROOM_BEACON_INFO.stable) fakeRealm.givenWhere() .givenEqualTo(EventEntityFields.EVENT_ID, A_REDACTED_EVENT_ID) .givenFindFirst(redactedEventEntity) diff --git a/vector/src/main/java/im/vector/app/core/extensions/TimelineEvent.kt b/vector/src/main/java/im/vector/app/core/extensions/TimelineEvent.kt index d907f39ee3..c94f9cd921 100644 --- a/vector/src/main/java/im/vector/app/core/extensions/TimelineEvent.kt +++ b/vector/src/main/java/im/vector/app/core/extensions/TimelineEvent.kt @@ -19,7 +19,6 @@ package im.vector.app.core.extensions import im.vector.app.features.voicebroadcast.VoiceBroadcastConstants import im.vector.app.features.voicebroadcast.model.MessageVoiceBroadcastInfoContent import org.matrix.android.sdk.api.session.events.model.EventType -import org.matrix.android.sdk.api.session.events.model.toContent import org.matrix.android.sdk.api.session.events.model.toModel import org.matrix.android.sdk.api.session.room.model.message.MessageContent import org.matrix.android.sdk.api.session.room.send.SendState @@ -28,7 +27,7 @@ import org.matrix.android.sdk.api.session.room.timeline.getLastMessageContent fun TimelineEvent.canReact(): Boolean { // Only event of type EventType.MESSAGE, EventType.STICKER and EventType.POLL_START are supported for the moment - return root.getClearType() in listOf(EventType.MESSAGE, EventType.STICKER) + EventType.POLL_START && + return root.getClearType() in listOf(EventType.MESSAGE, EventType.STICKER) + EventType.POLL_START.values && root.sendState == SendState.SYNCED && !root.isRedacted() } @@ -41,7 +40,7 @@ fun TimelineEvent.getVectorLastMessageContent(): MessageContent? { // Iterate on event types which are not part of the matrix sdk, otherwise fallback to the sdk method return when (root.getClearType()) { VoiceBroadcastConstants.STATE_ROOM_VOICE_BROADCAST_INFO -> { - (annotations?.editSummary?.latestEdit?.getClearContent()?.toModel().toContent().toModel() + (annotations?.editSummary?.latestEdit?.getClearContent()?.toModel() ?: root.getClearContent().toModel()) } else -> getLastMessageContent() diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineFragment.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineFragment.kt index 9bed0aae04..34d7e45028 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineFragment.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineFragment.kt @@ -1774,7 +1774,7 @@ class TimelineFragment : timelineViewModel.handle(RoomDetailAction.UpdateQuickReactAction(action.eventId, action.clickedOn, action.add)) } is EventSharedAction.Edit -> { - if (action.eventType in EventType.POLL_START) { + if (action.eventType in EventType.POLL_START.values) { navigator.openCreatePoll(requireContext(), timelineArgs.roomId, action.eventId, PollMode.EDIT) } else if (withState(messageComposerViewModel) { it.isVoiceMessageIdle }) { messageComposerViewModel.handle(MessageComposerAction.EnterEditMode(action.eventId)) diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/action/CheckIfCanRedactEventUseCase.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/action/CheckIfCanRedactEventUseCase.kt index 8cb82691d9..dedd4a53c8 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/action/CheckIfCanRedactEventUseCase.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/action/CheckIfCanRedactEventUseCase.kt @@ -33,8 +33,8 @@ class CheckIfCanRedactEventUseCase @Inject constructor( EventType.STICKER, VoiceBroadcastConstants.STATE_ROOM_VOICE_BROADCAST_INFO, ) + - EventType.POLL_START + - EventType.STATE_ROOM_BEACON_INFO + EventType.POLL_START.values + + EventType.STATE_ROOM_BEACON_INFO.values return event.root.getClearType() in canRedactEventTypes && // Message sent by the current user can always be redacted, else check permission for messages sent by other users diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/action/CheckIfCanReplyEventUseCase.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/action/CheckIfCanReplyEventUseCase.kt index c312ef31b7..a9df059cc1 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/action/CheckIfCanReplyEventUseCase.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/action/CheckIfCanReplyEventUseCase.kt @@ -26,7 +26,7 @@ class CheckIfCanReplyEventUseCase @Inject constructor() { fun execute(event: TimelineEvent, messageContent: MessageContent?, actionPermissions: ActionPermissions): Boolean { // Only EventType.MESSAGE, EventType.POLL_START and EventType.STATE_ROOM_BEACON_INFO event types are supported for the moment - if (event.root.getClearType() !in EventType.STATE_ROOM_BEACON_INFO + EventType.POLL_START + EventType.MESSAGE) return false + if (event.root.getClearType() !in EventType.STATE_ROOM_BEACON_INFO.values + EventType.POLL_START.values + EventType.MESSAGE) return false if (!actionPermissions.canSendMessage) return false return when (messageContent?.msgType) { MessageType.MSGTYPE_TEXT, diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/action/MessageActionsViewModel.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/action/MessageActionsViewModel.kt index 0c44ee386d..a6d7e8386f 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/action/MessageActionsViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/action/MessageActionsViewModel.kt @@ -215,7 +215,7 @@ class MessageActionsViewModel @AssistedInject constructor( EventType.CALL_ANSWER -> { noticeEventFormatter.format(timelineEvent, room?.roomSummary()?.isDirect.orFalse()) } - in EventType.POLL_START -> { + in EventType.POLL_START.values -> { timelineEvent.root.getClearContent().toModel(catchError = true) ?.getBestPollCreationInfo()?.question?.getBestQuestion() ?: "" } @@ -383,7 +383,7 @@ class MessageActionsViewModel @AssistedInject constructor( } if (canRedact(timelineEvent, actionPermissions)) { - if (timelineEvent.root.getClearType() in EventType.POLL_START) { + if (timelineEvent.root.getClearType() in EventType.POLL_START.values) { add( EventSharedAction.Redact( eventId, @@ -530,13 +530,13 @@ class MessageActionsViewModel @AssistedInject constructor( private fun canViewReactions(event: TimelineEvent): Boolean { // Only event of type EventType.MESSAGE, EventType.STICKER and EventType.POLL_START are supported for the moment - if (event.root.getClearType() !in listOf(EventType.MESSAGE, EventType.STICKER) + EventType.POLL_START) return false + if (event.root.getClearType() !in listOf(EventType.MESSAGE, EventType.STICKER) + EventType.POLL_START.values) return false return event.annotations?.reactionsSummary?.isNotEmpty() ?: false } private fun canEdit(event: TimelineEvent, myUserId: String, actionPermissions: ActionPermissions): Boolean { // Only event of type EventType.MESSAGE and EventType.POLL_START are supported for the moment - if (event.root.getClearType() !in listOf(EventType.MESSAGE) + EventType.POLL_START) return false + if (event.root.getClearType() !in listOf(EventType.MESSAGE) + EventType.POLL_START.values) return false if (!actionPermissions.canSendMessage) return false // TODO if user is admin or moderator val messageContent = event.root.getClearContent().toModel() @@ -582,14 +582,14 @@ class MessageActionsViewModel @AssistedInject constructor( } private fun canEndPoll(event: TimelineEvent, actionPermissions: ActionPermissions): Boolean { - return event.root.getClearType() in EventType.POLL_START && + return event.root.getClearType() in EventType.POLL_START.values && canRedact(event, actionPermissions) && event.annotations?.pollResponseSummary?.closedTime == null } private fun canEditPoll(event: TimelineEvent): Boolean { - return event.root.getClearType() in EventType.POLL_START && + return event.root.getClearType() in EventType.POLL_START.values && event.annotations?.pollResponseSummary?.closedTime == null && - event.annotations?.pollResponseSummary?.aggregatedContent?.totalVotes ?: 0 == 0 + (event.annotations?.pollResponseSummary?.aggregatedContent?.totalVotes ?: 0) == 0 } } diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/MessageItemFactory.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/MessageItemFactory.kt index 373410775b..42e031a3c4 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/MessageItemFactory.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/MessageItemFactory.kt @@ -45,6 +45,7 @@ import im.vector.app.features.home.room.detail.timeline.helper.MessageInformatio import im.vector.app.features.home.room.detail.timeline.helper.MessageItemAttributesFactory import im.vector.app.features.home.room.detail.timeline.helper.TimelineMediaSizeProvider import im.vector.app.features.home.room.detail.timeline.item.AbsMessageItem +import im.vector.app.features.home.room.detail.timeline.item.BaseEventItem import im.vector.app.features.home.room.detail.timeline.item.MessageAudioItem import im.vector.app.features.home.room.detail.timeline.item.MessageAudioItem_ import im.vector.app.features.home.room.detail.timeline.item.MessageFileItem @@ -324,9 +325,11 @@ class MessageItemFactory @Inject constructor( informationData: MessageInformationData, highlight: Boolean, attributes: AbsMessageItem.Attributes - ): MessageVoiceItem? { + ): BaseEventItem<*>? { // Do not display voice broadcast messages - if (params.event.root.asMessageAudioEvent().isVoiceBroadcast()) return null + if (params.event.root.asMessageAudioEvent().isVoiceBroadcast()) { + return noticeItemFactory.create(params) + } val fileUrl = getAudioFileUrl(messageContent, informationData) val playbackControlButtonClickListener = createOnPlaybackButtonClickListener(messageContent, informationData, params) diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/TimelineItemFactory.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/TimelineItemFactory.kt index 31ff257214..ae3ea143a7 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/TimelineItemFactory.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/TimelineItemFactory.kt @@ -88,7 +88,7 @@ class TimelineItemFactory @Inject constructor( EventType.STATE_ROOM_ENCRYPTION -> encryptionItemFactory.create(params) // State room create EventType.STATE_ROOM_CREATE -> roomCreateItemFactory.create(params) - in EventType.STATE_ROOM_BEACON_INFO -> messageItemFactory.create(params) + in EventType.STATE_ROOM_BEACON_INFO.values -> messageItemFactory.create(params) VoiceBroadcastConstants.STATE_ROOM_VOICE_BROADCAST_INFO -> messageItemFactory.create(params) // Unhandled state event types else -> { @@ -101,7 +101,7 @@ class TimelineItemFactory @Inject constructor( when (event.root.getClearType()) { // Message itemsX EventType.STICKER, - in EventType.POLL_START, + in EventType.POLL_START.values, EventType.MESSAGE -> messageItemFactory.create(params) EventType.REDACTION, EventType.KEY_VERIFICATION_ACCEPT, @@ -114,9 +114,9 @@ class TimelineItemFactory @Inject constructor( EventType.CALL_SELECT_ANSWER, EventType.CALL_NEGOTIATE, EventType.REACTION, - in EventType.POLL_RESPONSE, - in EventType.POLL_END -> noticeItemFactory.create(params) - in EventType.BEACON_LOCATION_DATA -> { + in EventType.POLL_RESPONSE.values, + in EventType.POLL_END.values -> noticeItemFactory.create(params) + in EventType.BEACON_LOCATION_DATA.values -> { if (event.root.isRedacted()) { messageItemFactory.create(params) } else { diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/VoiceBroadcastItemFactory.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/VoiceBroadcastItemFactory.kt index e4f7bed72f..cc3a015120 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/VoiceBroadcastItemFactory.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/VoiceBroadcastItemFactory.kt @@ -23,6 +23,7 @@ import im.vector.app.features.home.room.detail.timeline.helper.AvatarSizeProvide import im.vector.app.features.home.room.detail.timeline.helper.VoiceBroadcastEventsGroup import im.vector.app.features.home.room.detail.timeline.item.AbsMessageItem import im.vector.app.features.home.room.detail.timeline.item.AbsMessageVoiceBroadcastItem +import im.vector.app.features.home.room.detail.timeline.item.BaseEventItem import im.vector.app.features.home.room.detail.timeline.item.MessageVoiceBroadcastListeningItem import im.vector.app.features.home.room.detail.timeline.item.MessageVoiceBroadcastListeningItem_ import im.vector.app.features.home.room.detail.timeline.item.MessageVoiceBroadcastRecordingItem @@ -47,6 +48,7 @@ class VoiceBroadcastItemFactory @Inject constructor( private val voiceBroadcastRecorder: VoiceBroadcastRecorder?, private val voiceBroadcastPlayer: VoiceBroadcastPlayer, private val playbackTracker: AudioMessagePlaybackTracker, + private val noticeItemFactory: NoticeItemFactory, ) { fun create( @@ -54,9 +56,11 @@ class VoiceBroadcastItemFactory @Inject constructor( messageContent: MessageVoiceBroadcastInfoContent, highlight: Boolean, attributes: AbsMessageItem.Attributes, - ): AbsMessageVoiceBroadcastItem<*>? { + ): BaseEventItem<*>? { // Only display item of the initial event with updated data - if (messageContent.voiceBroadcastState != VoiceBroadcastState.STARTED) return null + if (messageContent.voiceBroadcastState != VoiceBroadcastState.STARTED) { + return noticeItemFactory.create(params) + } val voiceBroadcastEventsGroup = params.eventsGroup?.let { VoiceBroadcastEventsGroup(it) } ?: return null val voiceBroadcastEvent = voiceBroadcastEventsGroup.getLastDisplayableEvent().root.asVoiceBroadcastEvent() ?: return null diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/format/DisplayableEventFormatter.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/format/DisplayableEventFormatter.kt index eb531b6f1b..aaa0fc10c9 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/format/DisplayableEventFormatter.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/format/DisplayableEventFormatter.kt @@ -122,17 +122,17 @@ class DisplayableEventFormatter @Inject constructor( EventType.CALL_CANDIDATES -> { span { } } - in EventType.POLL_START -> { + in EventType.POLL_START.values -> { timelineEvent.root.getClearContent().toModel(catchError = true)?.getBestPollCreationInfo()?.question?.getBestQuestion() ?: stringProvider.getString(R.string.sent_a_poll) } - in EventType.POLL_RESPONSE -> { + in EventType.POLL_RESPONSE.values -> { stringProvider.getString(R.string.poll_response_room_list_preview) } - in EventType.POLL_END -> { + in EventType.POLL_END.values -> { stringProvider.getString(R.string.poll_end_room_list_preview) } - in EventType.STATE_ROOM_BEACON_INFO -> { + in EventType.STATE_ROOM_BEACON_INFO.values -> { simpleFormat(senderName, stringProvider.getString(R.string.sent_live_location), appendAuthor) } else -> { @@ -220,17 +220,17 @@ class DisplayableEventFormatter @Inject constructor( emojiSpanify.spanify(stringProvider.getString(R.string.sent_a_reaction, it.key)) } ?: span { } } - in EventType.POLL_START -> { + in EventType.POLL_START.values -> { event.getClearContent().toModel(catchError = true)?.pollCreationInfo?.question?.question ?: stringProvider.getString(R.string.sent_a_poll) } - in EventType.POLL_RESPONSE -> { + in EventType.POLL_RESPONSE.values -> { stringProvider.getString(R.string.poll_response_room_list_preview) } - in EventType.POLL_END -> { + in EventType.POLL_END.values -> { stringProvider.getString(R.string.poll_end_room_list_preview) } - in EventType.STATE_ROOM_BEACON_INFO -> { + in EventType.STATE_ROOM_BEACON_INFO.values -> { stringProvider.getString(R.string.sent_live_location) } else -> { diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/format/NoticeEventFormatter.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/format/NoticeEventFormatter.kt index 19f9fc17a3..3f702ed72d 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/format/NoticeEventFormatter.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/format/NoticeEventFormatter.kt @@ -21,6 +21,7 @@ import im.vector.app.R import im.vector.app.core.resources.StringProvider import im.vector.app.features.roomprofile.permissions.RoleFormatter import im.vector.app.features.settings.VectorPreferences +import im.vector.app.features.voicebroadcast.VoiceBroadcastConstants import org.matrix.android.sdk.api.crypto.MXCRYPTO_ALGORITHM_MEGOLM import org.matrix.android.sdk.api.extensions.appendNl import org.matrix.android.sdk.api.extensions.orFalse @@ -106,9 +107,10 @@ class NoticeEventFormatter @Inject constructor( EventType.STATE_SPACE_PARENT, EventType.REDACTION, EventType.STICKER, - in EventType.POLL_RESPONSE, - in EventType.POLL_END, - in EventType.BEACON_LOCATION_DATA -> formatDebug(timelineEvent.root) + in EventType.POLL_RESPONSE.values, + in EventType.POLL_END.values, + in EventType.BEACON_LOCATION_DATA.values, + VoiceBroadcastConstants.STATE_ROOM_VOICE_BROADCAST_INFO -> formatDebug(timelineEvent.root) else -> { Timber.v("Type $type not handled by this formatter") null diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/helper/TimelineDisplayableEvents.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/helper/TimelineDisplayableEvents.kt index 2411cb3877..51e961f247 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/helper/TimelineDisplayableEvents.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/helper/TimelineDisplayableEvents.kt @@ -54,9 +54,9 @@ object TimelineDisplayableEvents { EventType.KEY_VERIFICATION_CANCEL, VoiceBroadcastConstants.STATE_ROOM_VOICE_BROADCAST_INFO, ) + - EventType.POLL_START + - EventType.STATE_ROOM_BEACON_INFO + - EventType.BEACON_LOCATION_DATA + EventType.POLL_START.values + + EventType.STATE_ROOM_BEACON_INFO.values + + EventType.BEACON_LOCATION_DATA.values } fun TimelineEvent.isRoomConfiguration(roomCreatorUserId: String?): Boolean { diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/helper/TimelineEventVisibilityHelper.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/helper/TimelineEventVisibilityHelper.kt index d22b649b36..1360151074 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/helper/TimelineEventVisibilityHelper.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/helper/TimelineEventVisibilityHelper.kt @@ -18,6 +18,11 @@ package im.vector.app.features.home.room.detail.timeline.helper import im.vector.app.core.extensions.localDateTime import im.vector.app.core.resources.UserPreferencesProvider +import im.vector.app.features.voicebroadcast.VoiceBroadcastConstants +import im.vector.app.features.voicebroadcast.isVoiceBroadcast +import im.vector.app.features.voicebroadcast.model.VoiceBroadcastState +import im.vector.app.features.voicebroadcast.model.asVoiceBroadcastEvent +import org.matrix.android.sdk.api.extensions.orFalse import org.matrix.android.sdk.api.session.events.model.Event import org.matrix.android.sdk.api.session.events.model.EventType import org.matrix.android.sdk.api.session.events.model.RelationType @@ -28,6 +33,7 @@ import org.matrix.android.sdk.api.session.events.model.toModel import org.matrix.android.sdk.api.session.room.model.Membership import org.matrix.android.sdk.api.session.room.model.RoomMemberContent import org.matrix.android.sdk.api.session.room.model.localecho.RoomLocalEcho +import org.matrix.android.sdk.api.session.room.model.message.asMessageAudioEvent import org.matrix.android.sdk.api.session.room.timeline.TimelineEvent import javax.inject.Inject @@ -242,10 +248,19 @@ class TimelineEventVisibilityHelper @Inject constructor( } else root.eventId != rootThreadEventId } - if (root.getClearType() in EventType.BEACON_LOCATION_DATA) { + if (root.getClearType() in EventType.BEACON_LOCATION_DATA.values) { return !root.isRedacted() } + if (root.getClearType() == VoiceBroadcastConstants.STATE_ROOM_VOICE_BROADCAST_INFO && + root.asVoiceBroadcastEvent()?.content?.voiceBroadcastState != VoiceBroadcastState.STARTED) { + return true + } + + if (root.asMessageAudioEvent()?.isVoiceBroadcast().orFalse()) { + return true + } + return false } diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/style/TimelineMessageLayoutFactory.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/style/TimelineMessageLayoutFactory.kt index 379e5b3b91..c207a5f67e 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/style/TimelineMessageLayoutFactory.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/style/TimelineMessageLayoutFactory.kt @@ -47,8 +47,10 @@ class TimelineMessageLayoutFactory @Inject constructor( private val EVENT_TYPES_WITH_BUBBLE_LAYOUT = setOf( EventType.MESSAGE, EventType.ENCRYPTED, - EventType.STICKER - ) + EventType.POLL_START + EventType.STATE_ROOM_BEACON_INFO + EventType.STICKER, + ) + + EventType.POLL_START.values + + EventType.STATE_ROOM_BEACON_INFO.values // Can't be rendered in bubbles, so get back to default layout private val MSG_TYPES_WITHOUT_BUBBLE_LAYOUT = setOf( diff --git a/vector/src/main/java/im/vector/app/features/location/LocationSharingViewModel.kt b/vector/src/main/java/im/vector/app/features/location/LocationSharingViewModel.kt index 4c7abd99b8..cdef7d3302 100644 --- a/vector/src/main/java/im/vector/app/features/location/LocationSharingViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/location/LocationSharingViewModel.kt @@ -83,7 +83,7 @@ class LocationSharingViewModel @AssistedInject constructor( .distinctUntilChanged() .setOnEach { val powerLevelsHelper = PowerLevelsHelper(it) - val canShareLiveLocation = EventType.STATE_ROOM_BEACON_INFO + val canShareLiveLocation = EventType.STATE_ROOM_BEACON_INFO.values .all { beaconInfoType -> powerLevelsHelper.isUserAllowedToSend(session.myUserId, true, beaconInfoType) } diff --git a/vector/src/main/java/im/vector/app/features/notifications/NotifiableEventResolver.kt b/vector/src/main/java/im/vector/app/features/notifications/NotifiableEventResolver.kt index ba1d5c7f6f..d28ab22684 100644 --- a/vector/src/main/java/im/vector/app/features/notifications/NotifiableEventResolver.kt +++ b/vector/src/main/java/im/vector/app/features/notifications/NotifiableEventResolver.kt @@ -66,7 +66,7 @@ class NotifiableEventResolver @Inject constructor( ) { private val nonEncryptedNotifiableEventTypes: List = - listOf(EventType.MESSAGE) + EventType.POLL_START + EventType.STATE_ROOM_BEACON_INFO + listOf(EventType.MESSAGE) + EventType.POLL_START.values + EventType.STATE_ROOM_BEACON_INFO.values suspend fun resolveEvent(event: Event, session: Session, isNoisy: Boolean): NotifiableEvent? { val roomID = event.roomId ?: return null diff --git a/vector/src/test/java/im/vector/app/features/home/room/detail/timeline/action/CheckIfCanRedactEventUseCaseTest.kt b/vector/src/test/java/im/vector/app/features/home/room/detail/timeline/action/CheckIfCanRedactEventUseCaseTest.kt index e2157c3af0..bedb289a39 100644 --- a/vector/src/test/java/im/vector/app/features/home/room/detail/timeline/action/CheckIfCanRedactEventUseCaseTest.kt +++ b/vector/src/test/java/im/vector/app/features/home/room/detail/timeline/action/CheckIfCanRedactEventUseCaseTest.kt @@ -35,8 +35,13 @@ class CheckIfCanRedactEventUseCaseTest { @Test fun `given an event which can be redacted and owned by user when use case executes then the result is true`() { - val canRedactEventTypes = listOf(EventType.MESSAGE, EventType.STICKER, VoiceBroadcastConstants.STATE_ROOM_VOICE_BROADCAST_INFO) + - EventType.POLL_START + EventType.STATE_ROOM_BEACON_INFO + val canRedactEventTypes = listOf( + EventType.MESSAGE, + EventType.STICKER, + VoiceBroadcastConstants.STATE_ROOM_VOICE_BROADCAST_INFO + ) + + EventType.POLL_START.values + + EventType.STATE_ROOM_BEACON_INFO.values canRedactEventTypes.forEach { eventType -> val event = givenAnEvent( diff --git a/vector/src/test/java/im/vector/app/features/home/room/detail/timeline/action/CheckIfCanReplyEventUseCaseTest.kt b/vector/src/test/java/im/vector/app/features/home/room/detail/timeline/action/CheckIfCanReplyEventUseCaseTest.kt index 83d23681fc..51082e0e06 100644 --- a/vector/src/test/java/im/vector/app/features/home/room/detail/timeline/action/CheckIfCanReplyEventUseCaseTest.kt +++ b/vector/src/test/java/im/vector/app/features/home/room/detail/timeline/action/CheckIfCanReplyEventUseCaseTest.kt @@ -43,7 +43,7 @@ class CheckIfCanReplyEventUseCaseTest { @Test fun `given reply is allowed for the event type when use case is executed then result is true`() { - val eventTypes = EventType.STATE_ROOM_BEACON_INFO + EventType.POLL_START + EventType.MESSAGE + val eventTypes = EventType.STATE_ROOM_BEACON_INFO.values + EventType.POLL_START.values + EventType.MESSAGE eventTypes.forEach { eventType -> val event = givenAnEvent(eventType) diff --git a/vector/src/test/java/im/vector/app/test/fakes/FakeCreatePollViewStates.kt b/vector/src/test/java/im/vector/app/test/fakes/FakeCreatePollViewStates.kt index 04f3526602..42a500671b 100644 --- a/vector/src/test/java/im/vector/app/test/fakes/FakeCreatePollViewStates.kt +++ b/vector/src/test/java/im/vector/app/test/fakes/FakeCreatePollViewStates.kt @@ -63,7 +63,7 @@ object FakeCreatePollViewStates { ) private val A_POLL_START_EVENT = Event( - type = EventType.POLL_START.first(), + type = EventType.POLL_START.stable, eventId = A_FAKE_EVENT_ID, originServerTs = 1652435922563, senderId = A_FAKE_USER_ID, @@ -80,8 +80,8 @@ object FakeCreatePollViewStates { ) val initialCreatePollViewState = CreatePollViewState(createPollArgs).copy( - canCreatePoll = false, - canAddMoreOptions = true + canCreatePoll = false, + canAddMoreOptions = true ) val pollViewStateWithOnlyQuestion = initialCreatePollViewState.copy(