2018-10-25 15:25:58 +00:00
|
|
|
package im.vector.matrix.android.internal.session.room.timeline
|
|
|
|
|
|
|
|
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.interceptor.EnrichedEventInterceptor
|
|
|
|
import im.vector.matrix.android.api.session.events.model.EnrichedEvent
|
|
|
|
import im.vector.matrix.android.api.session.room.TimelineHolder
|
|
|
|
import im.vector.matrix.android.internal.database.mapper.asDomain
|
2018-11-15 18:00:15 +00:00
|
|
|
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.EventEntityFields
|
|
|
|
import im.vector.matrix.android.internal.database.query.where
|
2018-12-18 11:13:46 +00:00
|
|
|
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
|
2019-01-07 10:39:26 +00:00
|
|
|
import im.vector.matrix.android.internal.util.tryTransactionAsync
|
2018-11-19 14:47:54 +00:00
|
|
|
import io.realm.Realm
|
|
|
|
import io.realm.RealmQuery
|
2018-10-25 15:25:58 +00:00
|
|
|
|
2018-11-25 15:17:13 +00:00
|
|
|
private const val PAGE_SIZE = 30
|
2018-10-31 15:23:02 +00:00
|
|
|
|
2018-11-08 10:04:40 +00:00
|
|
|
internal class DefaultTimelineHolder(private val roomId: String,
|
2018-11-13 09:50:53 +00:00
|
|
|
private val monarchy: Monarchy,
|
2018-12-14 16:39:25 +00:00
|
|
|
private val taskExecutor: TaskExecutor,
|
2018-11-27 21:42:46 +00:00
|
|
|
private val boundaryCallback: TimelineBoundaryCallback,
|
2018-12-18 11:13:46 +00:00
|
|
|
private val contextOfEventTask: GetContextOfEventTask,
|
|
|
|
private val roomMemberExtractor: RoomMemberExtractor
|
2018-10-25 15:25:58 +00:00
|
|
|
) : TimelineHolder {
|
|
|
|
|
|
|
|
private val eventInterceptors = ArrayList<EnrichedEventInterceptor>()
|
|
|
|
|
2018-11-19 14:47:54 +00:00
|
|
|
override fun timeline(eventId: String?): LiveData<PagedList<EnrichedEvent>> {
|
2018-11-29 17:35:24 +00:00
|
|
|
clearUnlinkedEvents()
|
2018-11-27 11:06:40 +00:00
|
|
|
if (eventId != null) {
|
2018-11-27 21:42:46 +00:00
|
|
|
fetchEventIfNeeded(eventId)
|
2018-11-27 11:06:40 +00:00
|
|
|
}
|
2018-11-19 14:47:54 +00:00
|
|
|
val realmDataSourceFactory = monarchy.createDataSourceFactory {
|
|
|
|
buildDataSourceFactoryQuery(it, eventId)
|
2018-10-25 15:25:58 +00:00
|
|
|
}
|
|
|
|
val domainSourceFactory = realmDataSourceFactory
|
2018-12-18 11:13:46 +00:00
|
|
|
.map { eventEntity ->
|
|
|
|
val roomMember = roomMemberExtractor.extractFrom(eventEntity)
|
|
|
|
EnrichedEvent(eventEntity.asDomain(), eventEntity.localId, roomMember)
|
2018-10-25 15:25:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
val pagedListConfig = PagedList.Config.Builder()
|
|
|
|
.setEnablePlaceholders(false)
|
2018-10-31 15:23:02 +00:00
|
|
|
.setPageSize(PAGE_SIZE)
|
2018-10-25 15:25:58 +00:00
|
|
|
.build()
|
|
|
|
|
|
|
|
val livePagedListBuilder = LivePagedListBuilder(domainSourceFactory, pagedListConfig).setBoundaryCallback(boundaryCallback)
|
|
|
|
return monarchy.findAllPagedWithChanges(realmDataSourceFactory, livePagedListBuilder)
|
|
|
|
}
|
2018-11-19 14:47:54 +00:00
|
|
|
|
2018-11-29 17:35:24 +00:00
|
|
|
private fun clearUnlinkedEvents() {
|
2019-01-07 10:39:26 +00:00
|
|
|
monarchy.tryTransactionAsync { realm ->
|
2018-11-29 17:35:24 +00:00
|
|
|
val unlinkedEvents = EventEntity
|
|
|
|
.where(realm, roomId = roomId)
|
|
|
|
.equalTo(EventEntityFields.IS_UNLINKED, true)
|
|
|
|
.findAll()
|
|
|
|
unlinkedEvents.deleteAllFromRealm()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-11-27 21:42:46 +00:00
|
|
|
private fun fetchEventIfNeeded(eventId: String) {
|
|
|
|
if (!isEventPersisted(eventId)) {
|
2018-12-14 16:39:25 +00:00
|
|
|
val params = GetContextOfEventTask.Params(roomId, eventId)
|
2018-12-17 15:42:22 +00:00
|
|
|
contextOfEventTask.configureWith(params).executeBy(taskExecutor)
|
2018-11-27 21:42:46 +00:00
|
|
|
}
|
|
|
|
}
|
2018-11-27 11:06:40 +00:00
|
|
|
|
2018-11-27 21:42:46 +00:00
|
|
|
private fun isEventPersisted(eventId: String): Boolean {
|
|
|
|
var isEventPersisted = false
|
|
|
|
monarchy.doWithRealm {
|
|
|
|
isEventPersisted = EventEntity.where(it, eventId = eventId).findFirst() != null
|
|
|
|
}
|
|
|
|
return isEventPersisted
|
2018-11-27 11:06:40 +00:00
|
|
|
}
|
|
|
|
|
2018-11-19 14:47:54 +00:00
|
|
|
private fun buildDataSourceFactoryQuery(realm: Realm, eventId: String?): RealmQuery<EventEntity> {
|
|
|
|
val query = if (eventId == null) {
|
|
|
|
EventEntity
|
2018-11-29 17:35:24 +00:00
|
|
|
.where(realm, roomId = roomId, linkFilterMode = EventEntity.LinkFilterMode.LINKED_ONLY)
|
2018-11-19 14:47:54 +00:00
|
|
|
.equalTo("${EventEntityFields.CHUNK}.${ChunkEntityFields.IS_LAST}", true)
|
|
|
|
} else {
|
|
|
|
EventEntity
|
2018-11-29 17:35:24 +00:00
|
|
|
.where(realm, roomId = roomId, linkFilterMode = EventEntity.LinkFilterMode.BOTH)
|
2018-11-19 14:47:54 +00:00
|
|
|
.`in`("${EventEntityFields.CHUNK}.${ChunkEntityFields.EVENTS.EVENT_ID}", arrayOf(eventId))
|
|
|
|
}
|
|
|
|
return query.sort(EventEntityFields.DISPLAY_INDEX)
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2018-10-25 15:25:58 +00:00
|
|
|
}
|