Refactor a bit EnrichedEvent and Content. Metadata will only be used for unexpected data.

This commit is contained in:
ganfra 2018-12-18 12:13:46 +01:00
parent de4281c954
commit 39ad44e9aa
16 changed files with 73 additions and 129 deletions

View File

@ -1,7 +1,7 @@
package im.vector.riotredesign.features.home.room.detail.timeline package im.vector.riotredesign.features.home.room.detail.timeline


import im.vector.matrix.android.api.session.events.model.EnrichedEvent import im.vector.matrix.android.api.session.events.model.EnrichedEvent
import im.vector.matrix.android.api.session.events.model.roomMember import im.vector.matrix.android.api.session.events.model.toModel
import im.vector.matrix.android.api.session.room.model.MessageContent import im.vector.matrix.android.api.session.room.model.MessageContent
import org.threeten.bp.LocalDateTime import org.threeten.bp.LocalDateTime


@ -10,12 +10,12 @@ class MessageItemFactory(private val timelineDateFormatter: TimelineDateFormatte
private val messagesDisplayedWithInformation = HashSet<String?>() private val messagesDisplayedWithInformation = HashSet<String?>()


fun create(event: EnrichedEvent, nextEvent: EnrichedEvent?, addDaySeparator: Boolean, date: LocalDateTime): MessageItem? { fun create(event: EnrichedEvent, nextEvent: EnrichedEvent?, addDaySeparator: Boolean, date: LocalDateTime): MessageItem? {
val messageContent = event.root.content<MessageContent>() val messageContent: MessageContent? = event.root.content.toModel()
val roomMember = event.roomMember() val roomMember = event.roomMember
if (messageContent == null || roomMember == null) { if (messageContent == null || roomMember == null) {
return null return null
} }
val nextRoomMember = nextEvent?.roomMember() val nextRoomMember = nextEvent?.roomMember
if (addDaySeparator || nextRoomMember != roomMember) { if (addDaySeparator || nextRoomMember != roomMember) {
messagesDisplayedWithInformation.add(event.root.eventId) messagesDisplayedWithInformation.add(event.root.eventId)
} }

View File

@ -5,7 +5,6 @@ import com.airbnb.epoxy.EpoxyAsyncUtil
import com.airbnb.epoxy.EpoxyController import com.airbnb.epoxy.EpoxyController
import im.vector.matrix.android.api.session.events.model.EnrichedEvent import im.vector.matrix.android.api.session.events.model.EnrichedEvent
import im.vector.matrix.android.api.session.events.model.EventType import im.vector.matrix.android.api.session.events.model.EventType
import im.vector.matrix.android.api.session.events.model.localId
import im.vector.riotredesign.core.extensions.localDateTime import im.vector.riotredesign.core.extensions.localDateTime
import im.vector.riotredesign.features.home.LoadingItemModel_ import im.vector.riotredesign.features.home.LoadingItemModel_


@ -67,7 +66,7 @@ class TimelineEventController(private val roomId: String,
} }
item item
?.onBind { timeline?.loadAround(index) } ?.onBind { timeline?.loadAround(index) }
?.id(event.localId()) ?.id(event.localId)
?.addTo(this) ?.addTo(this)


if (addDaySeparator) { if (addDaySeparator) {

View File

@ -2,7 +2,11 @@ package im.vector.matrix.android.api.session.events.model


import im.vector.matrix.android.api.session.room.model.RoomMember import im.vector.matrix.android.api.session.room.model.RoomMember


data class EnrichedEvent(val root: Event) { data class EnrichedEvent(
val root: Event,
val localId: String,
val roomMember: RoomMember?
) {


val metadata = HashMap<String, Any>() val metadata = HashMap<String, Any>()


@ -18,20 +22,4 @@ data class EnrichedEvent(val root: Event) {
inline fun <reified T> getMetadata(key: String): T? { inline fun <reified T> getMetadata(key: String): T? {
return metadata[key] as T? return metadata[key] as T?
} }

companion object {
const val ROOM_MEMBER = "ROOM_MEMBER"
const val IS_LAST_EVENT = "IS_LAST_EVENT"
const val READ_RECEIPTS = "READ_RECEIPTS"
const val LOCAL_ID = "LOCAL_ID"
}

}

fun EnrichedEvent.roomMember(): RoomMember? {
return getMetadata<RoomMember>(EnrichedEvent.ROOM_MEMBER)
}

fun EnrichedEvent.localId(): String? {
return getMetadata<String>(EnrichedEvent.LOCAL_ID)
} }

View File

@ -8,6 +8,14 @@ import java.lang.reflect.ParameterizedType


typealias Content = Map<String, @JvmSuppressWildcards Any> typealias Content = Map<String, @JvmSuppressWildcards Any>


inline fun <reified T> Content?.toModel(): T? {
return this?.let {
val moshi = MoshiProvider.providesMoshi()
val moshiAdapter = moshi.adapter(T::class.java)
return moshiAdapter.fromJsonValue(it)
}
}

@JsonClass(generateAdapter = true) @JsonClass(generateAdapter = true)
data class Event( data class Event(
@Json(name = "type") val type: String, @Json(name = "type") val type: String,
@ -27,28 +35,6 @@ data class Event(
return EventType.isStateEvent(type) return EventType.isStateEvent(type)
} }


inline fun <reified T> content(): T? {
return toModel(content)
}

inline fun <reified T> prevContent(): T? {
return toModel(prevContent)
}

inline fun <reified T> toModel(data: Content?): T? {
val moshi = MoshiProvider.providesMoshi()
val moshiAdapter = moshi.adapter(T::class.java)
return moshiAdapter.fromJsonValue(data)
}

internal inline fun <reified T> pickContent(stateIndex: Int): T? {
return if (stateIndex < 0) {
prevContent<T>()
} else {
content<T>()
}
}

companion object { companion object {
internal val CONTENT_TYPE: ParameterizedType = Types.newParameterizedType(Map::class.java, String::class.java, Any::class.java) internal val CONTENT_TYPE: ParameterizedType = Types.newParameterizedType(Map::class.java, String::class.java, Any::class.java)
} }

View File

@ -67,4 +67,4 @@ object EventType {
return STATE_EVENTS.contains(type) return STATE_EVENTS.contains(type)
} }


} }

View File

@ -10,11 +10,15 @@ internal object ContentMapper {
private val adapter = moshi.adapter<Content>(Event.CONTENT_TYPE) private val adapter = moshi.adapter<Content>(Event.CONTENT_TYPE)


fun map(content: String?): Content? { fun map(content: String?): Content? {
return adapter.fromJson(content ?: "") return content?.let {
adapter.fromJson(it)
}
} }


fun map(content: Content?): String { fun map(content: Content?): String? {
return adapter.toJson(content) return content?.let {
adapter.toJson(it)
}
} }


} }

View File

@ -9,7 +9,7 @@ import java.util.*
internal open class EventEntity(@PrimaryKey var localId: String = UUID.randomUUID().toString(), internal open class EventEntity(@PrimaryKey var localId: String = UUID.randomUUID().toString(),
var eventId: String = "", var eventId: String = "",
var type: String = "", var type: String = "",
var content: String = "", var content: String? = null,
var prevContent: String? = null, var prevContent: String? = null,
var stateKey: String? = null, var stateKey: String? = null,
var originServerTs: Long? = null, var originServerTs: Long? = null,

View File

@ -1,34 +0,0 @@
package im.vector.matrix.android.internal.session.events.interceptor

import com.zhuinden.monarchy.Monarchy
import im.vector.matrix.android.api.session.events.interceptor.EnrichedEventInterceptor
import im.vector.matrix.android.api.session.events.model.EnrichedEvent
import im.vector.matrix.android.api.session.events.model.EventType
import im.vector.matrix.android.internal.database.model.EventEntity
import im.vector.matrix.android.internal.database.query.where
import im.vector.matrix.android.internal.session.room.members.RoomMemberExtractor


internal class MessageEventInterceptor(private val monarchy: Monarchy,
private val roomId: String) : EnrichedEventInterceptor {

override fun canEnrich(event: EnrichedEvent): Boolean {
return event.root.type == EventType.MESSAGE
}

override fun enrich(event: EnrichedEvent) {
monarchy.doWithRealm { realm ->
if (event.root.eventId == null) {
return@doWithRealm
}
val rootEntity = EventEntity.where(realm, eventId = event.root.eventId).findFirst()
?: return@doWithRealm
event.enrichWith(EnrichedEvent.LOCAL_ID, rootEntity.localId)

val roomMember = RoomMemberExtractor(realm, roomId).extractFrom(rootEntity)
event.enrichWith(EnrichedEvent.ROOM_MEMBER, roomMember)
}
}


}

View File

@ -1,11 +1,12 @@
package im.vector.matrix.android.internal.session.room package im.vector.matrix.android.internal.session.room


import com.zhuinden.monarchy.Monarchy import com.zhuinden.monarchy.Monarchy
import im.vector.matrix.android.api.auth.data.Credentials
import im.vector.matrix.android.api.session.events.model.EventType import im.vector.matrix.android.api.session.events.model.EventType
import im.vector.matrix.android.api.session.events.model.toModel
import im.vector.matrix.android.api.session.room.Room import im.vector.matrix.android.api.session.room.Room
import im.vector.matrix.android.api.session.room.model.MyMembership import im.vector.matrix.android.api.session.room.model.MyMembership
import im.vector.matrix.android.api.session.room.model.RoomAvatarContent import im.vector.matrix.android.api.session.room.model.RoomAvatarContent
import im.vector.matrix.android.api.auth.data.Credentials
import im.vector.matrix.android.internal.database.mapper.asDomain import im.vector.matrix.android.internal.database.mapper.asDomain
import im.vector.matrix.android.internal.database.model.EventEntity import im.vector.matrix.android.internal.database.model.EventEntity
import im.vector.matrix.android.internal.database.query.last import im.vector.matrix.android.internal.database.query.last
@ -24,7 +25,7 @@ internal class RoomAvatarResolver(private val monarchy: Monarchy,
var res: String? = null var res: String? = null
monarchy.doWithRealm { realm -> monarchy.doWithRealm { realm ->
val roomName = EventEntity.where(realm, room.roomId, EventType.STATE_ROOM_AVATAR).last()?.asDomain() val roomName = EventEntity.where(realm, room.roomId, EventType.STATE_ROOM_AVATAR).last()?.asDomain()
res = roomName?.content<RoomAvatarContent>()?.avatarUrl res = roomName?.content.toModel<RoomAvatarContent>()?.avatarUrl
if (!res.isNullOrEmpty()) { if (!res.isNullOrEmpty()) {
return@doWithRealm return@doWithRealm
} }

View File

@ -7,10 +7,11 @@ import im.vector.matrix.android.api.session.room.send.EventFactory
import im.vector.matrix.android.internal.session.DefaultSession import im.vector.matrix.android.internal.session.DefaultSession
import im.vector.matrix.android.internal.session.room.members.DefaultLoadRoomMembersTask import im.vector.matrix.android.internal.session.room.members.DefaultLoadRoomMembersTask
import im.vector.matrix.android.internal.session.room.members.LoadRoomMembersTask import im.vector.matrix.android.internal.session.room.members.LoadRoomMembersTask
import im.vector.matrix.android.internal.session.room.members.RoomMemberExtractor
import im.vector.matrix.android.internal.session.room.send.DefaultSendService import im.vector.matrix.android.internal.session.room.send.DefaultSendService
import im.vector.matrix.android.internal.session.room.timeline.DefaultTimelineHolder
import im.vector.matrix.android.internal.session.room.timeline.DefaultGetContextOfEventTask import im.vector.matrix.android.internal.session.room.timeline.DefaultGetContextOfEventTask
import im.vector.matrix.android.internal.session.room.timeline.DefaultPaginationTask import im.vector.matrix.android.internal.session.room.timeline.DefaultPaginationTask
import im.vector.matrix.android.internal.session.room.timeline.DefaultTimelineHolder
import im.vector.matrix.android.internal.session.room.timeline.GetContextOfEventTask import im.vector.matrix.android.internal.session.room.timeline.GetContextOfEventTask
import im.vector.matrix.android.internal.session.room.timeline.PaginationTask import im.vector.matrix.android.internal.session.room.timeline.PaginationTask
import im.vector.matrix.android.internal.session.room.timeline.TimelineBoundaryCallback import im.vector.matrix.android.internal.session.room.timeline.TimelineBoundaryCallback
@ -54,7 +55,8 @@ class RoomModule {
factory { (roomId: String) -> factory { (roomId: String) ->
val helper = PagingRequestHelper(Executors.newSingleThreadExecutor()) val helper = PagingRequestHelper(Executors.newSingleThreadExecutor())
val timelineBoundaryCallback = TimelineBoundaryCallback(roomId, get(), get(), get(), helper) val timelineBoundaryCallback = TimelineBoundaryCallback(roomId, get(), get(), get(), helper)
DefaultTimelineHolder(roomId, get(), get() , timelineBoundaryCallback, get()) as TimelineHolder val roomMemberExtractor = RoomMemberExtractor(get(), roomId)
DefaultTimelineHolder(roomId, get(), get(), timelineBoundaryCallback, get(), roomMemberExtractor) as TimelineHolder
} }


factory { (roomId: String) -> factory { (roomId: String) ->

View File

@ -2,10 +2,11 @@ package im.vector.matrix.android.internal.session.room


import android.content.Context import android.content.Context
import com.zhuinden.monarchy.Monarchy import com.zhuinden.monarchy.Monarchy
import im.vector.matrix.android.api.auth.data.Credentials
import im.vector.matrix.android.api.session.events.model.EventType import im.vector.matrix.android.api.session.events.model.EventType
import im.vector.matrix.android.api.session.events.model.toModel
import im.vector.matrix.android.api.session.room.Room import im.vector.matrix.android.api.session.room.Room
import im.vector.matrix.android.api.session.room.model.RoomTopicContent import im.vector.matrix.android.api.session.room.model.RoomTopicContent
import im.vector.matrix.android.api.auth.data.Credentials
import im.vector.matrix.android.internal.database.RealmLiveEntityObserver import im.vector.matrix.android.internal.database.RealmLiveEntityObserver
import im.vector.matrix.android.internal.database.mapper.asDomain import im.vector.matrix.android.internal.database.mapper.asDomain
import im.vector.matrix.android.internal.database.model.EventEntity import im.vector.matrix.android.internal.database.model.EventEntity
@ -43,7 +44,7 @@ internal class RoomSummaryUpdater(monarchy: Monarchy,
return return
} }
val roomSummary = RoomSummaryEntity.where(realm, room.roomId).findFirst() val roomSummary = RoomSummaryEntity.where(realm, room.roomId).findFirst()
?: realm.createObject(room.roomId) ?: realm.createObject(room.roomId)


val lastMessageEvent = EventEntity.where(realm, room.roomId, EventType.MESSAGE).last() val lastMessageEvent = EventEntity.where(realm, room.roomId, EventType.MESSAGE).last()
val lastTopicEvent = EventEntity.where(realm, room.roomId, EventType.STATE_ROOM_TOPIC).last()?.asDomain() val lastTopicEvent = EventEntity.where(realm, room.roomId, EventType.STATE_ROOM_TOPIC).last()?.asDomain()
@ -52,7 +53,7 @@ internal class RoomSummaryUpdater(monarchy: Monarchy,


roomSummary.displayName = roomDisplayNameResolver.resolve(context, room).toString() roomSummary.displayName = roomDisplayNameResolver.resolve(context, room).toString()
roomSummary.avatarUrl = roomAvatarResolver.resolve(room) roomSummary.avatarUrl = roomAvatarResolver.resolve(room)
roomSummary.topic = lastTopicEvent?.content<RoomTopicContent>()?.topic roomSummary.topic = lastTopicEvent?.content.toModel<RoomTopicContent>()?.topic
roomSummary.lastMessage = lastMessageEvent roomSummary.lastMessage = lastMessageEvent
roomSummary.otherMemberIds.clear() roomSummary.otherMemberIds.clear()
roomSummary.otherMemberIds.addAll(otherRoomMembers.keys) roomSummary.otherMemberIds.addAll(otherRoomMembers.keys)

View File

@ -19,13 +19,14 @@ package im.vector.matrix.android.internal.session.room.members
import android.content.Context import android.content.Context
import com.zhuinden.monarchy.Monarchy import com.zhuinden.monarchy.Monarchy
import im.vector.matrix.android.R import im.vector.matrix.android.R
import im.vector.matrix.android.api.auth.data.Credentials
import im.vector.matrix.android.api.session.events.model.EventType import im.vector.matrix.android.api.session.events.model.EventType
import im.vector.matrix.android.api.session.events.model.toModel
import im.vector.matrix.android.api.session.room.Room import im.vector.matrix.android.api.session.room.Room
import im.vector.matrix.android.api.session.room.model.MyMembership import im.vector.matrix.android.api.session.room.model.MyMembership
import im.vector.matrix.android.api.session.room.model.RoomAliasesContent import im.vector.matrix.android.api.session.room.model.RoomAliasesContent
import im.vector.matrix.android.api.session.room.model.RoomCanonicalAliasContent import im.vector.matrix.android.api.session.room.model.RoomCanonicalAliasContent
import im.vector.matrix.android.api.session.room.model.RoomNameContent import im.vector.matrix.android.api.session.room.model.RoomNameContent
import im.vector.matrix.android.api.auth.data.Credentials
import im.vector.matrix.android.internal.database.mapper.asDomain import im.vector.matrix.android.internal.database.mapper.asDomain
import im.vector.matrix.android.internal.database.model.EventEntity import im.vector.matrix.android.internal.database.model.EventEntity
import im.vector.matrix.android.internal.database.model.RoomSummaryEntity import im.vector.matrix.android.internal.database.model.RoomSummaryEntity
@ -57,19 +58,19 @@ internal class RoomDisplayNameResolver(private val monarchy: Monarchy,
var name: CharSequence? = null var name: CharSequence? = null
monarchy.doWithRealm { realm -> monarchy.doWithRealm { realm ->
val roomName = EventEntity.where(realm, room.roomId, EventType.STATE_ROOM_NAME).last()?.asDomain() val roomName = EventEntity.where(realm, room.roomId, EventType.STATE_ROOM_NAME).last()?.asDomain()
name = roomName?.content<RoomNameContent>()?.name name = roomName?.content.toModel<RoomNameContent>()?.name
if (!name.isNullOrEmpty()) { if (!name.isNullOrEmpty()) {
return@doWithRealm return@doWithRealm
} }


val canonicalAlias = EventEntity.where(realm, room.roomId, EventType.STATE_CANONICAL_ALIAS).last()?.asDomain() val canonicalAlias = EventEntity.where(realm, room.roomId, EventType.STATE_CANONICAL_ALIAS).last()?.asDomain()
name = canonicalAlias?.content<RoomCanonicalAliasContent>()?.canonicalAlias name = canonicalAlias?.content.toModel<RoomCanonicalAliasContent>()?.canonicalAlias
if (!name.isNullOrEmpty()) { if (!name.isNullOrEmpty()) {
return@doWithRealm return@doWithRealm
} }


val aliases = EventEntity.where(realm, room.roomId, EventType.STATE_ROOM_ALIASES).last()?.asDomain() val aliases = EventEntity.where(realm, room.roomId, EventType.STATE_ROOM_ALIASES).last()?.asDomain()
name = aliases?.content<RoomAliasesContent>()?.aliases?.firstOrNull() name = aliases?.content.toModel<RoomAliasesContent>()?.aliases?.firstOrNull()
if (!name.isNullOrEmpty()) { if (!name.isNullOrEmpty()) {
return@doWithRealm return@doWithRealm
} }

View File

@ -1,17 +1,18 @@
package im.vector.matrix.android.internal.session.room.members package im.vector.matrix.android.internal.session.room.members


import com.zhuinden.monarchy.Monarchy
import im.vector.matrix.android.api.session.events.model.EventType import im.vector.matrix.android.api.session.events.model.EventType
import im.vector.matrix.android.api.session.events.model.toModel
import im.vector.matrix.android.api.session.room.model.RoomMember import im.vector.matrix.android.api.session.room.model.RoomMember
import im.vector.matrix.android.internal.database.mapper.asDomain 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.model.EventEntity
import im.vector.matrix.android.internal.database.model.EventEntityFields import im.vector.matrix.android.internal.database.model.EventEntityFields
import im.vector.matrix.android.internal.database.query.last import im.vector.matrix.android.internal.database.query.last
import im.vector.matrix.android.internal.database.query.next import im.vector.matrix.android.internal.database.query.next
import im.vector.matrix.android.internal.database.query.where import im.vector.matrix.android.internal.database.query.where
import io.realm.Realm
import io.realm.RealmQuery import io.realm.RealmQuery


internal class RoomMemberExtractor(private val realm: Realm, internal class RoomMemberExtractor(private val monarchy: Monarchy,
private val roomId: String) { private val roomId: String) {


fun extractFrom(event: EventEntity): RoomMember? { fun extractFrom(event: EventEntity): RoomMember? {
@ -20,24 +21,28 @@ internal class RoomMemberExtractor(private val realm: Realm,
val unlinked = event.isUnlinked val unlinked = event.isUnlinked
// When stateIndex is negative, we try to get the next stateEvent prevContent() // When stateIndex is negative, we try to get the next stateEvent prevContent()
// If prevContent is null we fallback to the Int.MIN state events content() // If prevContent is null we fallback to the Int.MIN state events content()
return if (event.stateIndex <= 0) { val content = if (event.stateIndex <= 0) {
baseQuery(realm, roomId, sender, unlinked).next(from = event.stateIndex)?.asDomain()?.prevContent() baseQuery(monarchy, roomId, sender, unlinked).next(from = event.stateIndex)?.prevContent
?: baseQuery(realm, roomId, sender, unlinked).last(since = event.stateIndex)?.asDomain()?.content() ?: baseQuery(monarchy, roomId, sender, unlinked).last(since = event.stateIndex)?.content
} else { } else {
baseQuery(realm, roomId, sender, unlinked).last(since = event.stateIndex)?.asDomain()?.content() baseQuery(monarchy, roomId, sender, unlinked).last(since = event.stateIndex)?.content
} }
return ContentMapper.map(content).toModel()
} }


private fun baseQuery(realm: Realm, private fun baseQuery(monarchy: Monarchy,
roomId: String, roomId: String,
sender: String, sender: String,
isUnlinked: Boolean): RealmQuery<EventEntity> { isUnlinked: Boolean): RealmQuery<EventEntity> {

lateinit var query: RealmQuery<EventEntity>
val filterMode = if (isUnlinked) EventEntity.LinkFilterMode.UNLINKED_ONLY else EventEntity.LinkFilterMode.LINKED_ONLY val filterMode = if (isUnlinked) EventEntity.LinkFilterMode.UNLINKED_ONLY else EventEntity.LinkFilterMode.LINKED_ONLY

monarchy.doWithRealm { realm ->
return EventEntity query = EventEntity
.where(realm, roomId = roomId, type = EventType.STATE_ROOM_MEMBER, linkFilterMode = filterMode) .where(realm, roomId = roomId, type = EventType.STATE_ROOM_MEMBER, linkFilterMode = filterMode)
.equalTo(EventEntityFields.STATE_KEY, sender) .equalTo(EventEntityFields.STATE_KEY, sender)

}
return query
} }





View File

@ -1,6 +1,7 @@
package im.vector.matrix.android.internal.session.room.members package im.vector.matrix.android.internal.session.room.members


import im.vector.matrix.android.api.session.events.model.EventType import im.vector.matrix.android.api.session.events.model.EventType
import im.vector.matrix.android.api.session.events.model.toModel
import im.vector.matrix.android.api.session.room.model.Membership import im.vector.matrix.android.api.session.room.model.Membership
import im.vector.matrix.android.api.session.room.model.RoomMember import im.vector.matrix.android.api.session.room.model.RoomMember
import im.vector.matrix.android.internal.database.mapper.asDomain import im.vector.matrix.android.internal.database.mapper.asDomain
@ -25,7 +26,7 @@ internal class RoomMembers(private val realm: Realm,
.findAll() .findAll()
.map { it.asDomain() } .map { it.asDomain() }
.associateBy { it.stateKey!! } .associateBy { it.stateKey!! }
.mapValues { it.value.content<RoomMember>()!! } .mapValues { it.value.content.toModel<RoomMember>()!! }
} }





View File

@ -7,14 +7,14 @@ import com.zhuinden.monarchy.Monarchy
import im.vector.matrix.android.api.session.events.interceptor.EnrichedEventInterceptor import im.vector.matrix.android.api.session.events.interceptor.EnrichedEventInterceptor
import im.vector.matrix.android.api.session.events.model.EnrichedEvent import im.vector.matrix.android.api.session.events.model.EnrichedEvent
import im.vector.matrix.android.api.session.room.TimelineHolder import im.vector.matrix.android.api.session.room.TimelineHolder
import im.vector.matrix.android.internal.task.TaskExecutor
import im.vector.matrix.android.internal.task.configureWith
import im.vector.matrix.android.internal.database.mapper.asDomain import im.vector.matrix.android.internal.database.mapper.asDomain
import im.vector.matrix.android.internal.database.model.ChunkEntityFields import im.vector.matrix.android.internal.database.model.ChunkEntityFields
import im.vector.matrix.android.internal.database.model.EventEntity import im.vector.matrix.android.internal.database.model.EventEntity
import im.vector.matrix.android.internal.database.model.EventEntityFields import im.vector.matrix.android.internal.database.model.EventEntityFields
import im.vector.matrix.android.internal.database.query.where import im.vector.matrix.android.internal.database.query.where
import im.vector.matrix.android.internal.session.events.interceptor.MessageEventInterceptor import im.vector.matrix.android.internal.session.room.members.RoomMemberExtractor
import im.vector.matrix.android.internal.task.TaskExecutor
import im.vector.matrix.android.internal.task.configureWith
import im.vector.matrix.android.internal.util.tryTransactionSync import im.vector.matrix.android.internal.util.tryTransactionSync
import io.realm.Realm import io.realm.Realm
import io.realm.RealmQuery import io.realm.RealmQuery
@ -25,15 +25,12 @@ internal class DefaultTimelineHolder(private val roomId: String,
private val monarchy: Monarchy, private val monarchy: Monarchy,
private val taskExecutor: TaskExecutor, private val taskExecutor: TaskExecutor,
private val boundaryCallback: TimelineBoundaryCallback, private val boundaryCallback: TimelineBoundaryCallback,
private val contextOfEventTask: GetContextOfEventTask private val contextOfEventTask: GetContextOfEventTask,
private val roomMemberExtractor: RoomMemberExtractor
) : TimelineHolder { ) : TimelineHolder {


private val eventInterceptors = ArrayList<EnrichedEventInterceptor>() private val eventInterceptors = ArrayList<EnrichedEventInterceptor>()


init {
eventInterceptors.add(MessageEventInterceptor(monarchy, roomId))
}

override fun timeline(eventId: String?): LiveData<PagedList<EnrichedEvent>> { override fun timeline(eventId: String?): LiveData<PagedList<EnrichedEvent>> {
clearUnlinkedEvents() clearUnlinkedEvents()
if (eventId != null) { if (eventId != null) {
@ -43,17 +40,9 @@ internal class DefaultTimelineHolder(private val roomId: String,
buildDataSourceFactoryQuery(it, eventId) buildDataSourceFactoryQuery(it, eventId)
} }
val domainSourceFactory = realmDataSourceFactory val domainSourceFactory = realmDataSourceFactory
.map { it.asDomain() } .map { eventEntity ->
.map { event -> val roomMember = roomMemberExtractor.extractFrom(eventEntity)

EnrichedEvent(eventEntity.asDomain(), eventEntity.localId, roomMember)
val enrichedEvent = EnrichedEvent(event)
eventInterceptors
.filter {
it.canEnrich(enrichedEvent)
}.forEach {
it.enrich(enrichedEvent)
}
enrichedEvent
} }


val pagedListConfig = PagedList.Config.Builder() val pagedListConfig = PagedList.Config.Builder()

View File

@ -3,6 +3,7 @@ package im.vector.matrix.android.internal.session.sync
import com.zhuinden.monarchy.Monarchy import com.zhuinden.monarchy.Monarchy
import im.vector.matrix.android.api.session.events.model.Event 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.api.session.events.model.EventType
import im.vector.matrix.android.api.session.events.model.toModel
import im.vector.matrix.android.api.session.room.model.MyMembership import im.vector.matrix.android.api.session.room.model.MyMembership
import im.vector.matrix.android.internal.database.helper.addAll import im.vector.matrix.android.internal.database.helper.addAll
import im.vector.matrix.android.internal.database.helper.addOrUpdate import im.vector.matrix.android.internal.database.helper.addOrUpdate
@ -166,7 +167,7 @@ internal class RoomSyncHandler(private val monarchy: Monarchy,
ephemeral: RoomSyncEphemeral) { ephemeral: RoomSyncEphemeral) {
ephemeral.events ephemeral.events
.filter { it.type == EventType.RECEIPT } .filter { it.type == EventType.RECEIPT }
.map { it.content<ReadReceiptContent>() } .map { it.content.toModel<ReadReceiptContent>() }
.flatMap { readReceiptHandler.handle(realm, roomId, it) } .flatMap { readReceiptHandler.handle(realm, roomId, it) }
} }
} }