Merge pull request #2075 from vector-im/feature/strict_mode_tracking
Feature/strict mode tracking
This commit is contained in:
commit
b9e8d7187c
@ -20,7 +20,7 @@ Build 🧱:
|
|||||||
-
|
-
|
||||||
|
|
||||||
Other changes:
|
Other changes:
|
||||||
-
|
- Performance: share Realm instance used on UI thread and improve SharedPreferences reading time.
|
||||||
|
|
||||||
Changes in Element 1.0.6 (2020-09-08)
|
Changes in Element 1.0.6 (2020-09-08)
|
||||||
===================================================
|
===================================================
|
||||||
|
@ -0,0 +1,35 @@
|
|||||||
|
/*
|
||||||
|
* 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 org.matrix.android.sdk.internal.database
|
||||||
|
|
||||||
|
import io.realm.Realm
|
||||||
|
import java.io.Closeable
|
||||||
|
|
||||||
|
internal class RealmInstanceWrapper(private val realm: Realm, private val closeRealmOnClose: Boolean) : Closeable {
|
||||||
|
|
||||||
|
override fun close() {
|
||||||
|
if (closeRealmOnClose) {
|
||||||
|
realm.close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun <R> withRealm(block: (Realm) -> R): R {
|
||||||
|
return use {
|
||||||
|
block(it.realm)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,72 @@
|
|||||||
|
/*
|
||||||
|
* 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 org.matrix.android.sdk.internal.database
|
||||||
|
|
||||||
|
import android.os.Looper
|
||||||
|
import androidx.annotation.MainThread
|
||||||
|
import com.zhuinden.monarchy.Monarchy
|
||||||
|
import io.realm.Realm
|
||||||
|
import org.matrix.android.sdk.internal.di.SessionDatabase
|
||||||
|
import org.matrix.android.sdk.internal.session.SessionLifecycleObserver
|
||||||
|
import org.matrix.android.sdk.internal.session.SessionScope
|
||||||
|
import javax.inject.Inject
|
||||||
|
import kotlin.concurrent.getOrSet
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class keeps an instance of realm open in the main thread so you can grab it whenever you want to get a realm
|
||||||
|
* instance. This does check each time if you are on the main thread or not and returns the appropriate realm instance.
|
||||||
|
*/
|
||||||
|
@SessionScope
|
||||||
|
internal class RealmSessionProvider @Inject constructor(@SessionDatabase private val monarchy: Monarchy)
|
||||||
|
: SessionLifecycleObserver {
|
||||||
|
|
||||||
|
private val realmThreadLocal = ThreadLocal<Realm>()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allow you to execute a block with an opened realm. It automatically closes it if necessary (ie. when not in main thread)
|
||||||
|
*/
|
||||||
|
fun <R> withRealm(block: (Realm) -> R): R {
|
||||||
|
return getRealmWrapper().withRealm(block)
|
||||||
|
}
|
||||||
|
|
||||||
|
@MainThread
|
||||||
|
override fun onStart() {
|
||||||
|
realmThreadLocal.getOrSet {
|
||||||
|
Realm.getInstance(monarchy.realmConfiguration)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@MainThread
|
||||||
|
override fun onStop() {
|
||||||
|
realmThreadLocal.get()?.close()
|
||||||
|
realmThreadLocal.remove()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getRealmWrapper(): RealmInstanceWrapper {
|
||||||
|
val isOnMainThread = isOnMainThread()
|
||||||
|
val realm = if (isOnMainThread) {
|
||||||
|
realmThreadLocal.getOrSet {
|
||||||
|
Realm.getInstance(monarchy.realmConfiguration)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Realm.getInstance(monarchy.realmConfiguration)
|
||||||
|
}
|
||||||
|
return RealmInstanceWrapper(realm, closeRealmOnClose = !isOnMainThread)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun isOnMainThread() = Looper.myLooper() == Looper.getMainLooper()
|
||||||
|
}
|
@ -18,26 +18,24 @@
|
|||||||
package org.matrix.android.sdk.internal.database.mapper
|
package org.matrix.android.sdk.internal.database.mapper
|
||||||
|
|
||||||
import org.matrix.android.sdk.api.session.room.model.ReadReceipt
|
import org.matrix.android.sdk.api.session.room.model.ReadReceipt
|
||||||
|
import org.matrix.android.sdk.internal.database.RealmSessionProvider
|
||||||
import org.matrix.android.sdk.internal.database.model.ReadReceiptsSummaryEntity
|
import org.matrix.android.sdk.internal.database.model.ReadReceiptsSummaryEntity
|
||||||
import org.matrix.android.sdk.internal.database.model.UserEntity
|
import org.matrix.android.sdk.internal.database.model.UserEntity
|
||||||
import org.matrix.android.sdk.internal.database.query.where
|
import org.matrix.android.sdk.internal.database.query.where
|
||||||
import org.matrix.android.sdk.internal.di.SessionDatabase
|
|
||||||
import io.realm.Realm
|
|
||||||
import io.realm.RealmConfiguration
|
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
internal class ReadReceiptsSummaryMapper @Inject constructor(@SessionDatabase private val realmConfiguration: RealmConfiguration) {
|
internal class ReadReceiptsSummaryMapper @Inject constructor(private val realmSessionProvider: RealmSessionProvider) {
|
||||||
|
|
||||||
fun map(readReceiptsSummaryEntity: ReadReceiptsSummaryEntity?): List<ReadReceipt> {
|
fun map(readReceiptsSummaryEntity: ReadReceiptsSummaryEntity?): List<ReadReceipt> {
|
||||||
if (readReceiptsSummaryEntity == null) {
|
if (readReceiptsSummaryEntity == null) {
|
||||||
return emptyList()
|
return emptyList()
|
||||||
}
|
}
|
||||||
return Realm.getInstance(realmConfiguration).use { realm ->
|
return realmSessionProvider.withRealm { realm ->
|
||||||
val readReceipts = readReceiptsSummaryEntity.readReceipts
|
val readReceipts = readReceiptsSummaryEntity.readReceipts
|
||||||
readReceipts
|
readReceipts
|
||||||
.mapNotNull {
|
.mapNotNull {
|
||||||
val user = UserEntity.where(realm, it.userId).findFirst()
|
val user = UserEntity.where(realm, it.userId).findFirst()
|
||||||
?: return@mapNotNull null
|
?: return@mapNotNull null
|
||||||
ReadReceipt(user.asDomain(), it.originServerTs.toLong())
|
ReadReceipt(user.asDomain(), it.originServerTs.toLong())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -47,6 +47,7 @@ import org.matrix.android.sdk.internal.crypto.secrets.DefaultSharedSecretStorage
|
|||||||
import org.matrix.android.sdk.internal.crypto.verification.VerificationMessageProcessor
|
import org.matrix.android.sdk.internal.crypto.verification.VerificationMessageProcessor
|
||||||
import org.matrix.android.sdk.internal.database.DatabaseCleaner
|
import org.matrix.android.sdk.internal.database.DatabaseCleaner
|
||||||
import org.matrix.android.sdk.internal.database.EventInsertLiveObserver
|
import org.matrix.android.sdk.internal.database.EventInsertLiveObserver
|
||||||
|
import org.matrix.android.sdk.internal.database.RealmSessionProvider
|
||||||
import org.matrix.android.sdk.internal.database.SessionRealmConfigurationFactory
|
import org.matrix.android.sdk.internal.database.SessionRealmConfigurationFactory
|
||||||
import org.matrix.android.sdk.internal.di.Authenticated
|
import org.matrix.android.sdk.internal.di.Authenticated
|
||||||
import org.matrix.android.sdk.internal.di.DeviceId
|
import org.matrix.android.sdk.internal.di.DeviceId
|
||||||
@ -325,23 +326,27 @@ internal abstract class SessionModule {
|
|||||||
|
|
||||||
@Binds
|
@Binds
|
||||||
@IntoSet
|
@IntoSet
|
||||||
abstract fun bindIntegrationManager(observer: IntegrationManager): SessionLifecycleObserver
|
abstract fun bindIntegrationManager(manager: IntegrationManager): SessionLifecycleObserver
|
||||||
|
|
||||||
@Binds
|
@Binds
|
||||||
@IntoSet
|
@IntoSet
|
||||||
abstract fun bindWidgetUrlFormatter(observer: DefaultWidgetURLFormatter): SessionLifecycleObserver
|
abstract fun bindWidgetUrlFormatter(formatter: DefaultWidgetURLFormatter): SessionLifecycleObserver
|
||||||
|
|
||||||
@Binds
|
@Binds
|
||||||
@IntoSet
|
@IntoSet
|
||||||
abstract fun bindShieldTrustUpdated(observer: ShieldTrustUpdater): SessionLifecycleObserver
|
abstract fun bindShieldTrustUpdated(updater: ShieldTrustUpdater): SessionLifecycleObserver
|
||||||
|
|
||||||
@Binds
|
@Binds
|
||||||
@IntoSet
|
@IntoSet
|
||||||
abstract fun bindIdentityService(observer: DefaultIdentityService): SessionLifecycleObserver
|
abstract fun bindIdentityService(service: DefaultIdentityService): SessionLifecycleObserver
|
||||||
|
|
||||||
@Binds
|
@Binds
|
||||||
@IntoSet
|
@IntoSet
|
||||||
abstract fun bindDatabaseCleaner(observer: DatabaseCleaner): SessionLifecycleObserver
|
abstract fun bindDatabaseCleaner(cleaner: DatabaseCleaner): SessionLifecycleObserver
|
||||||
|
|
||||||
|
@Binds
|
||||||
|
@IntoSet
|
||||||
|
abstract fun bindRealmSessionProvider(provider: RealmSessionProvider): SessionLifecycleObserver
|
||||||
|
|
||||||
@Binds
|
@Binds
|
||||||
abstract fun bindInitialSyncProgressService(service: DefaultInitialSyncProgressService): InitialSyncProgressService
|
abstract fun bindInitialSyncProgressService(service: DefaultInitialSyncProgressService): InitialSyncProgressService
|
||||||
|
@ -17,17 +17,16 @@
|
|||||||
|
|
||||||
package org.matrix.android.sdk.internal.session.room
|
package org.matrix.android.sdk.internal.session.room
|
||||||
|
|
||||||
import com.zhuinden.monarchy.Monarchy
|
import io.realm.Realm
|
||||||
import org.matrix.android.sdk.api.session.room.Room
|
import org.matrix.android.sdk.api.session.room.Room
|
||||||
import org.matrix.android.sdk.api.session.room.model.Membership
|
import org.matrix.android.sdk.api.session.room.model.Membership
|
||||||
|
import org.matrix.android.sdk.internal.database.RealmSessionProvider
|
||||||
import org.matrix.android.sdk.internal.database.model.RoomEntity
|
import org.matrix.android.sdk.internal.database.model.RoomEntity
|
||||||
import org.matrix.android.sdk.internal.database.model.RoomSummaryEntity
|
import org.matrix.android.sdk.internal.database.model.RoomSummaryEntity
|
||||||
import org.matrix.android.sdk.internal.database.model.RoomSummaryEntityFields
|
import org.matrix.android.sdk.internal.database.model.RoomSummaryEntityFields
|
||||||
import org.matrix.android.sdk.internal.database.query.where
|
import org.matrix.android.sdk.internal.database.query.where
|
||||||
import org.matrix.android.sdk.internal.di.SessionDatabase
|
|
||||||
import org.matrix.android.sdk.internal.session.SessionScope
|
import org.matrix.android.sdk.internal.session.SessionScope
|
||||||
import org.matrix.android.sdk.internal.session.room.membership.RoomMemberHelper
|
import org.matrix.android.sdk.internal.session.room.membership.RoomMemberHelper
|
||||||
import io.realm.Realm
|
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
internal interface RoomGetter {
|
internal interface RoomGetter {
|
||||||
@ -38,18 +37,18 @@ internal interface RoomGetter {
|
|||||||
|
|
||||||
@SessionScope
|
@SessionScope
|
||||||
internal class DefaultRoomGetter @Inject constructor(
|
internal class DefaultRoomGetter @Inject constructor(
|
||||||
@SessionDatabase private val monarchy: Monarchy,
|
private val realmSessionProvider: RealmSessionProvider,
|
||||||
private val roomFactory: RoomFactory
|
private val roomFactory: RoomFactory
|
||||||
) : RoomGetter {
|
) : RoomGetter {
|
||||||
|
|
||||||
override fun getRoom(roomId: String): Room? {
|
override fun getRoom(roomId: String): Room? {
|
||||||
return Realm.getInstance(monarchy.realmConfiguration).use { realm ->
|
return realmSessionProvider.withRealm { realm ->
|
||||||
createRoom(realm, roomId)
|
createRoom(realm, roomId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getDirectRoomWith(otherUserId: String): Room? {
|
override fun getDirectRoomWith(otherUserId: String): Room? {
|
||||||
return Realm.getInstance(monarchy.realmConfiguration).use { realm ->
|
return realmSessionProvider.withRealm { realm ->
|
||||||
RoomSummaryEntity.where(realm)
|
RoomSummaryEntity.where(realm)
|
||||||
.equalTo(RoomSummaryEntityFields.IS_DIRECT, true)
|
.equalTo(RoomSummaryEntityFields.IS_DIRECT, true)
|
||||||
.equalTo(RoomSummaryEntityFields.MEMBERSHIP_STR, Membership.JOIN.name)
|
.equalTo(RoomSummaryEntityFields.MEMBERSHIP_STR, Membership.JOIN.name)
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
package org.matrix.android.sdk.internal.session.room.send
|
package org.matrix.android.sdk.internal.session.room.send
|
||||||
|
|
||||||
import com.zhuinden.monarchy.Monarchy
|
import com.zhuinden.monarchy.Monarchy
|
||||||
|
import org.greenrobot.eventbus.EventBus
|
||||||
import org.matrix.android.sdk.api.session.events.model.Content
|
import org.matrix.android.sdk.api.session.events.model.Content
|
||||||
import org.matrix.android.sdk.api.session.events.model.Event
|
import org.matrix.android.sdk.api.session.events.model.Event
|
||||||
import org.matrix.android.sdk.api.session.events.model.EventType
|
import org.matrix.android.sdk.api.session.events.model.EventType
|
||||||
@ -27,6 +28,7 @@ import org.matrix.android.sdk.api.session.room.model.message.MessageType
|
|||||||
import org.matrix.android.sdk.api.session.room.send.SendState
|
import org.matrix.android.sdk.api.session.room.send.SendState
|
||||||
import org.matrix.android.sdk.api.session.room.timeline.TimelineEvent
|
import org.matrix.android.sdk.api.session.room.timeline.TimelineEvent
|
||||||
import org.matrix.android.sdk.internal.crypto.MXEventDecryptionResult
|
import org.matrix.android.sdk.internal.crypto.MXEventDecryptionResult
|
||||||
|
import org.matrix.android.sdk.internal.database.RealmSessionProvider
|
||||||
import org.matrix.android.sdk.internal.database.helper.nextId
|
import org.matrix.android.sdk.internal.database.helper.nextId
|
||||||
import org.matrix.android.sdk.internal.database.mapper.ContentMapper
|
import org.matrix.android.sdk.internal.database.mapper.ContentMapper
|
||||||
import org.matrix.android.sdk.internal.database.mapper.TimelineEventMapper
|
import org.matrix.android.sdk.internal.database.mapper.TimelineEventMapper
|
||||||
@ -43,12 +45,11 @@ import org.matrix.android.sdk.internal.session.room.membership.RoomMemberHelper
|
|||||||
import org.matrix.android.sdk.internal.session.room.summary.RoomSummaryUpdater
|
import org.matrix.android.sdk.internal.session.room.summary.RoomSummaryUpdater
|
||||||
import org.matrix.android.sdk.internal.session.room.timeline.DefaultTimeline
|
import org.matrix.android.sdk.internal.session.room.timeline.DefaultTimeline
|
||||||
import org.matrix.android.sdk.internal.util.awaitTransaction
|
import org.matrix.android.sdk.internal.util.awaitTransaction
|
||||||
import io.realm.Realm
|
|
||||||
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(@SessionDatabase private val monarchy: Monarchy,
|
internal class LocalEchoRepository @Inject constructor(@SessionDatabase private val monarchy: Monarchy,
|
||||||
|
private val realmSessionProvider: RealmSessionProvider,
|
||||||
private val roomSummaryUpdater: RoomSummaryUpdater,
|
private val roomSummaryUpdater: RoomSummaryUpdater,
|
||||||
private val eventBus: EventBus,
|
private val eventBus: EventBus,
|
||||||
private val timelineEventMapper: TimelineEventMapper) {
|
private val timelineEventMapper: TimelineEventMapper) {
|
||||||
@ -59,7 +60,7 @@ internal class LocalEchoRepository @Inject constructor(@SessionDatabase private
|
|||||||
if (event.eventId == null) {
|
if (event.eventId == null) {
|
||||||
throw IllegalStateException("You should have set an eventId for your event")
|
throw IllegalStateException("You should have set an eventId for your event")
|
||||||
}
|
}
|
||||||
val timelineEventEntity = Realm.getInstance(monarchy.realmConfiguration).use { realm ->
|
val timelineEventEntity = realmSessionProvider.withRealm { realm ->
|
||||||
val eventEntity = event.toEntity(roomId, SendState.UNSENT, System.currentTimeMillis())
|
val eventEntity = event.toEntity(roomId, SendState.UNSENT, System.currentTimeMillis())
|
||||||
val roomMemberHelper = RoomMemberHelper(realm, roomId)
|
val roomMemberHelper = RoomMemberHelper(realm, roomId)
|
||||||
val myUser = roomMemberHelper.getLastRoomMember(senderId)
|
val myUser = roomMemberHelper.getLastRoomMember(senderId)
|
||||||
@ -150,7 +151,7 @@ internal class LocalEchoRepository @Inject constructor(@SessionDatabase private
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun getAllEventsWithStates(roomId: String, states : List<SendState>): List<TimelineEvent> {
|
fun getAllEventsWithStates(roomId: String, states : List<SendState>): List<TimelineEvent> {
|
||||||
return Realm.getInstance(monarchy.realmConfiguration).use { realm ->
|
return realmSessionProvider.withRealm { realm ->
|
||||||
TimelineEventEntity
|
TimelineEventEntity
|
||||||
.findAllInRoomWithSendStates(realm, roomId, states)
|
.findAllInRoomWithSendStates(realm, roomId, states)
|
||||||
.sortedByDescending { it.displayIndex }
|
.sortedByDescending { it.displayIndex }
|
||||||
|
@ -20,24 +20,26 @@ package org.matrix.android.sdk.internal.session.room.state
|
|||||||
import androidx.lifecycle.LiveData
|
import androidx.lifecycle.LiveData
|
||||||
import androidx.lifecycle.Transformations
|
import androidx.lifecycle.Transformations
|
||||||
import com.zhuinden.monarchy.Monarchy
|
import com.zhuinden.monarchy.Monarchy
|
||||||
|
import io.realm.Realm
|
||||||
|
import io.realm.RealmQuery
|
||||||
|
import io.realm.kotlin.where
|
||||||
import org.matrix.android.sdk.api.query.QueryStringValue
|
import org.matrix.android.sdk.api.query.QueryStringValue
|
||||||
import org.matrix.android.sdk.api.session.events.model.Event
|
import org.matrix.android.sdk.api.session.events.model.Event
|
||||||
import org.matrix.android.sdk.api.util.Optional
|
import org.matrix.android.sdk.api.util.Optional
|
||||||
import org.matrix.android.sdk.api.util.toOptional
|
import org.matrix.android.sdk.api.util.toOptional
|
||||||
|
import org.matrix.android.sdk.internal.database.RealmSessionProvider
|
||||||
import org.matrix.android.sdk.internal.database.mapper.asDomain
|
import org.matrix.android.sdk.internal.database.mapper.asDomain
|
||||||
import org.matrix.android.sdk.internal.database.model.CurrentStateEventEntity
|
import org.matrix.android.sdk.internal.database.model.CurrentStateEventEntity
|
||||||
import org.matrix.android.sdk.internal.database.model.CurrentStateEventEntityFields
|
import org.matrix.android.sdk.internal.database.model.CurrentStateEventEntityFields
|
||||||
import org.matrix.android.sdk.internal.di.SessionDatabase
|
import org.matrix.android.sdk.internal.di.SessionDatabase
|
||||||
import org.matrix.android.sdk.internal.query.process
|
import org.matrix.android.sdk.internal.query.process
|
||||||
import io.realm.Realm
|
|
||||||
import io.realm.RealmQuery
|
|
||||||
import io.realm.kotlin.where
|
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
internal class StateEventDataSource @Inject constructor(@SessionDatabase private val monarchy: Monarchy) {
|
internal class StateEventDataSource @Inject constructor(@SessionDatabase private val monarchy: Monarchy,
|
||||||
|
private val realmSessionProvider: RealmSessionProvider) {
|
||||||
|
|
||||||
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 realmSessionProvider.withRealm { realm ->
|
||||||
buildStateEventQuery(realm, roomId, setOf(eventType), stateKey).findFirst()?.root?.asDomain()
|
buildStateEventQuery(realm, roomId, setOf(eventType), stateKey).findFirst()?.root?.asDomain()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -53,7 +55,7 @@ internal class StateEventDataSource @Inject constructor(@SessionDatabase private
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun getStateEvents(roomId: String, eventTypes: Set<String>, stateKey: QueryStringValue): List<Event> {
|
fun getStateEvents(roomId: String, eventTypes: Set<String>, stateKey: QueryStringValue): List<Event> {
|
||||||
return Realm.getInstance(monarchy.realmConfiguration).use { realm ->
|
return realmSessionProvider.withRealm { realm ->
|
||||||
buildStateEventQuery(realm, roomId, eventTypes, stateKey)
|
buildStateEventQuery(realm, roomId, eventTypes, stateKey)
|
||||||
.findAll()
|
.findAll()
|
||||||
.mapNotNull {
|
.mapNotNull {
|
||||||
|
@ -39,6 +39,7 @@ import org.matrix.android.sdk.api.session.room.timeline.Timeline
|
|||||||
import org.matrix.android.sdk.api.session.room.timeline.TimelineEvent
|
import org.matrix.android.sdk.api.session.room.timeline.TimelineEvent
|
||||||
import org.matrix.android.sdk.api.session.room.timeline.TimelineSettings
|
import org.matrix.android.sdk.api.session.room.timeline.TimelineSettings
|
||||||
import org.matrix.android.sdk.api.util.CancelableBag
|
import org.matrix.android.sdk.api.util.CancelableBag
|
||||||
|
import org.matrix.android.sdk.internal.database.RealmSessionProvider
|
||||||
import org.matrix.android.sdk.internal.database.mapper.TimelineEventMapper
|
import org.matrix.android.sdk.internal.database.mapper.TimelineEventMapper
|
||||||
import org.matrix.android.sdk.internal.database.model.ChunkEntity
|
import org.matrix.android.sdk.internal.database.model.ChunkEntity
|
||||||
import org.matrix.android.sdk.internal.database.model.ChunkEntityFields
|
import org.matrix.android.sdk.internal.database.model.ChunkEntityFields
|
||||||
@ -76,7 +77,8 @@ internal class DefaultTimeline(
|
|||||||
private val settings: TimelineSettings,
|
private val settings: TimelineSettings,
|
||||||
private val hiddenReadReceipts: TimelineHiddenReadReceipts,
|
private val hiddenReadReceipts: TimelineHiddenReadReceipts,
|
||||||
private val eventBus: EventBus,
|
private val eventBus: EventBus,
|
||||||
private val eventDecryptor: TimelineEventDecryptor
|
private val eventDecryptor: TimelineEventDecryptor,
|
||||||
|
private val realmSessionProvider: RealmSessionProvider
|
||||||
) : Timeline, TimelineHiddenReadReceipts.Delegate {
|
) : Timeline, TimelineHiddenReadReceipts.Delegate {
|
||||||
|
|
||||||
data class OnNewTimelineEvents(val roomId: String, val eventIds: List<String>)
|
data class OnNewTimelineEvents(val roomId: String, val eventIds: List<String>)
|
||||||
@ -136,13 +138,13 @@ internal class DefaultTimeline(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun pendingEventCount(): Int {
|
override fun pendingEventCount(): Int {
|
||||||
return Realm.getInstance(realmConfiguration).use {
|
return realmSessionProvider.withRealm {
|
||||||
RoomEntity.where(it, roomId).findFirst()?.sendingTimelineEvents?.count() ?: 0
|
RoomEntity.where(it, roomId).findFirst()?.sendingTimelineEvents?.count() ?: 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun failedToDeliverEventCount(): Int {
|
override fun failedToDeliverEventCount(): Int {
|
||||||
return Realm.getInstance(realmConfiguration).use {
|
return realmSessionProvider.withRealm {
|
||||||
TimelineEventEntity.findAllInRoomWithSendStates(it, roomId, SendState.HAS_FAILED_STATES).count()
|
TimelineEventEntity.findAllInRoomWithSendStates(it, roomId, SendState.HAS_FAILED_STATES).count()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -239,7 +241,7 @@ internal class DefaultTimeline(
|
|||||||
return eventId
|
return eventId
|
||||||
}
|
}
|
||||||
// Otherwise, we should check if the event is in the db, but is hidden because of filters
|
// Otherwise, we should check if the event is in the db, but is hidden because of filters
|
||||||
return Realm.getInstance(realmConfiguration).use { localRealm ->
|
return realmSessionProvider.withRealm { localRealm ->
|
||||||
val nonFilteredEvents = buildEventQuery(localRealm)
|
val nonFilteredEvents = buildEventQuery(localRealm)
|
||||||
.sort(TimelineEventEntityFields.DISPLAY_INDEX, Sort.DESCENDING)
|
.sort(TimelineEventEntityFields.DISPLAY_INDEX, Sort.DESCENDING)
|
||||||
.findAll()
|
.findAll()
|
||||||
|
@ -22,6 +22,9 @@ import androidx.lifecycle.Transformations
|
|||||||
import com.squareup.inject.assisted.Assisted
|
import com.squareup.inject.assisted.Assisted
|
||||||
import com.squareup.inject.assisted.AssistedInject
|
import com.squareup.inject.assisted.AssistedInject
|
||||||
import com.zhuinden.monarchy.Monarchy
|
import com.zhuinden.monarchy.Monarchy
|
||||||
|
import io.realm.Sort
|
||||||
|
import io.realm.kotlin.where
|
||||||
|
import org.greenrobot.eventbus.EventBus
|
||||||
import org.matrix.android.sdk.api.session.events.model.isImageMessage
|
import org.matrix.android.sdk.api.session.events.model.isImageMessage
|
||||||
import org.matrix.android.sdk.api.session.events.model.isVideoMessage
|
import org.matrix.android.sdk.api.session.events.model.isVideoMessage
|
||||||
import org.matrix.android.sdk.api.session.room.timeline.Timeline
|
import org.matrix.android.sdk.api.session.room.timeline.Timeline
|
||||||
@ -30,7 +33,7 @@ import org.matrix.android.sdk.api.session.room.timeline.TimelineService
|
|||||||
import org.matrix.android.sdk.api.session.room.timeline.TimelineSettings
|
import org.matrix.android.sdk.api.session.room.timeline.TimelineSettings
|
||||||
import org.matrix.android.sdk.api.util.Optional
|
import org.matrix.android.sdk.api.util.Optional
|
||||||
import org.matrix.android.sdk.api.util.toOptional
|
import org.matrix.android.sdk.api.util.toOptional
|
||||||
import org.matrix.android.sdk.internal.crypto.store.db.doWithRealm
|
import org.matrix.android.sdk.internal.database.RealmSessionProvider
|
||||||
import org.matrix.android.sdk.internal.database.mapper.ReadReceiptsSummaryMapper
|
import org.matrix.android.sdk.internal.database.mapper.ReadReceiptsSummaryMapper
|
||||||
import org.matrix.android.sdk.internal.database.mapper.TimelineEventMapper
|
import org.matrix.android.sdk.internal.database.mapper.TimelineEventMapper
|
||||||
import org.matrix.android.sdk.internal.database.model.TimelineEventEntity
|
import org.matrix.android.sdk.internal.database.model.TimelineEventEntity
|
||||||
@ -38,13 +41,10 @@ import org.matrix.android.sdk.internal.database.model.TimelineEventEntityFields
|
|||||||
import org.matrix.android.sdk.internal.database.query.where
|
import org.matrix.android.sdk.internal.database.query.where
|
||||||
import org.matrix.android.sdk.internal.di.SessionDatabase
|
import org.matrix.android.sdk.internal.di.SessionDatabase
|
||||||
import org.matrix.android.sdk.internal.task.TaskExecutor
|
import org.matrix.android.sdk.internal.task.TaskExecutor
|
||||||
import org.matrix.android.sdk.internal.util.fetchCopyMap
|
|
||||||
import io.realm.Sort
|
|
||||||
import io.realm.kotlin.where
|
|
||||||
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,
|
||||||
@SessionDatabase private val monarchy: Monarchy,
|
@SessionDatabase private val monarchy: Monarchy,
|
||||||
|
private val realmSessionProvider: RealmSessionProvider,
|
||||||
private val eventBus: EventBus,
|
private val eventBus: EventBus,
|
||||||
private val taskExecutor: TaskExecutor,
|
private val taskExecutor: TaskExecutor,
|
||||||
private val contextOfEventTask: GetContextOfEventTask,
|
private val contextOfEventTask: GetContextOfEventTask,
|
||||||
@ -73,17 +73,17 @@ internal class DefaultTimelineService @AssistedInject constructor(@Assisted priv
|
|||||||
hiddenReadReceipts = TimelineHiddenReadReceipts(readReceiptsSummaryMapper, roomId, settings),
|
hiddenReadReceipts = TimelineHiddenReadReceipts(readReceiptsSummaryMapper, roomId, settings),
|
||||||
eventBus = eventBus,
|
eventBus = eventBus,
|
||||||
eventDecryptor = eventDecryptor,
|
eventDecryptor = eventDecryptor,
|
||||||
fetchTokenAndPaginateTask = fetchTokenAndPaginateTask
|
fetchTokenAndPaginateTask = fetchTokenAndPaginateTask,
|
||||||
|
realmSessionProvider = realmSessionProvider
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getTimeLineEvent(eventId: String): TimelineEvent? {
|
override fun getTimeLineEvent(eventId: String): TimelineEvent? {
|
||||||
return monarchy
|
return realmSessionProvider.withRealm { realm ->
|
||||||
.fetchCopyMap({
|
TimelineEventEntity.where(realm, roomId = roomId, eventId = eventId).findFirst()?.let {
|
||||||
TimelineEventEntity.where(it, roomId = roomId, eventId = eventId).findFirst()
|
timelineEventMapper.map(it)
|
||||||
}, { entity, _ ->
|
}
|
||||||
timelineEventMapper.map(entity)
|
}
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getTimeLineEventLive(eventId: String): LiveData<Optional<TimelineEvent>> {
|
override fun getTimeLineEventLive(eventId: String): LiveData<Optional<TimelineEvent>> {
|
||||||
@ -98,7 +98,7 @@ internal class DefaultTimelineService @AssistedInject constructor(@Assisted priv
|
|||||||
|
|
||||||
override fun getAttachmentMessages(): List<TimelineEvent> {
|
override fun getAttachmentMessages(): List<TimelineEvent> {
|
||||||
// TODO pretty bad query.. maybe we should denormalize clear type in base?
|
// TODO pretty bad query.. maybe we should denormalize clear type in base?
|
||||||
return doWithRealm(monarchy.realmConfiguration) { realm ->
|
return realmSessionProvider.withRealm { realm ->
|
||||||
realm.where<TimelineEventEntity>()
|
realm.where<TimelineEventEntity>()
|
||||||
.equalTo(TimelineEventEntityFields.ROOM_ID, roomId)
|
.equalTo(TimelineEventEntityFields.ROOM_ID, roomId)
|
||||||
.sort(TimelineEventEntityFields.DISPLAY_INDEX, Sort.ASCENDING)
|
.sort(TimelineEventEntityFields.DISPLAY_INDEX, Sort.ASCENDING)
|
||||||
|
@ -23,9 +23,11 @@ import androidx.paging.DataSource
|
|||||||
import androidx.paging.LivePagedListBuilder
|
import androidx.paging.LivePagedListBuilder
|
||||||
import androidx.paging.PagedList
|
import androidx.paging.PagedList
|
||||||
import com.zhuinden.monarchy.Monarchy
|
import com.zhuinden.monarchy.Monarchy
|
||||||
|
import io.realm.Case
|
||||||
import org.matrix.android.sdk.api.session.user.model.User
|
import org.matrix.android.sdk.api.session.user.model.User
|
||||||
import org.matrix.android.sdk.api.util.Optional
|
import org.matrix.android.sdk.api.util.Optional
|
||||||
import org.matrix.android.sdk.api.util.toOptional
|
import org.matrix.android.sdk.api.util.toOptional
|
||||||
|
import org.matrix.android.sdk.internal.database.RealmSessionProvider
|
||||||
import org.matrix.android.sdk.internal.database.mapper.asDomain
|
import org.matrix.android.sdk.internal.database.mapper.asDomain
|
||||||
import org.matrix.android.sdk.internal.database.model.IgnoredUserEntity
|
import org.matrix.android.sdk.internal.database.model.IgnoredUserEntity
|
||||||
import org.matrix.android.sdk.internal.database.model.IgnoredUserEntityFields
|
import org.matrix.android.sdk.internal.database.model.IgnoredUserEntityFields
|
||||||
@ -33,11 +35,10 @@ import org.matrix.android.sdk.internal.database.model.UserEntity
|
|||||||
import org.matrix.android.sdk.internal.database.model.UserEntityFields
|
import org.matrix.android.sdk.internal.database.model.UserEntityFields
|
||||||
import org.matrix.android.sdk.internal.database.query.where
|
import org.matrix.android.sdk.internal.database.query.where
|
||||||
import org.matrix.android.sdk.internal.di.SessionDatabase
|
import org.matrix.android.sdk.internal.di.SessionDatabase
|
||||||
import org.matrix.android.sdk.internal.util.fetchCopied
|
|
||||||
import io.realm.Case
|
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
internal class UserDataSource @Inject constructor(@SessionDatabase private val monarchy: Monarchy) {
|
internal class UserDataSource @Inject constructor(@SessionDatabase private val monarchy: Monarchy,
|
||||||
|
private val realmSessionProvider: RealmSessionProvider) {
|
||||||
|
|
||||||
private val realmDataSourceFactory: Monarchy.RealmDataSourceFactory<UserEntity> by lazy {
|
private val realmDataSourceFactory: Monarchy.RealmDataSourceFactory<UserEntity> by lazy {
|
||||||
monarchy.createDataSourceFactory { realm ->
|
monarchy.createDataSourceFactory { realm ->
|
||||||
@ -58,10 +59,10 @@ internal class UserDataSource @Inject constructor(@SessionDatabase private val m
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun getUser(userId: String): User? {
|
fun getUser(userId: String): User? {
|
||||||
val userEntity = monarchy.fetchCopied { UserEntity.where(it, userId).findFirst() }
|
return realmSessionProvider.withRealm {
|
||||||
?: return null
|
val userEntity = UserEntity.where(it, userId).findFirst()
|
||||||
|
userEntity?.asDomain()
|
||||||
return userEntity.asDomain()
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getUserLive(userId: String): LiveData<Optional<User>> {
|
fun getUserLive(userId: String): LiveData<Optional<User>> {
|
||||||
|
@ -20,18 +20,20 @@ package org.matrix.android.sdk.internal.session.user.accountdata
|
|||||||
import androidx.lifecycle.LiveData
|
import androidx.lifecycle.LiveData
|
||||||
import androidx.lifecycle.Transformations
|
import androidx.lifecycle.Transformations
|
||||||
import com.zhuinden.monarchy.Monarchy
|
import com.zhuinden.monarchy.Monarchy
|
||||||
|
import io.realm.Realm
|
||||||
|
import io.realm.RealmQuery
|
||||||
|
import org.matrix.android.sdk.api.session.accountdata.UserAccountDataEvent
|
||||||
import org.matrix.android.sdk.api.util.Optional
|
import org.matrix.android.sdk.api.util.Optional
|
||||||
import org.matrix.android.sdk.api.util.toOptional
|
import org.matrix.android.sdk.api.util.toOptional
|
||||||
|
import org.matrix.android.sdk.internal.database.RealmSessionProvider
|
||||||
import org.matrix.android.sdk.internal.database.mapper.AccountDataMapper
|
import org.matrix.android.sdk.internal.database.mapper.AccountDataMapper
|
||||||
import org.matrix.android.sdk.internal.database.model.UserAccountDataEntity
|
import org.matrix.android.sdk.internal.database.model.UserAccountDataEntity
|
||||||
import org.matrix.android.sdk.internal.database.model.UserAccountDataEntityFields
|
import org.matrix.android.sdk.internal.database.model.UserAccountDataEntityFields
|
||||||
import org.matrix.android.sdk.internal.di.SessionDatabase
|
import org.matrix.android.sdk.internal.di.SessionDatabase
|
||||||
import org.matrix.android.sdk.api.session.accountdata.UserAccountDataEvent
|
|
||||||
import io.realm.Realm
|
|
||||||
import io.realm.RealmQuery
|
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
internal class AccountDataDataSource @Inject constructor(@SessionDatabase private val monarchy: Monarchy,
|
internal class AccountDataDataSource @Inject constructor(@SessionDatabase private val monarchy: Monarchy,
|
||||||
|
private val realmSessionProvider: RealmSessionProvider,
|
||||||
private val accountDataMapper: AccountDataMapper) {
|
private val accountDataMapper: AccountDataMapper) {
|
||||||
|
|
||||||
fun getAccountDataEvent(type: String): UserAccountDataEvent? {
|
fun getAccountDataEvent(type: String): UserAccountDataEvent? {
|
||||||
@ -45,10 +47,9 @@ internal class AccountDataDataSource @Inject constructor(@SessionDatabase privat
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun getAccountDataEvents(types: Set<String>): List<UserAccountDataEvent> {
|
fun getAccountDataEvents(types: Set<String>): List<UserAccountDataEvent> {
|
||||||
return monarchy.fetchAllMappedSync(
|
return realmSessionProvider.withRealm {
|
||||||
{ accountDataEventsQuery(it, types) },
|
accountDataEventsQuery(it, types).findAll().map(accountDataMapper::map)
|
||||||
accountDataMapper::map
|
}
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getLiveAccountDataEvents(types: Set<String>): LiveData<List<UserAccountDataEvent>> {
|
fun getLiveAccountDataEvents(types: Set<String>): LiveData<List<UserAccountDataEvent>> {
|
||||||
|
@ -23,17 +23,15 @@ import org.matrix.android.sdk.api.session.room.sender.SenderInfo
|
|||||||
import org.matrix.android.sdk.api.session.widgets.model.Widget
|
import org.matrix.android.sdk.api.session.widgets.model.Widget
|
||||||
import org.matrix.android.sdk.api.session.widgets.model.WidgetContent
|
import org.matrix.android.sdk.api.session.widgets.model.WidgetContent
|
||||||
import org.matrix.android.sdk.api.session.widgets.model.WidgetType
|
import org.matrix.android.sdk.api.session.widgets.model.WidgetType
|
||||||
import org.matrix.android.sdk.internal.di.SessionDatabase
|
import org.matrix.android.sdk.internal.database.RealmSessionProvider
|
||||||
import org.matrix.android.sdk.internal.di.UserId
|
import org.matrix.android.sdk.internal.di.UserId
|
||||||
import org.matrix.android.sdk.internal.session.room.membership.RoomMemberHelper
|
import org.matrix.android.sdk.internal.session.room.membership.RoomMemberHelper
|
||||||
import org.matrix.android.sdk.internal.session.user.UserDataSource
|
import org.matrix.android.sdk.internal.session.user.UserDataSource
|
||||||
import io.realm.Realm
|
|
||||||
import io.realm.RealmConfiguration
|
|
||||||
import java.net.URLEncoder
|
import java.net.URLEncoder
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
internal class WidgetFactory @Inject constructor(@SessionDatabase private val realmConfiguration: RealmConfiguration,
|
internal class WidgetFactory @Inject constructor(private val userDataSource: UserDataSource,
|
||||||
private val userDataSource: UserDataSource,
|
private val realmSessionProvider: RealmSessionProvider,
|
||||||
@UserId private val userId: String) {
|
@UserId private val userId: String) {
|
||||||
|
|
||||||
fun create(widgetEvent: Event): Widget? {
|
fun create(widgetEvent: Event): Widget? {
|
||||||
@ -44,7 +42,7 @@ internal class WidgetFactory @Inject constructor(@SessionDatabase private val re
|
|||||||
val senderInfo = if (widgetEvent.senderId == null || widgetEvent.roomId == null) {
|
val senderInfo = if (widgetEvent.senderId == null || widgetEvent.roomId == null) {
|
||||||
null
|
null
|
||||||
} else {
|
} else {
|
||||||
Realm.getInstance(realmConfiguration).use {
|
realmSessionProvider.withRealm {
|
||||||
val roomMemberHelper = RoomMemberHelper(it, widgetEvent.roomId)
|
val roomMemberHelper = RoomMemberHelper(it, widgetEvent.roomId)
|
||||||
val roomMemberSummaryEntity = roomMemberHelper.getLastRoomMember(widgetEvent.senderId)
|
val roomMemberSummaryEntity = roomMemberHelper.getLastRoomMember(widgetEvent.senderId)
|
||||||
SenderInfo(
|
SenderInfo(
|
||||||
|
@ -172,3 +172,6 @@ import org.matrix.androidsdk.crypto.data===2
|
|||||||
|
|
||||||
### Use `Context#getSystemService` extension function provided by `core-ktx`
|
### Use `Context#getSystemService` extension function provided by `core-ktx`
|
||||||
getSystemService\(Context
|
getSystemService\(Context
|
||||||
|
|
||||||
|
### Use DefaultSharedPreferences.getInstance() instead for better performance
|
||||||
|
PreferenceManager\.getDefaultSharedPreferences==2
|
||||||
|
@ -190,6 +190,8 @@ android {
|
|||||||
|
|
||||||
resValue "bool", "debug_mode", "true"
|
resValue "bool", "debug_mode", "true"
|
||||||
buildConfigField "boolean", "LOW_PRIVACY_LOG_ENABLE", "false"
|
buildConfigField "boolean", "LOW_PRIVACY_LOG_ENABLE", "false"
|
||||||
|
// Set to true if you want to enable strict mode in debug
|
||||||
|
buildConfigField "boolean", "ENABLE_STRICT_MODE_LOGS", "false"
|
||||||
|
|
||||||
signingConfig signingConfigs.debug
|
signingConfig signingConfigs.debug
|
||||||
}
|
}
|
||||||
@ -199,6 +201,7 @@ android {
|
|||||||
|
|
||||||
resValue "bool", "debug_mode", "false"
|
resValue "bool", "debug_mode", "false"
|
||||||
buildConfigField "boolean", "LOW_PRIVACY_LOG_ENABLE", "false"
|
buildConfigField "boolean", "LOW_PRIVACY_LOG_ENABLE", "false"
|
||||||
|
buildConfigField "boolean", "ENABLE_STRICT_MODE_LOGS", "false"
|
||||||
|
|
||||||
postprocessing {
|
postprocessing {
|
||||||
removeUnusedCode true
|
removeUnusedCode true
|
||||||
|
@ -22,7 +22,7 @@ import android.content.Intent
|
|||||||
import android.content.IntentFilter
|
import android.content.IntentFilter
|
||||||
import android.content.SharedPreferences
|
import android.content.SharedPreferences
|
||||||
import androidx.core.content.edit
|
import androidx.core.content.edit
|
||||||
import androidx.preference.PreferenceManager
|
import im.vector.app.core.di.DefaultSharedPreferences
|
||||||
import im.vector.app.core.utils.lsFiles
|
import im.vector.app.core.utils.lsFiles
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
|
|
||||||
@ -44,7 +44,7 @@ class DebugReceiver : BroadcastReceiver() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun dumpPreferences(context: Context) {
|
private fun dumpPreferences(context: Context) {
|
||||||
logPrefs("DefaultSharedPreferences", PreferenceManager.getDefaultSharedPreferences(context))
|
logPrefs("DefaultSharedPreferences", DefaultSharedPreferences.getInstance(context))
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun logPrefs(name: String, sharedPreferences: SharedPreferences?) {
|
private fun logPrefs(name: String, sharedPreferences: SharedPreferences?) {
|
||||||
@ -58,7 +58,7 @@ class DebugReceiver : BroadcastReceiver() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun alterScalarToken(context: Context) {
|
private fun alterScalarToken(context: Context) {
|
||||||
PreferenceManager.getDefaultSharedPreferences(context).edit {
|
DefaultSharedPreferences.getInstance(context).edit {
|
||||||
// putString("SCALAR_TOKEN_PREFERENCE_KEY" + Matrix.getInstance(context).defaultSession.myUserId, "bad_token")
|
// putString("SCALAR_TOKEN_PREFERENCE_KEY" + Matrix.getInstance(context).defaultSession.myUserId, "bad_token")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,6 @@ package im.vector.app.push.fcm
|
|||||||
|
|
||||||
import android.app.Activity
|
import android.app.Activity
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import androidx.preference.PreferenceManager
|
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.core.content.edit
|
import androidx.core.content.edit
|
||||||
import com.google.android.gms.common.ConnectionResult
|
import com.google.android.gms.common.ConnectionResult
|
||||||
@ -27,6 +26,7 @@ import com.google.android.gms.common.GoogleApiAvailability
|
|||||||
import com.google.firebase.iid.FirebaseInstanceId
|
import com.google.firebase.iid.FirebaseInstanceId
|
||||||
import im.vector.app.R
|
import im.vector.app.R
|
||||||
import im.vector.app.core.di.ActiveSessionHolder
|
import im.vector.app.core.di.ActiveSessionHolder
|
||||||
|
import im.vector.app.core.di.DefaultSharedPreferences
|
||||||
import im.vector.app.core.pushers.PushersManager
|
import im.vector.app.core.pushers.PushersManager
|
||||||
import im.vector.app.features.settings.VectorPreferences
|
import im.vector.app.features.settings.VectorPreferences
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
@ -46,7 +46,7 @@ object FcmHelper {
|
|||||||
* @return the FCM token or null if not received from FCM
|
* @return the FCM token or null if not received from FCM
|
||||||
*/
|
*/
|
||||||
fun getFcmToken(context: Context): String? {
|
fun getFcmToken(context: Context): String? {
|
||||||
return PreferenceManager.getDefaultSharedPreferences(context).getString(PREFS_KEY_FCM_TOKEN, null)
|
return DefaultSharedPreferences.getInstance(context).getString(PREFS_KEY_FCM_TOKEN, null)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -58,7 +58,7 @@ object FcmHelper {
|
|||||||
*/
|
*/
|
||||||
fun storeFcmToken(context: Context,
|
fun storeFcmToken(context: Context,
|
||||||
token: String?) {
|
token: String?) {
|
||||||
PreferenceManager.getDefaultSharedPreferences(context).edit {
|
DefaultSharedPreferences.getInstance(context).edit {
|
||||||
putString(PREFS_KEY_FCM_TOKEN, token)
|
putString(PREFS_KEY_FCM_TOKEN, token)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -21,6 +21,7 @@ import android.content.Context
|
|||||||
import android.content.res.Configuration
|
import android.content.res.Configuration
|
||||||
import android.os.Handler
|
import android.os.Handler
|
||||||
import android.os.HandlerThread
|
import android.os.HandlerThread
|
||||||
|
import android.os.StrictMode
|
||||||
import androidx.core.provider.FontRequest
|
import androidx.core.provider.FontRequest
|
||||||
import androidx.core.provider.FontsContractCompat
|
import androidx.core.provider.FontsContractCompat
|
||||||
import androidx.lifecycle.Lifecycle
|
import androidx.lifecycle.Lifecycle
|
||||||
@ -92,6 +93,7 @@ class VectorApplication :
|
|||||||
private var fontThreadHandler: Handler? = null
|
private var fontThreadHandler: Handler? = null
|
||||||
|
|
||||||
override fun onCreate() {
|
override fun onCreate() {
|
||||||
|
enableStrictModeIfNeeded()
|
||||||
super.onCreate()
|
super.onCreate()
|
||||||
appContext = this
|
appContext = this
|
||||||
vectorComponent = DaggerVectorComponent.factory().create(this)
|
vectorComponent = DaggerVectorComponent.factory().create(this)
|
||||||
@ -163,6 +165,15 @@ class VectorApplication :
|
|||||||
// initKnownEmojiHashSet(appContext)
|
// initKnownEmojiHashSet(appContext)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun enableStrictModeIfNeeded() {
|
||||||
|
if (BuildConfig.ENABLE_STRICT_MODE_LOGS) {
|
||||||
|
StrictMode.setThreadPolicy(StrictMode.ThreadPolicy.Builder()
|
||||||
|
.detectAll()
|
||||||
|
.penaltyLog()
|
||||||
|
.build())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun providesMatrixConfiguration() = MatrixConfiguration(BuildConfig.FLAVOR_DESCRIPTION)
|
override fun providesMatrixConfiguration() = MatrixConfiguration(BuildConfig.FLAVOR_DESCRIPTION)
|
||||||
|
|
||||||
override fun getWorkManagerConfiguration(): WorkConfiguration {
|
override fun getWorkManagerConfiguration(): WorkConfiguration {
|
||||||
|
@ -0,0 +1,31 @@
|
|||||||
|
/*
|
||||||
|
* 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.app.core.di
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.SharedPreferences
|
||||||
|
import androidx.preference.PreferenceManager
|
||||||
|
|
||||||
|
object DefaultSharedPreferences {
|
||||||
|
|
||||||
|
@Volatile private var INSTANCE: SharedPreferences? = null
|
||||||
|
|
||||||
|
fun getInstance(context: Context): SharedPreferences =
|
||||||
|
INSTANCE ?: synchronized(this) {
|
||||||
|
INSTANCE ?: PreferenceManager.getDefaultSharedPreferences(context.applicationContext).also { INSTANCE = it }
|
||||||
|
}
|
||||||
|
}
|
@ -100,7 +100,7 @@ class VectorGlideDataFetcher(private val activeSessionHolder: ActiveSessionHolde
|
|||||||
|
|
||||||
override fun loadData(priority: Priority, callback: DataFetcher.DataCallback<in InputStream>) {
|
override fun loadData(priority: Priority, callback: DataFetcher.DataCallback<in InputStream>) {
|
||||||
Timber.v("Load data: $data")
|
Timber.v("Load data: $data")
|
||||||
if (data.isLocalFile() && data.url != null) {
|
if (data.isLocalFile && data.url != null) {
|
||||||
val initialFile = File(data.url)
|
val initialFile = File(data.url)
|
||||||
callback.onDataReady(initialFile.inputStream())
|
callback.onDataReady(initialFile.inputStream())
|
||||||
return
|
return
|
||||||
|
@ -23,11 +23,11 @@ import android.widget.TextView
|
|||||||
import androidx.constraintlayout.widget.ConstraintLayout
|
import androidx.constraintlayout.widget.ConstraintLayout
|
||||||
import androidx.core.content.edit
|
import androidx.core.content.edit
|
||||||
import androidx.core.view.isVisible
|
import androidx.core.view.isVisible
|
||||||
import androidx.preference.PreferenceManager
|
|
||||||
import butterknife.BindView
|
import butterknife.BindView
|
||||||
import butterknife.ButterKnife
|
import butterknife.ButterKnife
|
||||||
import butterknife.OnClick
|
import butterknife.OnClick
|
||||||
import im.vector.app.R
|
import im.vector.app.R
|
||||||
|
import im.vector.app.core.di.DefaultSharedPreferences
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -57,7 +57,7 @@ class KeysBackupBanner @JvmOverloads constructor(
|
|||||||
|
|
||||||
init {
|
init {
|
||||||
setupView()
|
setupView()
|
||||||
PreferenceManager.getDefaultSharedPreferences(context).edit {
|
DefaultSharedPreferences.getInstance(context).edit {
|
||||||
putBoolean(BANNER_SETUP_DO_NOT_SHOW_AGAIN, false)
|
putBoolean(BANNER_SETUP_DO_NOT_SHOW_AGAIN, false)
|
||||||
putString(BANNER_RECOVER_DO_NOT_SHOW_FOR_VERSION, "")
|
putString(BANNER_RECOVER_DO_NOT_SHOW_FOR_VERSION, "")
|
||||||
}
|
}
|
||||||
@ -105,17 +105,17 @@ class KeysBackupBanner @JvmOverloads constructor(
|
|||||||
state.let {
|
state.let {
|
||||||
when (it) {
|
when (it) {
|
||||||
is State.Setup -> {
|
is State.Setup -> {
|
||||||
PreferenceManager.getDefaultSharedPreferences(context).edit {
|
DefaultSharedPreferences.getInstance(context).edit {
|
||||||
putBoolean(BANNER_SETUP_DO_NOT_SHOW_AGAIN, true)
|
putBoolean(BANNER_SETUP_DO_NOT_SHOW_AGAIN, true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
is State.Recover -> {
|
is State.Recover -> {
|
||||||
PreferenceManager.getDefaultSharedPreferences(context).edit {
|
DefaultSharedPreferences.getInstance(context).edit {
|
||||||
putString(BANNER_RECOVER_DO_NOT_SHOW_FOR_VERSION, it.version)
|
putString(BANNER_RECOVER_DO_NOT_SHOW_FOR_VERSION, it.version)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
is State.Update -> {
|
is State.Update -> {
|
||||||
PreferenceManager.getDefaultSharedPreferences(context).edit {
|
DefaultSharedPreferences.getInstance(context).edit {
|
||||||
putString(BANNER_UPDATE_DO_NOT_SHOW_FOR_VERSION, it.version)
|
putString(BANNER_UPDATE_DO_NOT_SHOW_FOR_VERSION, it.version)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -150,7 +150,7 @@ class KeysBackupBanner @JvmOverloads constructor(
|
|||||||
|
|
||||||
private fun renderSetup(nbOfKeys: Int) {
|
private fun renderSetup(nbOfKeys: Int) {
|
||||||
if (nbOfKeys == 0
|
if (nbOfKeys == 0
|
||||||
|| PreferenceManager.getDefaultSharedPreferences(context).getBoolean(BANNER_SETUP_DO_NOT_SHOW_AGAIN, false)) {
|
|| DefaultSharedPreferences.getInstance(context).getBoolean(BANNER_SETUP_DO_NOT_SHOW_AGAIN, false)) {
|
||||||
// Do not display the setup banner if there is no keys to backup, or if the user has already closed it
|
// Do not display the setup banner if there is no keys to backup, or if the user has already closed it
|
||||||
isVisible = false
|
isVisible = false
|
||||||
} else {
|
} else {
|
||||||
@ -164,7 +164,7 @@ class KeysBackupBanner @JvmOverloads constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun renderRecover(version: String) {
|
private fun renderRecover(version: String) {
|
||||||
if (version == PreferenceManager.getDefaultSharedPreferences(context).getString(BANNER_RECOVER_DO_NOT_SHOW_FOR_VERSION, null)) {
|
if (version == DefaultSharedPreferences.getInstance(context).getString(BANNER_RECOVER_DO_NOT_SHOW_FOR_VERSION, null)) {
|
||||||
isVisible = false
|
isVisible = false
|
||||||
} else {
|
} else {
|
||||||
isVisible = true
|
isVisible = true
|
||||||
@ -177,7 +177,7 @@ class KeysBackupBanner @JvmOverloads constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun renderUpdate(version: String) {
|
private fun renderUpdate(version: String) {
|
||||||
if (version == PreferenceManager.getDefaultSharedPreferences(context).getString(BANNER_UPDATE_DO_NOT_SHOW_FOR_VERSION, null)) {
|
if (version == DefaultSharedPreferences.getInstance(context).getString(BANNER_UPDATE_DO_NOT_SHOW_FOR_VERSION, null)) {
|
||||||
isVisible = false
|
isVisible = false
|
||||||
} else {
|
} else {
|
||||||
isVisible = true
|
isVisible = true
|
||||||
@ -258,7 +258,7 @@ class KeysBackupBanner @JvmOverloads constructor(
|
|||||||
* Inform the banner that a Recover has been done for this version, so do not show the Recover banner for this version
|
* Inform the banner that a Recover has been done for this version, so do not show the Recover banner for this version
|
||||||
*/
|
*/
|
||||||
fun onRecoverDoneForVersion(context: Context, version: String) {
|
fun onRecoverDoneForVersion(context: Context, version: String) {
|
||||||
PreferenceManager.getDefaultSharedPreferences(context).edit {
|
DefaultSharedPreferences.getInstance(context).edit {
|
||||||
putString(BANNER_RECOVER_DO_NOT_SHOW_FOR_VERSION, version)
|
putString(BANNER_RECOVER_DO_NOT_SHOW_FOR_VERSION, version)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -21,7 +21,7 @@ import android.media.Ringtone
|
|||||||
import android.media.RingtoneManager
|
import android.media.RingtoneManager
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import androidx.core.content.edit
|
import androidx.core.content.edit
|
||||||
import androidx.preference.PreferenceManager
|
import im.vector.app.core.di.DefaultSharedPreferences
|
||||||
import im.vector.app.features.settings.VectorPreferences
|
import im.vector.app.features.settings.VectorPreferences
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -40,7 +40,7 @@ import im.vector.app.features.settings.VectorPreferences
|
|||||||
* @see Ringtone
|
* @see Ringtone
|
||||||
*/
|
*/
|
||||||
fun getCallRingtoneUri(context: Context): Uri? {
|
fun getCallRingtoneUri(context: Context): Uri? {
|
||||||
val callRingtone: String? = PreferenceManager.getDefaultSharedPreferences(context)
|
val callRingtone: String? = DefaultSharedPreferences.getInstance(context)
|
||||||
.getString(VectorPreferences.SETTINGS_CALL_RINGTONE_URI_PREFERENCE_KEY, null)
|
.getString(VectorPreferences.SETTINGS_CALL_RINGTONE_URI_PREFERENCE_KEY, null)
|
||||||
|
|
||||||
callRingtone?.let {
|
callRingtone?.let {
|
||||||
@ -94,7 +94,7 @@ fun getCallRingtoneName(context: Context): String? {
|
|||||||
* @see Ringtone
|
* @see Ringtone
|
||||||
*/
|
*/
|
||||||
fun setCallRingtoneUri(context: Context, ringtoneUri: Uri) {
|
fun setCallRingtoneUri(context: Context, ringtoneUri: Uri) {
|
||||||
PreferenceManager.getDefaultSharedPreferences(context)
|
DefaultSharedPreferences.getInstance(context)
|
||||||
.edit {
|
.edit {
|
||||||
putString(VectorPreferences.SETTINGS_CALL_RINGTONE_URI_PREFERENCE_KEY, ringtoneUri.toString())
|
putString(VectorPreferences.SETTINGS_CALL_RINGTONE_URI_PREFERENCE_KEY, ringtoneUri.toString())
|
||||||
}
|
}
|
||||||
@ -104,14 +104,14 @@ fun setCallRingtoneUri(context: Context, ringtoneUri: Uri) {
|
|||||||
* Set using Riot default ringtone
|
* Set using Riot default ringtone
|
||||||
*/
|
*/
|
||||||
fun useRiotDefaultRingtone(context: Context): Boolean {
|
fun useRiotDefaultRingtone(context: Context): Boolean {
|
||||||
return PreferenceManager.getDefaultSharedPreferences(context).getBoolean(VectorPreferences.SETTINGS_CALL_RINGTONE_USE_RIOT_PREFERENCE_KEY, true)
|
return DefaultSharedPreferences.getInstance(context).getBoolean(VectorPreferences.SETTINGS_CALL_RINGTONE_USE_RIOT_PREFERENCE_KEY, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ask if default Riot ringtone has to be used
|
* Ask if default Riot ringtone has to be used
|
||||||
*/
|
*/
|
||||||
fun setUseRiotDefaultRingtone(context: Context, useRiotDefault: Boolean) {
|
fun setUseRiotDefaultRingtone(context: Context, useRiotDefault: Boolean) {
|
||||||
PreferenceManager.getDefaultSharedPreferences(context)
|
DefaultSharedPreferences.getInstance(context)
|
||||||
.edit {
|
.edit {
|
||||||
putBoolean(VectorPreferences.SETTINGS_CALL_RINGTONE_USE_RIOT_PREFERENCE_KEY, useRiotDefault)
|
putBoolean(VectorPreferences.SETTINGS_CALL_RINGTONE_USE_RIOT_PREFERENCE_KEY, useRiotDefault)
|
||||||
}
|
}
|
||||||
|
@ -20,8 +20,8 @@ import android.app.Activity
|
|||||||
import android.content.Context
|
import android.content.Context
|
||||||
import androidx.appcompat.app.AlertDialog
|
import androidx.appcompat.app.AlertDialog
|
||||||
import androidx.core.content.edit
|
import androidx.core.content.edit
|
||||||
import androidx.preference.PreferenceManager
|
|
||||||
import im.vector.app.R
|
import im.vector.app.R
|
||||||
|
import im.vector.app.core.di.DefaultSharedPreferences
|
||||||
import im.vector.app.core.utils.openUrlInChromeCustomTab
|
import im.vector.app.core.utils.openUrlInChromeCustomTab
|
||||||
import im.vector.app.features.settings.VectorSettingsUrls
|
import im.vector.app.features.settings.VectorSettingsUrls
|
||||||
|
|
||||||
@ -31,7 +31,7 @@ private const val CURRENT_DISCLAIMER_VALUE = 2
|
|||||||
private const val SHARED_PREF_KEY = "LAST_DISCLAIMER_VERSION_VALUE"
|
private const val SHARED_PREF_KEY = "LAST_DISCLAIMER_VERSION_VALUE"
|
||||||
|
|
||||||
fun showDisclaimerDialog(activity: Activity) {
|
fun showDisclaimerDialog(activity: Activity) {
|
||||||
val sharedPrefs = PreferenceManager.getDefaultSharedPreferences(activity)
|
val sharedPrefs = DefaultSharedPreferences.getInstance(activity)
|
||||||
|
|
||||||
if (sharedPrefs.getInt(SHARED_PREF_KEY, 0) < CURRENT_DISCLAIMER_VALUE) {
|
if (sharedPrefs.getInt(SHARED_PREF_KEY, 0) < CURRENT_DISCLAIMER_VALUE) {
|
||||||
sharedPrefs.edit {
|
sharedPrefs.edit {
|
||||||
@ -52,7 +52,7 @@ fun showDisclaimerDialog(activity: Activity) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun doNotShowDisclaimerDialog(context: Context) {
|
fun doNotShowDisclaimerDialog(context: Context) {
|
||||||
val sharedPrefs = PreferenceManager.getDefaultSharedPreferences(context)
|
val sharedPrefs = DefaultSharedPreferences.getInstance(context)
|
||||||
|
|
||||||
sharedPrefs.edit {
|
sharedPrefs.edit {
|
||||||
putInt(SHARED_PREF_KEY, CURRENT_DISCLAIMER_VALUE)
|
putInt(SHARED_PREF_KEY, CURRENT_DISCLAIMER_VALUE)
|
||||||
|
@ -896,13 +896,15 @@ class RoomDetailViewModel @AssistedInject constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun handleEventVisible(action: RoomDetailAction.TimelineEventTurnsVisible) {
|
private fun handleEventVisible(action: RoomDetailAction.TimelineEventTurnsVisible) {
|
||||||
if (action.event.root.sendState.isSent()) { // ignore pending/local events
|
viewModelScope.launch(Dispatchers.Default) {
|
||||||
visibleEventsObservable.accept(action)
|
if (action.event.root.sendState.isSent()) { // ignore pending/local events
|
||||||
}
|
visibleEventsObservable.accept(action)
|
||||||
// We need to update this with the related m.replace also (to move read receipt)
|
}
|
||||||
action.event.annotations?.editSummary?.sourceEvents?.forEach {
|
// We need to update this with the related m.replace also (to move read receipt)
|
||||||
room.getTimeLineEvent(it)?.let { event ->
|
action.event.annotations?.editSummary?.sourceEvents?.forEach {
|
||||||
visibleEventsObservable.accept(RoomDetailAction.TimelineEventTurnsVisible(event))
|
room.getTimeLineEvent(it)?.let { event ->
|
||||||
|
visibleEventsObservable.accept(RoomDetailAction.TimelineEventTurnsVisible(event))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -50,7 +50,7 @@ abstract class MessageImageVideoItem : AbsMessageItem<MessageImageVideoItem.Hold
|
|||||||
super.bind(holder)
|
super.bind(holder)
|
||||||
imageContentRenderer.render(mediaData, mode, holder.imageView)
|
imageContentRenderer.render(mediaData, mode, holder.imageView)
|
||||||
if (!attributes.informationData.sendState.hasFailed()) {
|
if (!attributes.informationData.sendState.hasFailed()) {
|
||||||
contentUploadStateTrackerBinder.bind(attributes.informationData.eventId, mediaData.isLocalFile(), holder.progressLayout)
|
contentUploadStateTrackerBinder.bind(attributes.informationData.eventId, mediaData.isLocalFile, holder.progressLayout)
|
||||||
} else {
|
} else {
|
||||||
holder.progressLayout.isVisible = false
|
holder.progressLayout.isVisible = false
|
||||||
}
|
}
|
||||||
|
@ -18,8 +18,8 @@ package im.vector.app.features.homeserver
|
|||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import androidx.core.content.edit
|
import androidx.core.content.edit
|
||||||
import androidx.preference.PreferenceManager
|
|
||||||
import im.vector.app.R
|
import im.vector.app.R
|
||||||
|
import im.vector.app.core.di.DefaultSharedPreferences
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Object to store and retrieve home and identity server urls
|
* Object to store and retrieve home and identity server urls
|
||||||
@ -38,7 +38,7 @@ object ServerUrlsRepository {
|
|||||||
* Save home and identity sever urls received by the Referrer receiver
|
* Save home and identity sever urls received by the Referrer receiver
|
||||||
*/
|
*/
|
||||||
fun setDefaultUrlsFromReferrer(context: Context, homeServerUrl: String, identityServerUrl: String) {
|
fun setDefaultUrlsFromReferrer(context: Context, homeServerUrl: String, identityServerUrl: String) {
|
||||||
PreferenceManager.getDefaultSharedPreferences(context)
|
DefaultSharedPreferences.getInstance(context)
|
||||||
.edit {
|
.edit {
|
||||||
if (homeServerUrl.isNotEmpty()) {
|
if (homeServerUrl.isNotEmpty()) {
|
||||||
putString(DEFAULT_REFERRER_HOME_SERVER_URL_PREF, homeServerUrl)
|
putString(DEFAULT_REFERRER_HOME_SERVER_URL_PREF, homeServerUrl)
|
||||||
@ -54,7 +54,7 @@ object ServerUrlsRepository {
|
|||||||
* Save home and identity sever urls entered by the user. May be custom or default value
|
* Save home and identity sever urls entered by the user. May be custom or default value
|
||||||
*/
|
*/
|
||||||
fun saveServerUrls(context: Context, homeServerUrl: String, identityServerUrl: String) {
|
fun saveServerUrls(context: Context, homeServerUrl: String, identityServerUrl: String) {
|
||||||
PreferenceManager.getDefaultSharedPreferences(context)
|
DefaultSharedPreferences.getInstance(context)
|
||||||
.edit {
|
.edit {
|
||||||
putString(HOME_SERVER_URL_PREF, homeServerUrl)
|
putString(HOME_SERVER_URL_PREF, homeServerUrl)
|
||||||
putString(IDENTITY_SERVER_URL_PREF, identityServerUrl)
|
putString(IDENTITY_SERVER_URL_PREF, identityServerUrl)
|
||||||
@ -65,7 +65,7 @@ object ServerUrlsRepository {
|
|||||||
* Return last used home server url, or the default one from referrer or the default one from resources
|
* Return last used home server url, or the default one from referrer or the default one from resources
|
||||||
*/
|
*/
|
||||||
fun getLastHomeServerUrl(context: Context): String {
|
fun getLastHomeServerUrl(context: Context): String {
|
||||||
val prefs = PreferenceManager.getDefaultSharedPreferences(context)
|
val prefs = DefaultSharedPreferences.getInstance(context)
|
||||||
|
|
||||||
return prefs.getString(HOME_SERVER_URL_PREF,
|
return prefs.getString(HOME_SERVER_URL_PREF,
|
||||||
prefs.getString(DEFAULT_REFERRER_HOME_SERVER_URL_PREF,
|
prefs.getString(DEFAULT_REFERRER_HOME_SERVER_URL_PREF,
|
||||||
|
@ -36,9 +36,9 @@ import im.vector.app.core.glide.GlideRequest
|
|||||||
import im.vector.app.core.ui.model.Size
|
import im.vector.app.core.ui.model.Size
|
||||||
import im.vector.app.core.utils.DimensionConverter
|
import im.vector.app.core.utils.DimensionConverter
|
||||||
import im.vector.app.core.utils.isLocalFile
|
import im.vector.app.core.utils.isLocalFile
|
||||||
|
import kotlinx.android.parcel.Parcelize
|
||||||
import org.matrix.android.sdk.api.session.content.ContentUrlResolver
|
import org.matrix.android.sdk.api.session.content.ContentUrlResolver
|
||||||
import org.matrix.android.sdk.internal.crypto.attachments.ElementToDecrypt
|
import org.matrix.android.sdk.internal.crypto.attachments.ElementToDecrypt
|
||||||
import kotlinx.android.parcel.Parcelize
|
|
||||||
import org.matrix.android.sdk.api.extensions.tryThis
|
import org.matrix.android.sdk.api.extensions.tryThis
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import java.io.File
|
import java.io.File
|
||||||
@ -69,12 +69,10 @@ class ImageContentRenderer @Inject constructor(private val activeSessionHolder:
|
|||||||
val maxHeight: Int,
|
val maxHeight: Int,
|
||||||
val width: Int?,
|
val width: Int?,
|
||||||
val maxWidth: Int,
|
val maxWidth: Int,
|
||||||
|
val isLocalFile: Boolean = url.isLocalFile(),
|
||||||
// If true will load non mxc url, be careful to set it only for images sent by you
|
// If true will load non mxc url, be careful to set it only for images sent by you
|
||||||
override val allowNonMxcUrls: Boolean = false
|
override val allowNonMxcUrls: Boolean = false
|
||||||
) : AttachmentData {
|
) : AttachmentData
|
||||||
|
|
||||||
fun isLocalFile() = url.isLocalFile()
|
|
||||||
}
|
|
||||||
|
|
||||||
enum class Mode {
|
enum class Mode {
|
||||||
FULL_SIZE,
|
FULL_SIZE,
|
||||||
@ -268,7 +266,7 @@ class ImageContentRenderer @Inject constructor(private val activeSessionHolder:
|
|||||||
|
|
||||||
private fun resolveUrl(data: Data) =
|
private fun resolveUrl(data: Data) =
|
||||||
(activeSessionHolder.getActiveSession().contentUrlResolver().resolveFullSize(data.url)
|
(activeSessionHolder.getActiveSession().contentUrlResolver().resolveFullSize(data.url)
|
||||||
?: data.url?.takeIf { data.isLocalFile() && data.allowNonMxcUrls })
|
?: data.url?.takeIf { data.isLocalFile && data.allowNonMxcUrls })
|
||||||
|
|
||||||
private fun processSize(data: Data, mode: Mode): Size {
|
private fun processSize(data: Data, mode: Mode): Size {
|
||||||
val maxImageWidth = data.maxWidth
|
val maxImageWidth = data.maxWidth
|
||||||
|
@ -19,6 +19,9 @@ package im.vector.app.features.rageshake
|
|||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import im.vector.app.features.settings.VectorPreferences
|
import im.vector.app.features.settings.VectorPreferences
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.GlobalScope
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.io.PrintWriter
|
import java.io.PrintWriter
|
||||||
@ -85,12 +88,14 @@ class VectorFileLogger @Inject constructor(val context: Context, private val vec
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun log(priority: Int, tag: String?, message: String, t: Throwable?) {
|
override fun log(priority: Int, tag: String?, message: String, t: Throwable?) {
|
||||||
if (sFileHandler == null) return
|
GlobalScope.launch(Dispatchers.IO) {
|
||||||
if (skipLog(priority)) return
|
if (sFileHandler == null) return@launch
|
||||||
if (t != null) {
|
if (skipLog(priority)) return@launch
|
||||||
logToFile(t)
|
if (t != null) {
|
||||||
|
logToFile(t)
|
||||||
|
}
|
||||||
|
logToFile(prioPrefixes[priority] ?: "$priority ", tag ?: "Tag", message)
|
||||||
}
|
}
|
||||||
logToFile(prioPrefixes[priority] ?: "$priority ", tag ?: "Tag", message)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun skipLog(priority: Int): Boolean {
|
private fun skipLog(priority: Int): Boolean {
|
||||||
@ -174,7 +179,8 @@ class VectorFileLogger @Inject constructor(val context: Context, private val vec
|
|||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private val LINE_SEPARATOR = System.getProperty("line.separator") ?: "\n"
|
private val LINE_SEPARATOR = System.getProperty("line.separator") ?: "\n"
|
||||||
// private val DATE_FORMAT = SimpleDateFormat("MM-dd HH:mm:ss.SSS", Locale.US)
|
|
||||||
|
// private val DATE_FORMAT = SimpleDateFormat("MM-dd HH:mm:ss.SSS", Locale.US)
|
||||||
private val DATE_FORMAT = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss*SSSZZZZ", Locale.US)
|
private val DATE_FORMAT = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss*SSSZZZZ", Locale.US)
|
||||||
|
|
||||||
private var mIsTimeZoneSet = false
|
private var mIsTimeZoneSet = false
|
||||||
@ -201,7 +207,6 @@ class VectorFileLogger @Inject constructor(val context: Context, private val vec
|
|||||||
if (null == sCacheDirectory) {
|
if (null == sCacheDirectory) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
val b = StringBuilder()
|
val b = StringBuilder()
|
||||||
b.append(Thread.currentThread().id)
|
b.append(Thread.currentThread().id)
|
||||||
b.append(" ")
|
b.append(" ")
|
||||||
|
@ -19,7 +19,7 @@ package im.vector.app.features.rageshake
|
|||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import androidx.core.content.edit
|
import androidx.core.content.edit
|
||||||
import androidx.preference.PreferenceManager
|
import im.vector.app.core.di.DefaultSharedPreferences
|
||||||
import im.vector.app.core.resources.VersionCodeProvider
|
import im.vector.app.core.resources.VersionCodeProvider
|
||||||
import im.vector.app.features.version.VersionProvider
|
import im.vector.app.features.version.VersionProvider
|
||||||
import org.matrix.android.sdk.api.Matrix
|
import org.matrix.android.sdk.api.Matrix
|
||||||
@ -61,7 +61,7 @@ class VectorUncaughtExceptionHandler @Inject constructor(private val bugReporter
|
|||||||
*/
|
*/
|
||||||
override fun uncaughtException(thread: Thread, throwable: Throwable) {
|
override fun uncaughtException(thread: Thread, throwable: Throwable) {
|
||||||
Timber.v("Uncaught exception: $throwable")
|
Timber.v("Uncaught exception: $throwable")
|
||||||
PreferenceManager.getDefaultSharedPreferences(context).edit {
|
DefaultSharedPreferences.getInstance(context).edit {
|
||||||
putBoolean(PREFS_CRASH_KEY, true)
|
putBoolean(PREFS_CRASH_KEY, true)
|
||||||
}
|
}
|
||||||
val b = StringBuilder()
|
val b = StringBuilder()
|
||||||
@ -115,7 +115,7 @@ class VectorUncaughtExceptionHandler @Inject constructor(private val bugReporter
|
|||||||
* @return true if the application crashed
|
* @return true if the application crashed
|
||||||
*/
|
*/
|
||||||
fun didAppCrash(context: Context): Boolean {
|
fun didAppCrash(context: Context): Boolean {
|
||||||
return PreferenceManager.getDefaultSharedPreferences(context)
|
return DefaultSharedPreferences.getInstance(context)
|
||||||
.getBoolean(PREFS_CRASH_KEY, false)
|
.getBoolean(PREFS_CRASH_KEY, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -123,7 +123,7 @@ class VectorUncaughtExceptionHandler @Inject constructor(private val bugReporter
|
|||||||
* Clear the crash status
|
* Clear the crash status
|
||||||
*/
|
*/
|
||||||
fun clearAppCrashStatus(context: Context) {
|
fun clearAppCrashStatus(context: Context) {
|
||||||
PreferenceManager.getDefaultSharedPreferences(context).edit {
|
DefaultSharedPreferences.getInstance(context).edit {
|
||||||
remove(PREFS_CRASH_KEY)
|
remove(PREFS_CRASH_KEY)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,14 @@ import com.airbnb.mvrx.MvRxViewModelFactory
|
|||||||
import com.airbnb.mvrx.ViewModelContext
|
import com.airbnb.mvrx.ViewModelContext
|
||||||
import com.squareup.inject.assisted.Assisted
|
import com.squareup.inject.assisted.Assisted
|
||||||
import com.squareup.inject.assisted.AssistedInject
|
import com.squareup.inject.assisted.AssistedInject
|
||||||
|
import im.vector.app.core.extensions.exhaustive
|
||||||
|
import im.vector.app.core.platform.EmptyViewEvents
|
||||||
|
import im.vector.app.core.platform.VectorViewModel
|
||||||
|
import im.vector.app.features.powerlevel.PowerLevelsObservableFactory
|
||||||
|
import io.reactivex.Observable
|
||||||
|
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||||
|
import io.reactivex.functions.BiFunction
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
import org.matrix.android.sdk.api.NoOpMatrixCallback
|
import org.matrix.android.sdk.api.NoOpMatrixCallback
|
||||||
import org.matrix.android.sdk.api.crypto.RoomEncryptionTrustLevel
|
import org.matrix.android.sdk.api.crypto.RoomEncryptionTrustLevel
|
||||||
import org.matrix.android.sdk.api.extensions.orFalse
|
import org.matrix.android.sdk.api.extensions.orFalse
|
||||||
@ -39,14 +47,6 @@ import org.matrix.android.sdk.rx.asObservable
|
|||||||
import org.matrix.android.sdk.rx.mapOptional
|
import org.matrix.android.sdk.rx.mapOptional
|
||||||
import org.matrix.android.sdk.rx.rx
|
import org.matrix.android.sdk.rx.rx
|
||||||
import org.matrix.android.sdk.rx.unwrap
|
import org.matrix.android.sdk.rx.unwrap
|
||||||
import im.vector.app.core.extensions.exhaustive
|
|
||||||
import im.vector.app.core.platform.EmptyViewEvents
|
|
||||||
import im.vector.app.core.platform.VectorViewModel
|
|
||||||
import im.vector.app.features.powerlevel.PowerLevelsObservableFactory
|
|
||||||
import io.reactivex.Observable
|
|
||||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
|
||||||
import io.reactivex.functions.BiFunction
|
|
||||||
import kotlinx.coroutines.launch
|
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
|
|
||||||
class RoomMemberListViewModel @AssistedInject constructor(@Assisted initialState: RoomMemberListViewState,
|
class RoomMemberListViewModel @AssistedInject constructor(@Assisted initialState: RoomMemberListViewState,
|
||||||
|
@ -19,8 +19,8 @@ package im.vector.app.features.settings
|
|||||||
import android.content.Context
|
import android.content.Context
|
||||||
import androidx.annotation.StringRes
|
import androidx.annotation.StringRes
|
||||||
import androidx.core.content.edit
|
import androidx.core.content.edit
|
||||||
import androidx.preference.PreferenceManager
|
|
||||||
import im.vector.app.R
|
import im.vector.app.R
|
||||||
|
import im.vector.app.core.di.DefaultSharedPreferences
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Object to manage the Font Scale choice of the user
|
* Object to manage the Font Scale choice of the user
|
||||||
@ -56,7 +56,7 @@ object FontScale {
|
|||||||
* @return the font scale value
|
* @return the font scale value
|
||||||
*/
|
*/
|
||||||
fun getFontScaleValue(context: Context): FontScaleValue {
|
fun getFontScaleValue(context: Context): FontScaleValue {
|
||||||
val preferences = PreferenceManager.getDefaultSharedPreferences(context)
|
val preferences = DefaultSharedPreferences.getInstance(context)
|
||||||
|
|
||||||
return if (APPLICATION_FONT_SCALE_KEY !in preferences) {
|
return if (APPLICATION_FONT_SCALE_KEY !in preferences) {
|
||||||
val fontScale = context.resources.configuration.fontScale
|
val fontScale = context.resources.configuration.fontScale
|
||||||
@ -81,7 +81,7 @@ object FontScale {
|
|||||||
* @param fontScaleValue the font scale value to store
|
* @param fontScaleValue the font scale value to store
|
||||||
*/
|
*/
|
||||||
private fun saveFontScaleValue(context: Context, fontScaleValue: FontScaleValue) {
|
private fun saveFontScaleValue(context: Context, fontScaleValue: FontScaleValue) {
|
||||||
PreferenceManager.getDefaultSharedPreferences(context)
|
DefaultSharedPreferences.getInstance(context)
|
||||||
.edit { putString(APPLICATION_FONT_SCALE_KEY, fontScaleValue.preferenceValue) }
|
.edit { putString(APPLICATION_FONT_SCALE_KEY, fontScaleValue.preferenceValue) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,9 +19,9 @@ package im.vector.app.features.settings
|
|||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.res.Configuration
|
import android.content.res.Configuration
|
||||||
import androidx.core.content.edit
|
import androidx.core.content.edit
|
||||||
import androidx.preference.PreferenceManager
|
|
||||||
import im.vector.app.BuildConfig
|
import im.vector.app.BuildConfig
|
||||||
import im.vector.app.R
|
import im.vector.app.R
|
||||||
|
import im.vector.app.core.di.DefaultSharedPreferences
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
@ -59,7 +59,7 @@ object VectorLocale {
|
|||||||
*/
|
*/
|
||||||
fun init(context: Context) {
|
fun init(context: Context) {
|
||||||
this.context = context
|
this.context = context
|
||||||
val preferences = PreferenceManager.getDefaultSharedPreferences(context)
|
val preferences = DefaultSharedPreferences.getInstance(context)
|
||||||
|
|
||||||
if (preferences.contains(APPLICATION_LOCALE_LANGUAGE_KEY)) {
|
if (preferences.contains(APPLICATION_LOCALE_LANGUAGE_KEY)) {
|
||||||
applicationLocale = Locale(preferences.getString(APPLICATION_LOCALE_LANGUAGE_KEY, "")!!,
|
applicationLocale = Locale(preferences.getString(APPLICATION_LOCALE_LANGUAGE_KEY, "")!!,
|
||||||
@ -85,7 +85,7 @@ object VectorLocale {
|
|||||||
fun saveApplicationLocale(locale: Locale) {
|
fun saveApplicationLocale(locale: Locale) {
|
||||||
applicationLocale = locale
|
applicationLocale = locale
|
||||||
|
|
||||||
PreferenceManager.getDefaultSharedPreferences(context).edit {
|
DefaultSharedPreferences.getInstance(context).edit {
|
||||||
val language = locale.language
|
val language = locale.language
|
||||||
if (language.isEmpty()) {
|
if (language.isEmpty()) {
|
||||||
remove(APPLICATION_LOCALE_LANGUAGE_KEY)
|
remove(APPLICATION_LOCALE_LANGUAGE_KEY)
|
||||||
|
@ -22,10 +22,10 @@ import android.media.RingtoneManager
|
|||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import android.provider.MediaStore
|
import android.provider.MediaStore
|
||||||
import androidx.core.content.edit
|
import androidx.core.content.edit
|
||||||
import androidx.preference.PreferenceManager
|
|
||||||
import com.squareup.seismic.ShakeDetector
|
import com.squareup.seismic.ShakeDetector
|
||||||
import im.vector.app.BuildConfig
|
import im.vector.app.BuildConfig
|
||||||
import im.vector.app.R
|
import im.vector.app.R
|
||||||
|
import im.vector.app.core.di.DefaultSharedPreferences
|
||||||
import im.vector.app.features.homeserver.ServerUrlsRepository
|
import im.vector.app.features.homeserver.ServerUrlsRepository
|
||||||
import im.vector.app.features.themes.ThemeUtils
|
import im.vector.app.features.themes.ThemeUtils
|
||||||
import org.matrix.android.sdk.api.extensions.tryThis
|
import org.matrix.android.sdk.api.extensions.tryThis
|
||||||
@ -227,7 +227,7 @@ class VectorPreferences @Inject constructor(private val context: Context) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private val defaultPrefs = PreferenceManager.getDefaultSharedPreferences(context)
|
private val defaultPrefs = DefaultSharedPreferences.getInstance(context)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clear the preferences.
|
* Clear the preferences.
|
||||||
|
@ -25,9 +25,10 @@ import androidx.annotation.AttrRes
|
|||||||
import androidx.annotation.ColorInt
|
import androidx.annotation.ColorInt
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import androidx.core.graphics.drawable.DrawableCompat
|
import androidx.core.graphics.drawable.DrawableCompat
|
||||||
import androidx.preference.PreferenceManager
|
|
||||||
import im.vector.app.R
|
import im.vector.app.R
|
||||||
|
import im.vector.app.core.di.DefaultSharedPreferences
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
|
import java.util.concurrent.atomic.AtomicReference
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Util class for managing themes.
|
* Util class for managing themes.
|
||||||
@ -42,6 +43,8 @@ object ThemeUtils {
|
|||||||
private const val THEME_BLACK_VALUE = "black"
|
private const val THEME_BLACK_VALUE = "black"
|
||||||
private const val THEME_STATUS_VALUE = "status"
|
private const val THEME_STATUS_VALUE = "status"
|
||||||
|
|
||||||
|
private var currentTheme = AtomicReference<String>(null)
|
||||||
|
|
||||||
private val mColorByAttr = HashMap<Int, Int>()
|
private val mColorByAttr = HashMap<Int, Int>()
|
||||||
|
|
||||||
// init the theme
|
// init the theme
|
||||||
@ -68,8 +71,15 @@ object ThemeUtils {
|
|||||||
* @return the selected application theme
|
* @return the selected application theme
|
||||||
*/
|
*/
|
||||||
fun getApplicationTheme(context: Context): String {
|
fun getApplicationTheme(context: Context): String {
|
||||||
return PreferenceManager.getDefaultSharedPreferences(context)
|
val currentTheme = this.currentTheme.get()
|
||||||
.getString(APPLICATION_THEME_KEY, THEME_LIGHT_VALUE) ?: THEME_LIGHT_VALUE
|
return if (currentTheme == null) {
|
||||||
|
val themeFromPref = DefaultSharedPreferences.getInstance(context)
|
||||||
|
.getString(APPLICATION_THEME_KEY, THEME_LIGHT_VALUE) ?: THEME_LIGHT_VALUE
|
||||||
|
this.currentTheme.set(themeFromPref)
|
||||||
|
themeFromPref
|
||||||
|
} else {
|
||||||
|
currentTheme
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -78,6 +88,7 @@ object ThemeUtils {
|
|||||||
* @param aTheme the new theme
|
* @param aTheme the new theme
|
||||||
*/
|
*/
|
||||||
fun setApplicationTheme(context: Context, aTheme: String) {
|
fun setApplicationTheme(context: Context, aTheme: String) {
|
||||||
|
currentTheme.set(aTheme)
|
||||||
when (aTheme) {
|
when (aTheme) {
|
||||||
THEME_DARK_VALUE -> context.setTheme(R.style.AppTheme_Dark)
|
THEME_DARK_VALUE -> context.setTheme(R.style.AppTheme_Dark)
|
||||||
THEME_BLACK_VALUE -> context.setTheme(R.style.AppTheme_Black)
|
THEME_BLACK_VALUE -> context.setTheme(R.style.AppTheme_Black)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user