mirror of
https://github.com/element-hq/element-android
synced 2024-11-24 10:25:35 +03:00
Merge pull request #334 from vector-im/feature/general_perf
Feature/general perf
This commit is contained in:
commit
252b2ea30a
25 changed files with 121 additions and 115 deletions
|
@ -19,4 +19,4 @@ package im.vector.matrix.android
|
|||
import im.vector.matrix.android.internal.util.MatrixCoroutineDispatchers
|
||||
import kotlinx.coroutines.Dispatchers.Main
|
||||
|
||||
internal val testCoroutineDispatchers = MatrixCoroutineDispatchers(Main, Main, Main, Main)
|
||||
internal val testCoroutineDispatchers = MatrixCoroutineDispatchers(Main, Main, Main, Main, Main)
|
|
@ -30,7 +30,7 @@ import im.vector.matrix.android.api.session.room.send.SendState
|
|||
*/
|
||||
data class TimelineEvent(
|
||||
val root: Event,
|
||||
val localId: String,
|
||||
val localId: Long,
|
||||
val displayIndex: Int,
|
||||
val senderName: String?,
|
||||
val isUniqueDisplayName: Boolean,
|
||||
|
|
|
@ -19,6 +19,7 @@ package im.vector.matrix.android.internal.database
|
|||
import com.zhuinden.monarchy.Monarchy
|
||||
import im.vector.matrix.android.internal.util.createBackgroundHandler
|
||||
import io.realm.OrderedCollectionChangeSet
|
||||
import io.realm.OrderedRealmCollectionChangeListener
|
||||
import io.realm.Realm
|
||||
import io.realm.RealmConfiguration
|
||||
import io.realm.RealmObject
|
||||
|
@ -33,7 +34,7 @@ internal interface LiveEntityObserver {
|
|||
}
|
||||
|
||||
internal abstract class RealmLiveEntityObserver<T : RealmObject>(protected val realmConfiguration: RealmConfiguration)
|
||||
: LiveEntityObserver {
|
||||
: LiveEntityObserver, OrderedRealmCollectionChangeListener<RealmResults<T>> {
|
||||
|
||||
private companion object {
|
||||
val BACKGROUND_HANDLER = createBackgroundHandler("LIVE_ENTITY_BACKGROUND")
|
||||
|
@ -50,9 +51,7 @@ internal abstract class RealmLiveEntityObserver<T : RealmObject>(protected val r
|
|||
val realm = Realm.getInstance(realmConfiguration)
|
||||
backgroundRealm.set(realm)
|
||||
val queryResults = query.createQuery(realm).findAll()
|
||||
queryResults.addChangeListener { t, changeSet ->
|
||||
onChanged(t, changeSet)
|
||||
}
|
||||
queryResults.addChangeListener(this)
|
||||
results = AtomicReference(queryResults)
|
||||
}
|
||||
}
|
||||
|
@ -73,19 +72,4 @@ internal abstract class RealmLiveEntityObserver<T : RealmObject>(protected val r
|
|||
return isStarted.get()
|
||||
}
|
||||
|
||||
private fun onChanged(realmResults: RealmResults<T>, changeSet: OrderedCollectionChangeSet) {
|
||||
val insertionIndexes = changeSet.insertions
|
||||
val updateIndexes = changeSet.changes
|
||||
val deletionIndexes = changeSet.deletions
|
||||
val inserted = realmResults.filterIndexed { index, _ -> insertionIndexes.contains(index) }
|
||||
val updated = realmResults.filterIndexed { index, _ -> updateIndexes.contains(index) }
|
||||
val deleted = realmResults.filterIndexed { index, _ -> deletionIndexes.contains(index) }
|
||||
processChanges(inserted, updated, deleted)
|
||||
}
|
||||
|
||||
/**
|
||||
* Do quick treatment or delegate on a task
|
||||
*/
|
||||
protected abstract fun processChanges(inserted: List<T>, updated: List<T>, deleted: List<T>)
|
||||
|
||||
}
|
|
@ -134,7 +134,8 @@ internal fun ChunkEntity.add(roomId: String,
|
|||
}
|
||||
}
|
||||
|
||||
val eventEntity = TimelineEventEntity().also {
|
||||
val localId = TimelineEventEntity.nextId(realm)
|
||||
val eventEntity = TimelineEventEntity(localId).also {
|
||||
it.root = event.toEntity(roomId).apply {
|
||||
this.stateIndex = currentStateIndex
|
||||
this.isUnlinked = isUnlinked
|
||||
|
|
|
@ -26,7 +26,6 @@ import im.vector.matrix.android.internal.database.query.fastContains
|
|||
import im.vector.matrix.android.internal.extensions.assertIsManaged
|
||||
import im.vector.matrix.android.internal.session.room.membership.RoomMembers
|
||||
|
||||
|
||||
internal fun RoomEntity.deleteOnCascade(chunkEntity: ChunkEntity) {
|
||||
chunks.remove(chunkEntity)
|
||||
chunkEntity.deleteOnCascade()
|
||||
|
@ -65,7 +64,8 @@ internal fun RoomEntity.addSendingEvent(event: Event) {
|
|||
}
|
||||
val roomMembers = RoomMembers(realm, roomId)
|
||||
val myUser = roomMembers.get(senderId)
|
||||
val timelineEventEntity = TimelineEventEntity().also {
|
||||
val localId = TimelineEventEntity.nextId(realm)
|
||||
val timelineEventEntity = TimelineEventEntity(localId).also {
|
||||
it.root = eventEntity
|
||||
it.eventId = event.eventId ?: ""
|
||||
it.roomId = roomId
|
||||
|
|
|
@ -30,9 +30,11 @@ import im.vector.matrix.android.internal.database.query.prev
|
|||
import im.vector.matrix.android.internal.database.query.where
|
||||
import im.vector.matrix.android.internal.extensions.assertIsManaged
|
||||
import im.vector.matrix.android.internal.session.room.membership.RoomMembers
|
||||
import io.realm.Realm
|
||||
import io.realm.RealmList
|
||||
import io.realm.RealmQuery
|
||||
|
||||
|
||||
internal fun TimelineEventEntity.updateSenderData() {
|
||||
assertIsManaged()
|
||||
val roomEntity = RoomEntity.where(realm, roomId = roomId).findFirst() ?: return
|
||||
|
@ -69,6 +71,15 @@ internal fun TimelineEventEntity.updateSenderData() {
|
|||
this.senderMembershipEvent = senderMembershipEvent
|
||||
}
|
||||
|
||||
internal fun TimelineEventEntity.Companion.nextId(realm: Realm): Long{
|
||||
val currentIdNum = realm.where(TimelineEventEntity::class.java).max(TimelineEventEntityFields.LOCAL_ID)
|
||||
return if (currentIdNum == null) {
|
||||
1
|
||||
} else {
|
||||
currentIdNum.toLong() + 1
|
||||
}
|
||||
}
|
||||
|
||||
private fun RealmList<TimelineEventEntity>.buildQuery(sender: String, isUnlinked: Boolean): RealmQuery<TimelineEventEntity> {
|
||||
return where()
|
||||
.equalTo(TimelineEventEntityFields.ROOT.STATE_KEY, sender)
|
||||
|
|
|
@ -35,7 +35,7 @@ internal object EventMapper {
|
|||
val uds = if (event.unsignedData == null) null
|
||||
else MoshiProvider.providesMoshi().adapter(UnsignedData::class.java).toJson(event.unsignedData)
|
||||
val eventEntity = EventEntity()
|
||||
eventEntity.eventId = event.eventId ?: UUID.randomUUID().toString()
|
||||
eventEntity.eventId = event.eventId ?: ""
|
||||
eventEntity.roomId = event.roomId ?: roomId
|
||||
eventEntity.content = ContentMapper.map(event.content)
|
||||
val resolvedPrevContent = event.prevContent ?: event.unsignedData?.prevContent
|
||||
|
|
|
@ -23,15 +23,6 @@ import im.vector.matrix.android.internal.database.model.TimelineEventEntity
|
|||
|
||||
internal object TimelineEventMapper {
|
||||
|
||||
fun map(timelineEvent: TimelineEvent, roomId: String): TimelineEventEntity {
|
||||
val timelineEventEntity = TimelineEventEntity()
|
||||
timelineEventEntity.root = timelineEvent.root.toEntity(roomId)
|
||||
timelineEventEntity.eventId = timelineEvent.root.eventId ?: ""
|
||||
timelineEventEntity.roomId = roomId
|
||||
timelineEventEntity.annotations = timelineEvent.annotations?.let { EventAnnotationsSummaryMapper.map(it, roomId) }
|
||||
return timelineEventEntity
|
||||
}
|
||||
|
||||
fun map(timelineEventEntity: TimelineEventEntity): TimelineEvent {
|
||||
|
||||
return TimelineEvent(
|
||||
|
@ -53,8 +44,4 @@ internal fun TimelineEventEntity.asDomain(): TimelineEvent {
|
|||
return TimelineEventMapper.map(this)
|
||||
}
|
||||
|
||||
internal fun TimelineEvent.toEntity(roomId: String): TimelineEventEntity {
|
||||
return TimelineEventMapper.map(this, roomId)
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -27,8 +27,7 @@ import io.realm.annotations.LinkingObjects
|
|||
import io.realm.annotations.PrimaryKey
|
||||
import java.util.*
|
||||
|
||||
internal open class EventEntity(@PrimaryKey var localId: String = UUID.randomUUID().toString(),
|
||||
@Index var eventId: String = "",
|
||||
internal open class EventEntity(@Index var eventId: String = "",
|
||||
@Index var roomId: String = "",
|
||||
@Index var type: String = "",
|
||||
var content: String? = null,
|
||||
|
|
|
@ -16,10 +16,6 @@
|
|||
|
||||
package im.vector.matrix.android.internal.database.model
|
||||
|
||||
import com.squareup.moshi.Types
|
||||
import im.vector.matrix.android.internal.crypto.MXEventDecryptionResult
|
||||
import im.vector.matrix.android.internal.database.mapper.ContentMapper
|
||||
import im.vector.matrix.android.internal.di.MoshiProvider
|
||||
import io.realm.RealmObject
|
||||
import io.realm.RealmResults
|
||||
import io.realm.annotations.Index
|
||||
|
@ -28,7 +24,7 @@ import io.realm.annotations.PrimaryKey
|
|||
import java.util.*
|
||||
|
||||
|
||||
internal open class TimelineEventEntity(@PrimaryKey var localId: String = UUID.randomUUID().toString(),
|
||||
internal open class TimelineEventEntity(var localId: Long = 0,
|
||||
@Index var eventId: String = "",
|
||||
@Index var roomId: String = "",
|
||||
var root: EventEntity? = null,
|
||||
|
|
|
@ -18,15 +18,15 @@ package im.vector.matrix.android.internal.di
|
|||
|
||||
import android.content.Context
|
||||
import android.content.res.Resources
|
||||
import android.os.Handler
|
||||
import android.os.HandlerThread
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import im.vector.matrix.android.internal.util.MatrixCoroutineDispatchers
|
||||
import im.vector.matrix.android.internal.util.createBackgroundHandler
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.android.asCoroutineDispatcher
|
||||
import kotlinx.coroutines.asCoroutineDispatcher
|
||||
import org.matrix.olm.OlmManager
|
||||
import java.util.concurrent.Executors
|
||||
|
||||
@Module
|
||||
internal object MatrixModule {
|
||||
|
@ -38,7 +38,8 @@ internal object MatrixModule {
|
|||
return MatrixCoroutineDispatchers(io = Dispatchers.IO,
|
||||
computation = Dispatchers.IO,
|
||||
main = Dispatchers.Main,
|
||||
crypto = createBackgroundHandler("Crypto_Thread").asCoroutineDispatcher()
|
||||
crypto = createBackgroundHandler("Crypto_Thread").asCoroutineDispatcher(),
|
||||
sync = Executors.newSingleThreadExecutor().asCoroutineDispatcher()
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@ import android.content.Context
|
|||
import android.os.Looper
|
||||
import androidx.annotation.MainThread
|
||||
import androidx.lifecycle.LiveData
|
||||
import dagger.Lazy
|
||||
import im.vector.matrix.android.api.MatrixCallback
|
||||
import im.vector.matrix.android.api.auth.data.SessionParams
|
||||
import im.vector.matrix.android.api.pushrules.PushRuleService
|
||||
|
@ -52,34 +53,34 @@ internal class DefaultSession @Inject constructor(override val sessionParams: Se
|
|||
private val context: Context,
|
||||
private val liveEntityObservers: Set<@JvmSuppressWildcards LiveEntityObserver>,
|
||||
private val sessionListeners: SessionListeners,
|
||||
private val roomService: RoomService,
|
||||
private val roomDirectoryService: RoomDirectoryService,
|
||||
private val groupService: GroupService,
|
||||
private val userService: UserService,
|
||||
private val filterService: FilterService,
|
||||
private val cacheService: CacheService,
|
||||
private val signOutService: SignOutService,
|
||||
private val pushRuleService: PushRuleService,
|
||||
private val pushersService: PushersService,
|
||||
private val cryptoService: CryptoManager,
|
||||
private val fileService: FileService,
|
||||
private val roomService: Lazy<RoomService>,
|
||||
private val roomDirectoryService: Lazy<RoomDirectoryService>,
|
||||
private val groupService: Lazy<GroupService>,
|
||||
private val userService: Lazy<UserService>,
|
||||
private val filterService: Lazy<FilterService>,
|
||||
private val cacheService: Lazy<CacheService>,
|
||||
private val signOutService: Lazy<SignOutService>,
|
||||
private val pushRuleService: Lazy<PushRuleService>,
|
||||
private val pushersService: Lazy<PushersService>,
|
||||
private val cryptoService: Lazy<CryptoManager>,
|
||||
private val fileService: Lazy<FileService>,
|
||||
private val syncThread: SyncThread,
|
||||
private val contentUrlResolver: ContentUrlResolver,
|
||||
private val contentUploadProgressTracker: ContentUploadStateTracker,
|
||||
private val initialSyncProgressService: InitialSyncProgressService)
|
||||
private val initialSyncProgressService: Lazy<InitialSyncProgressService>)
|
||||
: Session,
|
||||
RoomService by roomService,
|
||||
RoomDirectoryService by roomDirectoryService,
|
||||
GroupService by groupService,
|
||||
UserService by userService,
|
||||
CryptoService by cryptoService,
|
||||
CacheService by cacheService,
|
||||
SignOutService by signOutService,
|
||||
FilterService by filterService,
|
||||
PushRuleService by pushRuleService,
|
||||
PushersService by pushersService,
|
||||
FileService by fileService,
|
||||
InitialSyncProgressService by initialSyncProgressService {
|
||||
RoomService by roomService.get(),
|
||||
RoomDirectoryService by roomDirectoryService.get(),
|
||||
GroupService by groupService.get(),
|
||||
UserService by userService.get(),
|
||||
CryptoService by cryptoService.get(),
|
||||
CacheService by cacheService.get(),
|
||||
SignOutService by signOutService.get(),
|
||||
FilterService by filterService.get(),
|
||||
PushRuleService by pushRuleService.get(),
|
||||
PushersService by pushersService.get(),
|
||||
FileService by fileService.get(),
|
||||
InitialSyncProgressService by initialSyncProgressService.get() {
|
||||
|
||||
private var isOpen = false
|
||||
|
||||
|
@ -123,7 +124,7 @@ internal class DefaultSession @Inject constructor(override val sessionParams: Se
|
|||
assert(isOpen)
|
||||
stopSync()
|
||||
liveEntityObservers.forEach { it.dispose() }
|
||||
cryptoService.close()
|
||||
cryptoService.get().close()
|
||||
isOpen = false
|
||||
}
|
||||
|
||||
|
@ -140,15 +141,15 @@ internal class DefaultSession @Inject constructor(override val sessionParams: Se
|
|||
//syncThread.kill()
|
||||
|
||||
Timber.w("SIGN_OUT: call webservice")
|
||||
return signOutService.signOut(object : MatrixCallback<Unit> {
|
||||
return signOutService.get().signOut(object : MatrixCallback<Unit> {
|
||||
override fun onSuccess(data: Unit) {
|
||||
Timber.w("SIGN_OUT: call webservice -> SUCCESS: clear cache")
|
||||
|
||||
// Clear the cache
|
||||
cacheService.clearCache(object : MatrixCallback<Unit> {
|
||||
cacheService.get().clearCache(object : MatrixCallback<Unit> {
|
||||
override fun onSuccess(data: Unit) {
|
||||
Timber.w("SIGN_OUT: clear cache -> SUCCESS: clear crypto cache")
|
||||
cryptoService.clearCryptoCache(MatrixCallbackDelegate(callback))
|
||||
cryptoService.get().clearCryptoCache(MatrixCallbackDelegate(callback))
|
||||
|
||||
WorkManagerUtil.cancelAllWorks(context)
|
||||
}
|
||||
|
|
|
@ -22,13 +22,20 @@ import androidx.work.WorkManager
|
|||
import com.zhuinden.monarchy.Monarchy
|
||||
import im.vector.matrix.android.api.auth.data.Credentials
|
||||
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.model.GroupEntity
|
||||
import im.vector.matrix.android.internal.database.query.where
|
||||
import im.vector.matrix.android.internal.di.SessionDatabase
|
||||
import im.vector.matrix.android.internal.session.room.prune.PruneEventTask
|
||||
import im.vector.matrix.android.internal.task.configureWith
|
||||
import im.vector.matrix.android.internal.worker.WorkManagerUtil
|
||||
import im.vector.matrix.android.internal.worker.WorkManagerUtil.matrixOneTimeWorkRequestBuilder
|
||||
import im.vector.matrix.android.internal.worker.WorkerParamsFactory
|
||||
import io.realm.OrderedCollectionChangeSet
|
||||
import io.realm.RealmConfiguration
|
||||
import io.realm.RealmResults
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
|
||||
private const val GET_GROUP_DATA_WORKER = "GET_GROUP_DATA_WORKER"
|
||||
|
@ -40,8 +47,12 @@ internal class GroupSummaryUpdater @Inject constructor(private val context: Cont
|
|||
|
||||
override val query = Monarchy.Query<GroupEntity> { GroupEntity.where(it) }
|
||||
|
||||
override fun processChanges(inserted: List<GroupEntity>, updated: List<GroupEntity>, deleted: List<GroupEntity>) {
|
||||
val newGroupIds = inserted.map { it.groupId }
|
||||
override fun onChange(results: RealmResults<GroupEntity>, changeSet: OrderedCollectionChangeSet) {
|
||||
val newGroupIds = changeSet.insertions
|
||||
.asSequence()
|
||||
.mapNotNull { results[it]?.groupId}
|
||||
.toList()
|
||||
|
||||
val getGroupDataWorkerParams = GetGroupDataWorker.Params(credentials.userId, newGroupIds)
|
||||
val workData = WorkerParamsFactory.toData(getGroupDataWorkerParams)
|
||||
|
||||
|
@ -55,5 +66,4 @@ internal class GroupSummaryUpdater @Inject constructor(private val context: Cont
|
|||
.enqueue()
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -25,7 +25,9 @@ import im.vector.matrix.android.internal.database.query.types
|
|||
import im.vector.matrix.android.internal.di.SessionDatabase
|
||||
import im.vector.matrix.android.internal.task.TaskExecutor
|
||||
import im.vector.matrix.android.internal.task.configureWith
|
||||
import io.realm.OrderedCollectionChangeSet
|
||||
import io.realm.RealmConfiguration
|
||||
import io.realm.RealmResults
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
|
||||
|
@ -50,19 +52,18 @@ internal class EventRelationsAggregationUpdater @Inject constructor(@SessionData
|
|||
)
|
||||
}
|
||||
|
||||
override fun processChanges(inserted: List<EventEntity>, updated: List<EventEntity>, deleted: List<EventEntity>) {
|
||||
Timber.v("EventRelationsAggregationUpdater called with ${inserted.size} insertions")
|
||||
val domainInserted = inserted
|
||||
.map { it.asDomain() }
|
||||
override fun onChange(results: RealmResults<EventEntity>, changeSet: OrderedCollectionChangeSet) {
|
||||
Timber.v("EventRelationsAggregationUpdater called with ${changeSet.insertions.size} insertions")
|
||||
|
||||
val insertedDomains = changeSet.insertions
|
||||
.asSequence()
|
||||
.mapNotNull { results[it]?.asDomain() }
|
||||
.toList()
|
||||
val params = EventRelationsAggregationTask.Params(
|
||||
domainInserted,
|
||||
insertedDomains,
|
||||
credentials.userId
|
||||
)
|
||||
|
||||
task.configureWith(params)
|
||||
.executeBy(taskExecutor)
|
||||
|
||||
task.configureWith(params).executeBy(taskExecutor)
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -26,9 +26,12 @@ 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
|
||||
import im.vector.matrix.android.internal.session.room.EventRelationsAggregationTask
|
||||
import im.vector.matrix.android.internal.task.TaskExecutor
|
||||
import im.vector.matrix.android.internal.task.configureWith
|
||||
import io.realm.OrderedCollectionChangeSet
|
||||
import io.realm.RealmConfiguration
|
||||
import io.realm.RealmResults
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
|
||||
|
@ -44,18 +47,19 @@ internal class EventsPruner @Inject constructor(@SessionDatabase realmConfigurat
|
|||
|
||||
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")
|
||||
val redactionEvents = inserted.map { it.asDomain() }
|
||||
override fun onChange(results: RealmResults<EventEntity>, changeSet: OrderedCollectionChangeSet) {
|
||||
Timber.v("Event pruner called with ${changeSet.insertions.size} insertions")
|
||||
|
||||
val insertedDomains = changeSet.insertions
|
||||
.asSequence()
|
||||
.mapNotNull { results[it]?.asDomain() }
|
||||
.toList()
|
||||
|
||||
val params = PruneEventTask.Params(
|
||||
redactionEvents,
|
||||
insertedDomains,
|
||||
credentials.userId
|
||||
)
|
||||
|
||||
pruneEventTask.configureWith(params)
|
||||
.executeBy(taskExecutor)
|
||||
|
||||
pruneEventTask.configureWith(params).executeBy(taskExecutor)
|
||||
}
|
||||
|
||||
}
|
|
@ -43,7 +43,7 @@ import kotlin.collections.ArrayList
|
|||
import kotlin.collections.HashMap
|
||||
|
||||
|
||||
private const val INITIAL_LOAD_SIZE = 20
|
||||
private const val INITIAL_LOAD_SIZE = 10
|
||||
private const val MIN_FETCHING_COUNT = 30
|
||||
private const val DISPLAY_INDEX_UNKNOWN = Int.MIN_VALUE
|
||||
|
||||
|
@ -216,6 +216,7 @@ internal class DefaultTimeline(
|
|||
backgroundRealm.set(realm)
|
||||
clearUnlinkedEvents(realm)
|
||||
|
||||
|
||||
roomEntity = RoomEntity.where(realm, roomId = roomId).findFirst()?.also {
|
||||
it.sendingTimelineEvents.addChangeListener { _ ->
|
||||
postSnapshot()
|
||||
|
@ -242,6 +243,8 @@ internal class DefaultTimeline(
|
|||
Timber.v("Dispose timeline for roomId: $roomId and eventId: $initialEventId")
|
||||
BACKGROUND_HANDLER.post {
|
||||
cancelableBag.cancel()
|
||||
roomEntity?.sendingTimelineEvents?.removeAllChangeListeners()
|
||||
eventRelations.removeAllChangeListeners()
|
||||
liveEvents.removeAllChangeListeners()
|
||||
backgroundRealm.getAndSet(null).also {
|
||||
it.close()
|
||||
|
|
|
@ -105,8 +105,8 @@ open class SyncService : Service() {
|
|||
Timber.v("Execute sync request with timeout 0")
|
||||
val params = SyncTask.Params(TIME_OUT)
|
||||
cancelableTask = syncTask.configureWith(params)
|
||||
.callbackOn(TaskThread.CALLER)
|
||||
.executeOn(TaskThread.CALLER)
|
||||
.callbackOn(TaskThread.SYNC)
|
||||
.executeOn(TaskThread.SYNC)
|
||||
.dispatchTo(object : MatrixCallback<Unit> {
|
||||
override fun onSuccess(data: Unit) {
|
||||
cancelableTask = null
|
||||
|
|
|
@ -97,8 +97,8 @@ internal class SyncThread @Inject constructor(private val syncTask: SyncTask,
|
|||
val latch = CountDownLatch(1)
|
||||
val params = SyncTask.Params(DEFAULT_LONG_POOL_TIMEOUT)
|
||||
cancelableTask = syncTask.configureWith(params)
|
||||
.callbackOn(TaskThread.CALLER)
|
||||
.executeOn(TaskThread.CALLER)
|
||||
.callbackOn(TaskThread.SYNC)
|
||||
.executeOn(TaskThread.SYNC)
|
||||
.dispatchTo(object : MatrixCallback<Unit> {
|
||||
override fun onSuccess(data: Unit) {
|
||||
latch.countDown()
|
||||
|
|
|
@ -62,8 +62,8 @@ internal class SyncWorker(context: Context,
|
|||
val latch = CountDownLatch(1)
|
||||
val taskParams = SyncTask.Params(0)
|
||||
cancelableTask = syncTask.configureWith(taskParams)
|
||||
.callbackOn(TaskThread.CALLER)
|
||||
.executeOn(TaskThread.CALLER)
|
||||
.callbackOn(TaskThread.SYNC)
|
||||
.executeOn(TaskThread.SYNC)
|
||||
.dispatchTo(object : MatrixCallback<Unit> {
|
||||
override fun onSuccess(data: Unit) {
|
||||
latch.countDown()
|
||||
|
|
|
@ -22,13 +22,13 @@ 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
|
||||
import im.vector.matrix.android.internal.task.TaskExecutor
|
||||
import im.vector.matrix.android.internal.task.TaskThread
|
||||
import im.vector.matrix.android.internal.task.configureWith
|
||||
import io.realm.OrderedCollectionChangeSet
|
||||
import io.realm.RealmConfiguration
|
||||
import io.realm.RealmResults
|
||||
import io.realm.Sort
|
||||
import javax.inject.Inject
|
||||
|
||||
|
@ -42,15 +42,19 @@ internal class UserEntityUpdater @Inject constructor(@SessionDatabase realmConfi
|
|||
.types(it, listOf(EventType.STATE_ROOM_MEMBER))
|
||||
.sort(EventEntityFields.STATE_INDEX, Sort.DESCENDING)
|
||||
.distinct(EventEntityFields.STATE_KEY)
|
||||
|
||||
}
|
||||
|
||||
override fun processChanges(inserted: List<EventEntity>, updated: List<EventEntity>, deleted: List<EventEntity>) {
|
||||
val roomMembersEvents = inserted.map { it.eventId }
|
||||
override fun onChange(results: RealmResults<EventEntity>, changeSet: OrderedCollectionChangeSet) {
|
||||
val roomMembersEvents = changeSet.insertions
|
||||
.asSequence()
|
||||
.mapNotNull { results[it]?.eventId }
|
||||
.toList()
|
||||
|
||||
val taskParams = UpdateUserTask.Params(roomMembersEvents)
|
||||
updateUserTask
|
||||
.configureWith(taskParams)
|
||||
.executeOn(TaskThread.IO)
|
||||
.executeBy(taskExecutor)
|
||||
}
|
||||
|
||||
}
|
|
@ -77,6 +77,7 @@ internal class TaskExecutor @Inject constructor(private val coroutineDispatchers
|
|||
TaskThread.IO -> coroutineDispatchers.io
|
||||
TaskThread.CALLER -> EmptyCoroutineContext
|
||||
TaskThread.CRYPTO -> coroutineDispatchers.crypto
|
||||
TaskThread.SYNC -> coroutineDispatchers.sync
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -21,5 +21,6 @@ internal enum class TaskThread {
|
|||
COMPUTATION,
|
||||
IO,
|
||||
CALLER,
|
||||
CRYPTO
|
||||
CRYPTO,
|
||||
SYNC
|
||||
}
|
|
@ -22,5 +22,6 @@ internal data class MatrixCoroutineDispatchers(
|
|||
val io: CoroutineDispatcher,
|
||||
val computation: CoroutineDispatcher,
|
||||
val main: CoroutineDispatcher,
|
||||
val crypto: CoroutineDispatcher
|
||||
val crypto: CoroutineDispatcher,
|
||||
val sync: CoroutineDispatcher
|
||||
)
|
|
@ -18,6 +18,7 @@ package im.vector.riotx.features.home.room.detail.timeline
|
|||
|
||||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
import android.util.LongSparseArray
|
||||
import android.view.View
|
||||
import androidx.recyclerview.widget.DiffUtil
|
||||
import androidx.recyclerview.widget.ListUpdateCallback
|
||||
|
@ -82,8 +83,8 @@ class TimelineEventController @Inject constructor(private val dateFormatter: Tim
|
|||
fun onUrlLongClicked(url: String): Boolean
|
||||
}
|
||||
|
||||
private val collapsedEventIds = linkedSetOf<String>()
|
||||
private val mergeItemCollapseStates = HashMap<String, Boolean>()
|
||||
private val collapsedEventIds = linkedSetOf<Long>()
|
||||
private val mergeItemCollapseStates = HashMap<Long,Boolean>()
|
||||
private val modelCache = arrayListOf<CacheItemData?>()
|
||||
|
||||
private var currentSnapshot: List<TimelineEvent> = emptyList()
|
||||
|
@ -298,7 +299,7 @@ class TimelineEventController @Inject constructor(private val dateFormatter: Tim
|
|||
} else {
|
||||
collapsedEventIds.removeAll(mergedEventIds)
|
||||
}
|
||||
val mergeId = mergedEventIds.joinToString(separator = "_") { it }
|
||||
val mergeId = mergedEventIds.joinToString(separator = "_") { it.toString() }
|
||||
MergedHeaderItem(isCollapsed, mergeId, mergedData, avatarRenderer) {
|
||||
mergeItemCollapseStates[event.localId] = it
|
||||
requestModelBuild()
|
||||
|
@ -329,7 +330,7 @@ class TimelineEventController @Inject constructor(private val dateFormatter: Tim
|
|||
}
|
||||
|
||||
private data class CacheItemData(
|
||||
val localId: String,
|
||||
val localId: Long,
|
||||
val eventId: String?,
|
||||
val eventModel: EpoxyModel<*>? = null,
|
||||
val mergedHeaderModel: MergedHeaderItem? = null,
|
||||
|
|
|
@ -78,7 +78,7 @@ data class MergedHeaderItem(private val isCollapsed: Boolean,
|
|||
}
|
||||
|
||||
data class Data(
|
||||
val eventId: String,
|
||||
val eventId: Long,
|
||||
val userId: String,
|
||||
val memberName: String,
|
||||
val avatarUrl: String?
|
||||
|
|
Loading…
Reference in a new issue