mirror of
https://github.com/SchildiChat/SchildiChat-android.git
synced 2024-11-22 09:25:49 +03:00
Create the DM when sending an event
This commit is contained in:
parent
da70d520bc
commit
72896f1c8a
6 changed files with 319 additions and 17 deletions
1
changelog.d/5525.wip
Normal file
1
changelog.d/5525.wip
Normal file
|
@ -0,0 +1 @@
|
|||
Create DM room only on first message - Create the DM and navigate to the new room after sending an event
|
|
@ -16,10 +16,12 @@
|
|||
package org.matrix.android.sdk.internal.crypto.tasks
|
||||
|
||||
import org.matrix.android.sdk.api.session.events.model.Event
|
||||
import org.matrix.android.sdk.api.session.room.model.localecho.RoomLocalEcho
|
||||
import org.matrix.android.sdk.api.session.room.send.SendState
|
||||
import org.matrix.android.sdk.internal.network.GlobalErrorReceiver
|
||||
import org.matrix.android.sdk.internal.network.executeRequest
|
||||
import org.matrix.android.sdk.internal.session.room.RoomAPI
|
||||
import org.matrix.android.sdk.internal.session.room.create.CreateRoomFromLocalRoomTask
|
||||
import org.matrix.android.sdk.internal.session.room.membership.LoadRoomMembersTask
|
||||
import org.matrix.android.sdk.internal.session.room.send.LocalEchoRepository
|
||||
import org.matrix.android.sdk.internal.task.Task
|
||||
|
@ -37,12 +39,18 @@ internal class DefaultSendEventTask @Inject constructor(
|
|||
private val localEchoRepository: LocalEchoRepository,
|
||||
private val encryptEventTask: EncryptEventTask,
|
||||
private val loadRoomMembersTask: LoadRoomMembersTask,
|
||||
private val createRoomFromLocalRoomTask: CreateRoomFromLocalRoomTask,
|
||||
private val roomAPI: RoomAPI,
|
||||
private val globalErrorReceiver: GlobalErrorReceiver
|
||||
) : SendEventTask {
|
||||
|
||||
override suspend fun execute(params: SendEventTask.Params): String {
|
||||
try {
|
||||
if (RoomLocalEcho.isLocalEchoId(params.event.roomId.orEmpty())) {
|
||||
// Room is local, so create a real one and send the event to this new room
|
||||
return createRoomAndSendEvent(params)
|
||||
}
|
||||
|
||||
// Make sure to load all members in the room before sending the event.
|
||||
params.event.roomId
|
||||
?.takeIf { params.encrypt }
|
||||
|
@ -78,6 +86,12 @@ internal class DefaultSendEventTask @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
private suspend fun createRoomAndSendEvent(params: SendEventTask.Params): String {
|
||||
val roomId = createRoomFromLocalRoomTask.execute(CreateRoomFromLocalRoomTask.Params(params.event.roomId.orEmpty()))
|
||||
Timber.d("State event: convert local room (${params.event.roomId}) to existing room ($roomId) before sending the event.")
|
||||
return execute(params.copy(event = params.event.copy(roomId = roomId)))
|
||||
}
|
||||
|
||||
@Throws
|
||||
private suspend fun handleEncryption(params: SendEventTask.Params): Event {
|
||||
if (params.encrypt && !params.event.isEncrypted()) {
|
||||
|
|
|
@ -44,8 +44,10 @@ import org.matrix.android.sdk.internal.session.room.alias.DeleteRoomAliasTask
|
|||
import org.matrix.android.sdk.internal.session.room.alias.GetRoomIdByAliasTask
|
||||
import org.matrix.android.sdk.internal.session.room.alias.GetRoomLocalAliasesTask
|
||||
import org.matrix.android.sdk.internal.session.room.create.CreateLocalRoomTask
|
||||
import org.matrix.android.sdk.internal.session.room.create.CreateRoomFromLocalRoomTask
|
||||
import org.matrix.android.sdk.internal.session.room.create.CreateRoomTask
|
||||
import org.matrix.android.sdk.internal.session.room.create.DefaultCreateLocalRoomTask
|
||||
import org.matrix.android.sdk.internal.session.room.create.DefaultCreateRoomFromLocalRoomTask
|
||||
import org.matrix.android.sdk.internal.session.room.create.DefaultCreateRoomTask
|
||||
import org.matrix.android.sdk.internal.session.room.delete.DefaultDeleteLocalRoomTask
|
||||
import org.matrix.android.sdk.internal.session.room.delete.DeleteLocalRoomTask
|
||||
|
@ -213,6 +215,9 @@ internal abstract class RoomModule {
|
|||
@Binds
|
||||
abstract fun bindCreateLocalRoomTask(task: DefaultCreateLocalRoomTask): CreateLocalRoomTask
|
||||
|
||||
@Binds
|
||||
abstract fun bindCreateRoomFromLocalRoomTask(task: DefaultCreateRoomFromLocalRoomTask): CreateRoomFromLocalRoomTask
|
||||
|
||||
@Binds
|
||||
abstract fun bindDeleteLocalRoomTask(task: DefaultDeleteLocalRoomTask): DeleteLocalRoomTask
|
||||
|
||||
|
|
|
@ -0,0 +1,252 @@
|
|||
/*
|
||||
* Copyright 2022 The Matrix.org Foundation C.I.C.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.matrix.android.sdk.internal.session.room.create
|
||||
|
||||
import android.util.Patterns
|
||||
import androidx.core.net.toUri
|
||||
import com.google.i18n.phonenumbers.NumberParseException
|
||||
import com.google.i18n.phonenumbers.PhoneNumberUtil
|
||||
import com.zhuinden.monarchy.Monarchy
|
||||
import io.realm.Realm
|
||||
import org.matrix.android.sdk.api.extensions.ensurePrefix
|
||||
import org.matrix.android.sdk.api.query.QueryStringValue
|
||||
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.toContent
|
||||
import org.matrix.android.sdk.api.session.events.model.toModel
|
||||
import org.matrix.android.sdk.api.session.identity.ThreePid
|
||||
import org.matrix.android.sdk.api.session.room.model.PowerLevelsContent
|
||||
import org.matrix.android.sdk.api.session.room.model.RoomAliasesContent
|
||||
import org.matrix.android.sdk.api.session.room.model.RoomAvatarContent
|
||||
import org.matrix.android.sdk.api.session.room.model.RoomCanonicalAliasContent
|
||||
import org.matrix.android.sdk.api.session.room.model.RoomGuestAccessContent
|
||||
import org.matrix.android.sdk.api.session.room.model.RoomHistoryVisibilityContent
|
||||
import org.matrix.android.sdk.api.session.room.model.RoomJoinRules
|
||||
import org.matrix.android.sdk.api.session.room.model.RoomJoinRulesContent
|
||||
import org.matrix.android.sdk.api.session.room.model.RoomMemberContent
|
||||
import org.matrix.android.sdk.api.session.room.model.RoomNameContent
|
||||
import org.matrix.android.sdk.api.session.room.model.RoomTopicContent
|
||||
import org.matrix.android.sdk.api.session.room.model.create.CreateRoomParams
|
||||
import org.matrix.android.sdk.api.session.room.model.create.CreateRoomPreset
|
||||
import org.matrix.android.sdk.api.session.room.model.tombstone.RoomTombstoneContent
|
||||
import org.matrix.android.sdk.api.session.room.send.SendState
|
||||
import org.matrix.android.sdk.internal.database.mapper.asDomain
|
||||
import org.matrix.android.sdk.internal.database.mapper.toEntity
|
||||
import org.matrix.android.sdk.internal.database.model.CurrentStateEventEntity
|
||||
import org.matrix.android.sdk.internal.database.model.EventEntity
|
||||
import org.matrix.android.sdk.internal.database.model.EventInsertType
|
||||
import org.matrix.android.sdk.internal.database.query.copyToRealmOrIgnore
|
||||
import org.matrix.android.sdk.internal.database.query.getOrCreate
|
||||
import org.matrix.android.sdk.internal.database.query.where
|
||||
import org.matrix.android.sdk.internal.database.query.whereRoomId
|
||||
import org.matrix.android.sdk.internal.di.SessionDatabase
|
||||
import org.matrix.android.sdk.internal.di.UserId
|
||||
import org.matrix.android.sdk.internal.session.room.state.StateEventDataSource
|
||||
import org.matrix.android.sdk.internal.task.Task
|
||||
import org.matrix.android.sdk.internal.util.awaitTransaction
|
||||
import org.matrix.android.sdk.internal.util.time.Clock
|
||||
import java.util.UUID
|
||||
import javax.inject.Inject
|
||||
|
||||
/**
|
||||
* Create a Room from a "fake" local room.
|
||||
* The configuration of the local room will be use to configure the new room.
|
||||
* The potential local room members will also be invited to this new room.
|
||||
*
|
||||
* A "fake" local tombstone event will be created to indicate that the local room has been replacing by the new one.
|
||||
*/
|
||||
internal interface CreateRoomFromLocalRoomTask : Task<CreateRoomFromLocalRoomTask.Params, String> {
|
||||
data class Params(val localRoomId: String)
|
||||
}
|
||||
|
||||
internal class DefaultCreateRoomFromLocalRoomTask @Inject constructor(
|
||||
@UserId private val userId: String,
|
||||
@SessionDatabase private val monarchy: Monarchy,
|
||||
private val createRoomTask: CreateRoomTask,
|
||||
private val stateEventDataSource: StateEventDataSource,
|
||||
private val clock: Clock,
|
||||
) : CreateRoomFromLocalRoomTask {
|
||||
|
||||
override suspend fun execute(params: CreateRoomFromLocalRoomTask.Params): String {
|
||||
val replacementRoomId = stateEventDataSource.getStateEvent(params.localRoomId, EventType.STATE_ROOM_TOMBSTONE, QueryStringValue.NoCondition)
|
||||
?.content?.toModel<RoomTombstoneContent>()
|
||||
?.replacementRoomId
|
||||
|
||||
if (replacementRoomId != null) {
|
||||
return replacementRoomId
|
||||
}
|
||||
|
||||
val createRoomParams = getCreateRoomParams(params)
|
||||
val roomId = createRoomTask.execute(createRoomParams)
|
||||
createTombstoneEvent(params, roomId)
|
||||
return roomId
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the room configuration by parsing the state events related to the local room.
|
||||
*/
|
||||
private suspend fun getCreateRoomParams(params: CreateRoomFromLocalRoomTask.Params): CreateRoomParams {
|
||||
var createRoomParams = CreateRoomParams()
|
||||
monarchy.awaitTransaction { realm ->
|
||||
val stateEvents = CurrentStateEventEntity.whereRoomId(realm, params.localRoomId).findAll()
|
||||
stateEvents.forEach { event ->
|
||||
createRoomParams = when (event.type) {
|
||||
EventType.STATE_ROOM_MEMBER -> handleRoomMemberEvent(realm, event, createRoomParams)
|
||||
EventType.STATE_ROOM_HISTORY_VISIBILITY -> handleRoomHistoryVisibilityEvent(realm, event, createRoomParams)
|
||||
EventType.STATE_ROOM_ALIASES -> handleRoomAliasesEvent(realm, event, createRoomParams)
|
||||
EventType.STATE_ROOM_AVATAR -> handleRoomAvatarEvent(realm, event, createRoomParams)
|
||||
EventType.STATE_ROOM_CANONICAL_ALIAS -> handleRoomCanonicalAliasEvent(realm, event, createRoomParams)
|
||||
EventType.STATE_ROOM_GUEST_ACCESS -> handleRoomGuestAccessEvent(realm, event, createRoomParams)
|
||||
EventType.STATE_ROOM_ENCRYPTION -> handleRoomEncryptionEvent(createRoomParams)
|
||||
EventType.STATE_ROOM_POWER_LEVELS -> handleRoomPowerRoomLevelsEvent(realm, event, createRoomParams)
|
||||
EventType.STATE_ROOM_NAME -> handleRoomNameEvent(realm, event, createRoomParams)
|
||||
EventType.STATE_ROOM_TOPIC -> handleRoomTopicEvent(realm, event, createRoomParams)
|
||||
EventType.STATE_ROOM_THIRD_PARTY_INVITE -> handleRoomThirdPartyInviteEvent(event, createRoomParams)
|
||||
EventType.STATE_ROOM_JOIN_RULES -> handleRoomJoinRulesEvent(realm, event, createRoomParams)
|
||||
else -> createRoomParams
|
||||
}
|
||||
}
|
||||
}
|
||||
return createRoomParams
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a Tombstone event to indicate that the local room has been replaced by a new one.
|
||||
*/
|
||||
private suspend fun createTombstoneEvent(params: CreateRoomFromLocalRoomTask.Params, roomId: String) {
|
||||
val now = clock.epochMillis()
|
||||
val event = Event(
|
||||
type = EventType.STATE_ROOM_TOMBSTONE,
|
||||
senderId = userId,
|
||||
originServerTs = now,
|
||||
stateKey = "",
|
||||
eventId = UUID.randomUUID().toString(),
|
||||
content = RoomTombstoneContent(
|
||||
replacementRoomId = roomId
|
||||
).toContent()
|
||||
)
|
||||
monarchy.awaitTransaction { realm ->
|
||||
val eventEntity = event.toEntity(params.localRoomId, SendState.SYNCED, now).copyToRealmOrIgnore(realm, EventInsertType.INCREMENTAL_SYNC)
|
||||
if (event.stateKey != null && event.type != null && event.eventId != null) {
|
||||
CurrentStateEventEntity.getOrCreate(realm, params.localRoomId, event.stateKey, event.type).apply {
|
||||
eventId = event.eventId
|
||||
root = eventEntity
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ==========================================================================================
|
||||
* Local events handling
|
||||
* ========================================================================================== */
|
||||
|
||||
private fun handleRoomMemberEvent(realm: Realm, event: CurrentStateEventEntity, params: CreateRoomParams): CreateRoomParams = params.apply {
|
||||
val content = getEventContent<RoomMemberContent>(realm, event.eventId) ?: return@apply
|
||||
invitedUserIds.add(event.stateKey)
|
||||
if (content.isDirect) {
|
||||
setDirectMessage()
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleRoomHistoryVisibilityEvent(realm: Realm, event: CurrentStateEventEntity, params: CreateRoomParams): CreateRoomParams = params.apply {
|
||||
val content = getEventContent<RoomHistoryVisibilityContent>(realm, event.eventId) ?: return@apply
|
||||
historyVisibility = content.historyVisibility
|
||||
}
|
||||
|
||||
private fun handleRoomAliasesEvent(realm: Realm, event: CurrentStateEventEntity, params: CreateRoomParams): CreateRoomParams = params.apply {
|
||||
val content = getEventContent<RoomAliasesContent>(realm, event.eventId) ?: return@apply
|
||||
roomAliasName = content.aliases.firstOrNull()?.substringAfter("#")?.substringBefore(":")
|
||||
}
|
||||
|
||||
private fun handleRoomAvatarEvent(realm: Realm, event: CurrentStateEventEntity, params: CreateRoomParams): CreateRoomParams = params.apply {
|
||||
val content = getEventContent<RoomAvatarContent>(realm, event.eventId) ?: return@apply
|
||||
avatarUri = content.avatarUrl?.toUri()
|
||||
}
|
||||
|
||||
private fun handleRoomCanonicalAliasEvent(realm: Realm, event: CurrentStateEventEntity, params: CreateRoomParams): CreateRoomParams = params.apply {
|
||||
val content = getEventContent<RoomCanonicalAliasContent>(realm, event.eventId) ?: return@apply
|
||||
roomAliasName = content.canonicalAlias?.substringAfter("#")?.substringBefore(":")
|
||||
}
|
||||
|
||||
private fun handleRoomGuestAccessEvent(realm: Realm, event: CurrentStateEventEntity, params: CreateRoomParams): CreateRoomParams = params.apply {
|
||||
val content = getEventContent<RoomGuestAccessContent>(realm, event.eventId) ?: return@apply
|
||||
guestAccess = content.guestAccess
|
||||
}
|
||||
|
||||
private fun handleRoomEncryptionEvent(params: CreateRoomParams): CreateRoomParams = params.apply {
|
||||
// Having an encryption event means the room is encrypted, so just enable it again
|
||||
enableEncryption()
|
||||
}
|
||||
|
||||
private fun handleRoomPowerRoomLevelsEvent(realm: Realm, event: CurrentStateEventEntity, params: CreateRoomParams): CreateRoomParams = params.apply {
|
||||
val content = getEventContent<PowerLevelsContent>(realm, event.eventId) ?: return@apply
|
||||
powerLevelContentOverride = content
|
||||
}
|
||||
|
||||
private fun handleRoomNameEvent(realm: Realm, event: CurrentStateEventEntity, params: CreateRoomParams): CreateRoomParams = params.apply {
|
||||
val content = getEventContent<RoomNameContent>(realm, event.eventId) ?: return@apply
|
||||
name = content.name
|
||||
}
|
||||
|
||||
private fun handleRoomTopicEvent(realm: Realm, event: CurrentStateEventEntity, params: CreateRoomParams): CreateRoomParams = params.apply {
|
||||
val content = getEventContent<RoomTopicContent>(realm, event.eventId) ?: return@apply
|
||||
topic = content.topic
|
||||
}
|
||||
|
||||
private fun handleRoomThirdPartyInviteEvent(event: CurrentStateEventEntity, params: CreateRoomParams): CreateRoomParams = params.apply {
|
||||
when {
|
||||
event.stateKey.isEmail() -> invite3pids.add(ThreePid.Email(event.stateKey))
|
||||
event.stateKey.isMsisdn() -> invite3pids.add(ThreePid.Msisdn(event.stateKey))
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleRoomJoinRulesEvent(realm: Realm, event: CurrentStateEventEntity, params: CreateRoomParams): CreateRoomParams = params.apply {
|
||||
val content = getEventContent<RoomJoinRulesContent>(realm, event.eventId) ?: return@apply
|
||||
preset = when {
|
||||
// If preset has already been set for direct chat, keep it
|
||||
preset == CreateRoomPreset.PRESET_TRUSTED_PRIVATE_CHAT -> CreateRoomPreset.PRESET_TRUSTED_PRIVATE_CHAT
|
||||
content.joinRules == RoomJoinRules.PUBLIC -> CreateRoomPreset.PRESET_PUBLIC_CHAT
|
||||
content.joinRules == RoomJoinRules.INVITE -> CreateRoomPreset.PRESET_PRIVATE_CHAT
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
/* ==========================================================================================
|
||||
* Helper methods
|
||||
* ========================================================================================== */
|
||||
|
||||
private inline fun <reified T> getEventContent(realm: Realm, eventId: String): T? {
|
||||
return EventEntity.where(realm, eventId).findFirst()?.asDomain()?.getClearContent().toModel<T>()
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a CharSequence is an email.
|
||||
*/
|
||||
private fun CharSequence.isEmail() = Patterns.EMAIL_ADDRESS.matcher(this).matches()
|
||||
|
||||
/**
|
||||
* Check if a CharSequence is a phone number.
|
||||
*/
|
||||
private fun CharSequence.isMsisdn(): Boolean {
|
||||
return try {
|
||||
PhoneNumberUtil.getInstance().parse(ensurePrefix("+"), null)
|
||||
true
|
||||
} catch (e: NumberParseException) {
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
|
@ -16,10 +16,12 @@
|
|||
|
||||
package org.matrix.android.sdk.internal.session.room.state
|
||||
|
||||
import org.matrix.android.sdk.api.session.room.model.localecho.RoomLocalEcho
|
||||
import org.matrix.android.sdk.api.util.JsonDict
|
||||
import org.matrix.android.sdk.internal.network.GlobalErrorReceiver
|
||||
import org.matrix.android.sdk.internal.network.executeRequest
|
||||
import org.matrix.android.sdk.internal.session.room.RoomAPI
|
||||
import org.matrix.android.sdk.internal.session.room.create.CreateRoomFromLocalRoomTask
|
||||
import org.matrix.android.sdk.internal.task.Task
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
|
@ -35,28 +37,40 @@ internal interface SendStateTask : Task<SendStateTask.Params, String> {
|
|||
|
||||
internal class DefaultSendStateTask @Inject constructor(
|
||||
private val roomAPI: RoomAPI,
|
||||
private val globalErrorReceiver: GlobalErrorReceiver
|
||||
private val globalErrorReceiver: GlobalErrorReceiver,
|
||||
private val createRoomFromLocalRoomTask: CreateRoomFromLocalRoomTask,
|
||||
) : SendStateTask {
|
||||
|
||||
override suspend fun execute(params: SendStateTask.Params): String {
|
||||
return executeRequest(globalErrorReceiver) {
|
||||
val response = if (params.stateKey.isEmpty()) {
|
||||
roomAPI.sendStateEvent(
|
||||
roomId = params.roomId,
|
||||
stateEventType = params.eventType,
|
||||
params = params.body
|
||||
)
|
||||
if (RoomLocalEcho.isLocalEchoId(params.roomId)) {
|
||||
// Room is local, so create a real one and send the event to this new room
|
||||
createRoomAndSendEvent(params)
|
||||
} else {
|
||||
roomAPI.sendStateEvent(
|
||||
roomId = params.roomId,
|
||||
stateEventType = params.eventType,
|
||||
stateKey = params.stateKey,
|
||||
params = params.body
|
||||
)
|
||||
}
|
||||
response.eventId.also {
|
||||
Timber.d("State event: $it just sent in room ${params.roomId}")
|
||||
val response = if (params.stateKey.isEmpty()) {
|
||||
roomAPI.sendStateEvent(
|
||||
roomId = params.roomId,
|
||||
stateEventType = params.eventType,
|
||||
params = params.body
|
||||
)
|
||||
} else {
|
||||
roomAPI.sendStateEvent(
|
||||
roomId = params.roomId,
|
||||
stateEventType = params.eventType,
|
||||
stateKey = params.stateKey,
|
||||
params = params.body
|
||||
)
|
||||
}
|
||||
response.eventId.also {
|
||||
Timber.d("State event: $it just sent in room ${params.roomId}")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun createRoomAndSendEvent(params: SendStateTask.Params): String {
|
||||
val roomId = createRoomFromLocalRoomTask.execute(CreateRoomFromLocalRoomTask.Params(params.roomId))
|
||||
Timber.d("State event: convert local room (${params.roomId}) to existing room ($roomId) before sending the event.")
|
||||
return execute(params.copy(roomId = roomId))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -82,6 +82,7 @@ import org.matrix.android.sdk.api.query.QueryStringValue
|
|||
import org.matrix.android.sdk.api.raw.RawService
|
||||
import org.matrix.android.sdk.api.session.Session
|
||||
import org.matrix.android.sdk.api.session.crypto.MXCryptoError
|
||||
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.LocalEcho
|
||||
import org.matrix.android.sdk.api.session.events.model.RelationType
|
||||
|
@ -1269,11 +1270,26 @@ class TimelineViewModel @AssistedInject constructor(
|
|||
}
|
||||
}
|
||||
room.getStateEvent(EventType.STATE_ROOM_TOMBSTONE, QueryStringValue.IsEmpty)?.also {
|
||||
setState { copy(tombstoneEvent = it) }
|
||||
onRoomTombstoneUpdated(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private var roomTombstoneHandled = false
|
||||
private fun onRoomTombstoneUpdated(tombstoneEvent: Event) = withState { state ->
|
||||
if (roomTombstoneHandled) return@withState
|
||||
if (state.isLocalRoom()) {
|
||||
// Local room has been replaced, so navigate to the new room
|
||||
val roomId = tombstoneEvent.getClearContent()?.toModel<RoomTombstoneContent>()
|
||||
?.replacementRoomId
|
||||
?: return@withState
|
||||
_viewEvents.post(RoomDetailViewEvents.OpenRoom(roomId, closeCurrentRoom = true))
|
||||
roomTombstoneHandled = true
|
||||
} else {
|
||||
setState { copy(tombstoneEvent = tombstoneEvent) }
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Navigates to the appropriate event (by paginating the thread timeline until the event is found
|
||||
* in the snapshot. The main reason for this function is to support the /relations api
|
||||
|
|
Loading…
Reference in a new issue