Merge pull request #1504 from vector-im/feature/improve_perf

Feature/improve perf
This commit is contained in:
ganfra 2020-06-25 17:00:56 +02:00 committed by GitHub
commit f8452429a4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
144 changed files with 811 additions and 442 deletions

View file

@ -1,6 +1,9 @@
<component name="ProjectCodeStyleConfiguration"> <component name="ProjectCodeStyleConfiguration">
<code_scheme name="Project" version="173"> <code_scheme name="Project" version="173">
<option name="RIGHT_MARGIN" value="160" /> <option name="RIGHT_MARGIN" value="160" />
<AndroidXmlCodeStyleSettings>
<option name="ARRANGEMENT_SETTINGS_MIGRATED_TO_191" value="true" />
</AndroidXmlCodeStyleSettings>
<JetCodeStyleSettings> <JetCodeStyleSettings>
<option name="PACKAGES_TO_USE_STAR_IMPORTS"> <option name="PACKAGES_TO_USE_STAR_IMPORTS">
<value> <value>

View file

@ -43,6 +43,7 @@ import im.vector.matrix.android.api.session.signout.SignOutService
import im.vector.matrix.android.api.session.sync.FilterService import im.vector.matrix.android.api.session.sync.FilterService
import im.vector.matrix.android.api.session.sync.SyncState import im.vector.matrix.android.api.session.sync.SyncState
import im.vector.matrix.android.api.session.terms.TermsService import im.vector.matrix.android.api.session.terms.TermsService
import im.vector.matrix.android.api.session.typing.TypingUsersTracker
import im.vector.matrix.android.api.session.user.UserService import im.vector.matrix.android.api.session.user.UserService
import im.vector.matrix.android.api.session.widgets.WidgetService import im.vector.matrix.android.api.session.widgets.WidgetService
@ -146,6 +147,11 @@ interface Session :
*/ */
fun contentUploadProgressTracker(): ContentUploadStateTracker fun contentUploadProgressTracker(): ContentUploadStateTracker
/**
* Returns the TypingUsersTracker associated with the session
*/
fun typingUsersTracker(): TypingUsersTracker
/** /**
* Returns the cryptoService associated with the session * Returns the cryptoService associated with the session
*/ */

View file

@ -17,8 +17,8 @@ package im.vector.matrix.android.api.session.room.model
data class EventAnnotationsSummary( data class EventAnnotationsSummary(
var eventId: String, var eventId: String,
var reactionsSummary: List<ReactionAggregatedSummary>, var reactionsSummary: List<ReactionAggregatedSummary> = emptyList(),
var editSummary: EditAggregatedSummary?, var editSummary: EditAggregatedSummary? = null,
var pollResponseSummary: PollResponseAggregatedSummary?, var pollResponseSummary: PollResponseAggregatedSummary? = null,
var referencesAggregatedSummary: ReferencesAggregatedSummary? = null var referencesAggregatedSummary: ReferencesAggregatedSummary? = null
) )

View file

@ -48,7 +48,6 @@ data class RoomSummary constructor(
val isEncrypted: Boolean, val isEncrypted: Boolean,
val encryptionEventTs: Long?, val encryptionEventTs: Long?,
val inviterId: String? = null, val inviterId: String? = null,
val typingRoomMemberIds: List<String> = emptyList(),
val breadcrumbsIndex: Int = NOT_IN_BREADCRUMBS, val breadcrumbsIndex: Int = NOT_IN_BREADCRUMBS,
val roomEncryptionTrustLevel: RoomEncryptionTrustLevel? = null val roomEncryptionTrustLevel: RoomEncryptionTrustLevel? = null
) { ) {

View file

@ -0,0 +1,37 @@
/*
* Copyright (c) 2020 New Vector Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package im.vector.matrix.android.api.session.typing
import androidx.lifecycle.LiveData
import im.vector.matrix.android.api.session.room.sender.SenderInfo
/**
* Responsible for tracking typing users from each room.
* It's ephemeral data and it's only saved in memory.
*/
interface TypingUsersTracker {
/**
* Returns the sender information of all currently typing users in a room, excluding yourself.
*/
fun getTypingUsers(roomId: String): List<SenderInfo>
/**
* Returns a LiveData of the sender information of all currently typing users in a room, excluding yourself.
*/
fun getTypingUsersLive(roomId: String): LiveData<List<SenderInfo>>
}

View file

@ -84,6 +84,7 @@ import im.vector.matrix.android.internal.database.model.EventEntityFields
import im.vector.matrix.android.internal.database.query.whereType import im.vector.matrix.android.internal.database.query.whereType
import im.vector.matrix.android.internal.di.DeviceId import im.vector.matrix.android.internal.di.DeviceId
import im.vector.matrix.android.internal.di.MoshiProvider import im.vector.matrix.android.internal.di.MoshiProvider
import im.vector.matrix.android.internal.di.SessionDatabase
import im.vector.matrix.android.internal.di.UserId import im.vector.matrix.android.internal.di.UserId
import im.vector.matrix.android.internal.extensions.foldToCallback import im.vector.matrix.android.internal.extensions.foldToCallback
import im.vector.matrix.android.internal.session.SessionScope import im.vector.matrix.android.internal.session.SessionScope
@ -168,7 +169,7 @@ internal class DefaultCryptoService @Inject constructor(
private val setDeviceNameTask: SetDeviceNameTask, private val setDeviceNameTask: SetDeviceNameTask,
private val uploadKeysTask: UploadKeysTask, private val uploadKeysTask: UploadKeysTask,
private val loadRoomMembersTask: LoadRoomMembersTask, private val loadRoomMembersTask: LoadRoomMembersTask,
private val monarchy: Monarchy, @SessionDatabase private val monarchy: Monarchy,
private val coroutineDispatchers: MatrixCoroutineDispatchers, private val coroutineDispatchers: MatrixCoroutineDispatchers,
private val taskExecutor: TaskExecutor, private val taskExecutor: TaskExecutor,
private val cryptoCoroutineScope: CoroutineScope, private val cryptoCoroutineScope: CoroutineScope,

View file

@ -21,7 +21,8 @@ import im.vector.matrix.android.internal.database.model.RoomMemberSummaryEntityF
import im.vector.matrix.android.internal.database.model.RoomSummaryEntity import im.vector.matrix.android.internal.database.model.RoomSummaryEntity
import im.vector.matrix.android.internal.database.query.where import im.vector.matrix.android.internal.database.query.where
import im.vector.matrix.android.internal.di.SessionDatabase import im.vector.matrix.android.internal.di.SessionDatabase
import im.vector.matrix.android.internal.session.room.RoomSummaryUpdater import im.vector.matrix.android.internal.session.SessionLifecycleObserver
import im.vector.matrix.android.internal.session.room.summary.RoomSummaryUpdater
import im.vector.matrix.android.internal.session.room.membership.RoomMemberHelper import im.vector.matrix.android.internal.session.room.membership.RoomMemberHelper
import im.vector.matrix.android.internal.task.TaskExecutor import im.vector.matrix.android.internal.task.TaskExecutor
import im.vector.matrix.android.internal.util.createBackgroundHandler import im.vector.matrix.android.internal.util.createBackgroundHandler
@ -42,7 +43,7 @@ internal class ShieldTrustUpdater @Inject constructor(
private val taskExecutor: TaskExecutor, private val taskExecutor: TaskExecutor,
@SessionDatabase private val sessionRealmConfiguration: RealmConfiguration, @SessionDatabase private val sessionRealmConfiguration: RealmConfiguration,
private val roomSummaryUpdater: RoomSummaryUpdater private val roomSummaryUpdater: RoomSummaryUpdater
) { ): SessionLifecycleObserver {
companion object { companion object {
private val BACKGROUND_HANDLER = createBackgroundHandler("SHIELD_CRYPTO_DB_THREAD") private val BACKGROUND_HANDLER = createBackgroundHandler("SHIELD_CRYPTO_DB_THREAD")
@ -53,7 +54,7 @@ internal class ShieldTrustUpdater @Inject constructor(
private val isStarted = AtomicBoolean() private val isStarted = AtomicBoolean()
fun start() { override fun onStart() {
if (isStarted.compareAndSet(false, true)) { if (isStarted.compareAndSet(false, true)) {
eventBus.register(this) eventBus.register(this)
BACKGROUND_HANDLER.post { BACKGROUND_HANDLER.post {
@ -62,7 +63,7 @@ internal class ShieldTrustUpdater @Inject constructor(
} }
} }
fun stop() { override fun onStop() {
if (isStarted.compareAndSet(true, false)) { if (isStarted.compareAndSet(true, false)) {
eventBus.unregister(this) eventBus.unregister(this)
BACKGROUND_HANDLER.post { BACKGROUND_HANDLER.post {

View file

@ -17,6 +17,7 @@
package im.vector.matrix.android.internal.database package im.vector.matrix.android.internal.database
import com.zhuinden.monarchy.Monarchy import com.zhuinden.monarchy.Monarchy
import im.vector.matrix.android.internal.session.SessionLifecycleObserver
import im.vector.matrix.android.internal.util.createBackgroundHandler import im.vector.matrix.android.internal.util.createBackgroundHandler
import io.realm.OrderedRealmCollectionChangeListener import io.realm.OrderedRealmCollectionChangeListener
import io.realm.Realm import io.realm.Realm
@ -29,12 +30,7 @@ import kotlinx.coroutines.cancelChildren
import java.util.concurrent.atomic.AtomicBoolean import java.util.concurrent.atomic.AtomicBoolean
import java.util.concurrent.atomic.AtomicReference import java.util.concurrent.atomic.AtomicReference
internal interface LiveEntityObserver { internal interface LiveEntityObserver: SessionLifecycleObserver
fun start()
fun dispose()
fun cancelProcess()
fun isStarted(): Boolean
}
internal abstract class RealmLiveEntityObserver<T : RealmObject>(protected val realmConfiguration: RealmConfiguration) internal abstract class RealmLiveEntityObserver<T : RealmObject>(protected val realmConfiguration: RealmConfiguration)
: LiveEntityObserver, OrderedRealmCollectionChangeListener<RealmResults<T>> { : LiveEntityObserver, OrderedRealmCollectionChangeListener<RealmResults<T>> {
@ -49,7 +45,7 @@ internal abstract class RealmLiveEntityObserver<T : RealmObject>(protected val r
private val backgroundRealm = AtomicReference<Realm>() private val backgroundRealm = AtomicReference<Realm>()
private lateinit var results: AtomicReference<RealmResults<T>> private lateinit var results: AtomicReference<RealmResults<T>>
override fun start() { override fun onStart() {
if (isStarted.compareAndSet(false, true)) { if (isStarted.compareAndSet(false, true)) {
BACKGROUND_HANDLER.post { BACKGROUND_HANDLER.post {
val realm = Realm.getInstance(realmConfiguration) val realm = Realm.getInstance(realmConfiguration)
@ -61,7 +57,7 @@ internal abstract class RealmLiveEntityObserver<T : RealmObject>(protected val r
} }
} }
override fun dispose() { override fun onStop() {
if (isStarted.compareAndSet(true, false)) { if (isStarted.compareAndSet(true, false)) {
BACKGROUND_HANDLER.post { BACKGROUND_HANDLER.post {
results.getAndSet(null).removeAllChangeListeners() results.getAndSet(null).removeAllChangeListeners()
@ -73,11 +69,7 @@ internal abstract class RealmLiveEntityObserver<T : RealmObject>(protected val r
} }
} }
override fun cancelProcess() { override fun onClearCache() {
observerScope.coroutineContext.cancelChildren() observerScope.coroutineContext.cancelChildren()
} }
override fun isStarted(): Boolean {
return isStarted.get()
}
} }

View file

@ -54,7 +54,6 @@ internal class RoomSummaryMapper @Inject constructor(private val timelineEventMa
aliases = roomSummaryEntity.aliases.toList(), aliases = roomSummaryEntity.aliases.toList(),
isEncrypted = roomSummaryEntity.isEncrypted, isEncrypted = roomSummaryEntity.isEncrypted,
encryptionEventTs = roomSummaryEntity.encryptionEventTs, encryptionEventTs = roomSummaryEntity.encryptionEventTs,
typingRoomMemberIds = roomSummaryEntity.typingUserIds.toList(),
breadcrumbsIndex = roomSummaryEntity.breadcrumbsIndex, breadcrumbsIndex = roomSummaryEntity.breadcrumbsIndex,
roomEncryptionTrustLevel = roomSummaryEntity.roomEncryptionTrustLevel, roomEncryptionTrustLevel = roomSummaryEntity.roomEncryptionTrustLevel,
inviterId = roomSummaryEntity.inviterId inviterId = roomSummaryEntity.inviterId

View file

@ -49,7 +49,6 @@ internal open class RoomSummaryEntity(
var flatAliases: String = "", var flatAliases: String = "",
var isEncrypted: Boolean = false, var isEncrypted: Boolean = false,
var encryptionEventTs: Long? = 0, var encryptionEventTs: Long? = 0,
var typingUserIds: RealmList<String> = RealmList(),
var roomEncryptionTrustLevelStr: String? = null, var roomEncryptionTrustLevelStr: String? = null,
var inviterId: String? = null var inviterId: String? = null
) : RealmObject() { ) : RealmObject() {

View file

@ -15,15 +15,15 @@
*/ */
package im.vector.matrix.android.internal.database.query package im.vector.matrix.android.internal.database.query
import com.zhuinden.monarchy.Monarchy
import im.vector.matrix.android.api.session.events.model.LocalEcho import im.vector.matrix.android.api.session.events.model.LocalEcho
import im.vector.matrix.android.internal.database.model.ChunkEntity import im.vector.matrix.android.internal.database.model.ChunkEntity
import im.vector.matrix.android.internal.database.model.ReadMarkerEntity import im.vector.matrix.android.internal.database.model.ReadMarkerEntity
import im.vector.matrix.android.internal.database.model.ReadReceiptEntity import im.vector.matrix.android.internal.database.model.ReadReceiptEntity
import im.vector.matrix.android.internal.database.model.TimelineEventEntity import im.vector.matrix.android.internal.database.model.TimelineEventEntity
import io.realm.Realm import io.realm.Realm
import io.realm.RealmConfiguration
internal fun isEventRead(monarchy: Monarchy, internal fun isEventRead(realmConfiguration: RealmConfiguration,
userId: String?, userId: String?,
roomId: String?, roomId: String?,
eventId: String?): Boolean { eventId: String?): Boolean {
@ -35,14 +35,14 @@ internal fun isEventRead(monarchy: Monarchy,
} }
var isEventRead = false var isEventRead = false
monarchy.doWithRealm { realm -> Realm.getInstance(realmConfiguration).use { realm ->
val liveChunk = ChunkEntity.findLastForwardChunkOfRoom(realm, roomId) ?: return@doWithRealm val liveChunk = ChunkEntity.findLastForwardChunkOfRoom(realm, roomId) ?: return@use
val eventToCheck = liveChunk.timelineEvents.find(eventId) val eventToCheck = liveChunk.timelineEvents.find(eventId)
isEventRead = if (eventToCheck == null || eventToCheck.root?.sender == userId) { isEventRead = if (eventToCheck == null || eventToCheck.root?.sender == userId) {
true true
} else { } else {
val readReceipt = ReadReceiptEntity.where(realm, roomId, userId).findFirst() val readReceipt = ReadReceiptEntity.where(realm, roomId, userId).findFirst()
?: return@doWithRealm ?: return@use
val readReceiptIndex = liveChunk.timelineEvents.find(readReceipt.eventId)?.displayIndex val readReceiptIndex = liveChunk.timelineEvents.find(readReceipt.eventId)?.displayIndex
?: Int.MIN_VALUE ?: Int.MIN_VALUE
val eventToCheckIndex = eventToCheck.displayIndex val eventToCheckIndex = eventToCheck.displayIndex
@ -54,13 +54,13 @@ internal fun isEventRead(monarchy: Monarchy,
return isEventRead return isEventRead
} }
internal fun isReadMarkerMoreRecent(monarchy: Monarchy, internal fun isReadMarkerMoreRecent(realmConfiguration: RealmConfiguration,
roomId: String?, roomId: String?,
eventId: String?): Boolean { eventId: String?): Boolean {
if (roomId.isNullOrBlank() || eventId.isNullOrBlank()) { if (roomId.isNullOrBlank() || eventId.isNullOrBlank()) {
return false return false
} }
return Realm.getInstance(monarchy.realmConfiguration).use { realm -> return Realm.getInstance(realmConfiguration).use { realm ->
val eventToCheck = TimelineEventEntity.where(realm, roomId = roomId, eventId = eventId).findFirst() val eventToCheck = TimelineEventEntity.where(realm, roomId = roomId, eventId = eventId).findFirst()
val eventToCheckChunk = eventToCheck?.chunk?.firstOrNull() val eventToCheckChunk = eventToCheck?.chunk?.firstOrNull()
val readMarker = ReadMarkerEntity.where(realm, roomId).findFirst() ?: return false val readMarker = ReadMarkerEntity.where(realm, roomId).findFirst() ?: return false

View file

@ -46,12 +46,11 @@ import im.vector.matrix.android.api.session.signout.SignOutService
import im.vector.matrix.android.api.session.sync.FilterService import im.vector.matrix.android.api.session.sync.FilterService
import im.vector.matrix.android.api.session.sync.SyncState import im.vector.matrix.android.api.session.sync.SyncState
import im.vector.matrix.android.api.session.terms.TermsService import im.vector.matrix.android.api.session.terms.TermsService
import im.vector.matrix.android.api.session.typing.TypingUsersTracker
import im.vector.matrix.android.api.session.user.UserService import im.vector.matrix.android.api.session.user.UserService
import im.vector.matrix.android.api.session.widgets.WidgetService import im.vector.matrix.android.api.session.widgets.WidgetService
import im.vector.matrix.android.internal.auth.SessionParamsStore import im.vector.matrix.android.internal.auth.SessionParamsStore
import im.vector.matrix.android.internal.crypto.DefaultCryptoService import im.vector.matrix.android.internal.crypto.DefaultCryptoService
import im.vector.matrix.android.internal.crypto.crosssigning.ShieldTrustUpdater
import im.vector.matrix.android.internal.database.LiveEntityObserver
import im.vector.matrix.android.internal.di.SessionId import im.vector.matrix.android.internal.di.SessionId
import im.vector.matrix.android.internal.di.WorkManagerProvider import im.vector.matrix.android.internal.di.WorkManagerProvider
import im.vector.matrix.android.internal.session.identity.DefaultIdentityService import im.vector.matrix.android.internal.session.identity.DefaultIdentityService
@ -59,9 +58,9 @@ import im.vector.matrix.android.internal.session.room.timeline.TimelineEventDecr
import im.vector.matrix.android.internal.session.sync.SyncTokenStore import im.vector.matrix.android.internal.session.sync.SyncTokenStore
import im.vector.matrix.android.internal.session.sync.job.SyncThread import im.vector.matrix.android.internal.session.sync.job.SyncThread
import im.vector.matrix.android.internal.session.sync.job.SyncWorker import im.vector.matrix.android.internal.session.sync.job.SyncWorker
import im.vector.matrix.android.internal.session.widgets.WidgetDependenciesHolder
import im.vector.matrix.android.internal.task.TaskExecutor import im.vector.matrix.android.internal.task.TaskExecutor
import im.vector.matrix.android.internal.util.MatrixCoroutineDispatchers import im.vector.matrix.android.internal.util.MatrixCoroutineDispatchers
import im.vector.matrix.android.internal.util.createUIHandler
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import org.greenrobot.eventbus.EventBus import org.greenrobot.eventbus.EventBus
@ -78,7 +77,7 @@ internal class DefaultSession @Inject constructor(
private val eventBus: EventBus, private val eventBus: EventBus,
@SessionId @SessionId
override val sessionId: String, override val sessionId: String,
private val liveEntityObservers: Set<@JvmSuppressWildcards LiveEntityObserver>, private val lifecycleObservers: Set<@JvmSuppressWildcards SessionLifecycleObserver>,
private val sessionListeners: SessionListeners, private val sessionListeners: SessionListeners,
private val roomService: Lazy<RoomService>, private val roomService: Lazy<RoomService>,
private val roomDirectoryService: Lazy<RoomDirectoryService>, private val roomDirectoryService: Lazy<RoomDirectoryService>,
@ -100,6 +99,7 @@ internal class DefaultSession @Inject constructor(
private val syncTokenStore: SyncTokenStore, private val syncTokenStore: SyncTokenStore,
private val sessionParamsStore: SessionParamsStore, private val sessionParamsStore: SessionParamsStore,
private val contentUploadProgressTracker: ContentUploadStateTracker, private val contentUploadProgressTracker: ContentUploadStateTracker,
private val typingUsersTracker: TypingUsersTracker,
private val initialSyncProgressService: Lazy<InitialSyncProgressService>, private val initialSyncProgressService: Lazy<InitialSyncProgressService>,
private val homeServerCapabilitiesService: Lazy<HomeServerCapabilitiesService>, private val homeServerCapabilitiesService: Lazy<HomeServerCapabilitiesService>,
private val accountDataService: Lazy<AccountDataService>, private val accountDataService: Lazy<AccountDataService>,
@ -110,8 +110,6 @@ internal class DefaultSession @Inject constructor(
private val defaultIdentityService: DefaultIdentityService, private val defaultIdentityService: DefaultIdentityService,
private val integrationManagerService: IntegrationManagerService, private val integrationManagerService: IntegrationManagerService,
private val taskExecutor: TaskExecutor, private val taskExecutor: TaskExecutor,
private val widgetDependenciesHolder: WidgetDependenciesHolder,
private val shieldTrustUpdater: ShieldTrustUpdater,
private val callSignalingService: Lazy<CallSignalingService>) private val callSignalingService: Lazy<CallSignalingService>)
: Session, : Session,
RoomService by roomService.get(), RoomService by roomService.get(),
@ -138,6 +136,8 @@ internal class DefaultSession @Inject constructor(
private var syncThread: SyncThread? = null private var syncThread: SyncThread? = null
private val uiHandler = createUIHandler()
override val isOpenable: Boolean override val isOpenable: Boolean
get() = sessionParamsStore.get(sessionId)?.isTokenValid ?: false get() = sessionParamsStore.get(sessionId)?.isTokenValid ?: false
@ -145,12 +145,11 @@ internal class DefaultSession @Inject constructor(
override fun open() { override fun open() {
assert(!isOpen) assert(!isOpen)
isOpen = true isOpen = true
liveEntityObservers.forEach { it.start() } uiHandler.post {
lifecycleObservers.forEach { it.onStart() }
}
eventBus.register(this) eventBus.register(this)
timelineEventDecryptor.start() timelineEventDecryptor.start()
shieldTrustUpdater.start()
defaultIdentityService.start()
widgetDependenciesHolder.start()
} }
override fun requireBackgroundSync() { override fun requireBackgroundSync() {
@ -188,16 +187,12 @@ internal class DefaultSession @Inject constructor(
assert(isOpen) assert(isOpen)
stopSync() stopSync()
timelineEventDecryptor.destroy() timelineEventDecryptor.destroy()
liveEntityObservers.forEach { it.dispose() } uiHandler.post {
lifecycleObservers.forEach { it.onStop() }
}
cryptoService.get().close() cryptoService.get().close()
isOpen = false isOpen = false
eventBus.unregister(this) eventBus.unregister(this)
shieldTrustUpdater.stop()
taskExecutor.executorScope.launch(coroutineDispatchers.main) {
// This has to be done on main thread
defaultIdentityService.stop()
widgetDependenciesHolder.stop()
}
} }
override fun getSyncStateLive(): LiveData<SyncState> { override fun getSyncStateLive(): LiveData<SyncState> {
@ -217,7 +212,9 @@ internal class DefaultSession @Inject constructor(
override fun clearCache(callback: MatrixCallback<Unit>) { override fun clearCache(callback: MatrixCallback<Unit>) {
stopSync() stopSync()
stopAnyBackgroundSync() stopAnyBackgroundSync()
liveEntityObservers.forEach { it.cancelProcess() } uiHandler.post {
lifecycleObservers.forEach { it.onClearCache() }
}
cacheService.get().clearCache(callback) cacheService.get().clearCache(callback)
workManagerProvider.cancelAllWorks() workManagerProvider.cancelAllWorks()
} }
@ -239,6 +236,8 @@ internal class DefaultSession @Inject constructor(
override fun contentUploadProgressTracker() = contentUploadProgressTracker override fun contentUploadProgressTracker() = contentUploadProgressTracker
override fun typingUsersTracker() = typingUsersTracker
override fun cryptoService(): CryptoService = cryptoService.get() override fun cryptoService(): CryptoService = cryptoService.get()
override fun identityService() = defaultIdentityService override fun identityService() = defaultIdentityService

View file

@ -0,0 +1,49 @@
/*
* Copyright (c) 2020 New Vector Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package im.vector.matrix.android.internal.session
import androidx.annotation.MainThread
/**
* This defines methods associated with some lifecycle events of a session.
* A list of SessionLifecycle will be injected into [DefaultSession]
*/
internal interface SessionLifecycleObserver {
/*
Called when the session is opened
*/
@MainThread
fun onStart() {
// noop
}
/*
Called when the session is cleared
*/
@MainThread
fun onClearCache() {
// noop
}
/*
Called when the session is closed
*/
@MainThread
fun onStop() {
// noop
}
}

View file

@ -36,9 +36,10 @@ import im.vector.matrix.android.api.session.accountdata.AccountDataService
import im.vector.matrix.android.api.session.homeserver.HomeServerCapabilitiesService import im.vector.matrix.android.api.session.homeserver.HomeServerCapabilitiesService
import im.vector.matrix.android.api.session.securestorage.SecureStorageService import im.vector.matrix.android.api.session.securestorage.SecureStorageService
import im.vector.matrix.android.api.session.securestorage.SharedSecretStorageService import im.vector.matrix.android.api.session.securestorage.SharedSecretStorageService
import im.vector.matrix.android.api.session.typing.TypingUsersTracker
import im.vector.matrix.android.internal.crypto.crosssigning.ShieldTrustUpdater
import im.vector.matrix.android.internal.crypto.secrets.DefaultSharedSecretStorageService import im.vector.matrix.android.internal.crypto.secrets.DefaultSharedSecretStorageService
import im.vector.matrix.android.internal.crypto.verification.VerificationMessageLiveObserver import im.vector.matrix.android.internal.crypto.verification.VerificationMessageLiveObserver
import im.vector.matrix.android.internal.database.LiveEntityObserver
import im.vector.matrix.android.internal.database.SessionRealmConfigurationFactory import im.vector.matrix.android.internal.database.SessionRealmConfigurationFactory
import im.vector.matrix.android.internal.di.Authenticated import im.vector.matrix.android.internal.di.Authenticated
import im.vector.matrix.android.internal.di.DeviceId import im.vector.matrix.android.internal.di.DeviceId
@ -62,12 +63,16 @@ import im.vector.matrix.android.internal.network.token.HomeserverAccessTokenProv
import im.vector.matrix.android.internal.session.call.CallEventObserver import im.vector.matrix.android.internal.session.call.CallEventObserver
import im.vector.matrix.android.internal.session.group.GroupSummaryUpdater import im.vector.matrix.android.internal.session.group.GroupSummaryUpdater
import im.vector.matrix.android.internal.session.homeserver.DefaultHomeServerCapabilitiesService import im.vector.matrix.android.internal.session.homeserver.DefaultHomeServerCapabilitiesService
import im.vector.matrix.android.internal.session.identity.DefaultIdentityService
import im.vector.matrix.android.internal.session.integrationmanager.IntegrationManager
import im.vector.matrix.android.internal.session.room.EventRelationsAggregationUpdater import im.vector.matrix.android.internal.session.room.EventRelationsAggregationUpdater
import im.vector.matrix.android.internal.session.room.create.RoomCreateEventLiveObserver import im.vector.matrix.android.internal.session.room.create.RoomCreateEventLiveObserver
import im.vector.matrix.android.internal.session.room.prune.EventsPruner import im.vector.matrix.android.internal.session.room.prune.EventsPruner
import im.vector.matrix.android.internal.session.room.tombstone.RoomTombstoneEventLiveObserver import im.vector.matrix.android.internal.session.room.tombstone.RoomTombstoneEventLiveObserver
import im.vector.matrix.android.internal.session.securestorage.DefaultSecureStorageService import im.vector.matrix.android.internal.session.securestorage.DefaultSecureStorageService
import im.vector.matrix.android.internal.session.typing.DefaultTypingUsersTracker
import im.vector.matrix.android.internal.session.user.accountdata.DefaultAccountDataService import im.vector.matrix.android.internal.session.user.accountdata.DefaultAccountDataService
import im.vector.matrix.android.internal.session.widgets.DefaultWidgetURLFormatter
import im.vector.matrix.android.internal.util.md5 import im.vector.matrix.android.internal.util.md5
import io.realm.RealmConfiguration import io.realm.RealmConfiguration
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
@ -164,9 +169,9 @@ internal abstract class SessionModule {
@JvmStatic @JvmStatic
@Provides @Provides
@SessionDatabase
@SessionScope @SessionScope
fun providesMonarchy(@SessionDatabase fun providesMonarchy(@SessionDatabase realmConfiguration: RealmConfiguration): Monarchy {
realmConfiguration: RealmConfiguration): Monarchy {
return Monarchy.Builder() return Monarchy.Builder()
.setRealmConfiguration(realmConfiguration) .setRealmConfiguration(realmConfiguration)
.build() .build()
@ -234,31 +239,47 @@ internal abstract class SessionModule {
@Binds @Binds
@IntoSet @IntoSet
abstract fun bindGroupSummaryUpdater(updater: GroupSummaryUpdater): LiveEntityObserver abstract fun bindGroupSummaryUpdater(updater: GroupSummaryUpdater): SessionLifecycleObserver
@Binds @Binds
@IntoSet @IntoSet
abstract fun bindEventsPruner(pruner: EventsPruner): LiveEntityObserver abstract fun bindEventsPruner(pruner: EventsPruner): SessionLifecycleObserver
@Binds @Binds
@IntoSet @IntoSet
abstract fun bindEventRelationsAggregationUpdater(updater: EventRelationsAggregationUpdater): LiveEntityObserver abstract fun bindEventRelationsAggregationUpdater(updater: EventRelationsAggregationUpdater): SessionLifecycleObserver
@Binds @Binds
@IntoSet @IntoSet
abstract fun bindCallEventObserver(observer: CallEventObserver): LiveEntityObserver abstract fun bindRoomTombstoneEventLiveObserver(observer: RoomTombstoneEventLiveObserver): SessionLifecycleObserver
@Binds @Binds
@IntoSet @IntoSet
abstract fun bindRoomTombstoneEventLiveObserver(observer: RoomTombstoneEventLiveObserver): LiveEntityObserver abstract fun bindRoomCreateEventLiveObserver(observer: RoomCreateEventLiveObserver): SessionLifecycleObserver
@Binds @Binds
@IntoSet @IntoSet
abstract fun bindRoomCreateEventLiveObserver(observer: RoomCreateEventLiveObserver): LiveEntityObserver abstract fun bindVerificationMessageLiveObserver(observer: VerificationMessageLiveObserver): SessionLifecycleObserver
@Binds @Binds
@IntoSet @IntoSet
abstract fun bindVerificationMessageLiveObserver(observer: VerificationMessageLiveObserver): LiveEntityObserver abstract fun bindCallEventObserver(observer: CallEventObserver): SessionLifecycleObserver
@Binds
@IntoSet
abstract fun bindIntegrationManager(observer: IntegrationManager): SessionLifecycleObserver
@Binds
@IntoSet
abstract fun bindWidgetUrlFormatter(observer: DefaultWidgetURLFormatter): SessionLifecycleObserver
@Binds
@IntoSet
abstract fun bindShieldTrustUpdated(observer: ShieldTrustUpdater): SessionLifecycleObserver
@Binds
@IntoSet
abstract fun bindIdentityService(observer: DefaultIdentityService): SessionLifecycleObserver
@Binds @Binds
abstract fun bindInitialSyncProgressService(service: DefaultInitialSyncProgressService): InitialSyncProgressService abstract fun bindInitialSyncProgressService(service: DefaultInitialSyncProgressService): InitialSyncProgressService
@ -274,4 +295,7 @@ internal abstract class SessionModule {
@Binds @Binds
abstract fun bindSharedSecretStorageService(service: DefaultSharedSecretStorageService): SharedSecretStorageService abstract fun bindSharedSecretStorageService(service: DefaultSharedSecretStorageService): SharedSecretStorageService
@Binds
abstract fun bindTypingUsersTracker(tracker: DefaultTypingUsersTracker): TypingUsersTracker
} }

View file

@ -22,6 +22,7 @@ import im.vector.matrix.android.api.session.crypto.MXCryptoError
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.internal.crypto.algorithms.olm.OlmDecryptionResult import im.vector.matrix.android.internal.crypto.algorithms.olm.OlmDecryptionResult
import im.vector.matrix.android.internal.di.SessionDatabase
import im.vector.matrix.android.internal.task.Task import im.vector.matrix.android.internal.task.Task
import im.vector.matrix.android.internal.util.awaitTransaction import im.vector.matrix.android.internal.util.awaitTransaction
import io.realm.Realm import io.realm.Realm
@ -37,7 +38,7 @@ internal interface CallEventsObserverTask : Task<CallEventsObserverTask.Params,
} }
internal class DefaultCallEventsObserverTask @Inject constructor( internal class DefaultCallEventsObserverTask @Inject constructor(
private val monarchy: Monarchy, @SessionDatabase private val monarchy: Monarchy,
private val cryptoService: CryptoService, private val cryptoService: CryptoService,
private val callService: DefaultCallSignalingService) : CallEventsObserverTask { private val callService: DefaultCallSignalingService) : CallEventsObserverTask {

View file

@ -21,12 +21,13 @@ import im.vector.matrix.android.internal.database.model.FilterEntity
import im.vector.matrix.android.internal.database.model.FilterEntityFields import im.vector.matrix.android.internal.database.model.FilterEntityFields
import im.vector.matrix.android.internal.database.query.get import im.vector.matrix.android.internal.database.query.get
import im.vector.matrix.android.internal.database.query.getOrCreate import im.vector.matrix.android.internal.database.query.getOrCreate
import im.vector.matrix.android.internal.di.SessionDatabase
import im.vector.matrix.android.internal.util.awaitTransaction import im.vector.matrix.android.internal.util.awaitTransaction
import io.realm.Realm import io.realm.Realm
import io.realm.kotlin.where import io.realm.kotlin.where
import javax.inject.Inject import javax.inject.Inject
internal class DefaultFilterRepository @Inject constructor(private val monarchy: Monarchy) : FilterRepository { internal class DefaultFilterRepository @Inject constructor(@SessionDatabase private val monarchy: Monarchy) : FilterRepository {
override suspend fun storeFilter(filter: Filter, roomEventFilter: RoomEventFilter): Boolean { override suspend fun storeFilter(filter: Filter, roomEventFilter: RoomEventFilter): Boolean {
return Realm.getInstance(monarchy.realmConfiguration).use { realm -> return Realm.getInstance(monarchy.realmConfiguration).use { realm ->

View file

@ -20,6 +20,7 @@ import com.zhuinden.monarchy.Monarchy
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.internal.database.model.GroupSummaryEntity import im.vector.matrix.android.internal.database.model.GroupSummaryEntity
import im.vector.matrix.android.internal.database.query.where import im.vector.matrix.android.internal.database.query.where
import im.vector.matrix.android.internal.di.SessionDatabase
import im.vector.matrix.android.internal.network.executeRequest import im.vector.matrix.android.internal.network.executeRequest
import im.vector.matrix.android.internal.session.group.model.GroupRooms import im.vector.matrix.android.internal.session.group.model.GroupRooms
import im.vector.matrix.android.internal.session.group.model.GroupSummaryResponse import im.vector.matrix.android.internal.session.group.model.GroupSummaryResponse
@ -36,7 +37,7 @@ internal interface GetGroupDataTask : Task<GetGroupDataTask.Params, Unit> {
internal class DefaultGetGroupDataTask @Inject constructor( internal class DefaultGetGroupDataTask @Inject constructor(
private val groupAPI: GroupAPI, private val groupAPI: GroupAPI,
private val monarchy: Monarchy, @SessionDatabase private val monarchy: Monarchy,
private val eventBus: EventBus private val eventBus: EventBus
) : GetGroupDataTask { ) : GetGroupDataTask {

View file

@ -26,13 +26,14 @@ import im.vector.matrix.android.internal.database.mapper.asDomain
import im.vector.matrix.android.internal.database.model.GroupSummaryEntity import im.vector.matrix.android.internal.database.model.GroupSummaryEntity
import im.vector.matrix.android.internal.database.model.GroupSummaryEntityFields import im.vector.matrix.android.internal.database.model.GroupSummaryEntityFields
import im.vector.matrix.android.internal.database.query.where import im.vector.matrix.android.internal.database.query.where
import im.vector.matrix.android.internal.di.SessionDatabase
import im.vector.matrix.android.internal.query.process import im.vector.matrix.android.internal.query.process
import im.vector.matrix.android.internal.util.fetchCopyMap import im.vector.matrix.android.internal.util.fetchCopyMap
import io.realm.Realm import io.realm.Realm
import io.realm.RealmQuery import io.realm.RealmQuery
import javax.inject.Inject import javax.inject.Inject
internal class DefaultGroupService @Inject constructor(private val monarchy: Monarchy) : GroupService { internal class DefaultGroupService @Inject constructor(@SessionDatabase private val monarchy: Monarchy) : GroupService {
override fun getGroup(groupId: String): Group? { override fun getGroup(groupId: String): Group? {
return null return null

View file

@ -24,6 +24,7 @@ import im.vector.matrix.android.internal.database.awaitTransaction
import im.vector.matrix.android.internal.database.model.GroupEntity import im.vector.matrix.android.internal.database.model.GroupEntity
import im.vector.matrix.android.internal.database.model.GroupSummaryEntity import im.vector.matrix.android.internal.database.model.GroupSummaryEntity
import im.vector.matrix.android.internal.database.query.where import im.vector.matrix.android.internal.database.query.where
import im.vector.matrix.android.internal.di.SessionDatabase
import im.vector.matrix.android.internal.di.SessionId import im.vector.matrix.android.internal.di.SessionId
import im.vector.matrix.android.internal.di.WorkManagerProvider import im.vector.matrix.android.internal.di.WorkManagerProvider
import im.vector.matrix.android.internal.worker.WorkerParamsFactory import im.vector.matrix.android.internal.worker.WorkerParamsFactory
@ -37,7 +38,7 @@ private const val GET_GROUP_DATA_WORKER = "GET_GROUP_DATA_WORKER"
internal class GroupSummaryUpdater @Inject constructor( internal class GroupSummaryUpdater @Inject constructor(
private val workManagerProvider: WorkManagerProvider, private val workManagerProvider: WorkManagerProvider,
@SessionId private val sessionId: String, @SessionId private val sessionId: String,
private val monarchy: Monarchy) @SessionDatabase private val monarchy: Monarchy)
: RealmLiveEntityObserver<GroupEntity>(monarchy.realmConfiguration) { : RealmLiveEntityObserver<GroupEntity>(monarchy.realmConfiguration) {
override val query = Monarchy.Query { GroupEntity.where(it) } override val query = Monarchy.Query { GroupEntity.where(it) }

View file

@ -23,6 +23,7 @@ import im.vector.matrix.android.internal.auth.version.Versions
import im.vector.matrix.android.internal.auth.version.isLoginAndRegistrationSupportedBySdk import im.vector.matrix.android.internal.auth.version.isLoginAndRegistrationSupportedBySdk
import im.vector.matrix.android.internal.database.model.HomeServerCapabilitiesEntity import im.vector.matrix.android.internal.database.model.HomeServerCapabilitiesEntity
import im.vector.matrix.android.internal.database.query.getOrCreate import im.vector.matrix.android.internal.database.query.getOrCreate
import im.vector.matrix.android.internal.di.SessionDatabase
import im.vector.matrix.android.internal.di.UserId import im.vector.matrix.android.internal.di.UserId
import im.vector.matrix.android.internal.network.executeRequest import im.vector.matrix.android.internal.network.executeRequest
import im.vector.matrix.android.internal.session.integrationmanager.IntegrationManagerConfigExtractor import im.vector.matrix.android.internal.session.integrationmanager.IntegrationManagerConfigExtractor
@ -38,7 +39,7 @@ internal interface GetHomeServerCapabilitiesTask : Task<Unit, Unit>
internal class DefaultGetHomeServerCapabilitiesTask @Inject constructor( internal class DefaultGetHomeServerCapabilitiesTask @Inject constructor(
private val capabilitiesAPI: CapabilitiesAPI, private val capabilitiesAPI: CapabilitiesAPI,
private val monarchy: Monarchy, @SessionDatabase private val monarchy: Monarchy,
private val eventBus: EventBus, private val eventBus: EventBus,
private val getWellknownTask: GetWellknownTask, private val getWellknownTask: GetWellknownTask,
private val configExtractor: IntegrationManagerConfigExtractor, private val configExtractor: IntegrationManagerConfigExtractor,

View file

@ -22,10 +22,11 @@ import im.vector.matrix.android.api.session.homeserver.HomeServerCapabilitiesSer
import im.vector.matrix.android.internal.database.mapper.HomeServerCapabilitiesMapper import im.vector.matrix.android.internal.database.mapper.HomeServerCapabilitiesMapper
import im.vector.matrix.android.internal.database.model.HomeServerCapabilitiesEntity import im.vector.matrix.android.internal.database.model.HomeServerCapabilitiesEntity
import im.vector.matrix.android.internal.database.query.get import im.vector.matrix.android.internal.database.query.get
import im.vector.matrix.android.internal.di.SessionDatabase
import io.realm.Realm import io.realm.Realm
import javax.inject.Inject import javax.inject.Inject
internal class DefaultHomeServerCapabilitiesService @Inject constructor(private val monarchy: Monarchy) : HomeServerCapabilitiesService { internal class DefaultHomeServerCapabilitiesService @Inject constructor(@SessionDatabase private val monarchy: Monarchy) : HomeServerCapabilitiesService {
override fun getHomeServerCapabilities(): HomeServerCapabilities { override fun getHomeServerCapabilities(): HomeServerCapabilities {
return Realm.getInstance(monarchy.realmConfiguration).use { realm -> return Realm.getInstance(monarchy.realmConfiguration).use { realm ->

View file

@ -39,6 +39,7 @@ import im.vector.matrix.android.internal.di.AuthenticatedIdentity
import im.vector.matrix.android.internal.di.Unauthenticated import im.vector.matrix.android.internal.di.Unauthenticated
import im.vector.matrix.android.internal.extensions.observeNotNull import im.vector.matrix.android.internal.extensions.observeNotNull
import im.vector.matrix.android.internal.network.RetrofitFactory import im.vector.matrix.android.internal.network.RetrofitFactory
import im.vector.matrix.android.internal.session.SessionLifecycleObserver
import im.vector.matrix.android.internal.session.SessionScope import im.vector.matrix.android.internal.session.SessionScope
import im.vector.matrix.android.internal.session.identity.data.IdentityStore import im.vector.matrix.android.internal.session.identity.data.IdentityStore
import im.vector.matrix.android.internal.session.openid.GetOpenIdTokenTask import im.vector.matrix.android.internal.session.openid.GetOpenIdTokenTask
@ -82,14 +83,14 @@ internal class DefaultIdentityService @Inject constructor(
private val homeServerCapabilitiesService: HomeServerCapabilitiesService, private val homeServerCapabilitiesService: HomeServerCapabilitiesService,
private val sessionParams: SessionParams, private val sessionParams: SessionParams,
private val taskExecutor: TaskExecutor private val taskExecutor: TaskExecutor
) : IdentityService { ) : IdentityService, SessionLifecycleObserver {
private val lifecycleOwner: LifecycleOwner = LifecycleOwner { lifecycleRegistry } private val lifecycleOwner: LifecycleOwner = LifecycleOwner { lifecycleRegistry }
private val lifecycleRegistry: LifecycleRegistry = LifecycleRegistry(lifecycleOwner) private val lifecycleRegistry: LifecycleRegistry = LifecycleRegistry(lifecycleOwner)
private val listeners = mutableSetOf<IdentityServiceListener>() private val listeners = mutableSetOf<IdentityServiceListener>()
fun start() { override fun onStart() {
lifecycleRegistry.currentState = Lifecycle.State.STARTED lifecycleRegistry.currentState = Lifecycle.State.STARTED
// Observe the account data change // Observe the account data change
accountDataDataSource accountDataDataSource
@ -114,7 +115,7 @@ internal class DefaultIdentityService @Inject constructor(
} }
} }
fun stop() { override fun onStop() {
lifecycleRegistry.currentState = Lifecycle.State.DESTROYED lifecycleRegistry.currentState = Lifecycle.State.DESTROYED
} }

View file

@ -30,7 +30,9 @@ import im.vector.matrix.android.api.session.widgets.model.WidgetType
import im.vector.matrix.android.api.util.Cancelable import im.vector.matrix.android.api.util.Cancelable
import im.vector.matrix.android.api.util.NoOpCancellable import im.vector.matrix.android.api.util.NoOpCancellable
import im.vector.matrix.android.internal.database.model.WellknownIntegrationManagerConfigEntity import im.vector.matrix.android.internal.database.model.WellknownIntegrationManagerConfigEntity
import im.vector.matrix.android.internal.di.SessionDatabase
import im.vector.matrix.android.internal.extensions.observeNotNull import im.vector.matrix.android.internal.extensions.observeNotNull
import im.vector.matrix.android.internal.session.SessionLifecycleObserver
import im.vector.matrix.android.internal.session.SessionScope import im.vector.matrix.android.internal.session.SessionScope
import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountData import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountData
import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountDataEvent import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountDataEvent
@ -58,10 +60,11 @@ import javax.inject.Inject
@SessionScope @SessionScope
internal class IntegrationManager @Inject constructor(matrixConfiguration: MatrixConfiguration, internal class IntegrationManager @Inject constructor(matrixConfiguration: MatrixConfiguration,
private val taskExecutor: TaskExecutor, private val taskExecutor: TaskExecutor,
private val monarchy: Monarchy, @SessionDatabase private val monarchy: Monarchy,
private val updateUserAccountDataTask: UpdateUserAccountDataTask, private val updateUserAccountDataTask: UpdateUserAccountDataTask,
private val accountDataDataSource: AccountDataDataSource, private val accountDataDataSource: AccountDataDataSource,
private val widgetFactory: WidgetFactory) { private val widgetFactory: WidgetFactory)
: SessionLifecycleObserver {
private val currentConfigs = ArrayList<IntegrationManagerConfig>() private val currentConfigs = ArrayList<IntegrationManagerConfig>()
private val lifecycleOwner: LifecycleOwner = LifecycleOwner { lifecycleRegistry } private val lifecycleOwner: LifecycleOwner = LifecycleOwner { lifecycleRegistry }
@ -80,7 +83,7 @@ internal class IntegrationManager @Inject constructor(matrixConfiguration: Matri
currentConfigs.add(defaultConfig) currentConfigs.add(defaultConfig)
} }
fun start() { override fun onStart() {
lifecycleRegistry.currentState = Lifecycle.State.STARTED lifecycleRegistry.currentState = Lifecycle.State.STARTED
observeWellknownConfig() observeWellknownConfig()
accountDataDataSource accountDataDataSource
@ -108,7 +111,7 @@ internal class IntegrationManager @Inject constructor(matrixConfiguration: Matri
} }
} }
fun stop() { override fun onStop() {
lifecycleRegistry.currentState = Lifecycle.State.DESTROYED lifecycleRegistry.currentState = Lifecycle.State.DESTROYED
} }

View file

@ -28,6 +28,7 @@ import im.vector.matrix.android.api.util.Cancelable
import im.vector.matrix.android.internal.database.mapper.PushRulesMapper import im.vector.matrix.android.internal.database.mapper.PushRulesMapper
import im.vector.matrix.android.internal.database.model.PushRulesEntity import im.vector.matrix.android.internal.database.model.PushRulesEntity
import im.vector.matrix.android.internal.database.query.where 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.SessionScope
import im.vector.matrix.android.internal.session.pushers.AddPushRuleTask import im.vector.matrix.android.internal.session.pushers.AddPushRuleTask
import im.vector.matrix.android.internal.session.pushers.GetPushRulesTask import im.vector.matrix.android.internal.session.pushers.GetPushRulesTask
@ -47,7 +48,7 @@ internal class DefaultPushRuleService @Inject constructor(
private val updatePushRuleActionsTask: UpdatePushRuleActionsTask, private val updatePushRuleActionsTask: UpdatePushRuleActionsTask,
private val removePushRuleTask: RemovePushRuleTask, private val removePushRuleTask: RemovePushRuleTask,
private val taskExecutor: TaskExecutor, private val taskExecutor: TaskExecutor,
private val monarchy: Monarchy @SessionDatabase private val monarchy: Monarchy
) : PushRuleService { ) : PushRuleService {
private var listeners = mutableSetOf<PushRuleService.PushRuleListener>() private var listeners = mutableSetOf<PushRuleService.PushRuleListener>()

View file

@ -26,13 +26,14 @@ import im.vector.matrix.android.api.util.Cancelable
import im.vector.matrix.android.api.util.JsonDict import im.vector.matrix.android.api.util.JsonDict
import im.vector.matrix.android.api.util.Optional import im.vector.matrix.android.api.util.Optional
import im.vector.matrix.android.internal.database.model.UserThreePidEntity import im.vector.matrix.android.internal.database.model.UserThreePidEntity
import im.vector.matrix.android.internal.di.SessionDatabase
import im.vector.matrix.android.internal.task.TaskExecutor import im.vector.matrix.android.internal.task.TaskExecutor
import im.vector.matrix.android.internal.task.configureWith import im.vector.matrix.android.internal.task.configureWith
import io.realm.kotlin.where import io.realm.kotlin.where
import javax.inject.Inject import javax.inject.Inject
internal class DefaultProfileService @Inject constructor(private val taskExecutor: TaskExecutor, internal class DefaultProfileService @Inject constructor(private val taskExecutor: TaskExecutor,
private val monarchy: Monarchy, @SessionDatabase private val monarchy: Monarchy,
private val refreshUserThreePidsTask: RefreshUserThreePidsTask, private val refreshUserThreePidsTask: RefreshUserThreePidsTask,
private val getProfileInfoTask: GetProfileInfoTask, private val getProfileInfoTask: GetProfileInfoTask,
private val setDisplayNameTask: SetDisplayNameTask) : ProfileService { private val setDisplayNameTask: SetDisplayNameTask) : ProfileService {

View file

@ -18,6 +18,7 @@ package im.vector.matrix.android.internal.session.profile
import com.zhuinden.monarchy.Monarchy import com.zhuinden.monarchy.Monarchy
import im.vector.matrix.android.internal.database.model.UserThreePidEntity import im.vector.matrix.android.internal.database.model.UserThreePidEntity
import im.vector.matrix.android.internal.di.SessionDatabase
import im.vector.matrix.android.internal.network.executeRequest import im.vector.matrix.android.internal.network.executeRequest
import im.vector.matrix.android.internal.task.Task import im.vector.matrix.android.internal.task.Task
import org.greenrobot.eventbus.EventBus import org.greenrobot.eventbus.EventBus
@ -27,7 +28,7 @@ import javax.inject.Inject
internal abstract class RefreshUserThreePidsTask : Task<Unit, Unit> internal abstract class RefreshUserThreePidsTask : Task<Unit, Unit>
internal class DefaultRefreshUserThreePidsTask @Inject constructor(private val profileAPI: ProfileAPI, internal class DefaultRefreshUserThreePidsTask @Inject constructor(private val profileAPI: ProfileAPI,
private val monarchy: Monarchy, @SessionDatabase private val monarchy: Monarchy,
private val eventBus: EventBus) : RefreshUserThreePidsTask() { private val eventBus: EventBus) : RefreshUserThreePidsTask() {
override suspend fun execute(params: Unit) { override suspend fun execute(params: Unit) {

View file

@ -25,6 +25,7 @@ import im.vector.matrix.android.api.session.pushers.PusherState
import im.vector.matrix.android.internal.database.mapper.toEntity import im.vector.matrix.android.internal.database.mapper.toEntity
import im.vector.matrix.android.internal.database.model.PusherEntity import im.vector.matrix.android.internal.database.model.PusherEntity
import im.vector.matrix.android.internal.database.query.where import im.vector.matrix.android.internal.database.query.where
import im.vector.matrix.android.internal.di.SessionDatabase
import im.vector.matrix.android.internal.network.executeRequest import im.vector.matrix.android.internal.network.executeRequest
import im.vector.matrix.android.internal.util.awaitTransaction import im.vector.matrix.android.internal.util.awaitTransaction
import im.vector.matrix.android.internal.worker.SessionWorkerParams import im.vector.matrix.android.internal.worker.SessionWorkerParams
@ -45,7 +46,7 @@ internal class AddHttpPusherWorker(context: Context, params: WorkerParameters)
) : SessionWorkerParams ) : SessionWorkerParams
@Inject lateinit var pushersAPI: PushersAPI @Inject lateinit var pushersAPI: PushersAPI
@Inject lateinit var monarchy: Monarchy @Inject @SessionDatabase lateinit var monarchy: Monarchy
@Inject lateinit var eventBus: EventBus @Inject lateinit var eventBus: EventBus
override suspend fun doWork(): Result { override suspend fun doWork(): Result {

View file

@ -25,6 +25,7 @@ import im.vector.matrix.android.api.util.Cancelable
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.PusherEntity import im.vector.matrix.android.internal.database.model.PusherEntity
import im.vector.matrix.android.internal.database.query.where import im.vector.matrix.android.internal.database.query.where
import im.vector.matrix.android.internal.di.SessionDatabase
import im.vector.matrix.android.internal.di.SessionId import im.vector.matrix.android.internal.di.SessionId
import im.vector.matrix.android.internal.di.WorkManagerProvider import im.vector.matrix.android.internal.di.WorkManagerProvider
import im.vector.matrix.android.internal.task.TaskExecutor import im.vector.matrix.android.internal.task.TaskExecutor
@ -37,7 +38,7 @@ import javax.inject.Inject
internal class DefaultPushersService @Inject constructor( internal class DefaultPushersService @Inject constructor(
private val workManagerProvider: WorkManagerProvider, private val workManagerProvider: WorkManagerProvider,
private val monarchy: Monarchy, @SessionDatabase private val monarchy: Monarchy,
@SessionId private val sessionId: String, @SessionId private val sessionId: String,
private val getPusherTask: GetPushersTask, private val getPusherTask: GetPushersTask,
private val removePusherTask: RemovePusherTask, private val removePusherTask: RemovePusherTask,

View file

@ -19,6 +19,7 @@ import com.zhuinden.monarchy.Monarchy
import im.vector.matrix.android.api.session.pushers.PusherState import im.vector.matrix.android.api.session.pushers.PusherState
import im.vector.matrix.android.internal.database.mapper.toEntity import im.vector.matrix.android.internal.database.mapper.toEntity
import im.vector.matrix.android.internal.database.model.PusherEntity import im.vector.matrix.android.internal.database.model.PusherEntity
import im.vector.matrix.android.internal.di.SessionDatabase
import im.vector.matrix.android.internal.network.executeRequest import im.vector.matrix.android.internal.network.executeRequest
import im.vector.matrix.android.internal.task.Task import im.vector.matrix.android.internal.task.Task
import im.vector.matrix.android.internal.util.awaitTransaction import im.vector.matrix.android.internal.util.awaitTransaction
@ -29,7 +30,7 @@ internal interface GetPushersTask : Task<Unit, Unit>
internal class DefaultGetPushersTask @Inject constructor( internal class DefaultGetPushersTask @Inject constructor(
private val pushersAPI: PushersAPI, private val pushersAPI: PushersAPI,
private val monarchy: Monarchy, @SessionDatabase private val monarchy: Monarchy,
private val eventBus: EventBus private val eventBus: EventBus
) : GetPushersTask { ) : GetPushersTask {

View file

@ -21,6 +21,7 @@ import im.vector.matrix.android.api.session.pushers.PusherState
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.PusherEntity import im.vector.matrix.android.internal.database.model.PusherEntity
import im.vector.matrix.android.internal.database.query.where import im.vector.matrix.android.internal.database.query.where
import im.vector.matrix.android.internal.di.SessionDatabase
import im.vector.matrix.android.internal.network.executeRequest import im.vector.matrix.android.internal.network.executeRequest
import im.vector.matrix.android.internal.task.Task import im.vector.matrix.android.internal.task.Task
import im.vector.matrix.android.internal.util.awaitTransaction import im.vector.matrix.android.internal.util.awaitTransaction
@ -35,7 +36,7 @@ internal interface RemovePusherTask : Task<RemovePusherTask.Params, Unit> {
internal class DefaultRemovePusherTask @Inject constructor( internal class DefaultRemovePusherTask @Inject constructor(
private val pushersAPI: PushersAPI, private val pushersAPI: PushersAPI,
private val monarchy: Monarchy, @SessionDatabase private val monarchy: Monarchy,
private val eventBus: EventBus private val eventBus: EventBus
) : RemovePusherTask { ) : RemovePusherTask {

View file

@ -21,6 +21,7 @@ import im.vector.matrix.android.api.pushrules.RuleSetKey
import im.vector.matrix.android.api.pushrules.rest.GetPushRulesResponse import im.vector.matrix.android.api.pushrules.rest.GetPushRulesResponse
import im.vector.matrix.android.internal.database.mapper.PushRulesMapper import im.vector.matrix.android.internal.database.mapper.PushRulesMapper
import im.vector.matrix.android.internal.database.model.PushRulesEntity import im.vector.matrix.android.internal.database.model.PushRulesEntity
import im.vector.matrix.android.internal.di.SessionDatabase
import im.vector.matrix.android.internal.task.Task import im.vector.matrix.android.internal.task.Task
import im.vector.matrix.android.internal.util.awaitTransaction import im.vector.matrix.android.internal.util.awaitTransaction
import javax.inject.Inject import javax.inject.Inject
@ -32,7 +33,7 @@ internal interface SavePushRulesTask : Task<SavePushRulesTask.Params, Unit> {
data class Params(val pushRules: GetPushRulesResponse) data class Params(val pushRules: GetPushRulesResponse)
} }
internal class DefaultSavePushRulesTask @Inject constructor(private val monarchy: Monarchy) : SavePushRulesTask { internal class DefaultSavePushRulesTask @Inject constructor(@SessionDatabase private val monarchy: Monarchy) : SavePushRulesTask {
override suspend fun execute(params: SavePushRulesTask.Params) { override suspend fun execute(params: SavePushRulesTask.Params) {
monarchy.awaitTransaction { realm -> monarchy.awaitTransaction { realm ->

View file

@ -17,8 +17,6 @@
package im.vector.matrix.android.internal.session.room package im.vector.matrix.android.internal.session.room
import androidx.lifecycle.LiveData import androidx.lifecycle.LiveData
import androidx.lifecycle.Transformations
import com.zhuinden.monarchy.Monarchy
import im.vector.matrix.android.api.MatrixCallback import im.vector.matrix.android.api.MatrixCallback
import im.vector.matrix.android.api.session.crypto.CryptoService import im.vector.matrix.android.api.session.crypto.CryptoService
import im.vector.matrix.android.api.session.events.model.EventType import im.vector.matrix.android.api.session.events.model.EventType
@ -38,21 +36,16 @@ import im.vector.matrix.android.api.session.room.timeline.TimelineService
import im.vector.matrix.android.api.session.room.typing.TypingService import im.vector.matrix.android.api.session.room.typing.TypingService
import im.vector.matrix.android.api.session.room.uploads.UploadsService import im.vector.matrix.android.api.session.room.uploads.UploadsService
import im.vector.matrix.android.api.util.Optional import im.vector.matrix.android.api.util.Optional
import im.vector.matrix.android.api.util.toOptional
import im.vector.matrix.android.internal.crypto.MXCRYPTO_ALGORITHM_MEGOLM import im.vector.matrix.android.internal.crypto.MXCRYPTO_ALGORITHM_MEGOLM
import im.vector.matrix.android.internal.database.mapper.RoomSummaryMapper
import im.vector.matrix.android.internal.database.model.RoomSummaryEntity
import im.vector.matrix.android.internal.database.model.RoomSummaryEntityFields
import im.vector.matrix.android.internal.database.query.where
import im.vector.matrix.android.internal.session.room.state.SendStateTask import im.vector.matrix.android.internal.session.room.state.SendStateTask
import im.vector.matrix.android.internal.session.room.summary.RoomSummaryDataSource
import im.vector.matrix.android.internal.task.TaskExecutor import im.vector.matrix.android.internal.task.TaskExecutor
import im.vector.matrix.android.internal.task.configureWith import im.vector.matrix.android.internal.task.configureWith
import java.security.InvalidParameterException import java.security.InvalidParameterException
import javax.inject.Inject import javax.inject.Inject
internal class DefaultRoom @Inject constructor(override val roomId: String, internal class DefaultRoom @Inject constructor(override val roomId: String,
private val monarchy: Monarchy, private val roomSummaryDataSource: RoomSummaryDataSource,
private val roomSummaryMapper: RoomSummaryMapper,
private val timelineService: TimelineService, private val timelineService: TimelineService,
private val sendService: SendService, private val sendService: SendService,
private val draftService: DraftService, private val draftService: DraftService,
@ -85,20 +78,11 @@ internal class DefaultRoom @Inject constructor(override val roomId: String,
RoomPushRuleService by roomPushRuleService { RoomPushRuleService by roomPushRuleService {
override fun getRoomSummaryLive(): LiveData<Optional<RoomSummary>> { override fun getRoomSummaryLive(): LiveData<Optional<RoomSummary>> {
val liveData = monarchy.findAllMappedWithChanges( return roomSummaryDataSource.getRoomSummaryLive(roomId)
{ realm -> RoomSummaryEntity.where(realm, roomId).isNotEmpty(RoomSummaryEntityFields.DISPLAY_NAME) },
{ roomSummaryMapper.map(it) }
)
return Transformations.map(liveData) { results ->
results.firstOrNull().toOptional()
}
} }
override fun roomSummary(): RoomSummary? { override fun roomSummary(): RoomSummary? {
return monarchy.fetchAllMappedSync( return roomSummaryDataSource.getRoomSummary(roomId)
{ realm -> RoomSummaryEntity.where(realm, roomId).isNotEmpty(RoomSummaryEntityFields.DISPLAY_NAME) },
{ roomSummaryMapper.map(it) }
).firstOrNull()
} }
override fun isEncrypted(): Boolean { override fun isEncrypted(): Boolean {

View file

@ -17,43 +17,32 @@
package im.vector.matrix.android.internal.session.room package im.vector.matrix.android.internal.session.room
import androidx.lifecycle.LiveData import androidx.lifecycle.LiveData
import com.zhuinden.monarchy.Monarchy
import im.vector.matrix.android.api.MatrixCallback import im.vector.matrix.android.api.MatrixCallback
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.RoomService import im.vector.matrix.android.api.session.room.RoomService
import im.vector.matrix.android.api.session.room.RoomSummaryQueryParams import im.vector.matrix.android.api.session.room.RoomSummaryQueryParams
import im.vector.matrix.android.api.session.room.model.RoomSummary import im.vector.matrix.android.api.session.room.model.RoomSummary
import im.vector.matrix.android.api.session.room.model.VersioningState
import im.vector.matrix.android.api.session.room.model.create.CreateRoomParams import im.vector.matrix.android.api.session.room.model.create.CreateRoomParams
import im.vector.matrix.android.api.util.Cancelable import im.vector.matrix.android.api.util.Cancelable
import im.vector.matrix.android.api.util.Optional import im.vector.matrix.android.api.util.Optional
import im.vector.matrix.android.internal.database.mapper.RoomSummaryMapper
import im.vector.matrix.android.internal.database.model.RoomSummaryEntity
import im.vector.matrix.android.internal.database.model.RoomSummaryEntityFields
import im.vector.matrix.android.internal.database.query.findByAlias
import im.vector.matrix.android.internal.database.query.where
import im.vector.matrix.android.internal.query.process
import im.vector.matrix.android.internal.session.room.alias.GetRoomIdByAliasTask import im.vector.matrix.android.internal.session.room.alias.GetRoomIdByAliasTask
import im.vector.matrix.android.internal.session.room.create.CreateRoomTask import im.vector.matrix.android.internal.session.room.create.CreateRoomTask
import im.vector.matrix.android.internal.session.room.membership.joining.JoinRoomTask import im.vector.matrix.android.internal.session.room.membership.joining.JoinRoomTask
import im.vector.matrix.android.internal.session.room.read.MarkAllRoomsReadTask import im.vector.matrix.android.internal.session.room.read.MarkAllRoomsReadTask
import im.vector.matrix.android.internal.session.room.summary.RoomSummaryDataSource
import im.vector.matrix.android.internal.session.user.accountdata.UpdateBreadcrumbsTask import im.vector.matrix.android.internal.session.user.accountdata.UpdateBreadcrumbsTask
import im.vector.matrix.android.internal.task.TaskExecutor import im.vector.matrix.android.internal.task.TaskExecutor
import im.vector.matrix.android.internal.task.configureWith import im.vector.matrix.android.internal.task.configureWith
import im.vector.matrix.android.internal.util.fetchCopyMap
import io.realm.Realm
import io.realm.RealmQuery
import javax.inject.Inject import javax.inject.Inject
internal class DefaultRoomService @Inject constructor( internal class DefaultRoomService @Inject constructor(
private val monarchy: Monarchy,
private val roomSummaryMapper: RoomSummaryMapper,
private val createRoomTask: CreateRoomTask, private val createRoomTask: CreateRoomTask,
private val joinRoomTask: JoinRoomTask, private val joinRoomTask: JoinRoomTask,
private val markAllRoomsReadTask: MarkAllRoomsReadTask, private val markAllRoomsReadTask: MarkAllRoomsReadTask,
private val updateBreadcrumbsTask: UpdateBreadcrumbsTask, private val updateBreadcrumbsTask: UpdateBreadcrumbsTask,
private val roomIdByAliasTask: GetRoomIdByAliasTask, private val roomIdByAliasTask: GetRoomIdByAliasTask,
private val roomGetter: RoomGetter, private val roomGetter: RoomGetter,
private val roomSummaryDataSource: RoomSummaryDataSource,
private val taskExecutor: TaskExecutor private val taskExecutor: TaskExecutor
) : RoomService { ) : RoomService {
@ -74,61 +63,23 @@ internal class DefaultRoomService @Inject constructor(
} }
override fun getRoomSummary(roomIdOrAlias: String): RoomSummary? { override fun getRoomSummary(roomIdOrAlias: String): RoomSummary? {
return monarchy return roomSummaryDataSource.getRoomSummary(roomIdOrAlias)
.fetchCopyMap({
if (roomIdOrAlias.startsWith("!")) {
// It's a roomId
RoomSummaryEntity.where(it, roomId = roomIdOrAlias).findFirst()
} else {
// Assume it's a room alias
RoomSummaryEntity.findByAlias(it, roomIdOrAlias)
}
}, { entity, _ ->
roomSummaryMapper.map(entity)
})
} }
override fun getRoomSummaries(queryParams: RoomSummaryQueryParams): List<RoomSummary> { override fun getRoomSummaries(queryParams: RoomSummaryQueryParams): List<RoomSummary> {
return monarchy.fetchAllMappedSync( return roomSummaryDataSource.getRoomSummaries(queryParams)
{ roomSummariesQuery(it, queryParams) },
{ roomSummaryMapper.map(it) }
)
} }
override fun getRoomSummariesLive(queryParams: RoomSummaryQueryParams): LiveData<List<RoomSummary>> { override fun getRoomSummariesLive(queryParams: RoomSummaryQueryParams): LiveData<List<RoomSummary>> {
return monarchy.findAllMappedWithChanges( return roomSummaryDataSource.getRoomSummariesLive(queryParams)
{ roomSummariesQuery(it, queryParams) },
{ roomSummaryMapper.map(it) }
)
}
private fun roomSummariesQuery(realm: Realm, queryParams: RoomSummaryQueryParams): RealmQuery<RoomSummaryEntity> {
val query = RoomSummaryEntity.where(realm)
query.process(RoomSummaryEntityFields.DISPLAY_NAME, queryParams.displayName)
query.process(RoomSummaryEntityFields.CANONICAL_ALIAS, queryParams.canonicalAlias)
query.process(RoomSummaryEntityFields.MEMBERSHIP_STR, queryParams.memberships)
query.notEqualTo(RoomSummaryEntityFields.VERSIONING_STATE_STR, VersioningState.UPGRADED_ROOM_JOINED.name)
return query
} }
override fun getBreadcrumbs(queryParams: RoomSummaryQueryParams): List<RoomSummary> { override fun getBreadcrumbs(queryParams: RoomSummaryQueryParams): List<RoomSummary> {
return monarchy.fetchAllMappedSync( return roomSummaryDataSource.getBreadcrumbs(queryParams)
{ breadcrumbsQuery(it, queryParams) },
{ roomSummaryMapper.map(it) }
)
} }
override fun getBreadcrumbsLive(queryParams: RoomSummaryQueryParams): LiveData<List<RoomSummary>> { override fun getBreadcrumbsLive(queryParams: RoomSummaryQueryParams): LiveData<List<RoomSummary>> {
return monarchy.findAllMappedWithChanges( return roomSummaryDataSource.getBreadcrumbsLive(queryParams)
{ breadcrumbsQuery(it, queryParams) },
{ roomSummaryMapper.map(it) }
)
}
private fun breadcrumbsQuery(realm: Realm, queryParams: RoomSummaryQueryParams): RealmQuery<RoomSummaryEntity> {
return roomSummariesQuery(realm, queryParams)
.greaterThan(RoomSummaryEntityFields.BREADCRUMBS_INDEX, RoomSummary.NOT_IN_BREADCRUMBS)
.sort(RoomSummaryEntityFields.BREADCRUMBS_INDEX)
} }
override fun onRoomDisplayed(roomId: String): Cancelable { override fun onRoomDisplayed(roomId: String): Cancelable {

View file

@ -47,6 +47,7 @@ import im.vector.matrix.android.internal.database.model.TimelineEventEntity
import im.vector.matrix.android.internal.database.query.create import im.vector.matrix.android.internal.database.query.create
import im.vector.matrix.android.internal.database.query.getOrCreate import im.vector.matrix.android.internal.database.query.getOrCreate
import im.vector.matrix.android.internal.database.query.where import im.vector.matrix.android.internal.database.query.where
import im.vector.matrix.android.internal.di.SessionDatabase
import im.vector.matrix.android.internal.task.Task import im.vector.matrix.android.internal.task.Task
import im.vector.matrix.android.internal.util.awaitTransaction import im.vector.matrix.android.internal.util.awaitTransaction
import io.realm.Realm import io.realm.Realm
@ -92,7 +93,7 @@ private fun VerificationState?.toState(newState: VerificationState): Verificatio
* Called by EventRelationAggregationUpdater, when new events that can affect relations are inserted in base. * Called by EventRelationAggregationUpdater, when new events that can affect relations are inserted in base.
*/ */
internal class DefaultEventRelationsAggregationTask @Inject constructor( internal class DefaultEventRelationsAggregationTask @Inject constructor(
private val monarchy: Monarchy, @SessionDatabase private val monarchy: Monarchy,
private val cryptoService: CryptoService) : EventRelationsAggregationTask { private val cryptoService: CryptoService) : EventRelationsAggregationTask {
// OPT OUT serer aggregation until API mature enough // OPT OUT serer aggregation until API mature enough

View file

@ -16,7 +16,6 @@
package im.vector.matrix.android.internal.session.room package im.vector.matrix.android.internal.session.room
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.events.model.toModel
import im.vector.matrix.android.api.session.room.model.RoomAvatarContent import im.vector.matrix.android.api.session.room.model.RoomAvatarContent
@ -26,23 +25,23 @@ import im.vector.matrix.android.internal.database.model.RoomMemberSummaryEntityF
import im.vector.matrix.android.internal.database.query.getOrNull import im.vector.matrix.android.internal.database.query.getOrNull
import im.vector.matrix.android.internal.di.UserId import im.vector.matrix.android.internal.di.UserId
import im.vector.matrix.android.internal.session.room.membership.RoomMemberHelper import im.vector.matrix.android.internal.session.room.membership.RoomMemberHelper
import io.realm.Realm
import javax.inject.Inject import javax.inject.Inject
internal class RoomAvatarResolver @Inject constructor(private val monarchy: Monarchy, internal class RoomAvatarResolver @Inject constructor(@UserId private val userId: String) {
@UserId private val userId: String) {
/** /**
* Compute the room avatar url * Compute the room avatar url
* @param realm: the current instance of realm
* @param roomId the roomId of the room to resolve avatar * @param roomId the roomId of the room to resolve avatar
* @return the room avatar url, can be a fallback to a room member avatar or null * @return the room avatar url, can be a fallback to a room member avatar or null
*/ */
fun resolve(roomId: String): String? { fun resolve(realm: Realm, roomId: String): String? {
var res: String? = null var res: String?
monarchy.doWithRealm { realm ->
val roomName = CurrentStateEventEntity.getOrNull(realm, roomId, type = EventType.STATE_ROOM_AVATAR, stateKey = "")?.root val roomName = CurrentStateEventEntity.getOrNull(realm, roomId, type = EventType.STATE_ROOM_AVATAR, stateKey = "")?.root
res = ContentMapper.map(roomName?.content).toModel<RoomAvatarContent>()?.avatarUrl res = ContentMapper.map(roomName?.content).toModel<RoomAvatarContent>()?.avatarUrl
if (!res.isNullOrEmpty()) { if (!res.isNullOrEmpty()) {
return@doWithRealm return res
} }
val roomMembers = RoomMemberHelper(realm, roomId) val roomMembers = RoomMemberHelper(realm, roomId)
val members = roomMembers.queryActiveRoomMembersEvent().findAll() val members = roomMembers.queryActiveRoomMembersEvent().findAll()
@ -53,7 +52,6 @@ internal class RoomAvatarResolver @Inject constructor(private val monarchy: Mona
val firstOtherMember = members.where().notEqualTo(RoomMemberSummaryEntityFields.USER_ID, userId).findFirst() val firstOtherMember = members.where().notEqualTo(RoomMemberSummaryEntityFields.USER_ID, userId).findFirst()
res = firstOtherMember?.avatarUrl res = firstOtherMember?.avatarUrl
} }
}
return res return res
} }
} }

View file

@ -16,10 +16,8 @@
package im.vector.matrix.android.internal.session.room package im.vector.matrix.android.internal.session.room
import com.zhuinden.monarchy.Monarchy
import im.vector.matrix.android.api.session.crypto.CryptoService import im.vector.matrix.android.api.session.crypto.CryptoService
import im.vector.matrix.android.api.session.room.Room import im.vector.matrix.android.api.session.room.Room
import im.vector.matrix.android.internal.database.mapper.RoomSummaryMapper
import im.vector.matrix.android.internal.session.SessionScope import im.vector.matrix.android.internal.session.SessionScope
import im.vector.matrix.android.internal.session.room.call.DefaultRoomCallService import im.vector.matrix.android.internal.session.room.call.DefaultRoomCallService
import im.vector.matrix.android.internal.session.room.draft.DefaultDraftService import im.vector.matrix.android.internal.session.room.draft.DefaultDraftService
@ -31,6 +29,7 @@ import im.vector.matrix.android.internal.session.room.reporting.DefaultReporting
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.state.DefaultStateService import im.vector.matrix.android.internal.session.room.state.DefaultStateService
import im.vector.matrix.android.internal.session.room.state.SendStateTask import im.vector.matrix.android.internal.session.room.state.SendStateTask
import im.vector.matrix.android.internal.session.room.summary.RoomSummaryDataSource
import im.vector.matrix.android.internal.session.room.tags.DefaultTagsService import im.vector.matrix.android.internal.session.room.tags.DefaultTagsService
import im.vector.matrix.android.internal.session.room.timeline.DefaultTimelineService import im.vector.matrix.android.internal.session.room.timeline.DefaultTimelineService
import im.vector.matrix.android.internal.session.room.typing.DefaultTypingService import im.vector.matrix.android.internal.session.room.typing.DefaultTypingService
@ -43,9 +42,8 @@ internal interface RoomFactory {
} }
@SessionScope @SessionScope
internal class DefaultRoomFactory @Inject constructor(private val monarchy: Monarchy, internal class DefaultRoomFactory @Inject constructor(private val cryptoService: CryptoService,
private val roomSummaryMapper: RoomSummaryMapper, private val roomSummaryDataSource: RoomSummaryDataSource,
private val cryptoService: CryptoService,
private val timelineServiceFactory: DefaultTimelineService.Factory, private val timelineServiceFactory: DefaultTimelineService.Factory,
private val sendServiceFactory: DefaultSendService.Factory, private val sendServiceFactory: DefaultSendService.Factory,
private val draftServiceFactory: DefaultDraftService.Factory, private val draftServiceFactory: DefaultDraftService.Factory,
@ -66,8 +64,7 @@ internal class DefaultRoomFactory @Inject constructor(private val monarchy: Mona
override fun create(roomId: String): Room { override fun create(roomId: String): Room {
return DefaultRoom( return DefaultRoom(
roomId = roomId, roomId = roomId,
monarchy = monarchy, roomSummaryDataSource = roomSummaryDataSource,
roomSummaryMapper = roomSummaryMapper,
timelineService = timelineServiceFactory.create(roomId), timelineService = timelineServiceFactory.create(roomId),
sendService = sendServiceFactory.create(roomId), sendService = sendServiceFactory.create(roomId),
draftService = draftServiceFactory.create(roomId), draftService = draftServiceFactory.create(roomId),

View file

@ -23,6 +23,7 @@ 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.model.RoomSummaryEntity
import im.vector.matrix.android.internal.database.model.RoomSummaryEntityFields import im.vector.matrix.android.internal.database.model.RoomSummaryEntityFields
import im.vector.matrix.android.internal.database.query.where 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.SessionScope
import im.vector.matrix.android.internal.session.room.membership.RoomMemberHelper import im.vector.matrix.android.internal.session.room.membership.RoomMemberHelper
import io.realm.Realm import io.realm.Realm
@ -36,7 +37,7 @@ internal interface RoomGetter {
@SessionScope @SessionScope
internal class DefaultRoomGetter @Inject constructor( internal class DefaultRoomGetter @Inject constructor(
private val monarchy: Monarchy, @SessionDatabase private val monarchy: Monarchy,
private val roomFactory: RoomFactory private val roomFactory: RoomFactory
) : RoomGetter { ) : RoomGetter {

View file

@ -20,6 +20,7 @@ import com.zhuinden.monarchy.Monarchy
import im.vector.matrix.android.api.util.Optional import im.vector.matrix.android.api.util.Optional
import im.vector.matrix.android.internal.database.model.RoomSummaryEntity import im.vector.matrix.android.internal.database.model.RoomSummaryEntity
import im.vector.matrix.android.internal.database.query.findByAlias import im.vector.matrix.android.internal.database.query.findByAlias
import im.vector.matrix.android.internal.di.SessionDatabase
import im.vector.matrix.android.internal.network.executeRequest 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.RoomAPI
import im.vector.matrix.android.internal.task.Task import im.vector.matrix.android.internal.task.Task
@ -35,7 +36,7 @@ internal interface GetRoomIdByAliasTask : Task<GetRoomIdByAliasTask.Params, Opti
} }
internal class DefaultGetRoomIdByAliasTask @Inject constructor( internal class DefaultGetRoomIdByAliasTask @Inject constructor(
private val monarchy: Monarchy, @SessionDatabase private val monarchy: Monarchy,
private val roomAPI: RoomAPI, private val roomAPI: RoomAPI,
private val eventBus: EventBus private val eventBus: EventBus
) : GetRoomIdByAliasTask { ) : GetRoomIdByAliasTask {

View file

@ -45,7 +45,7 @@ internal interface CreateRoomTask : Task<CreateRoomParams, String>
internal class DefaultCreateRoomTask @Inject constructor( internal class DefaultCreateRoomTask @Inject constructor(
private val roomAPI: RoomAPI, private val roomAPI: RoomAPI,
private val monarchy: Monarchy, @SessionDatabase private val monarchy: Monarchy,
private val directChatsHelper: DirectChatsHelper, private val directChatsHelper: DirectChatsHelper,
private val updateUserAccountDataTask: UpdateUserAccountDataTask, private val updateUserAccountDataTask: UpdateUserAccountDataTask,
private val readMarkersTask: SetReadMarkersTask, private val readMarkersTask: SetReadMarkersTask,

View file

@ -26,13 +26,14 @@ import im.vector.matrix.android.internal.database.model.DraftEntity
import im.vector.matrix.android.internal.database.model.RoomSummaryEntity import im.vector.matrix.android.internal.database.model.RoomSummaryEntity
import im.vector.matrix.android.internal.database.model.UserDraftsEntity import im.vector.matrix.android.internal.database.model.UserDraftsEntity
import im.vector.matrix.android.internal.database.query.where import im.vector.matrix.android.internal.database.query.where
import im.vector.matrix.android.internal.di.SessionDatabase
import im.vector.matrix.android.internal.util.awaitTransaction import im.vector.matrix.android.internal.util.awaitTransaction
import io.realm.Realm import io.realm.Realm
import io.realm.kotlin.createObject import io.realm.kotlin.createObject
import timber.log.Timber import timber.log.Timber
import javax.inject.Inject import javax.inject.Inject
class DraftRepository @Inject constructor(private val monarchy: Monarchy) { class DraftRepository @Inject constructor(@SessionDatabase private val monarchy: Monarchy) {
suspend fun saveDraft(roomId: String, userDraft: UserDraft) { suspend fun saveDraft(roomId: String, userDraft: UserDraft) {
monarchy.awaitTransaction { monarchy.awaitTransaction {

View file

@ -29,6 +29,7 @@ import im.vector.matrix.android.api.util.Cancelable
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.RoomMemberSummaryEntity import im.vector.matrix.android.internal.database.model.RoomMemberSummaryEntity
import im.vector.matrix.android.internal.database.model.RoomMemberSummaryEntityFields import im.vector.matrix.android.internal.database.model.RoomMemberSummaryEntityFields
import im.vector.matrix.android.internal.di.SessionDatabase
import im.vector.matrix.android.internal.di.UserId import im.vector.matrix.android.internal.di.UserId
import im.vector.matrix.android.internal.query.process import im.vector.matrix.android.internal.query.process
import im.vector.matrix.android.internal.session.room.membership.admin.MembershipAdminTask import im.vector.matrix.android.internal.session.room.membership.admin.MembershipAdminTask
@ -43,7 +44,7 @@ import io.realm.RealmQuery
internal class DefaultMembershipService @AssistedInject constructor( internal class DefaultMembershipService @AssistedInject constructor(
@Assisted private val roomId: String, @Assisted private val roomId: String,
private val monarchy: Monarchy, @SessionDatabase private val monarchy: Monarchy,
private val taskExecutor: TaskExecutor, private val taskExecutor: TaskExecutor,
private val loadRoomMembersTask: LoadRoomMembersTask, private val loadRoomMembersTask: LoadRoomMembersTask,
private val inviteTask: InviteTask, private val inviteTask: InviteTask,

View file

@ -25,9 +25,10 @@ import im.vector.matrix.android.internal.database.model.RoomEntity
import im.vector.matrix.android.internal.database.query.copyToRealmOrIgnore import im.vector.matrix.android.internal.database.query.copyToRealmOrIgnore
import im.vector.matrix.android.internal.database.query.getOrCreate import im.vector.matrix.android.internal.database.query.getOrCreate
import im.vector.matrix.android.internal.database.query.where import im.vector.matrix.android.internal.database.query.where
import im.vector.matrix.android.internal.di.SessionDatabase
import im.vector.matrix.android.internal.network.executeRequest 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.RoomAPI
import im.vector.matrix.android.internal.session.room.RoomSummaryUpdater import im.vector.matrix.android.internal.session.room.summary.RoomSummaryUpdater
import im.vector.matrix.android.internal.session.sync.SyncTokenStore import im.vector.matrix.android.internal.session.sync.SyncTokenStore
import im.vector.matrix.android.internal.task.Task import im.vector.matrix.android.internal.task.Task
import im.vector.matrix.android.internal.util.awaitTransaction import im.vector.matrix.android.internal.util.awaitTransaction
@ -46,7 +47,7 @@ internal interface LoadRoomMembersTask : Task<LoadRoomMembersTask.Params, Unit>
internal class DefaultLoadRoomMembersTask @Inject constructor( internal class DefaultLoadRoomMembersTask @Inject constructor(
private val roomAPI: RoomAPI, private val roomAPI: RoomAPI,
private val monarchy: Monarchy, @SessionDatabase private val monarchy: Monarchy,
private val syncTokenStore: SyncTokenStore, private val syncTokenStore: SyncTokenStore,
private val roomSummaryUpdater: RoomSummaryUpdater, private val roomSummaryUpdater: RoomSummaryUpdater,
private val roomMemberEventHandler: RoomMemberEventHandler, private val roomMemberEventHandler: RoomMemberEventHandler,

View file

@ -17,7 +17,6 @@
package im.vector.matrix.android.internal.session.room.membership package im.vector.matrix.android.internal.session.room.membership
import android.content.Context import android.content.Context
import com.zhuinden.monarchy.Monarchy
import im.vector.matrix.android.R import im.vector.matrix.android.R
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.events.model.toModel
@ -34,48 +33,47 @@ import im.vector.matrix.android.internal.database.model.RoomSummaryEntity
import im.vector.matrix.android.internal.database.query.getOrNull import im.vector.matrix.android.internal.database.query.getOrNull
import im.vector.matrix.android.internal.database.query.where import im.vector.matrix.android.internal.database.query.where
import im.vector.matrix.android.internal.di.UserId import im.vector.matrix.android.internal.di.UserId
import io.realm.Realm
import javax.inject.Inject import javax.inject.Inject
/** /**
* This class computes room display name * This class computes room display name
*/ */
internal class RoomDisplayNameResolver @Inject constructor(private val context: Context, internal class RoomDisplayNameResolver @Inject constructor(private val context: Context,
private val monarchy: Monarchy,
@UserId private val userId: String @UserId private val userId: String
) { ) {
/** /**
* Compute the room display name * Compute the room display name
* *
* @param realm: the current instance of realm
* @param roomId: the roomId to resolve the name of. * @param roomId: the roomId to resolve the name of.
* @return the room display name * @return the room display name
*/ */
fun resolve(roomId: String): CharSequence { fun resolve(realm: Realm, roomId: String): CharSequence {
// this algorithm is the one defined in // this algorithm is the one defined in
// https://github.com/matrix-org/matrix-js-sdk/blob/develop/lib/models/room.js#L617 // https://github.com/matrix-org/matrix-js-sdk/blob/develop/lib/models/room.js#L617
// calculateRoomName(room, userId) // calculateRoomName(room, userId)
// For Lazy Loaded room, see algorithm here: // For Lazy Loaded room, see algorithm here:
// https://docs.google.com/document/d/11i14UI1cUz-OJ0knD5BFu7fmT6Fo327zvMYqfSAR7xs/edit#heading=h.qif6pkqyjgzn // https://docs.google.com/document/d/11i14UI1cUz-OJ0knD5BFu7fmT6Fo327zvMYqfSAR7xs/edit#heading=h.qif6pkqyjgzn
var name: CharSequence? = null var name: CharSequence?
monarchy.doWithRealm { realm ->
val roomEntity = RoomEntity.where(realm, roomId = roomId).findFirst() val roomEntity = RoomEntity.where(realm, roomId = roomId).findFirst()
val roomName = CurrentStateEventEntity.getOrNull(realm, roomId, type = EventType.STATE_ROOM_NAME, stateKey = "")?.root val roomName = CurrentStateEventEntity.getOrNull(realm, roomId, type = EventType.STATE_ROOM_NAME, stateKey = "")?.root
name = ContentMapper.map(roomName?.content).toModel<RoomNameContent>()?.name name = ContentMapper.map(roomName?.content).toModel<RoomNameContent>()?.name
if (!name.isNullOrEmpty()) { if (!name.isNullOrEmpty()) {
return@doWithRealm return name
} }
val canonicalAlias = CurrentStateEventEntity.getOrNull(realm, roomId, type = EventType.STATE_ROOM_CANONICAL_ALIAS, stateKey = "")?.root val canonicalAlias = CurrentStateEventEntity.getOrNull(realm, roomId, type = EventType.STATE_ROOM_CANONICAL_ALIAS, stateKey = "")?.root
name = ContentMapper.map(canonicalAlias?.content).toModel<RoomCanonicalAliasContent>()?.canonicalAlias name = ContentMapper.map(canonicalAlias?.content).toModel<RoomCanonicalAliasContent>()?.canonicalAlias
if (!name.isNullOrEmpty()) { if (!name.isNullOrEmpty()) {
return@doWithRealm return name
} }
val aliases = CurrentStateEventEntity.getOrNull(realm, roomId, type = EventType.STATE_ROOM_ALIASES, stateKey = "")?.root val aliases = CurrentStateEventEntity.getOrNull(realm, roomId, type = EventType.STATE_ROOM_ALIASES, stateKey = "")?.root
name = ContentMapper.map(aliases?.content).toModel<RoomAliasesContent>()?.aliases?.firstOrNull() name = ContentMapper.map(aliases?.content).toModel<RoomAliasesContent>()?.aliases?.firstOrNull()
if (!name.isNullOrEmpty()) { if (!name.isNullOrEmpty()) {
return@doWithRealm return name
} }
val roomMembers = RoomMemberHelper(realm, roomId) val roomMembers = RoomMemberHelper(realm, roomId)
@ -121,8 +119,6 @@ internal class RoomDisplayNameResolver @Inject constructor(private val context:
roomMembers.getNumberOfJoinedMembers() - 1) roomMembers.getNumberOfJoinedMembers() - 1)
} }
} }
return@doWithRealm
}
return name ?: roomId return name ?: roomId
} }

View file

@ -28,12 +28,13 @@ import im.vector.matrix.android.api.session.room.notification.RoomPushRuleServic
import im.vector.matrix.android.api.util.Cancelable import im.vector.matrix.android.api.util.Cancelable
import im.vector.matrix.android.internal.database.model.PushRuleEntity import im.vector.matrix.android.internal.database.model.PushRuleEntity
import im.vector.matrix.android.internal.database.query.where import im.vector.matrix.android.internal.database.query.where
import im.vector.matrix.android.internal.di.SessionDatabase
import im.vector.matrix.android.internal.task.TaskExecutor import im.vector.matrix.android.internal.task.TaskExecutor
import im.vector.matrix.android.internal.task.configureWith import im.vector.matrix.android.internal.task.configureWith
internal class DefaultRoomPushRuleService @AssistedInject constructor(@Assisted private val roomId: String, internal class DefaultRoomPushRuleService @AssistedInject constructor(@Assisted private val roomId: String,
private val setRoomNotificationStateTask: SetRoomNotificationStateTask, private val setRoomNotificationStateTask: SetRoomNotificationStateTask,
private val monarchy: Monarchy, @SessionDatabase private val monarchy: Monarchy,
private val taskExecutor: TaskExecutor) private val taskExecutor: TaskExecutor)
: RoomPushRuleService { : RoomPushRuleService {

View file

@ -21,6 +21,7 @@ import im.vector.matrix.android.api.pushrules.RuleScope
import im.vector.matrix.android.api.session.room.notification.RoomNotificationState import im.vector.matrix.android.api.session.room.notification.RoomNotificationState
import im.vector.matrix.android.internal.database.model.PushRuleEntity import im.vector.matrix.android.internal.database.model.PushRuleEntity
import im.vector.matrix.android.internal.database.query.where import im.vector.matrix.android.internal.database.query.where
import im.vector.matrix.android.internal.di.SessionDatabase
import im.vector.matrix.android.internal.session.pushers.AddPushRuleTask import im.vector.matrix.android.internal.session.pushers.AddPushRuleTask
import im.vector.matrix.android.internal.session.pushers.RemovePushRuleTask import im.vector.matrix.android.internal.session.pushers.RemovePushRuleTask
import im.vector.matrix.android.internal.task.Task import im.vector.matrix.android.internal.task.Task
@ -34,7 +35,7 @@ internal interface SetRoomNotificationStateTask : Task<SetRoomNotificationStateT
) )
} }
internal class DefaultSetRoomNotificationStateTask @Inject constructor(private val monarchy: Monarchy, internal class DefaultSetRoomNotificationStateTask @Inject constructor(@SessionDatabase private val monarchy: Monarchy,
private val removePushRuleTask: RemovePushRuleTask, private val removePushRuleTask: RemovePushRuleTask,
private val addPushRuleTask: AddPushRuleTask) private val addPushRuleTask: AddPushRuleTask)
: SetRoomNotificationStateTask { : SetRoomNotificationStateTask {

View file

@ -27,6 +27,7 @@ import im.vector.matrix.android.internal.database.model.TimelineEventEntity
import im.vector.matrix.android.internal.database.query.findWithSenderMembershipEvent import im.vector.matrix.android.internal.database.query.findWithSenderMembershipEvent
import im.vector.matrix.android.internal.database.query.where import im.vector.matrix.android.internal.database.query.where
import im.vector.matrix.android.internal.di.MoshiProvider import im.vector.matrix.android.internal.di.MoshiProvider
import im.vector.matrix.android.internal.di.SessionDatabase
import im.vector.matrix.android.internal.task.Task import im.vector.matrix.android.internal.task.Task
import im.vector.matrix.android.internal.util.awaitTransaction import im.vector.matrix.android.internal.util.awaitTransaction
import io.realm.Realm import io.realm.Realm
@ -40,7 +41,7 @@ internal interface PruneEventTask : Task<PruneEventTask.Params, Unit> {
) )
} }
internal class DefaultPruneEventTask @Inject constructor(private val monarchy: Monarchy) : PruneEventTask { internal class DefaultPruneEventTask @Inject constructor(@SessionDatabase private val monarchy: Monarchy) : PruneEventTask {
override suspend fun execute(params: PruneEventTask.Params) { override suspend fun execute(params: PruneEventTask.Params) {
monarchy.awaitTransaction { realm -> monarchy.awaitTransaction { realm ->

View file

@ -32,13 +32,14 @@ import im.vector.matrix.android.internal.database.model.ReadReceiptEntity
import im.vector.matrix.android.internal.database.model.ReadReceiptsSummaryEntity import im.vector.matrix.android.internal.database.model.ReadReceiptsSummaryEntity
import im.vector.matrix.android.internal.database.query.isEventRead import im.vector.matrix.android.internal.database.query.isEventRead
import im.vector.matrix.android.internal.database.query.where import im.vector.matrix.android.internal.database.query.where
import im.vector.matrix.android.internal.di.SessionDatabase
import im.vector.matrix.android.internal.di.UserId import im.vector.matrix.android.internal.di.UserId
import im.vector.matrix.android.internal.task.TaskExecutor import im.vector.matrix.android.internal.task.TaskExecutor
import im.vector.matrix.android.internal.task.configureWith import im.vector.matrix.android.internal.task.configureWith
internal class DefaultReadService @AssistedInject constructor( internal class DefaultReadService @AssistedInject constructor(
@Assisted private val roomId: String, @Assisted private val roomId: String,
private val monarchy: Monarchy, @SessionDatabase private val monarchy: Monarchy,
private val taskExecutor: TaskExecutor, private val taskExecutor: TaskExecutor,
private val setReadMarkersTask: SetReadMarkersTask, private val setReadMarkersTask: SetReadMarkersTask,
private val readReceiptsSummaryMapper: ReadReceiptsSummaryMapper, private val readReceiptsSummaryMapper: ReadReceiptsSummaryMapper,
@ -82,7 +83,7 @@ internal class DefaultReadService @AssistedInject constructor(
} }
override fun isEventRead(eventId: String): Boolean { override fun isEventRead(eventId: String): Boolean {
return isEventRead(monarchy, userId, roomId, eventId) return isEventRead(monarchy.realmConfiguration, userId, roomId, eventId)
} }
override fun getReadMarkerLive(): LiveData<Optional<String>> { override fun getReadMarkerLive(): LiveData<Optional<String>> {

View file

@ -24,6 +24,7 @@ import im.vector.matrix.android.internal.database.query.isEventRead
import im.vector.matrix.android.internal.database.query.isReadMarkerMoreRecent import im.vector.matrix.android.internal.database.query.isReadMarkerMoreRecent
import im.vector.matrix.android.internal.database.query.latestEvent import im.vector.matrix.android.internal.database.query.latestEvent
import im.vector.matrix.android.internal.database.query.where import im.vector.matrix.android.internal.database.query.where
import im.vector.matrix.android.internal.di.SessionDatabase
import im.vector.matrix.android.internal.di.UserId import im.vector.matrix.android.internal.di.UserId
import im.vector.matrix.android.internal.network.executeRequest 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.RoomAPI
@ -53,7 +54,7 @@ private const val READ_RECEIPT = "m.read"
internal class DefaultSetReadMarkersTask @Inject constructor( internal class DefaultSetReadMarkersTask @Inject constructor(
private val roomAPI: RoomAPI, private val roomAPI: RoomAPI,
private val monarchy: Monarchy, @SessionDatabase private val monarchy: Monarchy,
private val roomFullyReadHandler: RoomFullyReadHandler, private val roomFullyReadHandler: RoomFullyReadHandler,
private val readReceiptHandler: ReadReceiptHandler, private val readReceiptHandler: ReadReceiptHandler,
@UserId private val userId: String, @UserId private val userId: String,
@ -74,7 +75,7 @@ internal class DefaultSetReadMarkersTask @Inject constructor(
} else { } else {
params.readReceiptEventId params.readReceiptEventId
} }
if (fullyReadEventId != null && !isReadMarkerMoreRecent(monarchy, params.roomId, fullyReadEventId)) { if (fullyReadEventId != null && !isReadMarkerMoreRecent(monarchy.realmConfiguration, params.roomId, fullyReadEventId)) {
if (LocalEcho.isLocalEchoId(fullyReadEventId)) { if (LocalEcho.isLocalEchoId(fullyReadEventId)) {
Timber.w("Can't set read marker for local event $fullyReadEventId") Timber.w("Can't set read marker for local event $fullyReadEventId")
} else { } else {
@ -82,7 +83,7 @@ internal class DefaultSetReadMarkersTask @Inject constructor(
} }
} }
if (readReceiptEventId != null if (readReceiptEventId != null
&& !isEventRead(monarchy, userId, params.roomId, readReceiptEventId)) { && !isEventRead(monarchy.realmConfiguration, userId, params.roomId, readReceiptEventId)) {
if (LocalEcho.isLocalEchoId(readReceiptEventId)) { if (LocalEcho.isLocalEchoId(readReceiptEventId)) {
Timber.w("Can't set read receipt for local event $readReceiptEventId") Timber.w("Can't set read receipt for local event $readReceiptEventId")
} else { } else {

View file

@ -37,6 +37,7 @@ import im.vector.matrix.android.internal.database.mapper.asDomain
import im.vector.matrix.android.internal.database.model.EventAnnotationsSummaryEntity import im.vector.matrix.android.internal.database.model.EventAnnotationsSummaryEntity
import im.vector.matrix.android.internal.database.model.TimelineEventEntity import im.vector.matrix.android.internal.database.model.TimelineEventEntity
import im.vector.matrix.android.internal.database.query.where import im.vector.matrix.android.internal.database.query.where
import im.vector.matrix.android.internal.di.SessionDatabase
import im.vector.matrix.android.internal.di.SessionId import im.vector.matrix.android.internal.di.SessionId
import im.vector.matrix.android.internal.session.room.send.EncryptEventWorker import im.vector.matrix.android.internal.session.room.send.EncryptEventWorker
import im.vector.matrix.android.internal.session.room.send.LocalEchoEventFactory import im.vector.matrix.android.internal.session.room.send.LocalEchoEventFactory
@ -58,7 +59,7 @@ internal class DefaultRelationService @AssistedInject constructor(
private val findReactionEventForUndoTask: FindReactionEventForUndoTask, private val findReactionEventForUndoTask: FindReactionEventForUndoTask,
private val fetchEditHistoryTask: FetchEditHistoryTask, private val fetchEditHistoryTask: FetchEditHistoryTask,
private val timelineEventMapper: TimelineEventMapper, private val timelineEventMapper: TimelineEventMapper,
private val monarchy: Monarchy, @SessionDatabase private val monarchy: Monarchy,
private val taskExecutor: TaskExecutor) private val taskExecutor: TaskExecutor)
: RelationService { : RelationService {

View file

@ -20,6 +20,7 @@ import im.vector.matrix.android.internal.database.model.EventAnnotationsSummaryE
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.ReactionAggregatedSummaryEntityFields import im.vector.matrix.android.internal.database.model.ReactionAggregatedSummaryEntityFields
import im.vector.matrix.android.internal.database.query.where import im.vector.matrix.android.internal.database.query.where
import im.vector.matrix.android.internal.di.SessionDatabase
import im.vector.matrix.android.internal.di.UserId import im.vector.matrix.android.internal.di.UserId
import im.vector.matrix.android.internal.task.Task import im.vector.matrix.android.internal.task.Task
import io.realm.Realm import io.realm.Realm
@ -39,7 +40,7 @@ internal interface FindReactionEventForUndoTask : Task<FindReactionEventForUndoT
} }
internal class DefaultFindReactionEventForUndoTask @Inject constructor( internal class DefaultFindReactionEventForUndoTask @Inject constructor(
private val monarchy: Monarchy, @SessionDatabase private val monarchy: Monarchy,
@UserId private val userId: String) : FindReactionEventForUndoTask { @UserId private val userId: String) : FindReactionEventForUndoTask {
override suspend fun execute(params: FindReactionEventForUndoTask.Params): FindReactionEventForUndoTask.Result { override suspend fun execute(params: FindReactionEventForUndoTask.Params): FindReactionEventForUndoTask.Result {

View file

@ -20,6 +20,7 @@ import im.vector.matrix.android.internal.database.model.EventAnnotationsSummaryE
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.ReactionAggregatedSummaryEntityFields import im.vector.matrix.android.internal.database.model.ReactionAggregatedSummaryEntityFields
import im.vector.matrix.android.internal.database.query.where import im.vector.matrix.android.internal.database.query.where
import im.vector.matrix.android.internal.di.SessionDatabase
import im.vector.matrix.android.internal.di.UserId import im.vector.matrix.android.internal.di.UserId
import im.vector.matrix.android.internal.task.Task import im.vector.matrix.android.internal.task.Task
import io.realm.Realm import io.realm.Realm
@ -40,7 +41,7 @@ internal interface UpdateQuickReactionTask : Task<UpdateQuickReactionTask.Params
) )
} }
internal class DefaultUpdateQuickReactionTask @Inject constructor(private val monarchy: Monarchy, internal class DefaultUpdateQuickReactionTask @Inject constructor(@SessionDatabase private val monarchy: Monarchy,
@UserId private val userId: String) : UpdateQuickReactionTask { @UserId private val userId: String) : UpdateQuickReactionTask {
override suspend fun execute(params: UpdateQuickReactionTask.Params): UpdateQuickReactionTask.Result { override suspend fun execute(params: UpdateQuickReactionTask.Params): UpdateQuickReactionTask.Result {

View file

@ -33,7 +33,8 @@ 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.model.TimelineEventEntity
import im.vector.matrix.android.internal.database.query.findAllInRoomWithSendStates import im.vector.matrix.android.internal.database.query.findAllInRoomWithSendStates
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.room.RoomSummaryUpdater import im.vector.matrix.android.internal.di.SessionDatabase
import im.vector.matrix.android.internal.session.room.summary.RoomSummaryUpdater
import im.vector.matrix.android.internal.session.room.membership.RoomMemberHelper import im.vector.matrix.android.internal.session.room.membership.RoomMemberHelper
import im.vector.matrix.android.internal.session.room.timeline.DefaultTimeline import im.vector.matrix.android.internal.session.room.timeline.DefaultTimeline
import im.vector.matrix.android.internal.util.awaitTransaction import im.vector.matrix.android.internal.util.awaitTransaction
@ -42,7 +43,7 @@ import org.greenrobot.eventbus.EventBus
import timber.log.Timber import timber.log.Timber
import javax.inject.Inject import javax.inject.Inject
internal class LocalEchoRepository @Inject constructor(private val monarchy: Monarchy, internal class LocalEchoRepository @Inject constructor(@SessionDatabase private val monarchy: Monarchy,
private val roomSummaryUpdater: RoomSummaryUpdater, private val roomSummaryUpdater: RoomSummaryUpdater,
private val eventBus: EventBus, private val eventBus: EventBus,
private val timelineEventMapper: TimelineEventMapper) { private val timelineEventMapper: TimelineEventMapper) {

View file

@ -24,10 +24,11 @@ import im.vector.matrix.android.internal.crypto.MXEventDecryptionResult
import im.vector.matrix.android.internal.database.mapper.ContentMapper 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.query.where import im.vector.matrix.android.internal.database.query.where
import im.vector.matrix.android.internal.di.SessionDatabase
import timber.log.Timber import timber.log.Timber
import javax.inject.Inject import javax.inject.Inject
internal class LocalEchoUpdater @Inject constructor(private val monarchy: Monarchy) { internal class LocalEchoUpdater @Inject constructor(@SessionDatabase private val monarchy: Monarchy) {
fun updateSendState(eventId: String, sendState: SendState) { fun updateSendState(eventId: String, sendState: SendState) {
Timber.v("Update local state of $eventId to ${sendState.name}") Timber.v("Update local state of $eventId to ${sendState.name}")

View file

@ -26,13 +26,14 @@ import im.vector.matrix.android.api.util.toOptional
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.CurrentStateEventEntity import im.vector.matrix.android.internal.database.model.CurrentStateEventEntity
import im.vector.matrix.android.internal.database.model.CurrentStateEventEntityFields import im.vector.matrix.android.internal.database.model.CurrentStateEventEntityFields
import im.vector.matrix.android.internal.di.SessionDatabase
import im.vector.matrix.android.internal.query.process import im.vector.matrix.android.internal.query.process
import io.realm.Realm import io.realm.Realm
import io.realm.RealmQuery import io.realm.RealmQuery
import io.realm.kotlin.where import io.realm.kotlin.where
import javax.inject.Inject import javax.inject.Inject
internal class StateEventDataSource @Inject constructor(private val monarchy: Monarchy) { internal class StateEventDataSource @Inject constructor(@SessionDatabase private val monarchy: Monarchy) {
fun getStateEvent(roomId: String, eventType: String, stateKey: QueryStringValue): Event? { fun getStateEvent(roomId: String, eventType: String, stateKey: QueryStringValue): Event? {
return Realm.getInstance(monarchy.realmConfiguration).use { realm -> return Realm.getInstance(monarchy.realmConfiguration).use { realm ->

View file

@ -0,0 +1,109 @@
/*
* Copyright (c) 2020 New Vector Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package im.vector.matrix.android.internal.session.room.summary
import androidx.lifecycle.LiveData
import androidx.lifecycle.Transformations
import com.zhuinden.monarchy.Monarchy
import im.vector.matrix.android.api.session.room.RoomSummaryQueryParams
import im.vector.matrix.android.api.session.room.model.RoomSummary
import im.vector.matrix.android.api.session.room.model.VersioningState
import im.vector.matrix.android.api.util.Optional
import im.vector.matrix.android.api.util.toOptional
import im.vector.matrix.android.internal.database.mapper.RoomSummaryMapper
import im.vector.matrix.android.internal.database.model.RoomSummaryEntity
import im.vector.matrix.android.internal.database.model.RoomSummaryEntityFields
import im.vector.matrix.android.internal.database.query.findByAlias
import im.vector.matrix.android.internal.database.query.where
import im.vector.matrix.android.internal.di.SessionDatabase
import im.vector.matrix.android.internal.query.process
import im.vector.matrix.android.internal.util.fetchCopyMap
import io.realm.Realm
import io.realm.RealmQuery
import javax.inject.Inject
internal class RoomSummaryDataSource @Inject constructor(@SessionDatabase private val monarchy: Monarchy,
private val roomSummaryMapper: RoomSummaryMapper) {
fun getRoomSummary(roomIdOrAlias: String): RoomSummary? {
return monarchy
.fetchCopyMap({
if (roomIdOrAlias.startsWith("!")) {
// It's a roomId
RoomSummaryEntity.where(it, roomId = roomIdOrAlias).findFirst()
} else {
// Assume it's a room alias
RoomSummaryEntity.findByAlias(it, roomIdOrAlias)
}
}, { entity, _ ->
roomSummaryMapper.map(entity)
})
}
fun getRoomSummaryLive(roomId: String): LiveData<Optional<RoomSummary>> {
val liveData = monarchy.findAllMappedWithChanges(
{ realm -> RoomSummaryEntity.where(realm, roomId).isNotEmpty(RoomSummaryEntityFields.DISPLAY_NAME) },
{ roomSummaryMapper.map(it) }
)
return Transformations.map(liveData) { results ->
results.firstOrNull().toOptional()
}
}
fun getRoomSummaries(queryParams: RoomSummaryQueryParams): List<RoomSummary> {
return monarchy.fetchAllMappedSync(
{ roomSummariesQuery(it, queryParams) },
{ roomSummaryMapper.map(it) }
)
}
fun getRoomSummariesLive(queryParams: RoomSummaryQueryParams): LiveData<List<RoomSummary>> {
return monarchy.findAllMappedWithChanges(
{ roomSummariesQuery(it, queryParams) },
{ roomSummaryMapper.map(it) }
)
}
fun getBreadcrumbs(queryParams: RoomSummaryQueryParams): List<RoomSummary> {
return monarchy.fetchAllMappedSync(
{ breadcrumbsQuery(it, queryParams) },
{ roomSummaryMapper.map(it) }
)
}
fun getBreadcrumbsLive(queryParams: RoomSummaryQueryParams): LiveData<List<RoomSummary>> {
return monarchy.findAllMappedWithChanges(
{ breadcrumbsQuery(it, queryParams) },
{ roomSummaryMapper.map(it) }
)
}
private fun breadcrumbsQuery(realm: Realm, queryParams: RoomSummaryQueryParams): RealmQuery<RoomSummaryEntity> {
return roomSummariesQuery(realm, queryParams)
.greaterThan(RoomSummaryEntityFields.BREADCRUMBS_INDEX, RoomSummary.NOT_IN_BREADCRUMBS)
.sort(RoomSummaryEntityFields.BREADCRUMBS_INDEX)
}
private fun roomSummariesQuery(realm: Realm, queryParams: RoomSummaryQueryParams): RealmQuery<RoomSummaryEntity> {
val query = RoomSummaryEntity.where(realm)
query.process(RoomSummaryEntityFields.DISPLAY_NAME, queryParams.displayName)
query.process(RoomSummaryEntityFields.CANONICAL_ALIAS, queryParams.canonicalAlias)
query.process(RoomSummaryEntityFields.MEMBERSHIP_STR, queryParams.memberships)
query.notEqualTo(RoomSummaryEntityFields.VERSIONING_STATE_STR, VersioningState.UPGRADED_ROOM_JOINED.name)
return query
}
}

View file

@ -14,9 +14,8 @@
* limitations under the License. * limitations under the License.
*/ */
package im.vector.matrix.android.internal.session.room package im.vector.matrix.android.internal.session.room.summary
import com.zhuinden.monarchy.Monarchy
import dagger.Lazy import dagger.Lazy
import im.vector.matrix.android.api.crypto.RoomEncryptionTrustLevel import im.vector.matrix.android.api.crypto.RoomEncryptionTrustLevel
import im.vector.matrix.android.api.session.events.model.EventType import im.vector.matrix.android.api.session.events.model.EventType
@ -40,10 +39,10 @@ import im.vector.matrix.android.internal.database.query.isEventRead
import im.vector.matrix.android.internal.database.query.latestEvent import im.vector.matrix.android.internal.database.query.latestEvent
import im.vector.matrix.android.internal.database.query.whereType import im.vector.matrix.android.internal.database.query.whereType
import im.vector.matrix.android.internal.di.UserId import im.vector.matrix.android.internal.di.UserId
import im.vector.matrix.android.internal.session.room.RoomAvatarResolver
import im.vector.matrix.android.internal.session.room.membership.RoomDisplayNameResolver import im.vector.matrix.android.internal.session.room.membership.RoomDisplayNameResolver
import im.vector.matrix.android.internal.session.room.membership.RoomMemberHelper import im.vector.matrix.android.internal.session.room.membership.RoomMemberHelper
import im.vector.matrix.android.internal.session.room.timeline.TimelineEventDecryptor import im.vector.matrix.android.internal.session.room.timeline.TimelineEventDecryptor
import im.vector.matrix.android.internal.session.sync.RoomSyncHandler
import im.vector.matrix.android.internal.session.sync.model.RoomSyncSummary import im.vector.matrix.android.internal.session.sync.model.RoomSyncSummary
import im.vector.matrix.android.internal.session.sync.model.RoomSyncUnreadNotifications import im.vector.matrix.android.internal.session.sync.model.RoomSyncUnreadNotifications
import io.realm.Realm import io.realm.Realm
@ -56,8 +55,7 @@ internal class RoomSummaryUpdater @Inject constructor(
private val roomDisplayNameResolver: RoomDisplayNameResolver, private val roomDisplayNameResolver: RoomDisplayNameResolver,
private val roomAvatarResolver: RoomAvatarResolver, private val roomAvatarResolver: RoomAvatarResolver,
private val timelineEventDecryptor: Lazy<TimelineEventDecryptor>, private val timelineEventDecryptor: Lazy<TimelineEventDecryptor>,
private val eventBus: EventBus, private val eventBus: EventBus) {
private val monarchy: Monarchy) {
companion object { companion object {
// TODO: maybe allow user of SDK to give that list // TODO: maybe allow user of SDK to give that list
@ -85,7 +83,6 @@ internal class RoomSummaryUpdater @Inject constructor(
roomSummary: RoomSyncSummary? = null, roomSummary: RoomSyncSummary? = null,
unreadNotifications: RoomSyncUnreadNotifications? = null, unreadNotifications: RoomSyncUnreadNotifications? = null,
updateMembers: Boolean = false, updateMembers: Boolean = false,
ephemeralResult: RoomSyncHandler.EphemeralResult? = null,
inviterId: String? = null) { inviterId: String? = null) {
val roomSummaryEntity = RoomSummaryEntity.getOrCreate(realm, roomId) val roomSummaryEntity = RoomSummaryEntity.getOrCreate(realm, roomId)
if (roomSummary != null) { if (roomSummary != null) {
@ -121,10 +118,10 @@ internal class RoomSummaryUpdater @Inject constructor(
roomSummaryEntity.hasUnreadMessages = roomSummaryEntity.notificationCount > 0 roomSummaryEntity.hasUnreadMessages = roomSummaryEntity.notificationCount > 0
// avoid this call if we are sure there are unread events // avoid this call if we are sure there are unread events
|| !isEventRead(monarchy, userId, roomId, latestPreviewableEvent?.eventId) || !isEventRead(realm.configuration, userId, roomId, latestPreviewableEvent?.eventId)
roomSummaryEntity.displayName = roomDisplayNameResolver.resolve(roomId).toString() roomSummaryEntity.displayName = roomDisplayNameResolver.resolve(realm, roomId).toString()
roomSummaryEntity.avatarUrl = roomAvatarResolver.resolve(roomId) roomSummaryEntity.avatarUrl = roomAvatarResolver.resolve(realm, roomId)
roomSummaryEntity.topic = ContentMapper.map(lastTopicEvent?.content).toModel<RoomTopicContent>()?.topic roomSummaryEntity.topic = ContentMapper.map(lastTopicEvent?.content).toModel<RoomTopicContent>()?.topic
roomSummaryEntity.latestPreviewableEvent = latestPreviewableEvent roomSummaryEntity.latestPreviewableEvent = latestPreviewableEvent
roomSummaryEntity.canonicalAlias = ContentMapper.map(lastCanonicalAliasEvent?.content).toModel<RoomCanonicalAliasContent>() roomSummaryEntity.canonicalAlias = ContentMapper.map(lastCanonicalAliasEvent?.content).toModel<RoomCanonicalAliasContent>()
@ -137,8 +134,6 @@ internal class RoomSummaryUpdater @Inject constructor(
roomSummaryEntity.flatAliases = roomAliases.joinToString(separator = "|", prefix = "|") roomSummaryEntity.flatAliases = roomAliases.joinToString(separator = "|", prefix = "|")
roomSummaryEntity.isEncrypted = encryptionEvent != null roomSummaryEntity.isEncrypted = encryptionEvent != null
roomSummaryEntity.encryptionEventTs = encryptionEvent?.originServerTs roomSummaryEntity.encryptionEventTs = encryptionEvent?.originServerTs
roomSummaryEntity.typingUserIds.clear()
roomSummaryEntity.typingUserIds.addAll(ephemeralResult?.typingUserIds.orEmpty())
if (roomSummaryEntity.membership == Membership.INVITE && inviterId != null) { if (roomSummaryEntity.membership == Membership.INVITE && inviterId != null) {
roomSummaryEntity.inviterId = inviterId roomSummaryEntity.inviterId = inviterId

View file

@ -341,6 +341,7 @@ internal class DefaultTimeline(
listeners.forEach { listeners.forEach {
it.onNewTimelineEvents(listOf(onLocalEchoCreated.timelineEvent.eventId)) it.onNewTimelineEvents(listOf(onLocalEchoCreated.timelineEvent.eventId))
} }
Timber.v("On local echo created: $onLocalEchoCreated")
inMemorySendingEvents.add(0, onLocalEchoCreated.timelineEvent) inMemorySendingEvents.add(0, onLocalEchoCreated.timelineEvent)
postSnapshot() postSnapshot()
} }
@ -790,11 +791,7 @@ internal class DefaultTimeline(
private fun List<TimelineEvent>.filterEventsWithSettings(): List<TimelineEvent> { private fun List<TimelineEvent>.filterEventsWithSettings(): List<TimelineEvent> {
return filter { return filter {
val filterType = if (settings.filterTypes) { val filterType = !settings.filterTypes || settings.allowedTypes.contains(it.root.type)
settings.allowedTypes.contains(it.root.type)
} else {
true
}
if (!filterType) return@filter false if (!filterType) return@filter false
val filterEdits = if (settings.filterEdits && it.root.type == EventType.MESSAGE) { val filterEdits = if (settings.filterEdits && it.root.type == EventType.MESSAGE) {
@ -805,7 +802,7 @@ internal class DefaultTimeline(
} }
if (!filterEdits) return@filter false if (!filterEdits) return@filter false
val filterRedacted = settings.filterRedacted && it.root.isRedacted() val filterRedacted = !settings.filterRedacted || it.root.isRedacted()
filterRedacted filterRedacted
} }

View file

@ -31,12 +31,13 @@ import im.vector.matrix.android.internal.database.mapper.ReadReceiptsSummaryMapp
import im.vector.matrix.android.internal.database.mapper.TimelineEventMapper import im.vector.matrix.android.internal.database.mapper.TimelineEventMapper
import im.vector.matrix.android.internal.database.model.TimelineEventEntity import im.vector.matrix.android.internal.database.model.TimelineEventEntity
import im.vector.matrix.android.internal.database.query.where import im.vector.matrix.android.internal.database.query.where
import im.vector.matrix.android.internal.di.SessionDatabase
import im.vector.matrix.android.internal.task.TaskExecutor import im.vector.matrix.android.internal.task.TaskExecutor
import im.vector.matrix.android.internal.util.fetchCopyMap import im.vector.matrix.android.internal.util.fetchCopyMap
import org.greenrobot.eventbus.EventBus import org.greenrobot.eventbus.EventBus
internal class DefaultTimelineService @AssistedInject constructor(@Assisted private val roomId: String, internal class DefaultTimelineService @AssistedInject constructor(@Assisted private val roomId: String,
private val monarchy: Monarchy, @SessionDatabase private val monarchy: Monarchy,
private val eventBus: EventBus, private val eventBus: EventBus,
private val taskExecutor: TaskExecutor, private val taskExecutor: TaskExecutor,
private val contextOfEventTask: GetContextOfEventTask, private val contextOfEventTask: GetContextOfEventTask,

View file

@ -19,6 +19,7 @@ package im.vector.matrix.android.internal.session.room.timeline
import com.zhuinden.monarchy.Monarchy import com.zhuinden.monarchy.Monarchy
import im.vector.matrix.android.internal.database.model.ChunkEntity import im.vector.matrix.android.internal.database.model.ChunkEntity
import im.vector.matrix.android.internal.database.query.findIncludingEvent import im.vector.matrix.android.internal.database.query.findIncludingEvent
import im.vector.matrix.android.internal.di.SessionDatabase
import im.vector.matrix.android.internal.network.executeRequest import im.vector.matrix.android.internal.network.executeRequest
import im.vector.matrix.android.internal.session.filter.FilterRepository import im.vector.matrix.android.internal.session.filter.FilterRepository
import im.vector.matrix.android.internal.session.room.RoomAPI import im.vector.matrix.android.internal.session.room.RoomAPI
@ -38,7 +39,7 @@ internal interface FetchNextTokenAndPaginateTask : Task<FetchNextTokenAndPaginat
internal class DefaultFetchNextTokenAndPaginateTask @Inject constructor( internal class DefaultFetchNextTokenAndPaginateTask @Inject constructor(
private val roomAPI: RoomAPI, private val roomAPI: RoomAPI,
private val monarchy: Monarchy, @SessionDatabase private val monarchy: Monarchy,
private val filterRepository: FilterRepository, private val filterRepository: FilterRepository,
private val paginationTask: PaginationTask, private val paginationTask: PaginationTask,
private val eventBus: EventBus private val eventBus: EventBus

View file

@ -39,7 +39,8 @@ import im.vector.matrix.android.internal.database.query.findLastForwardChunkOfRo
import im.vector.matrix.android.internal.database.query.getOrCreate import im.vector.matrix.android.internal.database.query.getOrCreate
import im.vector.matrix.android.internal.database.query.latestEvent import im.vector.matrix.android.internal.database.query.latestEvent
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.room.RoomSummaryUpdater import im.vector.matrix.android.internal.di.SessionDatabase
import im.vector.matrix.android.internal.session.room.summary.RoomSummaryUpdater
import im.vector.matrix.android.internal.util.awaitTransaction import im.vector.matrix.android.internal.util.awaitTransaction
import io.realm.Realm import io.realm.Realm
import timber.log.Timber import timber.log.Timber
@ -48,7 +49,7 @@ import javax.inject.Inject
/** /**
* Insert Chunk in DB, and eventually merge with existing chunk event * Insert Chunk in DB, and eventually merge with existing chunk event
*/ */
internal class TokenChunkEventPersistor @Inject constructor(private val monarchy: Monarchy) { internal class TokenChunkEventPersistor @Inject constructor(@SessionDatabase private val monarchy: Monarchy) {
/** /**
* <pre> * <pre>

View file

@ -30,6 +30,7 @@ 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.TimelineEventFilter import im.vector.matrix.android.internal.database.query.TimelineEventFilter
import im.vector.matrix.android.internal.database.query.whereType import im.vector.matrix.android.internal.database.query.whereType
import im.vector.matrix.android.internal.di.SessionDatabase
import im.vector.matrix.android.internal.network.executeRequest import im.vector.matrix.android.internal.network.executeRequest
import im.vector.matrix.android.internal.session.filter.FilterFactory import im.vector.matrix.android.internal.session.filter.FilterFactory
import im.vector.matrix.android.internal.session.room.RoomAPI import im.vector.matrix.android.internal.session.room.RoomAPI
@ -54,7 +55,7 @@ internal interface GetUploadsTask : Task<GetUploadsTask.Params, GetUploadsResult
internal class DefaultGetUploadsTask @Inject constructor( internal class DefaultGetUploadsTask @Inject constructor(
private val roomAPI: RoomAPI, private val roomAPI: RoomAPI,
private val tokenStore: SyncTokenStore, private val tokenStore: SyncTokenStore,
private val monarchy: Monarchy, @SessionDatabase private val monarchy: Monarchy,
private val eventBus: EventBus) private val eventBus: EventBus)
: GetUploadsTask { : GetUploadsTask {

View file

@ -46,7 +46,7 @@ import im.vector.matrix.android.internal.di.MoshiProvider
import im.vector.matrix.android.internal.di.UserId import im.vector.matrix.android.internal.di.UserId
import im.vector.matrix.android.internal.session.DefaultInitialSyncProgressService import im.vector.matrix.android.internal.session.DefaultInitialSyncProgressService
import im.vector.matrix.android.internal.session.mapWithProgress import im.vector.matrix.android.internal.session.mapWithProgress
import im.vector.matrix.android.internal.session.room.RoomSummaryUpdater import im.vector.matrix.android.internal.session.room.summary.RoomSummaryUpdater
import im.vector.matrix.android.internal.session.room.membership.RoomMemberEventHandler import im.vector.matrix.android.internal.session.room.membership.RoomMemberEventHandler
import im.vector.matrix.android.internal.session.room.read.FullyReadContent import im.vector.matrix.android.internal.session.room.read.FullyReadContent
import im.vector.matrix.android.internal.session.room.timeline.DefaultTimeline import im.vector.matrix.android.internal.session.room.timeline.DefaultTimeline
@ -69,6 +69,7 @@ internal class RoomSyncHandler @Inject constructor(private val readReceiptHandle
private val roomFullyReadHandler: RoomFullyReadHandler, private val roomFullyReadHandler: RoomFullyReadHandler,
private val cryptoService: DefaultCryptoService, private val cryptoService: DefaultCryptoService,
private val roomMemberEventHandler: RoomMemberEventHandler, private val roomMemberEventHandler: RoomMemberEventHandler,
private val roomTypingUsersHandler: RoomTypingUsersHandler,
@UserId private val userId: String, @UserId private val userId: String,
private val eventBus: EventBus) { private val eventBus: EventBus) {
@ -170,14 +171,15 @@ internal class RoomSyncHandler @Inject constructor(private val readReceiptHandle
it.type == EventType.STATE_ROOM_MEMBER it.type == EventType.STATE_ROOM_MEMBER
} != null } != null
roomTypingUsersHandler.handle(realm, roomId, ephemeralResult)
roomSummaryUpdater.update( roomSummaryUpdater.update(
realm, realm,
roomId, roomId,
Membership.JOIN, Membership.JOIN,
roomSync.summary, roomSync.summary,
roomSync.unreadNotifications, roomSync.unreadNotifications,
updateMembers = hasRoomMember, updateMembers = hasRoomMember
ephemeralResult = ephemeralResult) )
return roomEntity return roomEntity
} }

View file

@ -0,0 +1,43 @@
/*
* Copyright (c) 2020 New Vector Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package im.vector.matrix.android.internal.session.sync
import im.vector.matrix.android.api.session.room.sender.SenderInfo
import im.vector.matrix.android.internal.di.UserId
import im.vector.matrix.android.internal.session.room.membership.RoomMemberHelper
import im.vector.matrix.android.internal.session.typing.DefaultTypingUsersTracker
import io.realm.Realm
import javax.inject.Inject
internal class RoomTypingUsersHandler @Inject constructor(@UserId private val userId: String,
private val typingUsersTracker: DefaultTypingUsersTracker) {
fun handle(realm: Realm, roomId: String, ephemeralResult: RoomSyncHandler.EphemeralResult?) {
val roomMemberHelper = RoomMemberHelper(realm, roomId)
val typingIds = ephemeralResult?.typingUserIds?.filter { it != userId } ?: emptyList()
val senderInfo = typingIds.map { userId ->
val roomMemberSummaryEntity = roomMemberHelper.getLastRoomMember(userId)
SenderInfo(
userId = userId,
displayName = roomMemberSummaryEntity?.displayName,
isUniqueDisplayName = roomMemberHelper.isUniqueDisplayName(roomMemberSummaryEntity?.displayName),
avatarUrl = roomMemberSummaryEntity?.avatarUrl
)
}
typingUsersTracker.setTypingUsersFromRoom(roomId, senderInfo)
}
}

View file

@ -21,6 +21,7 @@ import im.vector.matrix.android.R
import im.vector.matrix.android.api.pushrules.PushRuleService import im.vector.matrix.android.api.pushrules.PushRuleService
import im.vector.matrix.android.api.pushrules.RuleScope import im.vector.matrix.android.api.pushrules.RuleScope
import im.vector.matrix.android.internal.crypto.DefaultCryptoService import im.vector.matrix.android.internal.crypto.DefaultCryptoService
import im.vector.matrix.android.internal.di.SessionDatabase
import im.vector.matrix.android.internal.session.DefaultInitialSyncProgressService import im.vector.matrix.android.internal.session.DefaultInitialSyncProgressService
import im.vector.matrix.android.internal.session.notification.ProcessEventForPushTask import im.vector.matrix.android.internal.session.notification.ProcessEventForPushTask
import im.vector.matrix.android.internal.session.reportSubtask import im.vector.matrix.android.internal.session.reportSubtask
@ -31,7 +32,7 @@ import timber.log.Timber
import javax.inject.Inject import javax.inject.Inject
import kotlin.system.measureTimeMillis import kotlin.system.measureTimeMillis
internal class SyncResponseHandler @Inject constructor(private val monarchy: Monarchy, internal class SyncResponseHandler @Inject constructor(@SessionDatabase private val monarchy: Monarchy,
private val roomSyncHandler: RoomSyncHandler, private val roomSyncHandler: RoomSyncHandler,
private val userAccountDataSyncHandler: UserAccountDataSyncHandler, private val userAccountDataSyncHandler: UserAccountDataSyncHandler,
private val groupSyncHandler: GroupSyncHandler, private val groupSyncHandler: GroupSyncHandler,
@ -68,7 +69,6 @@ internal class SyncResponseHandler @Inject constructor(private val monarchy: Mon
}.also { }.also {
Timber.v("Finish handling toDevice in $it ms") Timber.v("Finish handling toDevice in $it ms")
} }
// Start one big transaction // Start one big transaction
monarchy.awaitTransaction { realm -> monarchy.awaitTransaction { realm ->
measureTimeMillis { measureTimeMillis {
@ -103,7 +103,6 @@ internal class SyncResponseHandler @Inject constructor(private val monarchy: Mon
} }
tokenStore.saveToken(realm, syncResponse.nextBatch) tokenStore.saveToken(realm, syncResponse.nextBatch)
} }
// Everything else we need to do outside the transaction // Everything else we need to do outside the transaction
syncResponse.rooms?.also { syncResponse.rooms?.also {
checkPushRules(it, isInitialSync) checkPushRules(it, isInitialSync)

View file

@ -18,10 +18,11 @@ package im.vector.matrix.android.internal.session.sync
import com.zhuinden.monarchy.Monarchy import com.zhuinden.monarchy.Monarchy
import im.vector.matrix.android.internal.database.model.SyncEntity import im.vector.matrix.android.internal.database.model.SyncEntity
import im.vector.matrix.android.internal.di.SessionDatabase
import io.realm.Realm import io.realm.Realm
import javax.inject.Inject import javax.inject.Inject
internal class SyncTokenStore @Inject constructor(private val monarchy: Monarchy) { internal class SyncTokenStore @Inject constructor(@SessionDatabase private val monarchy: Monarchy) {
fun getLastToken(): String? { fun getLastToken(): String? {
return Realm.getInstance(monarchy.realmConfiguration).use { return Realm.getInstance(monarchy.realmConfiguration).use {

View file

@ -38,6 +38,7 @@ import im.vector.matrix.android.internal.database.query.getDirectRooms
import im.vector.matrix.android.internal.database.query.getOrCreate import im.vector.matrix.android.internal.database.query.getOrCreate
import im.vector.matrix.android.internal.database.query.where import im.vector.matrix.android.internal.database.query.where
import im.vector.matrix.android.internal.di.MoshiProvider import im.vector.matrix.android.internal.di.MoshiProvider
import im.vector.matrix.android.internal.di.SessionDatabase
import im.vector.matrix.android.internal.di.UserId import im.vector.matrix.android.internal.di.UserId
import im.vector.matrix.android.internal.session.room.membership.RoomMemberHelper import im.vector.matrix.android.internal.session.room.membership.RoomMemberHelper
import im.vector.matrix.android.internal.session.sync.model.InvitedRoomSync import im.vector.matrix.android.internal.session.sync.model.InvitedRoomSync
@ -56,7 +57,7 @@ import timber.log.Timber
import javax.inject.Inject import javax.inject.Inject
internal class UserAccountDataSyncHandler @Inject constructor( internal class UserAccountDataSyncHandler @Inject constructor(
private val monarchy: Monarchy, @SessionDatabase private val monarchy: Monarchy,
@UserId private val userId: String, @UserId private val userId: String,
private val directChatsHelper: DirectChatsHelper, private val directChatsHelper: DirectChatsHelper,
private val updateUserAccountDataTask: UpdateUserAccountDataTask) { private val updateUserAccountDataTask: UpdateUserAccountDataTask) {

View file

@ -24,6 +24,7 @@ import im.vector.matrix.android.api.failure.isTokenError
import im.vector.matrix.android.api.session.sync.SyncState import im.vector.matrix.android.api.session.sync.SyncState
import im.vector.matrix.android.internal.network.NetworkConnectivityChecker import im.vector.matrix.android.internal.network.NetworkConnectivityChecker
import im.vector.matrix.android.internal.session.sync.SyncTask import im.vector.matrix.android.internal.session.sync.SyncTask
import im.vector.matrix.android.internal.session.typing.DefaultTypingUsersTracker
import im.vector.matrix.android.internal.util.BackgroundDetectionObserver import im.vector.matrix.android.internal.util.BackgroundDetectionObserver
import im.vector.matrix.android.internal.util.Debouncer import im.vector.matrix.android.internal.util.Debouncer
import im.vector.matrix.android.internal.util.createUIHandler import im.vector.matrix.android.internal.util.createUIHandler
@ -44,6 +45,7 @@ private const val RETRY_WAIT_TIME_MS = 10_000L
private const val DEFAULT_LONG_POOL_TIMEOUT = 30_000L private const val DEFAULT_LONG_POOL_TIMEOUT = 30_000L
internal class SyncThread @Inject constructor(private val syncTask: SyncTask, internal class SyncThread @Inject constructor(private val syncTask: SyncTask,
private val typingUsersTracker: DefaultTypingUsersTracker,
private val networkConnectivityChecker: NetworkConnectivityChecker, private val networkConnectivityChecker: NetworkConnectivityChecker,
private val backgroundDetectionObserver: BackgroundDetectionObserver) private val backgroundDetectionObserver: BackgroundDetectionObserver)
: Thread(), NetworkConnectivityChecker.Listener, BackgroundDetectionObserver.Listener { : Thread(), NetworkConnectivityChecker.Listener, BackgroundDetectionObserver.Listener {
@ -196,7 +198,14 @@ internal class SyncThread @Inject constructor(private val syncTask: SyncTask,
private fun updateStateTo(newState: SyncState) { private fun updateStateTo(newState: SyncState) {
Timber.v("Update state from $state to $newState") Timber.v("Update state from $state to $newState")
if (newState == state) {
return
}
state = newState state = newState
// We clear typing users if the sync is not running
if (newState !is SyncState.Running) {
typingUsersTracker.clear()
}
debouncer.debounce("post_state", Runnable { debouncer.debounce("post_state", Runnable {
liveState.value = newState liveState.value = newState
}, 150) }, 150)

View file

@ -0,0 +1,62 @@
/*
* Copyright (c) 2020 New Vector Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package im.vector.matrix.android.internal.session.typing
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import im.vector.matrix.android.api.session.room.sender.SenderInfo
import im.vector.matrix.android.api.session.typing.TypingUsersTracker
import im.vector.matrix.android.internal.session.SessionScope
import javax.inject.Inject
@SessionScope
internal class DefaultTypingUsersTracker @Inject constructor() : TypingUsersTracker {
private val typingUsers = mutableMapOf<String, List<SenderInfo>>()
private val typingUsersLiveData = mutableMapOf<String, MutableLiveData<List<SenderInfo>>>()
/**
* Set all currently typing users for a room (excluding yourself)
*/
fun setTypingUsersFromRoom(roomId: String, senderInfoList: List<SenderInfo>) {
val hasNewValue = typingUsers[roomId] != senderInfoList
if (hasNewValue) {
typingUsers[roomId] = senderInfoList
typingUsersLiveData[roomId]?.postValue(senderInfoList)
}
}
/**
* Can be called when there is no sync so you don't get stuck with ephemeral data
*/
fun clear() {
val roomIds = typingUsers.keys
roomIds.forEach {
setTypingUsersFromRoom(it, emptyList())
}
}
override fun getTypingUsers(roomId: String): List<SenderInfo> {
return typingUsers[roomId] ?: emptyList()
}
override fun getTypingUsersLive(roomId: String): LiveData<List<SenderInfo>> {
return typingUsersLiveData.getOrPut(roomId) {
MutableLiveData(getTypingUsers(roomId))
}
}
}

View file

@ -31,10 +31,11 @@ import im.vector.matrix.android.internal.database.model.IgnoredUserEntityFields
import im.vector.matrix.android.internal.database.model.UserEntity import im.vector.matrix.android.internal.database.model.UserEntity
import im.vector.matrix.android.internal.database.model.UserEntityFields import im.vector.matrix.android.internal.database.model.UserEntityFields
import im.vector.matrix.android.internal.database.query.where import im.vector.matrix.android.internal.database.query.where
import im.vector.matrix.android.internal.di.SessionDatabase
import im.vector.matrix.android.internal.util.fetchCopied import im.vector.matrix.android.internal.util.fetchCopied
import javax.inject.Inject import javax.inject.Inject
internal class UserDataSource @Inject constructor(private val monarchy: Monarchy) { internal class UserDataSource @Inject constructor(@SessionDatabase private val monarchy: Monarchy) {
private val realmDataSourceFactory: Monarchy.RealmDataSourceFactory<UserEntity> by lazy { private val realmDataSourceFactory: Monarchy.RealmDataSourceFactory<UserEntity> by lazy {
monarchy.createDataSourceFactory { realm -> monarchy.createDataSourceFactory { realm ->

View file

@ -18,6 +18,7 @@ package im.vector.matrix.android.internal.session.user
import com.zhuinden.monarchy.Monarchy import com.zhuinden.monarchy.Monarchy
import im.vector.matrix.android.internal.database.model.UserEntity import im.vector.matrix.android.internal.database.model.UserEntity
import im.vector.matrix.android.internal.di.SessionDatabase
import im.vector.matrix.android.internal.util.awaitTransaction import im.vector.matrix.android.internal.util.awaitTransaction
import javax.inject.Inject import javax.inject.Inject
@ -25,7 +26,7 @@ internal interface UserStore {
suspend fun createOrUpdate(userId: String, displayName: String? = null, avatarUrl: String? = null) suspend fun createOrUpdate(userId: String, displayName: String? = null, avatarUrl: String? = null)
} }
internal class RealmUserStore @Inject constructor(private val monarchy: Monarchy) : UserStore { internal class RealmUserStore @Inject constructor(@SessionDatabase private val monarchy: Monarchy) : UserStore {
override suspend fun createOrUpdate(userId: String, displayName: String?, avatarUrl: String?) { override suspend fun createOrUpdate(userId: String, displayName: String?, avatarUrl: String?) {
monarchy.awaitTransaction { monarchy.awaitTransaction {

View file

@ -24,12 +24,13 @@ import im.vector.matrix.android.api.util.toOptional
import im.vector.matrix.android.internal.database.mapper.AccountDataMapper import im.vector.matrix.android.internal.database.mapper.AccountDataMapper
import im.vector.matrix.android.internal.database.model.UserAccountDataEntity import im.vector.matrix.android.internal.database.model.UserAccountDataEntity
import im.vector.matrix.android.internal.database.model.UserAccountDataEntityFields import im.vector.matrix.android.internal.database.model.UserAccountDataEntityFields
import im.vector.matrix.android.internal.di.SessionDatabase
import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountDataEvent import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountDataEvent
import io.realm.Realm import io.realm.Realm
import io.realm.RealmQuery import io.realm.RealmQuery
import javax.inject.Inject import javax.inject.Inject
internal class AccountDataDataSource @Inject constructor(private val monarchy: Monarchy, internal class AccountDataDataSource @Inject constructor(@SessionDatabase private val monarchy: Monarchy,
private val accountDataMapper: AccountDataMapper) { private val accountDataMapper: AccountDataMapper) {
fun getAccountDataEvent(type: String): UserAccountDataEvent? { fun getAccountDataEvent(type: String): UserAccountDataEvent? {

View file

@ -23,6 +23,7 @@ import im.vector.matrix.android.api.session.accountdata.AccountDataService
import im.vector.matrix.android.api.session.events.model.Content import im.vector.matrix.android.api.session.events.model.Content
import im.vector.matrix.android.api.util.Cancelable import im.vector.matrix.android.api.util.Cancelable
import im.vector.matrix.android.api.util.Optional import im.vector.matrix.android.api.util.Optional
import im.vector.matrix.android.internal.di.SessionDatabase
import im.vector.matrix.android.internal.session.sync.UserAccountDataSyncHandler import im.vector.matrix.android.internal.session.sync.UserAccountDataSyncHandler
import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountDataEvent import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountDataEvent
import im.vector.matrix.android.internal.task.TaskExecutor import im.vector.matrix.android.internal.task.TaskExecutor
@ -30,7 +31,7 @@ import im.vector.matrix.android.internal.task.configureWith
import javax.inject.Inject import javax.inject.Inject
internal class DefaultAccountDataService @Inject constructor( internal class DefaultAccountDataService @Inject constructor(
private val monarchy: Monarchy, @SessionDatabase private val monarchy: Monarchy,
private val updateUserAccountDataTask: UpdateUserAccountDataTask, private val updateUserAccountDataTask: UpdateUserAccountDataTask,
private val userAccountDataSyncHandler: UserAccountDataSyncHandler, private val userAccountDataSyncHandler: UserAccountDataSyncHandler,
private val accountDataDataSource: AccountDataDataSource, private val accountDataDataSource: AccountDataDataSource,

View file

@ -22,6 +22,7 @@ import im.vector.matrix.android.internal.database.model.RoomSummaryEntity
import im.vector.matrix.android.internal.database.model.RoomSummaryEntityFields import im.vector.matrix.android.internal.database.model.RoomSummaryEntityFields
import im.vector.matrix.android.internal.database.query.getOrCreate import im.vector.matrix.android.internal.database.query.getOrCreate
import im.vector.matrix.android.internal.database.query.where import im.vector.matrix.android.internal.database.query.where
import im.vector.matrix.android.internal.di.SessionDatabase
import im.vector.matrix.android.internal.task.Task import im.vector.matrix.android.internal.task.Task
import im.vector.matrix.android.internal.util.awaitTransaction import im.vector.matrix.android.internal.util.awaitTransaction
import io.realm.RealmList import io.realm.RealmList
@ -37,7 +38,7 @@ internal interface SaveBreadcrumbsTask : Task<SaveBreadcrumbsTask.Params, Unit>
} }
internal class DefaultSaveBreadcrumbsTask @Inject constructor( internal class DefaultSaveBreadcrumbsTask @Inject constructor(
private val monarchy: Monarchy @SessionDatabase private val monarchy: Monarchy
) : SaveBreadcrumbsTask { ) : SaveBreadcrumbsTask {
override suspend fun execute(params: SaveBreadcrumbsTask.Params) { override suspend fun execute(params: SaveBreadcrumbsTask.Params) {

View file

@ -17,6 +17,7 @@ package im.vector.matrix.android.internal.session.user.accountdata
import com.zhuinden.monarchy.Monarchy import com.zhuinden.monarchy.Monarchy
import im.vector.matrix.android.internal.database.model.IgnoredUserEntity import im.vector.matrix.android.internal.database.model.IgnoredUserEntity
import im.vector.matrix.android.internal.di.SessionDatabase
import im.vector.matrix.android.internal.task.Task import im.vector.matrix.android.internal.task.Task
import im.vector.matrix.android.internal.util.awaitTransaction import im.vector.matrix.android.internal.util.awaitTransaction
import javax.inject.Inject import javax.inject.Inject
@ -30,7 +31,7 @@ internal interface SaveIgnoredUsersTask : Task<SaveIgnoredUsersTask.Params, Unit
) )
} }
internal class DefaultSaveIgnoredUsersTask @Inject constructor(private val monarchy: Monarchy) : SaveIgnoredUsersTask { internal class DefaultSaveIgnoredUsersTask @Inject constructor(@SessionDatabase private val monarchy: Monarchy) : SaveIgnoredUsersTask {
override suspend fun execute(params: SaveIgnoredUsersTask.Params) { override suspend fun execute(params: SaveIgnoredUsersTask.Params) {
monarchy.awaitTransaction { realm -> monarchy.awaitTransaction { realm ->

View file

@ -19,6 +19,7 @@ package im.vector.matrix.android.internal.session.user.accountdata
import com.zhuinden.monarchy.Monarchy import com.zhuinden.monarchy.Monarchy
import im.vector.matrix.android.internal.database.model.BreadcrumbsEntity import im.vector.matrix.android.internal.database.model.BreadcrumbsEntity
import im.vector.matrix.android.internal.database.query.get import im.vector.matrix.android.internal.database.query.get
import im.vector.matrix.android.internal.di.SessionDatabase
import im.vector.matrix.android.internal.session.sync.model.accountdata.BreadcrumbsContent import im.vector.matrix.android.internal.session.sync.model.accountdata.BreadcrumbsContent
import im.vector.matrix.android.internal.task.Task import im.vector.matrix.android.internal.task.Task
import im.vector.matrix.android.internal.util.fetchCopied import im.vector.matrix.android.internal.util.fetchCopied
@ -36,7 +37,7 @@ internal interface UpdateBreadcrumbsTask : Task<UpdateBreadcrumbsTask.Params, Un
internal class DefaultUpdateBreadcrumbsTask @Inject constructor( internal class DefaultUpdateBreadcrumbsTask @Inject constructor(
private val saveBreadcrumbsTask: SaveBreadcrumbsTask, private val saveBreadcrumbsTask: SaveBreadcrumbsTask,
private val updateUserAccountDataTask: UpdateUserAccountDataTask, private val updateUserAccountDataTask: UpdateUserAccountDataTask,
private val monarchy: Monarchy @SessionDatabase private val monarchy: Monarchy
) : UpdateBreadcrumbsTask { ) : UpdateBreadcrumbsTask {
override suspend fun execute(params: UpdateBreadcrumbsTask.Params) { override suspend fun execute(params: UpdateBreadcrumbsTask.Params) {

View file

@ -18,6 +18,7 @@ package im.vector.matrix.android.internal.session.user.accountdata
import com.zhuinden.monarchy.Monarchy import com.zhuinden.monarchy.Monarchy
import im.vector.matrix.android.internal.database.model.IgnoredUserEntity import im.vector.matrix.android.internal.database.model.IgnoredUserEntity
import im.vector.matrix.android.internal.di.SessionDatabase
import im.vector.matrix.android.internal.di.UserId import im.vector.matrix.android.internal.di.UserId
import im.vector.matrix.android.internal.network.executeRequest import im.vector.matrix.android.internal.network.executeRequest
import im.vector.matrix.android.internal.session.sync.model.accountdata.IgnoredUsersContent import im.vector.matrix.android.internal.session.sync.model.accountdata.IgnoredUsersContent
@ -36,7 +37,7 @@ internal interface UpdateIgnoredUserIdsTask : Task<UpdateIgnoredUserIdsTask.Para
internal class DefaultUpdateIgnoredUserIdsTask @Inject constructor( internal class DefaultUpdateIgnoredUserIdsTask @Inject constructor(
private val accountDataApi: AccountDataAPI, private val accountDataApi: AccountDataAPI,
private val monarchy: Monarchy, @SessionDatabase private val monarchy: Monarchy,
private val saveIgnoredUsersTask: SaveIgnoredUsersTask, private val saveIgnoredUsersTask: SaveIgnoredUsersTask,
@UserId private val userId: String, @UserId private val userId: String,
private val eventBus: EventBus private val eventBus: EventBus

View file

@ -23,6 +23,7 @@ import im.vector.matrix.android.internal.database.awaitNotEmptyResult
import im.vector.matrix.android.internal.database.model.CurrentStateEventEntity import im.vector.matrix.android.internal.database.model.CurrentStateEventEntity
import im.vector.matrix.android.internal.database.model.CurrentStateEventEntityFields import im.vector.matrix.android.internal.database.model.CurrentStateEventEntityFields
import im.vector.matrix.android.internal.database.query.whereStateKey import im.vector.matrix.android.internal.database.query.whereStateKey
import im.vector.matrix.android.internal.di.SessionDatabase
import im.vector.matrix.android.internal.di.UserId import im.vector.matrix.android.internal.di.UserId
import im.vector.matrix.android.internal.network.executeRequest 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.RoomAPI
@ -39,7 +40,7 @@ internal interface CreateWidgetTask : Task<CreateWidgetTask.Params, Unit> {
) )
} }
internal class DefaultCreateWidgetTask @Inject constructor(private val monarchy: Monarchy, internal class DefaultCreateWidgetTask @Inject constructor(@SessionDatabase private val monarchy: Monarchy,
private val roomAPI: RoomAPI, private val roomAPI: RoomAPI,
@UserId private val userId: String, @UserId private val userId: String,
private val eventBus: EventBus) : CreateWidgetTask { private val eventBus: EventBus) : CreateWidgetTask {

View file

@ -20,6 +20,7 @@ import im.vector.matrix.android.api.MatrixConfiguration
import im.vector.matrix.android.api.session.integrationmanager.IntegrationManagerConfig import im.vector.matrix.android.api.session.integrationmanager.IntegrationManagerConfig
import im.vector.matrix.android.api.session.integrationmanager.IntegrationManagerService import im.vector.matrix.android.api.session.integrationmanager.IntegrationManagerService
import im.vector.matrix.android.api.session.widgets.WidgetURLFormatter import im.vector.matrix.android.api.session.widgets.WidgetURLFormatter
import im.vector.matrix.android.internal.session.SessionLifecycleObserver
import im.vector.matrix.android.internal.session.SessionScope import im.vector.matrix.android.internal.session.SessionScope
import im.vector.matrix.android.internal.session.integrationmanager.IntegrationManager import im.vector.matrix.android.internal.session.integrationmanager.IntegrationManager
import im.vector.matrix.android.internal.session.widgets.token.GetScalarTokenTask import im.vector.matrix.android.internal.session.widgets.token.GetScalarTokenTask
@ -30,17 +31,17 @@ import javax.inject.Inject
internal class DefaultWidgetURLFormatter @Inject constructor(private val integrationManager: IntegrationManager, internal class DefaultWidgetURLFormatter @Inject constructor(private val integrationManager: IntegrationManager,
private val getScalarTokenTask: GetScalarTokenTask, private val getScalarTokenTask: GetScalarTokenTask,
private val matrixConfiguration: MatrixConfiguration private val matrixConfiguration: MatrixConfiguration
) : IntegrationManagerService.Listener, WidgetURLFormatter { ) : IntegrationManagerService.Listener, WidgetURLFormatter, SessionLifecycleObserver {
private lateinit var currentConfig: IntegrationManagerConfig private lateinit var currentConfig: IntegrationManagerConfig
private var whiteListedUrls: List<String> = emptyList() private var whiteListedUrls: List<String> = emptyList()
fun start() { override fun onStart() {
setupWithConfiguration() setupWithConfiguration()
integrationManager.addListener(this) integrationManager.addListener(this)
} }
fun stop() { override fun onStop() {
integrationManager.removeListener(this) integrationManager.removeListener(this)
} }

View file

@ -1,37 +0,0 @@
/*
* Copyright (c) 2020 New Vector Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package im.vector.matrix.android.internal.session.widgets
import im.vector.matrix.android.internal.session.integrationmanager.IntegrationManager
import javax.inject.Inject
internal class WidgetDependenciesHolder @Inject constructor(private val integrationManager: IntegrationManager,
private val widgetManager: WidgetManager,
private val widgetURLFormatter: DefaultWidgetURLFormatter) {
fun start() {
integrationManager.start()
widgetManager.start()
widgetURLFormatter.start()
}
fun stop() {
widgetURLFormatter.stop()
widgetManager.stop()
integrationManager.stop()
}
}

View file

@ -34,6 +34,7 @@ import im.vector.matrix.android.api.session.widgets.WidgetManagementFailure
import im.vector.matrix.android.api.session.widgets.model.Widget import im.vector.matrix.android.api.session.widgets.model.Widget
import im.vector.matrix.android.api.util.Cancelable import im.vector.matrix.android.api.util.Cancelable
import im.vector.matrix.android.internal.di.UserId import im.vector.matrix.android.internal.di.UserId
import im.vector.matrix.android.internal.session.SessionLifecycleObserver
import im.vector.matrix.android.internal.session.SessionScope import im.vector.matrix.android.internal.session.SessionScope
import im.vector.matrix.android.internal.session.integrationmanager.IntegrationManager import im.vector.matrix.android.internal.session.integrationmanager.IntegrationManager
import im.vector.matrix.android.internal.session.room.state.StateEventDataSource import im.vector.matrix.android.internal.session.room.state.StateEventDataSource
@ -54,17 +55,19 @@ internal class WidgetManager @Inject constructor(private val integrationManager:
private val taskExecutor: TaskExecutor, private val taskExecutor: TaskExecutor,
private val createWidgetTask: CreateWidgetTask, private val createWidgetTask: CreateWidgetTask,
private val widgetFactory: WidgetFactory, private val widgetFactory: WidgetFactory,
@UserId private val userId: String) : IntegrationManagerService.Listener { @UserId private val userId: String)
: IntegrationManagerService.Listener, SessionLifecycleObserver {
private val lifecycleOwner: LifecycleOwner = LifecycleOwner { lifecycleRegistry } private val lifecycleOwner: LifecycleOwner = LifecycleOwner { lifecycleRegistry }
private val lifecycleRegistry: LifecycleRegistry = LifecycleRegistry(lifecycleOwner) private val lifecycleRegistry: LifecycleRegistry = LifecycleRegistry(lifecycleOwner)
fun start() { override fun onStart() {
lifecycleRegistry.currentState = Lifecycle.State.STARTED lifecycleRegistry.currentState = Lifecycle.State.STARTED
integrationManager.addListener(this) integrationManager.addListener(this)
} }
fun stop() { override fun onStop() {
integrationManager.removeListener(this) integrationManager.removeListener(this)
lifecycleRegistry.currentState = Lifecycle.State.DESTROYED lifecycleRegistry.currentState = Lifecycle.State.DESTROYED
} }

View file

@ -19,11 +19,12 @@ package im.vector.matrix.android.internal.session.widgets.token
import com.zhuinden.monarchy.Monarchy import com.zhuinden.monarchy.Monarchy
import im.vector.matrix.android.internal.database.model.ScalarTokenEntity import im.vector.matrix.android.internal.database.model.ScalarTokenEntity
import im.vector.matrix.android.internal.database.query.where import im.vector.matrix.android.internal.database.query.where
import im.vector.matrix.android.internal.di.SessionDatabase
import im.vector.matrix.android.internal.util.awaitTransaction import im.vector.matrix.android.internal.util.awaitTransaction
import im.vector.matrix.android.internal.util.fetchCopyMap import im.vector.matrix.android.internal.util.fetchCopyMap
import javax.inject.Inject import javax.inject.Inject
internal class ScalarTokenStore @Inject constructor(private val monarchy: Monarchy) { internal class ScalarTokenStore @Inject constructor(@SessionDatabase private val monarchy: Monarchy) {
fun getToken(apiUrl: String): String? { fun getToken(apiUrl: String): String? {
return monarchy.fetchCopyMap({ realm -> return monarchy.fetchCopyMap({ realm ->

View file

@ -29,6 +29,7 @@ abstract class DividerItem : VectorEpoxyModel<DividerItem.Holder>() {
@EpoxyAttribute var color: Int = -1 @EpoxyAttribute var color: Int = -1
override fun bind(holder: Holder) { override fun bind(holder: Holder) {
super.bind(holder)
if (color != -1) { if (color != -1) {
holder.view.setBackgroundColor(color) holder.view.setBackgroundColor(color)
} }

View file

@ -33,6 +33,7 @@ abstract class ErrorWithRetryItem : VectorEpoxyModel<ErrorWithRetryItem.Holder>(
var listener: (() -> Unit)? = null var listener: (() -> Unit)? = null
override fun bind(holder: Holder) { override fun bind(holder: Holder) {
super.bind(holder)
holder.textView.text = text holder.textView.text = text
holder.buttonView.isVisible = listener != null holder.buttonView.isVisible = listener != null
holder.buttonView.setOnClickListener { listener?.invoke() } holder.buttonView.setOnClickListener { listener?.invoke() }

View file

@ -28,6 +28,7 @@ abstract class HelpFooterItem : VectorEpoxyModel<HelpFooterItem.Holder>() {
var text: String? = null var text: String? = null
override fun bind(holder: Holder) { override fun bind(holder: Holder) {
super.bind(holder)
holder.textView.text = text holder.textView.text = text
} }

View file

@ -28,6 +28,7 @@ abstract class NoResultItem : VectorEpoxyModel<NoResultItem.Holder>() {
var text: String? = null var text: String? = null
override fun bind(holder: Holder) { override fun bind(holder: Holder) {
super.bind(holder)
holder.textView.text = text holder.textView.text = text
} }

View file

@ -16,6 +16,10 @@
package im.vector.riotx.core.epoxy package im.vector.riotx.core.epoxy
import androidx.annotation.CallSuper
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.LifecycleRegistry
import com.airbnb.epoxy.EpoxyModelWithHolder import com.airbnb.epoxy.EpoxyModelWithHolder
import com.airbnb.epoxy.VisibilityState import com.airbnb.epoxy.VisibilityState
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
@ -26,13 +30,24 @@ import kotlinx.coroutines.cancelChildren
/** /**
* EpoxyModelWithHolder which can listen to visibility state change * EpoxyModelWithHolder which can listen to visibility state change
*/ */
abstract class VectorEpoxyModel<H : VectorEpoxyHolder> : EpoxyModelWithHolder<H>() { abstract class VectorEpoxyModel<H : VectorEpoxyHolder> : EpoxyModelWithHolder<H>(), LifecycleOwner {
protected val coroutineScope = CoroutineScope(SupervisorJob() + Dispatchers.Main) protected val coroutineScope = CoroutineScope(SupervisorJob() + Dispatchers.Main)
private val lifecycleRegistry: LifecycleRegistry = LifecycleRegistry(this)
override fun getLifecycle() = lifecycleRegistry
private var onModelVisibilityStateChangedListener: OnVisibilityStateChangedListener? = null private var onModelVisibilityStateChangedListener: OnVisibilityStateChangedListener? = null
@CallSuper
override fun bind(holder: H) {
super.bind(holder)
lifecycleRegistry.currentState = Lifecycle.State.STARTED
}
@CallSuper
override fun unbind(holder: H) { override fun unbind(holder: H) {
lifecycleRegistry.currentState = Lifecycle.State.DESTROYED
coroutineScope.coroutineContext.cancelChildren() coroutineScope.coroutineContext.cancelChildren()
super.unbind(holder) super.unbind(holder)
} }

View file

@ -58,6 +58,7 @@ abstract class BottomSheetActionItem : VectorEpoxyModel<BottomSheetActionItem.Ho
lateinit var listener: View.OnClickListener lateinit var listener: View.OnClickListener
override fun bind(holder: Holder) { override fun bind(holder: Holder) {
super.bind(holder)
holder.view.setOnClickListener { holder.view.setOnClickListener {
listener.onClick(it) listener.onClick(it)
} }

View file

@ -49,6 +49,7 @@ abstract class BottomSheetMessagePreviewItem : VectorEpoxyModel<BottomSheetMessa
var userClicked: (() -> Unit)? = null var userClicked: (() -> Unit)? = null
override fun bind(holder: Holder) { override fun bind(holder: Holder) {
super.bind(holder)
avatarRenderer.render(matrixItem, holder.avatar) avatarRenderer.render(matrixItem, holder.avatar)
holder.avatar.setOnClickListener { userClicked?.invoke() } holder.avatar.setOnClickListener { userClicked?.invoke() }
holder.sender.setTextOrHide(matrixItem.displayName) holder.sender.setTextOrHide(matrixItem.displayName)

View file

@ -41,6 +41,7 @@ abstract class BottomSheetQuickReactionsItem : VectorEpoxyModel<BottomSheetQuick
var listener: Listener? = null var listener: Listener? = null
override fun bind(holder: Holder) { override fun bind(holder: Holder) {
super.bind(holder)
holder.textViews.forEachIndexed { index, textView -> holder.textViews.forEachIndexed { index, textView ->
textView.typeface = fontProvider.typeface ?: Typeface.DEFAULT textView.typeface = fontProvider.typeface ?: Typeface.DEFAULT
textView.text = texts[index] textView.text = texts[index]

View file

@ -49,6 +49,7 @@ abstract class BottomSheetRoomPreviewItem : VectorEpoxyModel<BottomSheetRoomPrev
@EpoxyAttribute var favoriteClickListener: ClickListener? = null @EpoxyAttribute var favoriteClickListener: ClickListener? = null
override fun bind(holder: Holder) { override fun bind(holder: Holder) {
super.bind(holder)
avatarRenderer.render(matrixItem, holder.avatar) avatarRenderer.render(matrixItem, holder.avatar)
holder.avatar.onClick(settingsClickListener) holder.avatar.onClick(settingsClickListener)
holder.roomName.setTextOrHide(matrixItem.displayName) holder.roomName.setTextOrHide(matrixItem.displayName)

View file

@ -41,6 +41,7 @@ abstract class BottomSheetSendStateItem : VectorEpoxyModel<BottomSheetSendStateI
var drawableStart: Int = 0 var drawableStart: Int = 0
override fun bind(holder: Holder) { override fun bind(holder: Holder) {
super.bind(holder)
holder.progress.isVisible = showProgress holder.progress.isVisible = showProgress
holder.text.setCompoundDrawablesWithIntrinsicBounds(drawableStart, 0, 0, 0) holder.text.setCompoundDrawablesWithIntrinsicBounds(drawableStart, 0, 0, 0)
holder.text.text = text holder.text.text = text

View file

@ -40,6 +40,7 @@ abstract class ProfileMatrixItem : VectorEpoxyModel<ProfileMatrixItem.Holder>()
@EpoxyAttribute var clickListener: View.OnClickListener? = null @EpoxyAttribute var clickListener: View.OnClickListener? = null
override fun bind(holder: Holder) { override fun bind(holder: Holder) {
super.bind(holder)
val bestName = matrixItem.getBestName() val bestName = matrixItem.getBestName()
val matrixId = matrixItem.id.takeIf { it != bestName } val matrixId = matrixItem.id.takeIf { it != bestName }
holder.view.setOnClickListener(clickListener) holder.view.setOnClickListener(clickListener)

View file

@ -47,6 +47,7 @@ abstract class GenericButtonItem : VectorEpoxyModel<GenericButtonItem.Holder>()
var iconRes: Int? = null var iconRes: Int? = null
override fun bind(holder: Holder) { override fun bind(holder: Holder) {
super.bind(holder)
holder.button.text = text holder.button.text = text
val textColor = textColor ?: ThemeUtils.getColor(holder.view.context, R.attr.riotx_text_primary) val textColor = textColor ?: ThemeUtils.getColor(holder.view.context, R.attr.riotx_text_primary)
holder.button.setTextColor(textColor) holder.button.setTextColor(textColor)

View file

@ -52,6 +52,7 @@ abstract class GenericFooterItem : VectorEpoxyModel<GenericFooterItem.Holder>()
var textColor: Int? = null var textColor: Int? = null
override fun bind(holder: Holder) { override fun bind(holder: Holder) {
super.bind(holder)
holder.text.setTextOrHide(text) holder.text.setTextOrHide(text)
when (style) { when (style) {
GenericItem.STYLE.BIG_TEXT -> holder.text.textSize = 18f GenericItem.STYLE.BIG_TEXT -> holder.text.textSize = 18f

View file

@ -74,6 +74,7 @@ abstract class GenericItem : VectorEpoxyModel<GenericItem.Holder>() {
var itemClickAction: Action? = null var itemClickAction: Action? = null
override fun bind(holder: Holder) { override fun bind(holder: Holder) {
super.bind(holder)
holder.titleText.setTextOrHide(title) holder.titleText.setTextOrHide(title)
if (titleIconResourceId != -1) { if (titleIconResourceId != -1) {

View file

@ -33,6 +33,7 @@ abstract class GenericItemHeader : VectorEpoxyModel<GenericItemHeader.Holder>()
var text: String? = null var text: String? = null
override fun bind(holder: Holder) { override fun bind(holder: Holder) {
super.bind(holder)
holder.text.setTextOrHide(text) holder.text.setTextOrHide(text)
} }

View file

@ -57,6 +57,7 @@ abstract class GenericItemWithValue : VectorEpoxyModel<GenericItemWithValue.Hold
var itemClickAction: View.OnClickListener? = null var itemClickAction: View.OnClickListener? = null
override fun bind(holder: Holder) { override fun bind(holder: Holder) {
super.bind(holder)
holder.titleText.setTextOrHide(title) holder.titleText.setTextOrHide(title)
if (titleIconResourceId != -1) { if (titleIconResourceId != -1) {

View file

@ -13,7 +13,5 @@ abstract class GenericLoaderItem : VectorEpoxyModel<GenericLoaderItem.Holder>()
// Maybe/Later add some style configuration, SMALL/BIG ? // Maybe/Later add some style configuration, SMALL/BIG ?
override fun bind(holder: Holder) {}
class Holder : VectorEpoxyHolder() class Holder : VectorEpoxyHolder()
} }

View file

@ -33,6 +33,7 @@ abstract class AttachmentPreviewItem<H : AttachmentPreviewItem.Holder> : VectorE
abstract val attachment: ContentAttachmentData abstract val attachment: ContentAttachmentData
override fun bind(holder: H) { override fun bind(holder: H) {
super.bind(holder)
if (attachment.type == ContentAttachmentData.Type.VIDEO || attachment.type == ContentAttachmentData.Type.IMAGE) { if (attachment.type == ContentAttachmentData.Type.VIDEO || attachment.type == ContentAttachmentData.Type.IMAGE) {
Glide.with(holder.view.context) Glide.with(holder.view.context)
.asBitmap() .asBitmap()

View file

@ -37,6 +37,7 @@ abstract class AutocompleteMatrixItem : VectorEpoxyModel<AutocompleteMatrixItem.
@EpoxyAttribute var clickListener: View.OnClickListener? = null @EpoxyAttribute var clickListener: View.OnClickListener? = null
override fun bind(holder: Holder) { override fun bind(holder: Holder) {
super.bind(holder)
holder.view.setOnClickListener(clickListener) holder.view.setOnClickListener(clickListener)
holder.nameView.text = matrixItem.getBestName() holder.nameView.text = matrixItem.getBestName()
holder.subNameView.setTextOrHide(subName) holder.subNameView.setTextOrHide(subName)

Some files were not shown because too many files have changed in this diff Show more