forked from GitHub-Mirror/riotX-android
Add a way to enrich event with useful data to be displayed.
This commit is contained in:
parent
0f4d15e488
commit
279241974a
@ -1,14 +1,18 @@
|
||||
package im.vector.riotredesign.features.home
|
||||
|
||||
import android.support.v7.util.DiffUtil
|
||||
import im.vector.matrix.android.api.session.events.model.Event
|
||||
import im.vector.matrix.android.api.session.events.model.EnrichedEvent
|
||||
|
||||
class EventDiffUtilCallback : DiffUtil.ItemCallback<Event>() {
|
||||
override fun areItemsTheSame(p0: Event, p1: Event): Boolean {
|
||||
return p0.eventId == p1.eventId
|
||||
class EventDiffUtilCallback : DiffUtil.ItemCallback<EnrichedEvent>() {
|
||||
override fun areItemsTheSame(p0: EnrichedEvent, p1: EnrichedEvent): Boolean {
|
||||
return p0.core.eventId == p1.core.eventId
|
||||
}
|
||||
|
||||
override fun areContentsTheSame(p0: Event, p1: Event): Boolean {
|
||||
return p0 == p1
|
||||
override fun areContentsTheSame(p0: EnrichedEvent, p1: EnrichedEvent): Boolean {
|
||||
return p0.core == p1.core
|
||||
&& p0.getMetaEvents()
|
||||
.zip(p1.getMetaEvents()) { a, b ->
|
||||
a.eventId == b.eventId
|
||||
}.none { !it }
|
||||
}
|
||||
}
|
@ -9,7 +9,7 @@ import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import im.vector.matrix.android.api.Matrix
|
||||
import im.vector.matrix.android.api.session.events.model.Event
|
||||
import im.vector.matrix.android.api.session.events.model.EnrichedEvent
|
||||
import im.vector.matrix.android.api.session.room.Room
|
||||
import im.vector.riotredesign.R
|
||||
import im.vector.riotredesign.core.platform.RiotFragment
|
||||
@ -46,7 +46,7 @@ class RoomDetailFragment : RiotFragment(), TimelineEventAdapter.Callback {
|
||||
room.liveTimeline().observe(this, Observer { renderEvents(it) })
|
||||
}
|
||||
|
||||
private fun renderEvents(events: PagedList<Event>?) {
|
||||
private fun renderEvents(events: PagedList<EnrichedEvent>?) {
|
||||
timelineAdapter.submitList(events)
|
||||
}
|
||||
|
||||
@ -65,7 +65,7 @@ class RoomDetailFragment : RiotFragment(), TimelineEventAdapter.Callback {
|
||||
//recyclerView.setController(timelineEventController)
|
||||
}
|
||||
|
||||
override fun onEventsListChanged(oldList: List<Event>?, newList: List<Event>?) {
|
||||
override fun onEventsListChanged(oldList: List<EnrichedEvent>?, newList: List<EnrichedEvent>?) {
|
||||
if (oldList == null && newList != null) {
|
||||
recyclerView.scrollToPosition(0)
|
||||
}
|
||||
|
@ -7,7 +7,10 @@ import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.TextView
|
||||
import im.vector.matrix.android.api.session.events.model.Event
|
||||
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.room.model.MessageContent
|
||||
import im.vector.matrix.android.api.session.room.model.RoomMember
|
||||
import im.vector.riotredesign.R
|
||||
|
||||
/**
|
||||
@ -15,10 +18,10 @@ import im.vector.riotredesign.R
|
||||
*/
|
||||
|
||||
class TimelineEventAdapter(private val callback: Callback? = null)
|
||||
: PagedListAdapter<Event, TimelineEventAdapter.ViewHolder>(EventDiffUtilCallback()) {
|
||||
: PagedListAdapter<EnrichedEvent, TimelineEventAdapter.ViewHolder>(EventDiffUtilCallback()) {
|
||||
|
||||
|
||||
private var currentList: List<Event>? = null
|
||||
private var currentList: List<EnrichedEvent>? = null
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, position: Int): ViewHolder {
|
||||
val view = LayoutInflater.from(parent.context).inflate(R.layout.item_event, parent, false)
|
||||
@ -30,27 +33,33 @@ class TimelineEventAdapter(private val callback: Callback? = null)
|
||||
viewHolder.bind(event)
|
||||
}
|
||||
|
||||
|
||||
class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
|
||||
|
||||
val titleView = view.findViewById<TextView>(R.id.titleView)!!
|
||||
|
||||
fun bind(event: Event?) {
|
||||
if (event == null) {
|
||||
|
||||
fun bind(event: EnrichedEvent?) {
|
||||
if (event == null || event.core.type != EventType.MESSAGE) {
|
||||
titleView.text = null
|
||||
} else {
|
||||
titleView.text = event.toString()
|
||||
val messageContent = event.core.content<MessageContent>()
|
||||
val roomMember = event.getMetaEvents(EventType.STATE_ROOM_MEMBER).firstOrNull()?.content<RoomMember>()
|
||||
if (messageContent == null || roomMember == null) {
|
||||
titleView.text = null
|
||||
} else {
|
||||
val text = "${roomMember.displayName} : ${messageContent.body}"
|
||||
titleView.text = text
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCurrentListChanged(newList: PagedList<Event>?) {
|
||||
override fun onCurrentListChanged(newList: PagedList<EnrichedEvent>?) {
|
||||
callback?.onEventsListChanged(currentList, newList)
|
||||
currentList = newList
|
||||
}
|
||||
|
||||
interface Callback {
|
||||
fun onEventsListChanged(oldList: List<Event>?, newList: List<Event>?)
|
||||
fun onEventsListChanged(oldList: List<EnrichedEvent>?, newList: List<EnrichedEvent>?)
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -13,7 +13,7 @@ class TimelineEventController : PagedListEpoxyController<Event>(
|
||||
return if (item == null) {
|
||||
LoadingItemModel_().id(-currentPosition)
|
||||
} else {
|
||||
TimelineEventItem(item.toString()).id(currentPosition)
|
||||
TimelineEventItem(item.toString()).id(item.eventId)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,12 @@
|
||||
package im.vector.matrix.android.api.session.events.interceptor
|
||||
|
||||
import im.vector.matrix.android.api.session.events.model.EnrichedEvent
|
||||
|
||||
interface EnrichedEventInterceptor {
|
||||
|
||||
fun enrich(roomId: String, event: EnrichedEvent)
|
||||
|
||||
fun canEnrich(event: EnrichedEvent): Boolean
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,29 @@
|
||||
package im.vector.matrix.android.api.session.events.interceptor
|
||||
|
||||
import com.zhuinden.monarchy.Monarchy
|
||||
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.mapper.asDomain
|
||||
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.where
|
||||
|
||||
class MessageEventInterceptor(val monarchy: Monarchy) : EnrichedEventInterceptor {
|
||||
|
||||
override fun canEnrich(event: EnrichedEvent): Boolean {
|
||||
return event.core.type == EventType.MESSAGE
|
||||
}
|
||||
|
||||
override fun enrich(roomId: String, event: EnrichedEvent) {
|
||||
monarchy.doWithRealm { realm ->
|
||||
val roomMember = EventEntity
|
||||
.where(realm, roomId, EventType.STATE_ROOM_MEMBER)
|
||||
.equalTo("stateKey", event.core.sender)
|
||||
.last(from = event.core.originServerTs)
|
||||
?.asDomain()
|
||||
event.enrichWith(roomMember)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
package im.vector.matrix.android.api.session.events.model
|
||||
|
||||
data class EnrichedEvent(val core: Event) {
|
||||
|
||||
private val metaEventsByType = HashMap<String, ArrayList<Event>>()
|
||||
|
||||
fun enrichWith(events: List<Event>) {
|
||||
events.forEach { enrichWith(it) }
|
||||
}
|
||||
|
||||
fun enrichWith(event: Event?) {
|
||||
if (event == null) {
|
||||
return
|
||||
}
|
||||
var currentEventsForType = metaEventsByType[event.type]
|
||||
if (currentEventsForType == null) {
|
||||
currentEventsForType = ArrayList()
|
||||
metaEventsByType[event.type] = currentEventsForType
|
||||
}
|
||||
currentEventsForType.add(event)
|
||||
}
|
||||
|
||||
fun getMetaEvents(type: String): List<Event> {
|
||||
return metaEventsByType[type] ?: emptyList()
|
||||
}
|
||||
|
||||
fun getMetaEvents(): List<Event> {
|
||||
return metaEventsByType.values.flatten()
|
||||
}
|
||||
|
||||
override fun toString(): String {
|
||||
return super.toString()
|
||||
}
|
||||
|
||||
}
|
@ -2,12 +2,12 @@ package im.vector.matrix.android.api.session.room
|
||||
|
||||
import android.arch.lifecycle.LiveData
|
||||
import android.arch.paging.PagedList
|
||||
import im.vector.matrix.android.api.session.events.model.Event
|
||||
import im.vector.matrix.android.api.session.events.model.EnrichedEvent
|
||||
|
||||
interface Room {
|
||||
|
||||
val roomId: String
|
||||
|
||||
fun liveTimeline(): LiveData<PagedList<Event>>
|
||||
fun liveTimeline(): LiveData<PagedList<EnrichedEvent>>
|
||||
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
package im.vector.matrix.android.api.session.room.model
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
import com.squareup.moshi.JsonClass
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class MessageContent(
|
||||
|
||||
@Json(name = "msgtype") val type: String? = null,
|
||||
@Json(name = "body") val body: String? = null,
|
||||
@Json(name = "format") val format: String? = null,
|
||||
@Json(name = "formatted_body") val formattedBody: String? = null
|
||||
|
||||
)
|
@ -0,0 +1,17 @@
|
||||
package im.vector.matrix.android.api.session.room.model
|
||||
|
||||
object MessageType {
|
||||
|
||||
val MSGTYPE_TEXT = "m.text"
|
||||
val MSGTYPE_EMOTE = "m.emote"
|
||||
val MSGTYPE_NOTICE = "m.notice"
|
||||
val MSGTYPE_IMAGE = "m.image"
|
||||
val MSGTYPE_AUDIO = "m.audio"
|
||||
val MSGTYPE_VIDEO = "m.video"
|
||||
val MSGTYPE_LOCATION = "m.location"
|
||||
val MSGTYPE_FILE = "m.file"
|
||||
val FORMAT_MATRIX_HTML = "org.matrix.custom.html"
|
||||
// Add, in local, a fake message type in order to StickerMessage can inherit Message class
|
||||
// Because sticker isn't a message type but a event type without msgtype field
|
||||
val MSGTYPE_STICKER_LOCAL = "org.matrix.android.sdk.sticker"
|
||||
}
|
@ -7,9 +7,9 @@ import im.vector.matrix.android.api.session.events.model.UnsignedData
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class RoomMember(
|
||||
@Json(name = "membership") val membership: Membership,
|
||||
@Json(name = "display_name") val displayDame: String? = null,
|
||||
@Json(name = "displayname") val displayName: String? = null,
|
||||
@Json(name = "avatar_url") val avatarUrl: String? = null,
|
||||
@Json(name = "is_direct") val isDirect: Boolean = false,
|
||||
@Json(name = "third_party_invite") val thirdPartyInvite: Invite? = null,
|
||||
@Json(name = "unsigned_data") val unsignedData: UnsignedData? = null
|
||||
@Json(name = "unsigned") val unsignedData: UnsignedData? = null
|
||||
)
|
||||
|
@ -1,32 +1,26 @@
|
||||
package im.vector.matrix.android.internal.database.query
|
||||
|
||||
import im.vector.matrix.android.internal.database.model.ChunkEntity
|
||||
import im.vector.matrix.android.internal.database.model.EventEntity
|
||||
import io.realm.Realm
|
||||
import io.realm.RealmQuery
|
||||
import io.realm.RealmResults
|
||||
import io.realm.Sort
|
||||
|
||||
fun EventEntity.Companion.where(realm: Realm, roomId: String): RealmQuery<EventEntity> {
|
||||
return realm.where(EventEntity::class.java)
|
||||
.equalTo("chunk.room.roomId", roomId)
|
||||
}
|
||||
|
||||
fun EventEntity.Companion.where(realm: Realm, chunk: ChunkEntity?): RealmQuery<EventEntity> {
|
||||
fun EventEntity.Companion.where(realm: Realm, roomId: String, type: String? = null): RealmQuery<EventEntity> {
|
||||
var query = realm.where(EventEntity::class.java)
|
||||
if (chunk?.prevToken != null) {
|
||||
query = query.equalTo("chunk.prevToken", chunk.prevToken)
|
||||
}
|
||||
if (chunk?.nextToken != null) {
|
||||
query = query.equalTo("chunk.nextToken", chunk.nextToken)
|
||||
.equalTo("chunk.room.roomId", roomId)
|
||||
if (type != null) {
|
||||
query = query.equalTo("type", type)
|
||||
}
|
||||
return query
|
||||
}
|
||||
|
||||
fun RealmResults<EventEntity>.getLast(type: String? = null): EventEntity? {
|
||||
var query = this.where().sort("originServerTs", Sort.DESCENDING)
|
||||
if (type != null) {
|
||||
query = query.equalTo("type", type)
|
||||
|
||||
fun RealmQuery<EventEntity>.last(from: Long? = null): EventEntity? {
|
||||
var query = this
|
||||
if (from != null) {
|
||||
query = query.lessThanOrEqualTo("originServerTs", from)
|
||||
}
|
||||
return query.findFirst()
|
||||
}
|
||||
return query
|
||||
.sort("originServerTs", Sort.DESCENDING)
|
||||
.findFirst()
|
||||
}
|
||||
|
@ -4,9 +4,11 @@ import android.arch.lifecycle.LiveData
|
||||
import android.arch.paging.LivePagedListBuilder
|
||||
import android.arch.paging.PagedList
|
||||
import com.zhuinden.monarchy.Monarchy
|
||||
import im.vector.matrix.android.api.session.events.model.Event
|
||||
import im.vector.matrix.android.api.session.events.interceptor.EnrichedEventInterceptor
|
||||
import im.vector.matrix.android.api.session.events.interceptor.MessageEventInterceptor
|
||||
import im.vector.matrix.android.api.session.events.model.EnrichedEvent
|
||||
import im.vector.matrix.android.api.session.room.Room
|
||||
import im.vector.matrix.android.internal.database.mapper.EventMapper
|
||||
import im.vector.matrix.android.internal.database.mapper.asDomain
|
||||
import im.vector.matrix.android.internal.database.model.ChunkEntity
|
||||
import im.vector.matrix.android.internal.database.query.where
|
||||
import im.vector.matrix.android.internal.session.room.timeline.PaginationRequest
|
||||
@ -23,8 +25,13 @@ data class DefaultRoom(
|
||||
private val paginationRequest by inject<PaginationRequest>()
|
||||
private val monarchy by inject<Monarchy>()
|
||||
private val boundaryCallback = TimelineBoundaryCallback(paginationRequest, roomId, monarchy, Executors.newSingleThreadExecutor())
|
||||
private val eventInterceptors = ArrayList<EnrichedEventInterceptor>()
|
||||
|
||||
override fun liveTimeline(): LiveData<PagedList<Event>> {
|
||||
init {
|
||||
eventInterceptors.add(MessageEventInterceptor(monarchy))
|
||||
}
|
||||
|
||||
override fun liveTimeline(): LiveData<PagedList<EnrichedEvent>> {
|
||||
val realmDataSourceFactory = monarchy.createDataSourceFactory { realm ->
|
||||
ChunkEntity.where(realm, roomId)
|
||||
.findAll()
|
||||
@ -33,7 +40,18 @@ data class DefaultRoom(
|
||||
it.events.where().sort("originServerTs", Sort.DESCENDING)
|
||||
}
|
||||
}
|
||||
val domainSourceFactory = realmDataSourceFactory.map { EventMapper.map(it) }
|
||||
val domainSourceFactory = realmDataSourceFactory
|
||||
.map { it.asDomain() }
|
||||
.map { event ->
|
||||
val enrichedEvent = EnrichedEvent(event)
|
||||
eventInterceptors
|
||||
.filter {
|
||||
it.canEnrich(enrichedEvent)
|
||||
}.forEach {
|
||||
it.enrich(roomId, enrichedEvent)
|
||||
}
|
||||
enrichedEvent
|
||||
}
|
||||
|
||||
val pagedListConfig = PagedList.Config.Builder()
|
||||
.setEnablePlaceholders(false)
|
||||
@ -45,5 +63,4 @@ data class DefaultRoom(
|
||||
return monarchy.findAllPagedWithChanges(realmDataSourceFactory, livePagedListBuilder)
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -8,7 +8,7 @@ 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.RoomEntity
|
||||
import im.vector.matrix.android.internal.database.model.RoomSummaryEntity
|
||||
import im.vector.matrix.android.internal.database.query.getLast
|
||||
import im.vector.matrix.android.internal.database.query.last
|
||||
import im.vector.matrix.android.internal.database.query.where
|
||||
import io.realm.RealmResults
|
||||
import java.util.concurrent.atomic.AtomicBoolean
|
||||
@ -49,10 +49,9 @@ internal class RoomSummaryObserver(private val monarchy: Monarchy) {
|
||||
|
||||
private fun manageRoom(roomId: String) {
|
||||
monarchy.writeAsync { realm ->
|
||||
val roomEvents = EventEntity.where(realm, roomId).findAll()
|
||||
val lastNameEvent = roomEvents.getLast(EventType.STATE_ROOM_NAME)?.asDomain()
|
||||
val lastTopicEvent = roomEvents.getLast(EventType.STATE_ROOM_TOPIC)?.asDomain()
|
||||
val lastMessageEvent = roomEvents.getLast(EventType.MESSAGE)
|
||||
val lastNameEvent = EventEntity.where(realm, roomId, EventType.STATE_ROOM_NAME).last()?.asDomain()
|
||||
val lastTopicEvent = EventEntity.where(realm, roomId, EventType.STATE_ROOM_TOPIC).last()?.asDomain()
|
||||
val lastMessageEvent = EventEntity.where(realm, roomId, EventType.MESSAGE).last()
|
||||
|
||||
val roomSummary = realm.copyToRealmOrUpdate(RoomSummaryEntity(roomId))
|
||||
roomSummary.displayName = lastNameEvent?.content<RoomNameContent>()?.name
|
||||
|
@ -7,7 +7,6 @@ import com.zhuinden.monarchy.Monarchy
|
||||
import im.vector.matrix.android.api.MatrixCallback
|
||||
import im.vector.matrix.android.api.failure.Failure
|
||||
import im.vector.matrix.android.api.util.Cancelable
|
||||
import im.vector.matrix.android.internal.database.DBConstants
|
||||
import im.vector.matrix.android.internal.database.mapper.asEntity
|
||||
import im.vector.matrix.android.internal.database.model.ChunkEntity
|
||||
import im.vector.matrix.android.internal.database.model.RoomEntity
|
||||
@ -20,6 +19,7 @@ import im.vector.matrix.android.internal.network.executeRequest
|
||||
import im.vector.matrix.android.internal.session.room.RoomAPI
|
||||
import im.vector.matrix.android.internal.session.room.model.PaginationDirection
|
||||
import im.vector.matrix.android.internal.session.room.model.TokenChunkEvent
|
||||
import im.vector.matrix.android.internal.session.sync.StateEventsChunkHandler
|
||||
import im.vector.matrix.android.internal.util.CancelableCoroutine
|
||||
import im.vector.matrix.android.internal.util.MatrixCoroutineDispatchers
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
@ -89,19 +89,9 @@ class PaginationRequest(private val roomAPI: RoomAPI,
|
||||
currentChunk.prevToken = chunkEvent.prevToken
|
||||
|
||||
|
||||
val stateEventsChunk = ChunkEntity.findWithNextToken(realm, roomId, DBConstants.STATE_EVENTS_CHUNK_TOKEN)
|
||||
?: ChunkEntity().apply {
|
||||
this.prevToken = DBConstants.STATE_EVENTS_CHUNK_TOKEN
|
||||
this.nextToken = DBConstants.STATE_EVENTS_CHUNK_TOKEN
|
||||
}
|
||||
|
||||
chunkEvent.stateEvents.forEach { stateEvent ->
|
||||
val eventEntity = stateEvent.asEntity().let {
|
||||
realm.copyToRealmOrUpdate(it)
|
||||
}
|
||||
if (!stateEventsChunk.events.contains(eventEntity)) {
|
||||
stateEventsChunk.events.add(0, eventEntity)
|
||||
}
|
||||
val stateEventsChunk = StateEventsChunkHandler().handle(realm, roomId, chunkEvent.stateEvents)
|
||||
if (!roomEntity.chunks.contains(stateEventsChunk)) {
|
||||
roomEntity.chunks.add(stateEventsChunk)
|
||||
}
|
||||
|
||||
chunkEvent.chunk.forEach { event ->
|
||||
|
@ -4,7 +4,7 @@ import android.arch.paging.PagedList
|
||||
import com.zhuinden.monarchy.Monarchy
|
||||
import im.vector.matrix.android.api.MatrixCallback
|
||||
import im.vector.matrix.android.api.failure.Failure
|
||||
import im.vector.matrix.android.api.session.events.model.Event
|
||||
import im.vector.matrix.android.api.session.events.model.EnrichedEvent
|
||||
import im.vector.matrix.android.internal.database.model.ChunkEntity
|
||||
import im.vector.matrix.android.internal.database.query.findAllIncludingEvents
|
||||
import im.vector.matrix.android.internal.session.room.model.PaginationDirection
|
||||
@ -17,7 +17,7 @@ class TimelineBoundaryCallback(private val paginationRequest: PaginationRequest,
|
||||
private val roomId: String,
|
||||
private val monarchy: Monarchy,
|
||||
ioExecutor: Executor
|
||||
) : PagedList.BoundaryCallback<Event>() {
|
||||
) : PagedList.BoundaryCallback<EnrichedEvent>() {
|
||||
|
||||
private val helper = PagingRequestHelper(ioExecutor)
|
||||
|
||||
@ -25,25 +25,25 @@ class TimelineBoundaryCallback(private val paginationRequest: PaginationRequest,
|
||||
// actually, it's not possible
|
||||
}
|
||||
|
||||
override fun onItemAtEndLoaded(itemAtEnd: Event) {
|
||||
override fun onItemAtEndLoaded(itemAtEnd: EnrichedEvent) {
|
||||
helper.runIfNotRunning(PagingRequestHelper.RequestType.AFTER) {
|
||||
monarchy.doWithRealm { realm ->
|
||||
if (itemAtEnd.eventId == null) {
|
||||
if (itemAtEnd.core.eventId == null) {
|
||||
return@doWithRealm
|
||||
}
|
||||
val chunkEntity = ChunkEntity.findAllIncludingEvents(realm, Collections.singletonList(itemAtEnd.eventId)).firstOrNull()
|
||||
val chunkEntity = ChunkEntity.findAllIncludingEvents(realm, Collections.singletonList(itemAtEnd.core.eventId)).firstOrNull()
|
||||
paginationRequest.execute(roomId, chunkEntity?.prevToken, PaginationDirection.BACKWARDS, callback = createCallback(it))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onItemAtFrontLoaded(itemAtFront: Event) {
|
||||
override fun onItemAtFrontLoaded(itemAtFront: EnrichedEvent) {
|
||||
helper.runIfNotRunning(PagingRequestHelper.RequestType.BEFORE) {
|
||||
monarchy.doWithRealm { realm ->
|
||||
if (itemAtFront.eventId == null) {
|
||||
if (itemAtFront.core.eventId == null) {
|
||||
return@doWithRealm
|
||||
}
|
||||
val chunkEntity = ChunkEntity.findAllIncludingEvents(realm, Collections.singletonList(itemAtFront.eventId)).firstOrNull()
|
||||
val chunkEntity = ChunkEntity.findAllIncludingEvents(realm, Collections.singletonList(itemAtFront.core.eventId)).firstOrNull()
|
||||
paginationRequest.execute(roomId, chunkEntity?.nextToken, PaginationDirection.FORWARDS, callback = createCallback(it))
|
||||
}
|
||||
}
|
||||
|
@ -2,7 +2,6 @@ package im.vector.matrix.android.internal.session.sync
|
||||
|
||||
import com.zhuinden.monarchy.Monarchy
|
||||
import im.vector.matrix.android.api.session.events.model.Event
|
||||
import im.vector.matrix.android.internal.database.DBConstants
|
||||
import im.vector.matrix.android.internal.database.mapper.asEntity
|
||||
import im.vector.matrix.android.internal.database.model.ChunkEntity
|
||||
import im.vector.matrix.android.internal.database.model.RoomEntity
|
||||
@ -48,13 +47,13 @@ class RoomSyncHandler(private val monarchy: Monarchy) {
|
||||
|
||||
roomEntity.membership = RoomEntity.Membership.JOINED
|
||||
if (roomSync.state != null && roomSync.state.events.isNotEmpty()) {
|
||||
val chunkEntity = eventListToChunk(realm, roomId, roomSync.state.events, DBConstants.STATE_EVENTS_CHUNK_TOKEN, DBConstants.STATE_EVENTS_CHUNK_TOKEN)
|
||||
val chunkEntity = StateEventsChunkHandler().handle(realm, roomId, roomSync.state.events)
|
||||
if (!roomEntity.chunks.contains(chunkEntity)) {
|
||||
roomEntity.chunks.add(chunkEntity)
|
||||
}
|
||||
}
|
||||
if (roomSync.timeline != null && roomSync.timeline.events.isNotEmpty()) {
|
||||
val chunkEntity = eventListToChunk(realm, roomId, roomSync.timeline.events, roomSync.timeline.prevToken, isLimited = roomSync.timeline.limited)
|
||||
val chunkEntity = handleListOfEvent(realm, roomId, roomSync.timeline.events, roomSync.timeline.prevToken, isLimited = roomSync.timeline.limited)
|
||||
if (!roomEntity.chunks.contains(chunkEntity)) {
|
||||
roomEntity.chunks.add(chunkEntity)
|
||||
}
|
||||
@ -70,7 +69,7 @@ class RoomSyncHandler(private val monarchy: Monarchy) {
|
||||
roomEntity.roomId = roomId
|
||||
roomEntity.membership = RoomEntity.Membership.INVITED
|
||||
if (roomSync.inviteState != null && roomSync.inviteState.events.isNotEmpty()) {
|
||||
val chunkEntity = eventListToChunk(realm, roomId, roomSync.inviteState.events)
|
||||
val chunkEntity = handleListOfEvent(realm, roomId, roomSync.inviteState.events)
|
||||
if (!roomEntity.chunks.contains(chunkEntity)) {
|
||||
roomEntity.chunks.add(chunkEntity)
|
||||
}
|
||||
@ -87,12 +86,12 @@ class RoomSyncHandler(private val monarchy: Monarchy) {
|
||||
}
|
||||
}
|
||||
|
||||
private fun eventListToChunk(realm: Realm,
|
||||
roomId: String,
|
||||
eventList: List<Event>,
|
||||
prevToken: String? = null,
|
||||
nextToken: String? = null,
|
||||
isLimited: Boolean = true): ChunkEntity {
|
||||
private fun handleListOfEvent(realm: Realm,
|
||||
roomId: String,
|
||||
eventList: List<Event>,
|
||||
prevToken: String? = null,
|
||||
nextToken: String? = null,
|
||||
isLimited: Boolean = true): ChunkEntity {
|
||||
|
||||
val chunkEntity = if (!isLimited) {
|
||||
ChunkEntity.findLastLiveChunkFromRoom(realm, roomId)
|
||||
|
@ -0,0 +1,28 @@
|
||||
package im.vector.matrix.android.internal.session.sync
|
||||
|
||||
import im.vector.matrix.android.api.session.events.model.Event
|
||||
import im.vector.matrix.android.internal.database.DBConstants
|
||||
import im.vector.matrix.android.internal.database.mapper.asEntity
|
||||
import im.vector.matrix.android.internal.database.model.ChunkEntity
|
||||
import im.vector.matrix.android.internal.database.query.findWithNextToken
|
||||
import io.realm.Realm
|
||||
|
||||
class StateEventsChunkHandler {
|
||||
|
||||
fun handle(realm: Realm, roomId: String, stateEvents: List<Event>): ChunkEntity {
|
||||
val chunkEntity = ChunkEntity.findWithNextToken(realm, roomId, DBConstants.STATE_EVENTS_CHUNK_TOKEN)
|
||||
?: ChunkEntity(prevToken = DBConstants.STATE_EVENTS_CHUNK_TOKEN, nextToken = DBConstants.STATE_EVENTS_CHUNK_TOKEN)
|
||||
|
||||
stateEvents.forEach { event ->
|
||||
val eventEntity = event.asEntity().let {
|
||||
realm.copyToRealmOrUpdate(it)
|
||||
}
|
||||
if (!chunkEntity.events.contains(eventEntity)) {
|
||||
chunkEntity.events.add(eventEntity)
|
||||
}
|
||||
}
|
||||
return chunkEntity
|
||||
}
|
||||
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user