From 0a0f998785a1ae6653619652ee64d6a4c018d201 Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Thu, 29 Sep 2022 19:00:40 +0100 Subject: [PATCH] taking into account redactions and updating the message list --- .../dapk/st/domain/sync/RoomPersistence.kt | 17 +++++--- .../sqldelight/app/dapk/db/model/RoomEvent.sq | 6 ++- .../app/dapk/st/matrix/sync/RoomState.kt | 1 + .../kotlin/app/dapk/st/matrix/sync/Store.kt | 3 +- .../sync/internal/sync/RoomDataSource.kt | 39 ++++++++++++++++--- .../sync/internal/sync/RoomProcessor.kt | 4 ++ .../matrix/sync/internal/sync/SyncReducer.kt | 2 - 7 files changed, 58 insertions(+), 14 deletions(-) diff --git a/domains/store/src/main/kotlin/app/dapk/st/domain/sync/RoomPersistence.kt b/domains/store/src/main/kotlin/app/dapk/st/domain/sync/RoomPersistence.kt index 451effd..7523e1d 100644 --- a/domains/store/src/main/kotlin/app/dapk/st/domain/sync/RoomPersistence.kt +++ b/domains/store/src/main/kotlin/app/dapk/st/domain/sync/RoomPersistence.kt @@ -27,10 +27,10 @@ internal class RoomPersistence( private val coroutineDispatchers: CoroutineDispatchers, ) : RoomStore { - override suspend fun persist(roomId: RoomId, state: RoomState) { + override suspend fun persist(roomId: RoomId, events: List) { coroutineDispatchers.withIoContext { database.transaction { - state.events.forEach { + events.forEach { database.roomEventQueries.insertRoomEvent(roomId, it) } } @@ -38,9 +38,16 @@ internal class RoomPersistence( } override suspend fun remove(rooms: List) { - coroutineDispatchers - database.roomEventQueries.transaction { - rooms.forEach { database.roomEventQueries.remove(it.value) } + coroutineDispatchers.withIoContext { + database.roomEventQueries.transaction { + rooms.forEach { database.roomEventQueries.remove(it.value) } + } + } + } + + override suspend fun remove(eventId: EventId) { + coroutineDispatchers.withIoContext { + database.roomEventQueries.removeEvent(eventId.value) } } diff --git a/domains/store/src/main/sqldelight/app/dapk/db/model/RoomEvent.sq b/domains/store/src/main/sqldelight/app/dapk/db/model/RoomEvent.sq index 46883cf..d6067ed 100644 --- a/domains/store/src/main/sqldelight/app/dapk/db/model/RoomEvent.sq +++ b/domains/store/src/main/sqldelight/app/dapk/db/model/RoomEvent.sq @@ -36,4 +36,8 @@ LIMIT 100; remove: DELETE FROM dbRoomEvent -WHERE room_id = ?; \ No newline at end of file +WHERE room_id = ?; + +removeEvent: +DELETE FROM dbRoomEvent +WHERE event_id = ?; \ No newline at end of file diff --git a/matrix/services/sync/src/main/kotlin/app/dapk/st/matrix/sync/RoomState.kt b/matrix/services/sync/src/main/kotlin/app/dapk/st/matrix/sync/RoomState.kt index 139c7cc..68dcd8c 100644 --- a/matrix/services/sync/src/main/kotlin/app/dapk/st/matrix/sync/RoomState.kt +++ b/matrix/services/sync/src/main/kotlin/app/dapk/st/matrix/sync/RoomState.kt @@ -35,6 +35,7 @@ sealed class RoomEvent { @SerialName("meta") override val meta: MessageMeta, @SerialName("encrypted_content") val encryptedContent: MegOlmV1? = null, @SerialName("edited") val edited: Boolean = false, + @SerialName("redacted") val redacted: Boolean = false, ) : RoomEvent() { @Serializable diff --git a/matrix/services/sync/src/main/kotlin/app/dapk/st/matrix/sync/Store.kt b/matrix/services/sync/src/main/kotlin/app/dapk/st/matrix/sync/Store.kt index 6964ff4..2d43ad7 100644 --- a/matrix/services/sync/src/main/kotlin/app/dapk/st/matrix/sync/Store.kt +++ b/matrix/services/sync/src/main/kotlin/app/dapk/st/matrix/sync/Store.kt @@ -7,8 +7,9 @@ import kotlinx.coroutines.flow.Flow interface RoomStore { - suspend fun persist(roomId: RoomId, state: RoomState) + suspend fun persist(roomId: RoomId, events: List) suspend fun remove(rooms: List) + suspend fun remove(eventId: EventId) suspend fun retrieve(roomId: RoomId): RoomState? fun latest(roomId: RoomId): Flow suspend fun insertUnread(roomId: RoomId, eventIds: List) diff --git a/matrix/services/sync/src/main/kotlin/app/dapk/st/matrix/sync/internal/sync/RoomDataSource.kt b/matrix/services/sync/src/main/kotlin/app/dapk/st/matrix/sync/internal/sync/RoomDataSource.kt index df4bb80..7ab8f17 100644 --- a/matrix/services/sync/src/main/kotlin/app/dapk/st/matrix/sync/internal/sync/RoomDataSource.kt +++ b/matrix/services/sync/src/main/kotlin/app/dapk/st/matrix/sync/internal/sync/RoomDataSource.kt @@ -1,9 +1,7 @@ package app.dapk.st.matrix.sync.internal.sync -import app.dapk.st.matrix.common.MatrixLogTag -import app.dapk.st.matrix.common.MatrixLogger -import app.dapk.st.matrix.common.RoomId -import app.dapk.st.matrix.common.matrixLog +import app.dapk.st.matrix.common.* +import app.dapk.st.matrix.sync.RoomEvent import app.dapk.st.matrix.sync.RoomState import app.dapk.st.matrix.sync.RoomStore @@ -26,7 +24,7 @@ class RoomDataSource( logger.matrixLog(MatrixLogTag.SYNC, "no changes, not persisting") } else { roomCache[roomId] = newState - roomStore.persist(roomId, newState) + roomStore.persist(roomId, newState.events) } } @@ -34,4 +32,35 @@ class RoomDataSource( roomsLeft.forEach { roomCache.remove(it) } roomStore.remove(roomsLeft) } + + suspend fun redact(roomId: RoomId, event: EventId) { + val eventToRedactFromCache = roomCache[roomId]?.events?.find { it.eventId == event } + val redactedEvent = when { + eventToRedactFromCache != null -> { + eventToRedactFromCache.redact().also { redacted -> + val cachedRoomState = roomCache[roomId] + requireNotNull(cachedRoomState) + roomCache[roomId] = cachedRoomState.replaceEvent(eventToRedactFromCache, redacted) + } + } + + else -> roomStore.findEvent(event)?.redact() + } + + redactedEvent?.let { roomStore.persist(roomId, listOf(it)) } + } +} + +private fun RoomEvent.redact() = when (this) { + is RoomEvent.Image -> RoomEvent.Message(this.eventId, this.utcTimestamp, "Redacted", this.author, this.meta, redacted = true) + is RoomEvent.Message -> RoomEvent.Message(this.eventId, this.utcTimestamp, "Redacted", this.author, this.meta, redacted = true) + is RoomEvent.Reply -> RoomEvent.Message(this.eventId, this.utcTimestamp, "Redacted", this.author, this.meta, redacted = true) +} + +private fun RoomState.replaceEvent(old: RoomEvent, new: RoomEvent): RoomState { + val updatedEvents = this.events.toMutableList().apply { + remove(old) + add(new) + } + return this.copy(events = updatedEvents) } \ No newline at end of file diff --git a/matrix/services/sync/src/main/kotlin/app/dapk/st/matrix/sync/internal/sync/RoomProcessor.kt b/matrix/services/sync/src/main/kotlin/app/dapk/st/matrix/sync/internal/sync/RoomProcessor.kt index 5eb0353..d73f9f7 100644 --- a/matrix/services/sync/src/main/kotlin/app/dapk/st/matrix/sync/internal/sync/RoomProcessor.kt +++ b/matrix/services/sync/src/main/kotlin/app/dapk/st/matrix/sync/internal/sync/RoomProcessor.kt @@ -21,6 +21,10 @@ internal class RoomProcessor( val members = roomToProcess.apiSyncRoom.collectMembers(roomToProcess.userCredentials) roomMembersService.insert(roomToProcess.roomId, members) + roomToProcess.apiSyncRoom.timeline.apiTimelineEvents.filterIsInstance().forEach { + roomDataSource.redact(roomToProcess.roomId, it.redactedId) + } + val previousState = roomDataSource.read(roomToProcess.roomId) val (newEvents, distinctEvents) = timelineEventsProcessor.process( diff --git a/matrix/services/sync/src/main/kotlin/app/dapk/st/matrix/sync/internal/sync/SyncReducer.kt b/matrix/services/sync/src/main/kotlin/app/dapk/st/matrix/sync/internal/sync/SyncReducer.kt index 5875854..9bba338 100644 --- a/matrix/services/sync/src/main/kotlin/app/dapk/st/matrix/sync/internal/sync/SyncReducer.kt +++ b/matrix/services/sync/src/main/kotlin/app/dapk/st/matrix/sync/internal/sync/SyncReducer.kt @@ -61,8 +61,6 @@ internal class SyncReducer( } } - roomDataSource.remove(roomsLeft) - return ReducerResult( newRooms, (apiRoomsToProcess + roomsWithSideEffects).awaitAll().filterNotNull(),