mirror of
https://github.com/SchildiChat/SchildiChat-android.git
synced 2024-11-23 18:05:59 +03:00
Timeline is back
This commit is contained in:
parent
cbfd2af74b
commit
f01e796271
5 changed files with 67 additions and 41 deletions
|
@ -18,6 +18,7 @@ package im.vector.matrix.android.internal.database.helper
|
|||
|
||||
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.room.send.SendState
|
||||
import im.vector.matrix.android.internal.database.mapper.asDomain
|
||||
import im.vector.matrix.android.internal.database.mapper.toEntity
|
||||
import im.vector.matrix.android.internal.database.model.ChunkEntity
|
||||
|
@ -112,11 +113,16 @@ internal fun ChunkEntity.add(roomId: String,
|
|||
}
|
||||
}
|
||||
|
||||
val eventEntity = TimelineEventEntity().apply {
|
||||
this.root = event.toEntity(roomId)
|
||||
this.eventId = event.eventId ?: ""
|
||||
this.roomId = roomId
|
||||
this.annotations = EventAnnotationsSummaryEntity.where(realm, eventId).findFirst()
|
||||
val eventEntity = TimelineEventEntity().also {
|
||||
it.root = event.toEntity(roomId).apply {
|
||||
this.stateIndex = currentStateIndex
|
||||
this.isUnlinked = isUnlinked
|
||||
this.displayIndex = currentDisplayIndex
|
||||
this.sendState = SendState.SYNCED
|
||||
}
|
||||
it.eventId = event.eventId ?: ""
|
||||
it.roomId = roomId
|
||||
it.annotations = EventAnnotationsSummaryEntity.where(realm, it.eventId).findFirst()
|
||||
}
|
||||
val position = if (direction == PaginationDirection.FORWARDS) 0 else this.timelineEvents.size
|
||||
timelineEvents.add(position, eventEntity)
|
||||
|
|
|
@ -37,6 +37,24 @@ internal fun TimelineEventEntity.Companion.where(realm: Realm, eventIds: List<St
|
|||
return realm.where<TimelineEventEntity>().`in`(TimelineEventEntityFields.EVENT_ID, eventIds.toTypedArray())
|
||||
}
|
||||
|
||||
internal fun TimelineEventEntity.Companion.where(realm: Realm,
|
||||
roomId: String? = null,
|
||||
type: String? = null,
|
||||
linkFilterMode: EventEntity.LinkFilterMode = LINKED_ONLY): RealmQuery<TimelineEventEntity> {
|
||||
val query = realm.where<TimelineEventEntity>()
|
||||
if (roomId != null) {
|
||||
query.equalTo(TimelineEventEntityFields.ROOM_ID, roomId)
|
||||
}
|
||||
if (type != null) {
|
||||
query.equalTo(TimelineEventEntityFields.ROOT.TYPE, type)
|
||||
}
|
||||
return when (linkFilterMode) {
|
||||
LINKED_ONLY -> query.equalTo(TimelineEventEntityFields.ROOT.IS_UNLINKED, false)
|
||||
UNLINKED_ONLY -> query.equalTo(TimelineEventEntityFields.ROOT.IS_UNLINKED, true)
|
||||
BOTH -> query
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
internal fun TimelineEventEntity.Companion.latestEvent(realm: Realm,
|
||||
roomId: String,
|
||||
|
@ -51,9 +69,9 @@ internal fun TimelineEventEntity.Companion.latestEvent(realm: Realm,
|
|||
}
|
||||
val query = eventList?.where()
|
||||
if (includedTypes.isNotEmpty()) {
|
||||
query?.`in`(EventEntityFields.TYPE, includedTypes.toTypedArray())
|
||||
query?.`in`(TimelineEventEntityFields.ROOT.TYPE, includedTypes.toTypedArray())
|
||||
} else if (excludedTypes.isNotEmpty()) {
|
||||
query?.not()?.`in`(EventEntityFields.TYPE, excludedTypes.toTypedArray())
|
||||
query?.not()?.`in`(TimelineEventEntityFields.ROOT.TYPE, excludedTypes.toTypedArray())
|
||||
}
|
||||
return query
|
||||
?.sort(TimelineEventEntityFields.ROOT.DISPLAY_INDEX, Sort.DESCENDING)
|
||||
|
|
|
@ -22,6 +22,7 @@ import im.vector.matrix.android.api.session.events.model.EventType
|
|||
import im.vector.matrix.android.internal.database.RealmLiveEntityObserver
|
||||
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.types
|
||||
import im.vector.matrix.android.internal.database.query.where
|
||||
import im.vector.matrix.android.internal.di.SessionDatabase
|
||||
import im.vector.matrix.android.internal.session.SessionScope
|
||||
|
@ -41,7 +42,7 @@ internal class EventsPruner @Inject constructor(@SessionDatabase realmConfigurat
|
|||
private val taskExecutor: TaskExecutor) :
|
||||
RealmLiveEntityObserver<EventEntity>(realmConfiguration) {
|
||||
|
||||
override val query = Monarchy.Query<EventEntity> { EventEntity.where(it, type = EventType.REDACTION) }
|
||||
override val query = Monarchy.Query<EventEntity> { EventEntity.types(it, listOf(EventType.REDACTION)) }
|
||||
|
||||
override fun processChanges(inserted: List<EventEntity>, updated: List<EventEntity>, deleted: List<EventEntity>) {
|
||||
Timber.v("Event pruner called with ${inserted.size} insertions")
|
||||
|
|
|
@ -27,12 +27,12 @@ import im.vector.matrix.android.api.util.addTo
|
|||
import im.vector.matrix.android.internal.crypto.NewSessionListener
|
||||
import im.vector.matrix.android.internal.crypto.model.event.EncryptedEventContent
|
||||
import im.vector.matrix.android.internal.database.mapper.asDomain
|
||||
import im.vector.matrix.android.internal.database.model.*
|
||||
import im.vector.matrix.android.internal.database.model.ChunkEntity
|
||||
import im.vector.matrix.android.internal.database.model.ChunkEntityFields
|
||||
import im.vector.matrix.android.internal.database.model.EventAnnotationsSummaryEntity
|
||||
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.RoomEntity
|
||||
import im.vector.matrix.android.internal.database.model.TimelineEventEntity
|
||||
import im.vector.matrix.android.internal.database.query.findIncludingEvent
|
||||
import im.vector.matrix.android.internal.database.query.findLastLiveChunkFromRoom
|
||||
import im.vector.matrix.android.internal.database.query.where
|
||||
|
@ -91,7 +91,7 @@ internal class DefaultTimeline(
|
|||
private val cancelableBag = CancelableBag()
|
||||
private val debouncer = Debouncer(mainHandler)
|
||||
|
||||
private lateinit var liveEvents: RealmResults<EventEntity>
|
||||
private lateinit var liveEvents: RealmResults<TimelineEventEntity>
|
||||
private var roomEntity: RoomEntity? = null
|
||||
|
||||
private var prevDisplayIndex: Int = DISPLAY_INDEX_UNKNOWN
|
||||
|
@ -105,7 +105,7 @@ internal class DefaultTimeline(
|
|||
|
||||
private lateinit var eventRelations: RealmResults<EventAnnotationsSummaryEntity>
|
||||
|
||||
private val eventsChangeListener = OrderedRealmCollectionChangeListener<RealmResults<EventEntity>> { results, changeSet ->
|
||||
private val eventsChangeListener = OrderedRealmCollectionChangeListener<RealmResults<TimelineEventEntity>> { results, changeSet ->
|
||||
if (changeSet.state == OrderedCollectionChangeSet.State.INITIAL) {
|
||||
handleInitialLoad()
|
||||
} else {
|
||||
|
@ -118,9 +118,9 @@ internal class DefaultTimeline(
|
|||
}
|
||||
changeSet.insertionRanges.forEach { range ->
|
||||
val (startDisplayIndex, direction) = if (range.startIndex == 0) {
|
||||
Pair(liveEvents[range.length - 1]!!.displayIndex, Timeline.Direction.FORWARDS)
|
||||
Pair(liveEvents[range.length - 1]!!.root!!.displayIndex, Timeline.Direction.FORWARDS)
|
||||
} else {
|
||||
Pair(liveEvents[range.startIndex]!!.displayIndex, Timeline.Direction.BACKWARDS)
|
||||
Pair(liveEvents[range.startIndex]!!.root!!.displayIndex, Timeline.Direction.BACKWARDS)
|
||||
}
|
||||
val state = getPaginationState(direction)
|
||||
if (state.isPaginating) {
|
||||
|
@ -233,7 +233,7 @@ internal class DefaultTimeline(
|
|||
}
|
||||
|
||||
liveEvents = buildEventQuery(realm)
|
||||
.sort(EventEntityFields.DISPLAY_INDEX, Sort.DESCENDING)
|
||||
.sort(TimelineEventEntityFields.ROOT.DISPLAY_INDEX, Sort.DESCENDING)
|
||||
.findAllAsync()
|
||||
.also { it.addChangeListener(eventsChangeListener) }
|
||||
|
||||
|
@ -268,13 +268,13 @@ internal class DefaultTimeline(
|
|||
|
||||
private fun hasMoreInCache(direction: Timeline.Direction): Boolean {
|
||||
val localRealm = Realm.getInstance(realmConfiguration)
|
||||
val eventEntity = buildEventQuery(localRealm).findFirst(direction) ?: return false
|
||||
val timelineEventEntity = buildEventQuery(localRealm).findFirst(direction) ?: return false
|
||||
val hasMoreInCache = if (direction == Timeline.Direction.FORWARDS) {
|
||||
val firstEvent = builtEvents.firstOrNull() ?: return true
|
||||
firstEvent.displayIndex < eventEntity.displayIndex
|
||||
firstEvent.displayIndex < timelineEventEntity.root!!.displayIndex
|
||||
} else {
|
||||
val lastEvent = builtEvents.lastOrNull() ?: return true
|
||||
lastEvent.displayIndex > eventEntity.displayIndex
|
||||
lastEvent.displayIndex > timelineEventEntity.root!!.displayIndex
|
||||
}
|
||||
localRealm.close()
|
||||
return hasMoreInCache
|
||||
|
@ -287,7 +287,7 @@ internal class DefaultTimeline(
|
|||
currentChunk.isLastForward
|
||||
} else {
|
||||
val eventEntity = buildEventQuery(localRealm).findFirst(direction)
|
||||
currentChunk.isLastBackward || eventEntity?.type == EventType.STATE_ROOM_CREATE
|
||||
currentChunk.isLastBackward || eventEntity?.root?.type == EventType.STATE_ROOM_CREATE
|
||||
}
|
||||
localRealm.close()
|
||||
return hasReachedEnd
|
||||
|
@ -360,11 +360,11 @@ internal class DefaultTimeline(
|
|||
private fun handleInitialLoad() {
|
||||
var shouldFetchInitialEvent = false
|
||||
val initialDisplayIndex = if (isLive) {
|
||||
liveEvents.firstOrNull()?.displayIndex
|
||||
liveEvents.firstOrNull()?.root?.displayIndex
|
||||
} else {
|
||||
val initialEvent = liveEvents.where().equalTo(EventEntityFields.EVENT_ID, initialEventId).findFirst()
|
||||
val initialEvent = liveEvents.where().equalTo(TimelineEventEntityFields.EVENT_ID, initialEventId).findFirst()
|
||||
shouldFetchInitialEvent = initialEvent == null
|
||||
initialEvent?.displayIndex
|
||||
initialEvent?.root?.displayIndex
|
||||
} ?: DISPLAY_INDEX_UNKNOWN
|
||||
|
||||
prevDisplayIndex = initialDisplayIndex
|
||||
|
@ -448,14 +448,14 @@ internal class DefaultTimeline(
|
|||
if (offsetResults.isEmpty()) {
|
||||
return 0
|
||||
}
|
||||
val offsetIndex = offsetResults.last()!!.displayIndex
|
||||
val offsetIndex = offsetResults.last()!!.root!!.displayIndex
|
||||
if (direction == Timeline.Direction.BACKWARDS) {
|
||||
prevDisplayIndex = offsetIndex - 1
|
||||
} else {
|
||||
nextDisplayIndex = offsetIndex + 1
|
||||
}
|
||||
offsetResults.forEach { eventEntity ->
|
||||
val timelineEvent = timelineEventFactory.create(eventEntity, eventEntity.realm)
|
||||
val timelineEvent = eventEntity.asDomain()
|
||||
val position = if (direction == Timeline.Direction.FORWARDS) 0 else builtEvents.size
|
||||
builtEvents.add(position, timelineEvent)
|
||||
//Need to shift :/
|
||||
|
@ -472,16 +472,16 @@ internal class DefaultTimeline(
|
|||
*/
|
||||
private fun getOffsetResults(startDisplayIndex: Int,
|
||||
direction: Timeline.Direction,
|
||||
count: Long): RealmResults<EventEntity> {
|
||||
count: Long): RealmResults<TimelineEventEntity> {
|
||||
val offsetQuery = liveEvents.where()
|
||||
if (direction == Timeline.Direction.BACKWARDS) {
|
||||
offsetQuery
|
||||
.sort(EventEntityFields.DISPLAY_INDEX, Sort.DESCENDING)
|
||||
.lessThanOrEqualTo(EventEntityFields.DISPLAY_INDEX, startDisplayIndex)
|
||||
.sort(TimelineEventEntityFields.ROOT.DISPLAY_INDEX, Sort.DESCENDING)
|
||||
.lessThanOrEqualTo(TimelineEventEntityFields.ROOT.DISPLAY_INDEX, startDisplayIndex)
|
||||
} else {
|
||||
offsetQuery
|
||||
.sort(EventEntityFields.DISPLAY_INDEX, Sort.ASCENDING)
|
||||
.greaterThanOrEqualTo(EventEntityFields.DISPLAY_INDEX, startDisplayIndex)
|
||||
.sort(TimelineEventEntityFields.ROOT.DISPLAY_INDEX, Sort.ASCENDING)
|
||||
.greaterThanOrEqualTo(TimelineEventEntityFields.ROOT.DISPLAY_INDEX, startDisplayIndex)
|
||||
}
|
||||
return offsetQuery
|
||||
.filterAllowedTypes()
|
||||
|
@ -490,15 +490,15 @@ internal class DefaultTimeline(
|
|||
}
|
||||
|
||||
|
||||
private fun buildEventQuery(realm: Realm): RealmQuery<EventEntity> {
|
||||
private fun buildEventQuery(realm: Realm): RealmQuery<TimelineEventEntity> {
|
||||
return if (initialEventId == null) {
|
||||
EventEntity
|
||||
TimelineEventEntity
|
||||
.where(realm, roomId = roomId, linkFilterMode = EventEntity.LinkFilterMode.LINKED_ONLY)
|
||||
.equalTo("${EventEntityFields.CHUNK}.${ChunkEntityFields.IS_LAST_FORWARD}", true)
|
||||
.equalTo("${TimelineEventEntityFields.CHUNK}.${ChunkEntityFields.IS_LAST_FORWARD}", true)
|
||||
} else {
|
||||
EventEntity
|
||||
TimelineEventEntity
|
||||
.where(realm, roomId = roomId, linkFilterMode = EventEntity.LinkFilterMode.BOTH)
|
||||
.`in`("${EventEntityFields.CHUNK}.${ChunkEntityFields.EVENTS.EVENT_ID}", arrayOf(initialEventId))
|
||||
.`in`("${TimelineEventEntityFields.CHUNK}.${ChunkEntityFields.TIMELINE_EVENTS.EVENT_ID}", arrayOf(initialEventId))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -514,7 +514,7 @@ internal class DefaultTimeline(
|
|||
realm.executeTransaction {
|
||||
val unlinkedChunks = ChunkEntity
|
||||
.where(it, roomId = roomId)
|
||||
.equalTo(ChunkEntityFields.EVENTS.IS_UNLINKED, true)
|
||||
.equalTo("${ChunkEntityFields.TIMELINE_EVENTS.ROOT}.${EventEntityFields.IS_UNLINKED}", true)
|
||||
.findAll()
|
||||
unlinkedChunks.deleteAllFromRealm()
|
||||
}
|
||||
|
@ -537,19 +537,19 @@ internal class DefaultTimeline(
|
|||
return if (this == Timeline.Direction.BACKWARDS) PaginationDirection.BACKWARDS else PaginationDirection.FORWARDS
|
||||
}
|
||||
|
||||
private fun RealmQuery<EventEntity>.findFirst(direction: Timeline.Direction): EventEntity? {
|
||||
private fun RealmQuery<TimelineEventEntity>.findFirst(direction: Timeline.Direction): TimelineEventEntity? {
|
||||
return if (direction == Timeline.Direction.FORWARDS) {
|
||||
sort(EventEntityFields.DISPLAY_INDEX, Sort.DESCENDING)
|
||||
sort(TimelineEventEntityFields.ROOT.DISPLAY_INDEX, Sort.DESCENDING)
|
||||
} else {
|
||||
sort(EventEntityFields.DISPLAY_INDEX, Sort.ASCENDING)
|
||||
sort(TimelineEventEntityFields.ROOT.DISPLAY_INDEX, Sort.ASCENDING)
|
||||
}
|
||||
.filterAllowedTypes()
|
||||
.findFirst()
|
||||
}
|
||||
|
||||
private fun RealmQuery<EventEntity>.filterAllowedTypes(): RealmQuery<EventEntity> {
|
||||
private fun RealmQuery<TimelineEventEntity>.filterAllowedTypes(): RealmQuery<TimelineEventEntity> {
|
||||
if (allowedTypes != null) {
|
||||
`in`(EventEntityFields.TYPE, allowedTypes.toTypedArray())
|
||||
`in`(TimelineEventEntityFields.ROOT.TYPE, allowedTypes.toTypedArray())
|
||||
}
|
||||
return this
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@ import im.vector.matrix.android.api.session.events.model.EventType
|
|||
import im.vector.matrix.android.internal.database.RealmLiveEntityObserver
|
||||
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.types
|
||||
import im.vector.matrix.android.internal.database.query.where
|
||||
import im.vector.matrix.android.internal.di.SessionDatabase
|
||||
import im.vector.matrix.android.internal.session.SessionScope
|
||||
|
@ -38,7 +39,7 @@ internal class UserEntityUpdater @Inject constructor(@SessionDatabase realmConfi
|
|||
|
||||
override val query = Monarchy.Query<EventEntity> {
|
||||
EventEntity
|
||||
.where(it, type = EventType.STATE_ROOM_MEMBER)
|
||||
.types(it, listOf(EventType.STATE_ROOM_MEMBER))
|
||||
.sort(EventEntityFields.STATE_INDEX, Sort.DESCENDING)
|
||||
.distinct(EventEntityFields.STATE_KEY)
|
||||
|
||||
|
|
Loading…
Reference in a new issue