mirror of
https://github.com/vector-im/element-android.git
synced 2024-11-15 01:35:07 +08:00
Introduce ContentMapper, allowing to map a content directly without going through an event entity.
This commit is contained in:
parent
d9e24558ec
commit
0f667fe6e8
@ -0,0 +1,20 @@
|
||||
package im.vector.matrix.android.internal.database.mapper
|
||||
|
||||
import im.vector.matrix.android.api.session.events.model.Content
|
||||
import im.vector.matrix.android.api.session.events.model.Event
|
||||
import im.vector.matrix.android.internal.di.MoshiProvider
|
||||
|
||||
internal object ContentMapper {
|
||||
|
||||
private val moshi = MoshiProvider.providesMoshi()
|
||||
private val adapter = moshi.adapter<Content>(Event.CONTENT_TYPE)
|
||||
|
||||
fun map(content: String?): Content? {
|
||||
return adapter.fromJson(content ?: "")
|
||||
}
|
||||
|
||||
fun map(content: Content?): String {
|
||||
return adapter.toJson(content)
|
||||
}
|
||||
|
||||
}
|
@ -3,17 +3,23 @@ package im.vector.matrix.android.internal.database.mapper
|
||||
import im.vector.matrix.android.api.session.events.model.Event
|
||||
import im.vector.matrix.android.api.session.events.model.UnsignedData
|
||||
import im.vector.matrix.android.internal.database.model.EventEntity
|
||||
import im.vector.matrix.android.internal.di.MoshiProvider
|
||||
|
||||
|
||||
internal object EventMapper {
|
||||
|
||||
private val moshi = MoshiProvider.providesMoshi()
|
||||
private val adapter = moshi.adapter<Map<String, Any>>(Event.CONTENT_TYPE)
|
||||
|
||||
fun map(event: Event): EventEntity {
|
||||
val eventEntity = EventEntity()
|
||||
fill(eventEntity, with = event)
|
||||
eventEntity.eventId = event.eventId ?: ""
|
||||
eventEntity.content = ContentMapper.map(event.content)
|
||||
val resolvedPrevContent = event.prevContent ?: event.unsignedData?.prevContent
|
||||
eventEntity.prevContent = ContentMapper.map(resolvedPrevContent)
|
||||
eventEntity.stateKey = event.stateKey
|
||||
eventEntity.type = event.type
|
||||
eventEntity.sender = event.sender
|
||||
eventEntity.originServerTs = event.originServerTs
|
||||
eventEntity.redacts = event.redacts
|
||||
eventEntity.age = event.unsignedData?.age ?: event.originServerTs
|
||||
return eventEntity
|
||||
}
|
||||
|
||||
@ -21,8 +27,8 @@ internal object EventMapper {
|
||||
return Event(
|
||||
type = eventEntity.type,
|
||||
eventId = eventEntity.eventId,
|
||||
content = adapter.fromJson(eventEntity.content),
|
||||
prevContent = adapter.fromJson(eventEntity.prevContent ?: ""),
|
||||
content = ContentMapper.map(eventEntity.content),
|
||||
prevContent = ContentMapper.map(eventEntity.prevContent),
|
||||
originServerTs = eventEntity.originServerTs,
|
||||
sender = eventEntity.sender,
|
||||
stateKey = eventEntity.stateKey,
|
||||
@ -32,18 +38,6 @@ internal object EventMapper {
|
||||
)
|
||||
}
|
||||
|
||||
fun fill(eventEntity: EventEntity, with: Event) {
|
||||
eventEntity.eventId = with.eventId ?: ""
|
||||
eventEntity.content = adapter.toJson(with.content)
|
||||
val resolvedPrevContent = with.prevContent ?: with.unsignedData?.prevContent
|
||||
eventEntity.prevContent = adapter.toJson(resolvedPrevContent)
|
||||
eventEntity.stateKey = with.stateKey
|
||||
eventEntity.type = with.type
|
||||
eventEntity.sender = with.sender
|
||||
eventEntity.originServerTs = with.originServerTs
|
||||
eventEntity.redacts = with.redacts
|
||||
eventEntity.age = with.unsignedData?.age ?: with.originServerTs
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -54,7 +48,3 @@ internal fun EventEntity.asDomain(): Event {
|
||||
internal fun Event.asEntity(): EventEntity {
|
||||
return EventMapper.map(this)
|
||||
}
|
||||
|
||||
internal fun EventEntity.fillWith(event: Event) {
|
||||
EventMapper.fill(this, with = event)
|
||||
}
|
||||
|
@ -3,13 +3,11 @@ package im.vector.matrix.android.internal.session.events.prune
|
||||
import android.content.Context
|
||||
import androidx.work.Worker
|
||||
import androidx.work.WorkerParameters
|
||||
import arrow.core.Option
|
||||
import com.squareup.moshi.JsonClass
|
||||
import com.zhuinden.monarchy.Monarchy
|
||||
import im.vector.matrix.android.api.session.events.model.Event
|
||||
import im.vector.matrix.android.api.session.events.model.EventType
|
||||
import im.vector.matrix.android.internal.database.mapper.asDomain
|
||||
import im.vector.matrix.android.internal.database.mapper.asEntity
|
||||
import im.vector.matrix.android.internal.database.mapper.ContentMapper
|
||||
import im.vector.matrix.android.internal.database.model.EventEntity
|
||||
import im.vector.matrix.android.internal.database.query.where
|
||||
import im.vector.matrix.android.internal.util.WorkerParamsFactory
|
||||
@ -33,7 +31,7 @@ internal class PruneEventWorker(context: Context,
|
||||
|
||||
override fun doWork(): Result {
|
||||
val params = WorkerParamsFactory.fromData<Params>(inputData)
|
||||
?: return Result.failure()
|
||||
?: return Result.failure()
|
||||
|
||||
val result = monarchy.tryTransactionAsync { realm ->
|
||||
params.updateIndexes.forEach { index ->
|
||||
@ -48,39 +46,36 @@ internal class PruneEventWorker(context: Context,
|
||||
if (redactionEvent == null || redactionEvent.redacts.isNullOrEmpty()) {
|
||||
return
|
||||
}
|
||||
val eventToPrune = EventEntity.where(realm, eventId = redactionEvent.redacts).findFirst()?.asDomain()
|
||||
?: return
|
||||
val eventToPrune = EventEntity.where(realm, eventId = redactionEvent.redacts).findFirst()
|
||||
?: return
|
||||
|
||||
val allowedKeys = computeAllowedKeys(eventToPrune.type)
|
||||
val prunedContent = allowedKeys.fold(
|
||||
{ eventToPrune.content },
|
||||
{ eventToPrune.content?.filterKeys { key -> it.contains(key) } }
|
||||
)
|
||||
val eventToPruneEntity = eventToPrune.copy(content = prunedContent).asEntity()
|
||||
realm.insertOrUpdate(eventToPruneEntity)
|
||||
if (allowedKeys.isNotEmpty()) {
|
||||
val prunedContent = ContentMapper.map(eventToPrune.content)?.filterKeys { key -> allowedKeys.contains(key) }
|
||||
eventToPrune.content = ContentMapper.map(prunedContent)
|
||||
}
|
||||
}
|
||||
|
||||
private fun computeAllowedKeys(type: String): Option<List<String>> {
|
||||
private fun computeAllowedKeys(type: String): List<String> {
|
||||
// Add filtered content, allowed keys in content depends on the event type
|
||||
val result = when (type) {
|
||||
EventType.STATE_ROOM_MEMBER -> listOf("membership")
|
||||
EventType.STATE_ROOM_CREATE -> listOf("creator")
|
||||
EventType.STATE_ROOM_JOIN_RULES -> listOf("join_rule")
|
||||
return when (type) {
|
||||
EventType.STATE_ROOM_MEMBER -> listOf("membership")
|
||||
EventType.STATE_ROOM_CREATE -> listOf("creator")
|
||||
EventType.STATE_ROOM_JOIN_RULES -> listOf("join_rule")
|
||||
EventType.STATE_ROOM_POWER_LEVELS -> listOf("users",
|
||||
"users_default",
|
||||
"events",
|
||||
"events_default",
|
||||
"state_default",
|
||||
"ban",
|
||||
"kick",
|
||||
"redact",
|
||||
"invite")
|
||||
EventType.STATE_ROOM_ALIASES -> listOf("aliases")
|
||||
EventType.STATE_CANONICAL_ALIAS -> listOf("alias")
|
||||
EventType.FEEDBACK -> listOf("type", "target_event_id")
|
||||
else -> null
|
||||
"users_default",
|
||||
"events",
|
||||
"events_default",
|
||||
"state_default",
|
||||
"ban",
|
||||
"kick",
|
||||
"redact",
|
||||
"invite")
|
||||
EventType.STATE_ROOM_ALIASES -> listOf("aliases")
|
||||
EventType.STATE_CANONICAL_ALIAS -> listOf("alias")
|
||||
EventType.FEEDBACK -> listOf("type", "target_event_id")
|
||||
else -> emptyList()
|
||||
}
|
||||
return Option.fromNullable(result)
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user