Use StableUnstableId object for some event types

This commit is contained in:
Florian Renaud 2022-11-18 16:28:46 +01:00
parent f4b948af9d
commit eb12b1c99b
36 changed files with 104 additions and 97 deletions

View File

@ -66,7 +66,7 @@ class PollAggregationTest : InstrumentedTest {
val aliceEventsListener = object : Timeline.Listener { val aliceEventsListener = object : Timeline.Listener {
override fun onTimelineUpdated(snapshot: List<TimelineEvent>) { override fun onTimelineUpdated(snapshot: List<TimelineEvent>) {
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 pollEventId = pollEvent.eventId
val pollContent = pollEvent.root.content?.toModel<MessagePollContent>() val pollContent = pollEvent.root.content?.toModel<MessagePollContent>()
val pollSummary = pollEvent.annotations?.pollResponseSummary val pollSummary = pollEvent.annotations?.pollResponseSummary

View File

@ -390,11 +390,11 @@ 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.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? { fun Event.getRelationContent(): RelationDefaultContent? {
return if (isEncrypted()) { return if (isEncrypted()) {
@ -404,7 +404,7 @@ fun Event.getRelationContent(): RelationDefaultContent? {
// Special cases when there is only a local msgtype for some event types // Special cases when there is only a local msgtype for some event types
when (getClearType()) { when (getClearType()) {
EventType.STICKER -> getClearContent().toModel<MessageStickerContent>()?.relatesTo EventType.STICKER -> getClearContent().toModel<MessageStickerContent>()?.relatesTo
in EventType.BEACON_LOCATION_DATA -> getClearContent().toModel<MessageBeaconLocationDataContent>()?.relatesTo in EventType.BEACON_LOCATION_DATA.values -> getClearContent().toModel<MessageBeaconLocationDataContent>()?.relatesTo
else -> getClearContent()?.get("m.relates_to")?.toContent().toModel() else -> getClearContent()?.get("m.relates_to")?.toContent().toModel()
} }
} }
@ -451,7 +451,7 @@ fun Event.getPollContent(): MessagePollContent? {
} }
fun Event.supportsNotification() = 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() = fun Event.isContentReportable() =
this.getClearType() in EventType.MESSAGE + EventType.STATE_ROOM_BEACON_INFO this.getClearType() in EventType.MESSAGE + EventType.STATE_ROOM_BEACON_INFO.values

View File

@ -49,11 +49,10 @@ object EventType {
const val STATE_ROOM_JOIN_RULES = "m.room.join_rules" const val STATE_ROOM_JOIN_RULES = "m.room.join_rules"
const val STATE_ROOM_GUEST_ACCESS = "m.room.guest_access" const val STATE_ROOM_GUEST_ACCESS = "m.room.guest_access"
const val STATE_ROOM_POWER_LEVELS = "m.room.power_levels" 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 STATE_ROOM_BEACON_INFO = StableUnstableId(stable = "m.beacon_info", unstable = "org.matrix.msc3672.beacon_info")
val BEACON_LOCATION_DATA = listOf("org.matrix.msc3672.beacon", "m.beacon") 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_CHILD = "m.space.child"
const val STATE_SPACE_PARENT = "m.space.parent" const val STATE_SPACE_PARENT = "m.space.parent"
/** /**
@ -81,8 +80,7 @@ object EventType {
const val CALL_NEGOTIATE = "m.call.negotiate" const val CALL_NEGOTIATE = "m.call.negotiate"
const val CALL_REJECT = "m.call.reject" const val CALL_REJECT = "m.call.reject"
const val CALL_HANGUP = "m.call.hangup" const val CALL_HANGUP = "m.call.hangup"
const val CALL_ASSERTED_IDENTITY = "m.call.asserted_identity" val CALL_ASSERTED_IDENTITY = StableUnstableId(stable = "m.call.asserted_identity", unstable = "org.matrix.call.asserted_identity")
const val CALL_ASSERTED_IDENTITY_PREFIX = "org.matrix.call.asserted_identity"
// This type is not processed by the client, just sent to the server // This type is not processed by the client, just sent to the server
const val CALL_REPLACES = "m.call.replaces" const val CALL_REPLACES = "m.call.replaces"
@ -90,10 +88,7 @@ object EventType {
// Key share events // Key share events
const val ROOM_KEY_REQUEST = "m.room_key_request" const val ROOM_KEY_REQUEST = "m.room_key_request"
const val FORWARDED_ROOM_KEY = "m.forwarded_room_key" const val FORWARDED_ROOM_KEY = "m.forwarded_room_key"
val ROOM_KEY_WITHHELD = StableUnstableId( val ROOM_KEY_WITHHELD = StableUnstableId(stable = "m.room_key.withheld", unstable = "org.matrix.room_key.withheld")
stable = "m.room_key.withheld",
unstable = "org.matrix.room_key.withheld"
)
const val REQUEST_SECRET = "m.secret.request" const val REQUEST_SECRET = "m.secret.request"
const val SEND_SECRET = "m.secret.send" const val SEND_SECRET = "m.secret.send"
@ -111,9 +106,9 @@ object EventType {
const val REACTION = "m.reaction" const val REACTION = "m.reaction"
// Poll // Poll
val POLL_START = listOf("org.matrix.msc3381.poll.start", "m.poll.start") val POLL_START = StableUnstableId(stable = "m.poll.start", unstable = "org.matrix.msc3381.poll.start")
val POLL_RESPONSE = listOf("org.matrix.msc3381.poll.response", "m.poll.response") val POLL_RESPONSE = StableUnstableId(stable = "m.poll.response", unstable = "org.matrix.msc3381.poll.response")
val POLL_END = listOf("org.matrix.msc3381.poll.end", "m.poll.end") val POLL_END = StableUnstableId(stable = "m.poll.end", unstable = "org.matrix.msc3381.poll.end")
// Unwedging // Unwedging
internal const val DUMMY = "m.dummy" internal const val DUMMY = "m.dummy"

View File

@ -33,5 +33,7 @@ object RoomSummaryConstants {
EventType.ENCRYPTED, EventType.ENCRYPTED,
EventType.STICKER, EventType.STICKER,
EventType.REACTION EventType.REACTION
) + EventType.POLL_START + EventType.STATE_ROOM_BEACON_INFO ) +
EventType.POLL_START.values +
EventType.STATE_ROOM_BEACON_INFO.values
} }

View File

@ -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 // Polls/Beacon are not message contents like others as there is no msgtype subtype to discriminate moshi parsing
// so toModel<MessageContent> won't parse them correctly // so toModel<MessageContent> won't parse them correctly
// It's discriminated on event type instead. Maybe it shouldn't be MessageContent at all to avoid confusion? // 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<MessagePollContent>() in EventType.POLL_START.values -> (getLastEditNewContent() ?: root.getClearContent()).toModel<MessagePollContent>()
in EventType.STATE_ROOM_BEACON_INFO -> (getLastEditNewContent() ?: root.getClearContent()).toModel<MessageBeaconInfoContent>() in EventType.STATE_ROOM_BEACON_INFO.values -> (getLastEditNewContent() ?: root.getClearContent()).toModel<MessageBeaconInfoContent>()
in EventType.BEACON_LOCATION_DATA -> (getLastEditNewContent() ?: root.getClearContent()).toModel<MessageBeaconLocationDataContent>() in EventType.BEACON_LOCATION_DATA.values -> (getLastEditNewContent() ?: root.getClearContent()).toModel<MessageBeaconLocationDataContent>()
else -> (getLastEditNewContent() ?: root.getClearContent()).toModel() else -> (getLastEditNewContent() ?: root.getClearContent()).toModel()
} }
} }

View File

@ -41,9 +41,8 @@ internal class CallEventProcessor @Inject constructor(private val callSignalingH
EventType.CALL_INVITE, EventType.CALL_INVITE,
EventType.CALL_HANGUP, EventType.CALL_HANGUP,
EventType.ENCRYPTED, EventType.ENCRYPTED,
EventType.CALL_ASSERTED_IDENTITY, ) +
EventType.CALL_ASSERTED_IDENTITY_PREFIX EventType.CALL_ASSERTED_IDENTITY.values
)
private val eventsToPostProcess = mutableListOf<Event>() private val eventsToPostProcess = mutableListOf<Event>()

View File

@ -84,8 +84,7 @@ internal class CallSignalingHandler @Inject constructor(
EventType.CALL_NEGOTIATE -> { EventType.CALL_NEGOTIATE -> {
handleCallNegotiateEvent(event) handleCallNegotiateEvent(event)
} }
EventType.CALL_ASSERTED_IDENTITY, in EventType.CALL_ASSERTED_IDENTITY.values -> {
EventType.CALL_ASSERTED_IDENTITY_PREFIX -> {
handleCallAssertedIdentityEvent(event) handleCallAssertedIdentityEvent(event)
} }
} }

View File

@ -56,8 +56,8 @@ internal class DefaultProcessEventForPushTask @Inject constructor(
val allEvents = (newJoinEvents + inviteEvents).filter { event -> val allEvents = (newJoinEvents + inviteEvents).filter { event ->
when (event.type) { when (event.type) {
in EventType.POLL_START, in EventType.POLL_START.values,
in EventType.STATE_ROOM_BEACON_INFO, in EventType.STATE_ROOM_BEACON_INFO.values,
EventType.MESSAGE, EventType.MESSAGE,
EventType.REDACTION, EventType.REDACTION,
EventType.ENCRYPTED, EventType.ENCRYPTED,

View File

@ -91,7 +91,12 @@ internal class EventRelationsAggregationProcessor @Inject constructor(
EventType.KEY_VERIFICATION_READY, EventType.KEY_VERIFICATION_READY,
EventType.KEY_VERIFICATION_KEY, EventType.KEY_VERIFICATION_KEY,
EventType.ENCRYPTED 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 { override fun shouldProcess(eventId: String, eventType: String, insertType: EventInsertType): Boolean {
return allowedTypes.contains(eventType) 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() val content: MessagePollContent? = event.content.toModel()
if (content?.relatesTo?.type == RelationType.REPLACE) { if (content?.relatesTo?.type == RelationType.REPLACE) {
Timber.v("###REPLACE in room $roomId for event ${event.eventId}") 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) handleReplace(realm, event, roomId, isLocalEcho, content.relatesTo.eventId)
} }
} }
in EventType.POLL_RESPONSE -> { in EventType.POLL_RESPONSE.values -> {
event.content.toModel<MessagePollResponseContent>(catchError = true)?.let { event.content.toModel<MessagePollResponseContent>(catchError = true)?.let {
sessionManager.getSessionComponent(sessionId)?.session()?.let { session -> sessionManager.getSessionComponent(sessionId)?.session()?.let { session ->
pollAggregationProcessor.handlePollResponseEvent(session, realm, event) pollAggregationProcessor.handlePollResponseEvent(session, realm, event)
} }
} }
} }
in EventType.POLL_END -> { in EventType.POLL_END.values -> {
sessionManager.getSessionComponent(sessionId)?.session()?.let { session -> sessionManager.getSessionComponent(sessionId)?.session()?.let { session ->
getPowerLevelsHelper(event.roomId)?.let { getPowerLevelsHelper(event.roomId)?.let {
pollAggregationProcessor.handlePollEndEvent(session, it, realm, event) pollAggregationProcessor.handlePollEndEvent(session, it, realm, event)
} }
} }
} }
in EventType.STATE_ROOM_BEACON_INFO -> { in EventType.STATE_ROOM_BEACON_INFO.values -> {
event.content.toModel<MessageBeaconInfoContent>(catchError = true)?.let { event.content.toModel<MessageBeaconInfoContent>(catchError = true)?.let {
liveLocationAggregationProcessor.handleBeaconInfo(realm, event, it, roomId, isLocalEcho) liveLocationAggregationProcessor.handleBeaconInfo(realm, event, it, roomId, isLocalEcho)
} }
} }
in EventType.BEACON_LOCATION_DATA -> { in EventType.BEACON_LOCATION_DATA.values -> {
handleBeaconLocationData(event, realm, roomId, isLocalEcho) handleBeaconLocationData(event, realm, roomId, isLocalEcho)
} }
else -> Timber.v("UnHandled event ${event.eventId}") 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) pollAggregationProcessor.handlePollStartEvent(realm, event)
} }

View File

@ -39,7 +39,7 @@ internal class DefaultGetActiveBeaconInfoForUserTask @Inject constructor(
) : GetActiveBeaconInfoForUserTask { ) : GetActiveBeaconInfoForUserTask {
override suspend fun execute(params: GetActiveBeaconInfoForUserTask.Params): Event? { override suspend fun execute(params: GetActiveBeaconInfoForUserTask.Params): Event? {
return EventType.STATE_ROOM_BEACON_INFO return EventType.STATE_ROOM_BEACON_INFO.values
.mapNotNull { .mapNotNull {
stateEventDataSource.getStateEvent( stateEventDataSource.getStateEvent(
roomId = params.roomId, roomId = params.roomId,

View File

@ -48,7 +48,7 @@ internal class LiveLocationShareRedactionEventProcessor @Inject constructor() :
val redactedEvent = EventEntity.where(realm, eventId = event.redacts).findFirst() val redactedEvent = EventEntity.where(realm, eventId = event.redacts).findFirst()
?: return ?: 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) val liveSummary = LiveLocationShareAggregatedSummaryEntity.get(realm, eventId = redactedEvent.eventId)
if (liveSummary != null) { if (liveSummary != null) {

View File

@ -46,7 +46,7 @@ internal class DefaultStartLiveLocationShareTask @Inject constructor(
isLive = true, isLive = true,
unstableTimestampMillis = clock.epochMillis() unstableTimestampMillis = clock.epochMillis()
).toContent() ).toContent()
val eventType = EventType.STATE_ROOM_BEACON_INFO.first() val eventType = EventType.STATE_ROOM_BEACON_INFO.stable
val sendStateTaskParams = SendStateTask.Params( val sendStateTaskParams = SendStateTask.Params(
roomId = params.roomId, roomId = params.roomId,
stateKey = userId, stateKey = userId,

View File

@ -45,7 +45,7 @@ internal class DefaultStopLiveLocationShareTask @Inject constructor(
val sendStateTaskParams = SendStateTask.Params( val sendStateTaskParams = SendStateTask.Params(
roomId = params.roomId, roomId = params.roomId,
stateKey = stateKey, stateKey = stateKey,
eventType = EventType.STATE_ROOM_BEACON_INFO.first(), eventType = EventType.STATE_ROOM_BEACON_INFO.stable,
body = updatedContent body = updatedContent
) )
return try { return try {

View File

@ -74,9 +74,9 @@ internal class RedactionEventProcessor @Inject constructor() : EventInsertLivePr
when (typeToPrune) { when (typeToPrune) {
EventType.ENCRYPTED, EventType.ENCRYPTED,
EventType.MESSAGE, EventType.MESSAGE,
in EventType.STATE_ROOM_BEACON_INFO, in EventType.STATE_ROOM_BEACON_INFO.values,
in EventType.BEACON_LOCATION_DATA, in EventType.BEACON_LOCATION_DATA.values,
in EventType.POLL_START -> { in EventType.POLL_START.values -> {
Timber.d("REDACTION for message ${eventToPrune.eventId}") Timber.d("REDACTION for message ${eventToPrune.eventId}")
val unsignedData = EventMapper.map(eventToPrune).unsignedData val unsignedData = EventMapper.map(eventToPrune).unsignedData
?: UnsignedData(null, null) ?: UnsignedData(null, null)

View File

@ -181,7 +181,7 @@ internal class LocalEchoEventFactory @Inject constructor(
originServerTs = dummyOriginServerTs(), originServerTs = dummyOriginServerTs(),
senderId = userId, senderId = userId,
eventId = localId, eventId = localId,
type = EventType.POLL_START.first(), type = EventType.POLL_START.stable,
content = newContent.toContent().plus(additionalContent.orEmpty()) content = newContent.toContent().plus(additionalContent.orEmpty())
) )
} }
@ -206,7 +206,7 @@ internal class LocalEchoEventFactory @Inject constructor(
originServerTs = dummyOriginServerTs(), originServerTs = dummyOriginServerTs(),
senderId = userId, senderId = userId,
eventId = localId, eventId = localId,
type = EventType.POLL_RESPONSE.first(), type = EventType.POLL_RESPONSE.stable,
content = content.toContent().plus(additionalContent.orEmpty()), content = content.toContent().plus(additionalContent.orEmpty()),
unsignedData = UnsignedData(age = null, transactionId = localId) unsignedData = UnsignedData(age = null, transactionId = localId)
) )
@ -226,7 +226,7 @@ internal class LocalEchoEventFactory @Inject constructor(
originServerTs = dummyOriginServerTs(), originServerTs = dummyOriginServerTs(),
senderId = userId, senderId = userId,
eventId = localId, eventId = localId,
type = EventType.POLL_START.first(), type = EventType.POLL_START.stable,
content = content.toContent().plus(additionalContent.orEmpty()), content = content.toContent().plus(additionalContent.orEmpty()),
unsignedData = UnsignedData(age = null, transactionId = localId) unsignedData = UnsignedData(age = null, transactionId = localId)
) )
@ -249,7 +249,7 @@ internal class LocalEchoEventFactory @Inject constructor(
originServerTs = dummyOriginServerTs(), originServerTs = dummyOriginServerTs(),
senderId = userId, senderId = userId,
eventId = localId, eventId = localId,
type = EventType.POLL_END.first(), type = EventType.POLL_END.stable,
content = content.toContent().plus(additionalContent.orEmpty()), content = content.toContent().plus(additionalContent.orEmpty()),
unsignedData = UnsignedData(age = null, transactionId = localId) unsignedData = UnsignedData(age = null, transactionId = localId)
) )
@ -300,7 +300,7 @@ internal class LocalEchoEventFactory @Inject constructor(
originServerTs = dummyOriginServerTs(), originServerTs = dummyOriginServerTs(),
senderId = userId, senderId = userId,
eventId = localId, eventId = localId,
type = EventType.BEACON_LOCATION_DATA.first(), type = EventType.BEACON_LOCATION_DATA.stable,
content = content.toContent().plus(additionalContent.orEmpty()), content = content.toContent().plus(additionalContent.orEmpty()),
unsignedData = UnsignedData(age = null, transactionId = localId) unsignedData = UnsignedData(age = null, transactionId = localId)
) )

View File

@ -87,7 +87,7 @@ object PollEventsTestData {
) )
internal val A_POLL_START_EVENT = Event( internal val A_POLL_START_EVENT = Event(
type = EventType.POLL_START.first(), type = EventType.POLL_START.stable,
eventId = AN_EVENT_ID, eventId = AN_EVENT_ID,
originServerTs = 1652435922563, originServerTs = 1652435922563,
senderId = A_USER_ID_1, senderId = A_USER_ID_1,
@ -96,7 +96,7 @@ object PollEventsTestData {
) )
internal val A_POLL_RESPONSE_EVENT = Event( internal val A_POLL_RESPONSE_EVENT = Event(
type = EventType.POLL_RESPONSE.first(), type = EventType.POLL_RESPONSE.stable,
eventId = AN_EVENT_ID, eventId = AN_EVENT_ID,
originServerTs = 1652435922563, originServerTs = 1652435922563,
senderId = A_USER_ID_1, senderId = A_USER_ID_1,
@ -105,7 +105,7 @@ object PollEventsTestData {
) )
internal val A_POLL_END_EVENT = Event( internal val A_POLL_END_EVENT = Event(
type = EventType.POLL_END.first(), type = EventType.POLL_END.stable,
eventId = AN_EVENT_ID, eventId = AN_EVENT_ID,
originServerTs = 1652435922563, originServerTs = 1652435922563,
senderId = A_USER_ID_1, senderId = A_USER_ID_1,

View File

@ -69,7 +69,7 @@ class DefaultGetActiveBeaconInfoForUserTaskTest {
result shouldBeEqualTo currentStateEvent result shouldBeEqualTo currentStateEvent
fakeStateEventDataSource.verifyGetStateEvent( fakeStateEventDataSource.verifyGetStateEvent(
roomId = params.roomId, roomId = params.roomId,
eventType = EventType.STATE_ROOM_BEACON_INFO.first(), eventType = EventType.STATE_ROOM_BEACON_INFO.stable,
stateKey = QueryStringValue.Equals(A_USER_ID) stateKey = QueryStringValue.Equals(A_USER_ID)
) )
} }

View File

@ -75,7 +75,7 @@ internal class DefaultStartLiveLocationShareTaskTest {
val expectedParams = SendStateTask.Params( val expectedParams = SendStateTask.Params(
roomId = params.roomId, roomId = params.roomId,
stateKey = A_USER_ID, stateKey = A_USER_ID,
eventType = EventType.STATE_ROOM_BEACON_INFO.first(), eventType = EventType.STATE_ROOM_BEACON_INFO.stable,
body = expectedBeaconContent body = expectedBeaconContent
) )
fakeSendStateTask.verifyExecuteRetry( fakeSendStateTask.verifyExecuteRetry(

View File

@ -79,7 +79,7 @@ class DefaultStopLiveLocationShareTaskTest {
val expectedSendParams = SendStateTask.Params( val expectedSendParams = SendStateTask.Params(
roomId = params.roomId, roomId = params.roomId,
stateKey = A_USER_ID, stateKey = A_USER_ID,
eventType = EventType.STATE_ROOM_BEACON_INFO.first(), eventType = EventType.STATE_ROOM_BEACON_INFO.stable,
body = expectedBeaconContent body = expectedBeaconContent
) )
fakeSendStateTask.verifyExecuteRetry( fakeSendStateTask.verifyExecuteRetry(

View File

@ -79,7 +79,7 @@ class LiveLocationShareRedactionEventProcessorTest {
@Test @Test
fun `given a redacted live location share event when processing it then related summaries are deleted from database`() = runTest { 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 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<EventEntity>() fakeRealm.givenWhere<EventEntity>()
.givenEqualTo(EventEntityFields.EVENT_ID, A_REDACTED_EVENT_ID) .givenEqualTo(EventEntityFields.EVENT_ID, A_REDACTED_EVENT_ID)
.givenFindFirst(redactedEventEntity) .givenFindFirst(redactedEventEntity)

View File

@ -28,7 +28,7 @@ import org.matrix.android.sdk.api.session.room.timeline.getLastMessageContent
fun TimelineEvent.canReact(): Boolean { fun TimelineEvent.canReact(): Boolean {
// Only event of type EventType.MESSAGE, EventType.STICKER and EventType.POLL_START are supported for the moment // 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.sendState == SendState.SYNCED &&
!root.isRedacted() !root.isRedacted()
} }

View File

@ -1774,7 +1774,7 @@ class TimelineFragment :
timelineViewModel.handle(RoomDetailAction.UpdateQuickReactAction(action.eventId, action.clickedOn, action.add)) timelineViewModel.handle(RoomDetailAction.UpdateQuickReactAction(action.eventId, action.clickedOn, action.add))
} }
is EventSharedAction.Edit -> { 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) navigator.openCreatePoll(requireContext(), timelineArgs.roomId, action.eventId, PollMode.EDIT)
} else if (withState(messageComposerViewModel) { it.isVoiceMessageIdle }) { } else if (withState(messageComposerViewModel) { it.isVoiceMessageIdle }) {
messageComposerViewModel.handle(MessageComposerAction.EnterEditMode(action.eventId)) messageComposerViewModel.handle(MessageComposerAction.EnterEditMode(action.eventId))

View File

@ -33,8 +33,8 @@ class CheckIfCanRedactEventUseCase @Inject constructor(
EventType.STICKER, EventType.STICKER,
VoiceBroadcastConstants.STATE_ROOM_VOICE_BROADCAST_INFO, VoiceBroadcastConstants.STATE_ROOM_VOICE_BROADCAST_INFO,
) + ) +
EventType.POLL_START + EventType.POLL_START.values +
EventType.STATE_ROOM_BEACON_INFO EventType.STATE_ROOM_BEACON_INFO.values
return event.root.getClearType() in canRedactEventTypes && 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 // Message sent by the current user can always be redacted, else check permission for messages sent by other users

View File

@ -26,7 +26,7 @@ class CheckIfCanReplyEventUseCase @Inject constructor() {
fun execute(event: TimelineEvent, messageContent: MessageContent?, actionPermissions: ActionPermissions): Boolean { 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 // 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 if (!actionPermissions.canSendMessage) return false
return when (messageContent?.msgType) { return when (messageContent?.msgType) {
MessageType.MSGTYPE_TEXT, MessageType.MSGTYPE_TEXT,

View File

@ -215,7 +215,7 @@ class MessageActionsViewModel @AssistedInject constructor(
EventType.CALL_ANSWER -> { EventType.CALL_ANSWER -> {
noticeEventFormatter.format(timelineEvent, room?.roomSummary()?.isDirect.orFalse()) noticeEventFormatter.format(timelineEvent, room?.roomSummary()?.isDirect.orFalse())
} }
in EventType.POLL_START -> { in EventType.POLL_START.values -> {
timelineEvent.root.getClearContent().toModel<MessagePollContent>(catchError = true) timelineEvent.root.getClearContent().toModel<MessagePollContent>(catchError = true)
?.getBestPollCreationInfo()?.question?.getBestQuestion() ?: "" ?.getBestPollCreationInfo()?.question?.getBestQuestion() ?: ""
} }
@ -383,7 +383,7 @@ class MessageActionsViewModel @AssistedInject constructor(
} }
if (canRedact(timelineEvent, actionPermissions)) { if (canRedact(timelineEvent, actionPermissions)) {
if (timelineEvent.root.getClearType() in EventType.POLL_START) { if (timelineEvent.root.getClearType() in EventType.POLL_START.values) {
add( add(
EventSharedAction.Redact( EventSharedAction.Redact(
eventId, eventId,
@ -530,13 +530,13 @@ class MessageActionsViewModel @AssistedInject constructor(
private fun canViewReactions(event: TimelineEvent): Boolean { private fun canViewReactions(event: TimelineEvent): Boolean {
// Only event of type EventType.MESSAGE, EventType.STICKER and EventType.POLL_START are supported for the moment // 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 return event.annotations?.reactionsSummary?.isNotEmpty() ?: false
} }
private fun canEdit(event: TimelineEvent, myUserId: String, actionPermissions: ActionPermissions): Boolean { 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 // 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 if (!actionPermissions.canSendMessage) return false
// TODO if user is admin or moderator // TODO if user is admin or moderator
val messageContent = event.root.getClearContent().toModel<MessageContent>() val messageContent = event.root.getClearContent().toModel<MessageContent>()
@ -582,14 +582,14 @@ class MessageActionsViewModel @AssistedInject constructor(
} }
private fun canEndPoll(event: TimelineEvent, actionPermissions: ActionPermissions): Boolean { 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) && canRedact(event, actionPermissions) &&
event.annotations?.pollResponseSummary?.closedTime == null event.annotations?.pollResponseSummary?.closedTime == null
} }
private fun canEditPoll(event: TimelineEvent): Boolean { 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?.closedTime == null &&
event.annotations?.pollResponseSummary?.aggregatedContent?.totalVotes ?: 0 == 0 (event.annotations?.pollResponseSummary?.aggregatedContent?.totalVotes ?: 0) == 0
} }
} }

View File

@ -88,7 +88,7 @@ class TimelineItemFactory @Inject constructor(
EventType.STATE_ROOM_ENCRYPTION -> encryptionItemFactory.create(params) EventType.STATE_ROOM_ENCRYPTION -> encryptionItemFactory.create(params)
// State room create // State room create
EventType.STATE_ROOM_CREATE -> roomCreateItemFactory.create(params) 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) VoiceBroadcastConstants.STATE_ROOM_VOICE_BROADCAST_INFO -> messageItemFactory.create(params)
// Unhandled state event types // Unhandled state event types
else -> { else -> {
@ -101,7 +101,7 @@ class TimelineItemFactory @Inject constructor(
when (event.root.getClearType()) { when (event.root.getClearType()) {
// Message itemsX // Message itemsX
EventType.STICKER, EventType.STICKER,
in EventType.POLL_START, in EventType.POLL_START.values,
EventType.MESSAGE -> messageItemFactory.create(params) EventType.MESSAGE -> messageItemFactory.create(params)
EventType.REDACTION, EventType.REDACTION,
EventType.KEY_VERIFICATION_ACCEPT, EventType.KEY_VERIFICATION_ACCEPT,
@ -114,9 +114,9 @@ class TimelineItemFactory @Inject constructor(
EventType.CALL_SELECT_ANSWER, EventType.CALL_SELECT_ANSWER,
EventType.CALL_NEGOTIATE, EventType.CALL_NEGOTIATE,
EventType.REACTION, EventType.REACTION,
in EventType.POLL_RESPONSE, in EventType.POLL_RESPONSE.values,
in EventType.POLL_END -> noticeItemFactory.create(params) in EventType.POLL_END.values -> noticeItemFactory.create(params)
in EventType.BEACON_LOCATION_DATA -> { in EventType.BEACON_LOCATION_DATA.values -> {
if (event.root.isRedacted()) { if (event.root.isRedacted()) {
messageItemFactory.create(params) messageItemFactory.create(params)
} else { } else {

View File

@ -122,17 +122,17 @@ class DisplayableEventFormatter @Inject constructor(
EventType.CALL_CANDIDATES -> { EventType.CALL_CANDIDATES -> {
span { } span { }
} }
in EventType.POLL_START -> { in EventType.POLL_START.values -> {
timelineEvent.root.getClearContent().toModel<MessagePollContent>(catchError = true)?.getBestPollCreationInfo()?.question?.getBestQuestion() timelineEvent.root.getClearContent().toModel<MessagePollContent>(catchError = true)?.getBestPollCreationInfo()?.question?.getBestQuestion()
?: stringProvider.getString(R.string.sent_a_poll) ?: 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) 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) 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) simpleFormat(senderName, stringProvider.getString(R.string.sent_live_location), appendAuthor)
} }
else -> { else -> {
@ -220,17 +220,17 @@ class DisplayableEventFormatter @Inject constructor(
emojiSpanify.spanify(stringProvider.getString(R.string.sent_a_reaction, it.key)) emojiSpanify.spanify(stringProvider.getString(R.string.sent_a_reaction, it.key))
} ?: span { } } ?: span { }
} }
in EventType.POLL_START -> { in EventType.POLL_START.values -> {
event.getClearContent().toModel<MessagePollContent>(catchError = true)?.pollCreationInfo?.question?.question event.getClearContent().toModel<MessagePollContent>(catchError = true)?.pollCreationInfo?.question?.question
?: stringProvider.getString(R.string.sent_a_poll) ?: 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) 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) 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) stringProvider.getString(R.string.sent_live_location)
} }
else -> { else -> {

View File

@ -107,9 +107,9 @@ class NoticeEventFormatter @Inject constructor(
EventType.STATE_SPACE_PARENT, EventType.STATE_SPACE_PARENT,
EventType.REDACTION, EventType.REDACTION,
EventType.STICKER, EventType.STICKER,
in EventType.POLL_RESPONSE, in EventType.POLL_RESPONSE.values,
in EventType.POLL_END, in EventType.POLL_END.values,
in EventType.BEACON_LOCATION_DATA, in EventType.BEACON_LOCATION_DATA.values,
VoiceBroadcastConstants.STATE_ROOM_VOICE_BROADCAST_INFO -> formatDebug(timelineEvent.root) VoiceBroadcastConstants.STATE_ROOM_VOICE_BROADCAST_INFO -> formatDebug(timelineEvent.root)
else -> { else -> {
Timber.v("Type $type not handled by this formatter") Timber.v("Type $type not handled by this formatter")

View File

@ -54,9 +54,9 @@ object TimelineDisplayableEvents {
EventType.KEY_VERIFICATION_CANCEL, EventType.KEY_VERIFICATION_CANCEL,
VoiceBroadcastConstants.STATE_ROOM_VOICE_BROADCAST_INFO, VoiceBroadcastConstants.STATE_ROOM_VOICE_BROADCAST_INFO,
) + ) +
EventType.POLL_START + EventType.POLL_START.values +
EventType.STATE_ROOM_BEACON_INFO + EventType.STATE_ROOM_BEACON_INFO.values +
EventType.BEACON_LOCATION_DATA EventType.BEACON_LOCATION_DATA.values
} }
fun TimelineEvent.isRoomConfiguration(roomCreatorUserId: String?): Boolean { fun TimelineEvent.isRoomConfiguration(roomCreatorUserId: String?): Boolean {

View File

@ -248,7 +248,7 @@ class TimelineEventVisibilityHelper @Inject constructor(
} else root.eventId != rootThreadEventId } else root.eventId != rootThreadEventId
} }
if (root.getClearType() in EventType.BEACON_LOCATION_DATA) { if (root.getClearType() in EventType.BEACON_LOCATION_DATA.values) {
return !root.isRedacted() return !root.isRedacted()
} }

View File

@ -47,8 +47,10 @@ class TimelineMessageLayoutFactory @Inject constructor(
private val EVENT_TYPES_WITH_BUBBLE_LAYOUT = setOf( private val EVENT_TYPES_WITH_BUBBLE_LAYOUT = setOf(
EventType.MESSAGE, EventType.MESSAGE,
EventType.ENCRYPTED, EventType.ENCRYPTED,
EventType.STICKER EventType.STICKER,
) + EventType.POLL_START + EventType.STATE_ROOM_BEACON_INFO ) +
EventType.POLL_START.values +
EventType.STATE_ROOM_BEACON_INFO.values
// Can't be rendered in bubbles, so get back to default layout // Can't be rendered in bubbles, so get back to default layout
private val MSG_TYPES_WITHOUT_BUBBLE_LAYOUT = setOf( private val MSG_TYPES_WITHOUT_BUBBLE_LAYOUT = setOf(

View File

@ -83,7 +83,7 @@ class LocationSharingViewModel @AssistedInject constructor(
.distinctUntilChanged() .distinctUntilChanged()
.setOnEach { .setOnEach {
val powerLevelsHelper = PowerLevelsHelper(it) val powerLevelsHelper = PowerLevelsHelper(it)
val canShareLiveLocation = EventType.STATE_ROOM_BEACON_INFO val canShareLiveLocation = EventType.STATE_ROOM_BEACON_INFO.values
.all { beaconInfoType -> .all { beaconInfoType ->
powerLevelsHelper.isUserAllowedToSend(session.myUserId, true, beaconInfoType) powerLevelsHelper.isUserAllowedToSend(session.myUserId, true, beaconInfoType)
} }

View File

@ -66,7 +66,7 @@ class NotifiableEventResolver @Inject constructor(
) { ) {
private val nonEncryptedNotifiableEventTypes: List<String> = private val nonEncryptedNotifiableEventTypes: List<String> =
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? { suspend fun resolveEvent(event: Event, session: Session, isNoisy: Boolean): NotifiableEvent? {
val roomID = event.roomId ?: return null val roomID = event.roomId ?: return null

View File

@ -35,8 +35,13 @@ class CheckIfCanRedactEventUseCaseTest {
@Test @Test
fun `given an event which can be redacted and owned by user when use case executes then the result is true`() { 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) + val canRedactEventTypes = listOf(
EventType.POLL_START + EventType.STATE_ROOM_BEACON_INFO EventType.MESSAGE,
EventType.STICKER,
VoiceBroadcastConstants.STATE_ROOM_VOICE_BROADCAST_INFO
) +
EventType.POLL_START.values +
EventType.STATE_ROOM_BEACON_INFO.values
canRedactEventTypes.forEach { eventType -> canRedactEventTypes.forEach { eventType ->
val event = givenAnEvent( val event = givenAnEvent(

View File

@ -43,7 +43,7 @@ class CheckIfCanReplyEventUseCaseTest {
@Test @Test
fun `given reply is allowed for the event type when use case is executed then result is true`() { 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 -> eventTypes.forEach { eventType ->
val event = givenAnEvent(eventType) val event = givenAnEvent(eventType)

View File

@ -63,7 +63,7 @@ object FakeCreatePollViewStates {
) )
private val A_POLL_START_EVENT = Event( private val A_POLL_START_EVENT = Event(
type = EventType.POLL_START.first(), type = EventType.POLL_START.stable,
eventId = A_FAKE_EVENT_ID, eventId = A_FAKE_EVENT_ID,
originServerTs = 1652435922563, originServerTs = 1652435922563,
senderId = A_FAKE_USER_ID, senderId = A_FAKE_USER_ID,