Merge branch 'feature/fix_issues' into develop
This commit is contained in:
commit
9ff24cbf2a
@ -21,23 +21,24 @@ import im.vector.matrix.android.api.session.room.model.EventAnnotationsSummary
|
|||||||
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.timeline.TimelineEvent
|
import im.vector.matrix.android.api.session.room.timeline.TimelineEvent
|
||||||
import io.reactivex.Observable
|
import io.reactivex.Observable
|
||||||
|
import io.reactivex.schedulers.Schedulers
|
||||||
|
|
||||||
class RxRoom(private val room: Room) {
|
class RxRoom(private val room: Room) {
|
||||||
|
|
||||||
fun liveRoomSummary(fetchLastEvent: Boolean): Observable<RoomSummary> {
|
fun liveRoomSummary(fetchLastEvent: Boolean): Observable<RoomSummary> {
|
||||||
return room.liveRoomSummary(fetchLastEvent).asObservable()
|
return room.liveRoomSummary(fetchLastEvent).asObservable().observeOn(Schedulers.computation())
|
||||||
}
|
}
|
||||||
|
|
||||||
fun liveRoomMemberIds(): Observable<List<String>> {
|
fun liveRoomMemberIds(): Observable<List<String>> {
|
||||||
return room.getRoomMemberIdsLive().asObservable()
|
return room.getRoomMemberIdsLive().asObservable().observeOn(Schedulers.computation())
|
||||||
}
|
}
|
||||||
|
|
||||||
fun liveAnnotationSummary(eventId: String): Observable<EventAnnotationsSummary> {
|
fun liveAnnotationSummary(eventId: String): Observable<EventAnnotationsSummary> {
|
||||||
return room.getEventSummaryLive(eventId).asObservable()
|
return room.getEventSummaryLive(eventId).asObservable().observeOn(Schedulers.computation())
|
||||||
}
|
}
|
||||||
|
|
||||||
fun liveTimelineEvent(eventId: String): Observable<TimelineEvent> {
|
fun liveTimelineEvent(eventId: String): Observable<TimelineEvent> {
|
||||||
return room.liveTimeLineEvent(eventId).asObservable()
|
return room.liveTimeLineEvent(eventId).asObservable().observeOn(Schedulers.computation())
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -22,23 +22,24 @@ import im.vector.matrix.android.api.session.pushers.Pusher
|
|||||||
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.sync.SyncState
|
import im.vector.matrix.android.api.session.sync.SyncState
|
||||||
import io.reactivex.Observable
|
import io.reactivex.Observable
|
||||||
|
import io.reactivex.schedulers.Schedulers
|
||||||
|
|
||||||
class RxSession(private val session: Session) {
|
class RxSession(private val session: Session) {
|
||||||
|
|
||||||
fun liveRoomSummaries(fetchLastEvents: Boolean): Observable<List<RoomSummary>> {
|
fun liveRoomSummaries(fetchLastEvents: Boolean): Observable<List<RoomSummary>> {
|
||||||
return session.liveRoomSummaries(fetchLastEvents).asObservable()
|
return session.liveRoomSummaries(fetchLastEvents).asObservable().observeOn(Schedulers.computation())
|
||||||
}
|
}
|
||||||
|
|
||||||
fun liveGroupSummaries(): Observable<List<GroupSummary>> {
|
fun liveGroupSummaries(): Observable<List<GroupSummary>> {
|
||||||
return session.liveGroupSummaries().asObservable()
|
return session.liveGroupSummaries().asObservable().observeOn(Schedulers.computation())
|
||||||
}
|
}
|
||||||
|
|
||||||
fun liveSyncState(): Observable<SyncState> {
|
fun liveSyncState(): Observable<SyncState> {
|
||||||
return session.syncState().asObservable()
|
return session.syncState().asObservable().observeOn(Schedulers.computation())
|
||||||
}
|
}
|
||||||
|
|
||||||
fun livePushers(): Observable<List<Pusher>> {
|
fun livePushers(): Observable<List<Pusher>> {
|
||||||
return session.livePushers().asObservable()
|
return session.livePushers().asObservable().observeOn(Schedulers.computation())
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,10 @@
|
|||||||
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.util.createBackgroundHandler
|
||||||
import io.realm.OrderedCollectionChangeSet
|
import io.realm.OrderedCollectionChangeSet
|
||||||
|
import io.realm.Realm
|
||||||
|
import io.realm.RealmConfiguration
|
||||||
import io.realm.RealmObject
|
import io.realm.RealmObject
|
||||||
import io.realm.RealmResults
|
import io.realm.RealmResults
|
||||||
import java.util.concurrent.atomic.AtomicBoolean
|
import java.util.concurrent.atomic.AtomicBoolean
|
||||||
@ -29,17 +32,24 @@ internal interface LiveEntityObserver {
|
|||||||
fun isStarted(): Boolean
|
fun isStarted(): Boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
internal abstract class RealmLiveEntityObserver<T : RealmObject>(protected val monarchy: Monarchy)
|
internal abstract class RealmLiveEntityObserver<T : RealmObject>(protected val realmConfiguration: RealmConfiguration)
|
||||||
: LiveEntityObserver {
|
: LiveEntityObserver {
|
||||||
|
|
||||||
|
private companion object {
|
||||||
|
val BACKGROUND_HANDLER = createBackgroundHandler("LIVE_ENTITY_BACKGROUND")
|
||||||
|
}
|
||||||
|
|
||||||
protected abstract val query: Monarchy.Query<T>
|
protected abstract val query: Monarchy.Query<T>
|
||||||
private val isStarted = AtomicBoolean(false)
|
private val isStarted = AtomicBoolean(false)
|
||||||
|
private val backgroundRealm = AtomicReference<Realm>()
|
||||||
private lateinit var results: AtomicReference<RealmResults<T>>
|
private lateinit var results: AtomicReference<RealmResults<T>>
|
||||||
|
|
||||||
override fun start() {
|
override fun start() {
|
||||||
if (isStarted.compareAndSet(false, true)) {
|
if (isStarted.compareAndSet(false, true)) {
|
||||||
monarchy.postToMonarchyThread {
|
BACKGROUND_HANDLER.post {
|
||||||
val queryResults = query.createQuery(it).findAll()
|
val realm = Realm.getInstance(realmConfiguration)
|
||||||
|
backgroundRealm.set(realm)
|
||||||
|
val queryResults = query.createQuery(realm).findAll()
|
||||||
queryResults.addChangeListener { t, changeSet ->
|
queryResults.addChangeListener { t, changeSet ->
|
||||||
onChanged(t, changeSet)
|
onChanged(t, changeSet)
|
||||||
}
|
}
|
||||||
@ -50,8 +60,11 @@ internal abstract class RealmLiveEntityObserver<T : RealmObject>(protected val m
|
|||||||
|
|
||||||
override fun dispose() {
|
override fun dispose() {
|
||||||
if (isStarted.compareAndSet(true, false)) {
|
if (isStarted.compareAndSet(true, false)) {
|
||||||
monarchy.postToMonarchyThread {
|
BACKGROUND_HANDLER.post {
|
||||||
results.getAndSet(null).removeAllChangeListeners()
|
results.getAndSet(null).removeAllChangeListeners()
|
||||||
|
backgroundRealm.getAndSet(null).also {
|
||||||
|
it.close()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,6 +23,7 @@ import android.os.HandlerThread
|
|||||||
import dagger.Module
|
import dagger.Module
|
||||||
import dagger.Provides
|
import dagger.Provides
|
||||||
import im.vector.matrix.android.internal.util.MatrixCoroutineDispatchers
|
import im.vector.matrix.android.internal.util.MatrixCoroutineDispatchers
|
||||||
|
import im.vector.matrix.android.internal.util.createBackgroundHandler
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.android.asCoroutineDispatcher
|
import kotlinx.coroutines.android.asCoroutineDispatcher
|
||||||
import org.matrix.olm.OlmManager
|
import org.matrix.olm.OlmManager
|
||||||
@ -32,15 +33,12 @@ internal object MatrixModule {
|
|||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
@Provides
|
@Provides
|
||||||
|
@MatrixScope
|
||||||
fun providesMatrixCoroutineDispatchers(): MatrixCoroutineDispatchers {
|
fun providesMatrixCoroutineDispatchers(): MatrixCoroutineDispatchers {
|
||||||
val THREAD_CRYPTO_NAME = "Crypto_Thread"
|
|
||||||
val handlerThread = HandlerThread(THREAD_CRYPTO_NAME)
|
|
||||||
handlerThread.start()
|
|
||||||
|
|
||||||
return MatrixCoroutineDispatchers(io = Dispatchers.IO,
|
return MatrixCoroutineDispatchers(io = Dispatchers.IO,
|
||||||
computation = Dispatchers.IO,
|
computation = Dispatchers.IO,
|
||||||
main = Dispatchers.Main,
|
main = Dispatchers.Main,
|
||||||
crypto = Handler(handlerThread.looper).asCoroutineDispatcher("crypto")
|
crypto = createBackgroundHandler("Crypto_Thread").asCoroutineDispatcher()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -50,7 +50,6 @@ import javax.inject.Inject
|
|||||||
internal class DefaultSession @Inject constructor(override val sessionParams: SessionParams,
|
internal class DefaultSession @Inject constructor(override val sessionParams: SessionParams,
|
||||||
private val context: Context,
|
private val context: Context,
|
||||||
private val liveEntityObservers: Set<@JvmSuppressWildcards LiveEntityObserver>,
|
private val liveEntityObservers: Set<@JvmSuppressWildcards LiveEntityObserver>,
|
||||||
private val monarchy: Monarchy,
|
|
||||||
private val sessionListeners: SessionListeners,
|
private val sessionListeners: SessionListeners,
|
||||||
private val roomService: RoomService,
|
private val roomService: RoomService,
|
||||||
private val roomDirectoryService: RoomDirectoryService,
|
private val roomDirectoryService: RoomDirectoryService,
|
||||||
@ -66,16 +65,16 @@ internal class DefaultSession @Inject constructor(override val sessionParams: Se
|
|||||||
private val contentUrlResolver: ContentUrlResolver,
|
private val contentUrlResolver: ContentUrlResolver,
|
||||||
private val contentUploadProgressTracker: ContentUploadStateTracker)
|
private val contentUploadProgressTracker: ContentUploadStateTracker)
|
||||||
: Session,
|
: Session,
|
||||||
RoomService by roomService,
|
RoomService by roomService,
|
||||||
RoomDirectoryService by roomDirectoryService,
|
RoomDirectoryService by roomDirectoryService,
|
||||||
GroupService by groupService,
|
GroupService by groupService,
|
||||||
UserService by userService,
|
UserService by userService,
|
||||||
CryptoService by cryptoService,
|
CryptoService by cryptoService,
|
||||||
CacheService by cacheService,
|
CacheService by cacheService,
|
||||||
SignOutService by signOutService,
|
SignOutService by signOutService,
|
||||||
FilterService by filterService,
|
FilterService by filterService,
|
||||||
PushRuleService by pushRuleService,
|
PushRuleService by pushRuleService,
|
||||||
PushersService by pushersService {
|
PushersService by pushersService {
|
||||||
|
|
||||||
private var isOpen = false
|
private var isOpen = false
|
||||||
|
|
||||||
@ -85,9 +84,6 @@ internal class DefaultSession @Inject constructor(override val sessionParams: Se
|
|||||||
assertMainThread()
|
assertMainThread()
|
||||||
assert(!isOpen)
|
assert(!isOpen)
|
||||||
isOpen = true
|
isOpen = true
|
||||||
if (!monarchy.isMonarchyThreadOpen) {
|
|
||||||
monarchy.openManually()
|
|
||||||
}
|
|
||||||
liveEntityObservers.forEach { it.start() }
|
liveEntityObservers.forEach { it.start() }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -123,9 +119,6 @@ internal class DefaultSession @Inject constructor(override val sessionParams: Se
|
|||||||
stopSync()
|
stopSync()
|
||||||
liveEntityObservers.forEach { it.dispose() }
|
liveEntityObservers.forEach { it.dispose() }
|
||||||
cryptoService.close()
|
cryptoService.close()
|
||||||
if (monarchy.isMonarchyThreadOpen) {
|
|
||||||
monarchy.closeManually()
|
|
||||||
}
|
|
||||||
isOpen = false
|
isOpen = false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,14 +27,16 @@ import im.vector.matrix.android.api.auth.data.Credentials
|
|||||||
import im.vector.matrix.android.internal.database.RealmLiveEntityObserver
|
import im.vector.matrix.android.internal.database.RealmLiveEntityObserver
|
||||||
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.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.worker.WorkerParamsFactory
|
import im.vector.matrix.android.internal.worker.WorkerParamsFactory
|
||||||
|
import io.realm.RealmConfiguration
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
private const val GET_GROUP_DATA_WORKER = "GET_GROUP_DATA_WORKER"
|
private const val GET_GROUP_DATA_WORKER = "GET_GROUP_DATA_WORKER"
|
||||||
|
|
||||||
internal class GroupSummaryUpdater @Inject constructor(private val context: Context,
|
internal class GroupSummaryUpdater @Inject constructor(private val context: Context,
|
||||||
private val credentials: Credentials,
|
private val credentials: Credentials,
|
||||||
monarchy: Monarchy) : RealmLiveEntityObserver<GroupEntity>(monarchy) {
|
@SessionDatabase realmConfiguration: RealmConfiguration) : RealmLiveEntityObserver<GroupEntity>(realmConfiguration) {
|
||||||
|
|
||||||
override val query = Monarchy.Query<GroupEntity> { GroupEntity.where(it) }
|
override val query = Monarchy.Query<GroupEntity> { GroupEntity.where(it) }
|
||||||
|
|
||||||
|
@ -22,8 +22,10 @@ import im.vector.matrix.android.internal.database.RealmLiveEntityObserver
|
|||||||
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.EventEntity
|
import im.vector.matrix.android.internal.database.model.EventEntity
|
||||||
import im.vector.matrix.android.internal.database.query.types
|
import im.vector.matrix.android.internal.database.query.types
|
||||||
|
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.RealmConfiguration
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
@ -33,11 +35,11 @@ import javax.inject.Inject
|
|||||||
* The summaries can then be extracted and added (as a decoration) to a TimelineEvent for final display.
|
* The summaries can then be extracted and added (as a decoration) to a TimelineEvent for final display.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
internal class EventRelationsAggregationUpdater @Inject constructor(monarchy: Monarchy,
|
internal class EventRelationsAggregationUpdater @Inject constructor(@SessionDatabase realmConfiguration: RealmConfiguration,
|
||||||
private val credentials: Credentials,
|
private val credentials: Credentials,
|
||||||
private val task: EventRelationsAggregationTask,
|
private val task: EventRelationsAggregationTask,
|
||||||
private val taskExecutor: TaskExecutor) :
|
private val taskExecutor: TaskExecutor) :
|
||||||
RealmLiveEntityObserver<EventEntity>(monarchy) {
|
RealmLiveEntityObserver<EventEntity>(realmConfiguration) {
|
||||||
|
|
||||||
override val query = Monarchy.Query<EventEntity> {
|
override val query = Monarchy.Query<EventEntity> {
|
||||||
EventEntity.types(it, listOf(
|
EventEntity.types(it, listOf(
|
||||||
|
@ -61,9 +61,8 @@ internal class RoomSummaryUpdater @Inject constructor(private val credentials: C
|
|||||||
membership: Membership? = null,
|
membership: Membership? = null,
|
||||||
roomSummary: RoomSyncSummary? = null,
|
roomSummary: RoomSyncSummary? = null,
|
||||||
unreadNotifications: RoomSyncUnreadNotifications? = null) {
|
unreadNotifications: RoomSyncUnreadNotifications? = null) {
|
||||||
|
|
||||||
val roomSummaryEntity = RoomSummaryEntity.where(realm, roomId).findFirst()
|
val roomSummaryEntity = RoomSummaryEntity.where(realm, roomId).findFirst()
|
||||||
?: realm.createObject(roomId)
|
?: realm.createObject(roomId)
|
||||||
|
|
||||||
if (roomSummary != null) {
|
if (roomSummary != null) {
|
||||||
if (roomSummary.heroes.isNotEmpty()) {
|
if (roomSummary.heroes.isNotEmpty()) {
|
||||||
@ -77,12 +76,9 @@ internal class RoomSummaryUpdater @Inject constructor(private val credentials: C
|
|||||||
roomSummaryEntity.joinedMembersCount = roomSummary.joinedMembersCount
|
roomSummaryEntity.joinedMembersCount = roomSummary.joinedMembersCount
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (unreadNotifications?.highlightCount != null) {
|
roomSummaryEntity.highlightCount = unreadNotifications?.highlightCount ?: 0
|
||||||
roomSummaryEntity.highlightCount = unreadNotifications.highlightCount
|
roomSummaryEntity.notificationCount = unreadNotifications?.notificationCount ?:0
|
||||||
}
|
|
||||||
if (unreadNotifications?.notificationCount != null) {
|
|
||||||
roomSummaryEntity.notificationCount = unreadNotifications.notificationCount
|
|
||||||
}
|
|
||||||
if (membership != null) {
|
if (membership != null) {
|
||||||
roomSummaryEntity.membership = membership
|
roomSummaryEntity.membership = membership
|
||||||
}
|
}
|
||||||
|
@ -23,9 +23,11 @@ import im.vector.matrix.android.internal.database.RealmLiveEntityObserver
|
|||||||
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.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 im.vector.matrix.android.internal.session.SessionScope
|
import im.vector.matrix.android.internal.session.SessionScope
|
||||||
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.RealmConfiguration
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
@ -33,11 +35,11 @@ import javax.inject.Inject
|
|||||||
* Listens to the database for the insertion of any redaction event.
|
* Listens to the database for the insertion of any redaction event.
|
||||||
* As it will actually delete the content, it should be called last in the list of listener.
|
* As it will actually delete the content, it should be called last in the list of listener.
|
||||||
*/
|
*/
|
||||||
internal class EventsPruner @Inject constructor(monarchy: Monarchy,
|
internal class EventsPruner @Inject constructor(@SessionDatabase realmConfiguration: RealmConfiguration,
|
||||||
private val credentials: Credentials,
|
private val credentials: Credentials,
|
||||||
private val pruneEventTask: PruneEventTask,
|
private val pruneEventTask: PruneEventTask,
|
||||||
private val taskExecutor: TaskExecutor) :
|
private val taskExecutor: TaskExecutor) :
|
||||||
RealmLiveEntityObserver<EventEntity>(monarchy) {
|
RealmLiveEntityObserver<EventEntity>(realmConfiguration) {
|
||||||
|
|
||||||
override val query = Monarchy.Query<EventEntity> { EventEntity.where(it, type = EventType.REDACTION) }
|
override val query = Monarchy.Query<EventEntity> { EventEntity.where(it, type = EventType.REDACTION) }
|
||||||
|
|
||||||
|
@ -16,9 +16,6 @@
|
|||||||
|
|
||||||
package im.vector.matrix.android.internal.session.room.timeline
|
package im.vector.matrix.android.internal.session.room.timeline
|
||||||
|
|
||||||
import android.os.Handler
|
|
||||||
import android.os.HandlerThread
|
|
||||||
import android.os.Looper
|
|
||||||
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
|
||||||
@ -43,6 +40,8 @@ import im.vector.matrix.android.internal.database.query.whereInRoom
|
|||||||
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.Debouncer
|
import im.vector.matrix.android.internal.util.Debouncer
|
||||||
|
import im.vector.matrix.android.internal.util.createBackgroundHandler
|
||||||
|
import im.vector.matrix.android.internal.util.createUIHandler
|
||||||
import io.realm.OrderedCollectionChangeSet
|
import io.realm.OrderedCollectionChangeSet
|
||||||
import io.realm.OrderedRealmCollectionChangeListener
|
import io.realm.OrderedRealmCollectionChangeListener
|
||||||
import io.realm.Realm
|
import io.realm.Realm
|
||||||
@ -75,9 +74,7 @@ internal class DefaultTimeline(
|
|||||||
) : Timeline {
|
) : Timeline {
|
||||||
|
|
||||||
private companion object {
|
private companion object {
|
||||||
val BACKGROUND_HANDLER = Handler(
|
val BACKGROUND_HANDLER = createBackgroundHandler("TIMELINE_DB_THREAD")
|
||||||
HandlerThread("TIMELINE_DB_THREAD").apply { start() }.looper
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override var listener: Timeline.Listener? = null
|
override var listener: Timeline.Listener? = null
|
||||||
@ -90,7 +87,7 @@ internal class DefaultTimeline(
|
|||||||
|
|
||||||
private val isStarted = AtomicBoolean(false)
|
private val isStarted = AtomicBoolean(false)
|
||||||
private val isReady = AtomicBoolean(false)
|
private val isReady = AtomicBoolean(false)
|
||||||
private val mainHandler = Handler(Looper.getMainLooper())
|
private val mainHandler = createUIHandler()
|
||||||
private val backgroundRealm = AtomicReference<Realm>()
|
private val backgroundRealm = AtomicReference<Realm>()
|
||||||
private val cancelableBag = CancelableBag()
|
private val cancelableBag = CancelableBag()
|
||||||
private val debouncer = Debouncer(mainHandler)
|
private val debouncer = Debouncer(mainHandler)
|
||||||
|
@ -22,17 +22,19 @@ import im.vector.matrix.android.internal.database.RealmLiveEntityObserver
|
|||||||
import im.vector.matrix.android.internal.database.model.EventEntity
|
import im.vector.matrix.android.internal.database.model.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.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.task.TaskExecutor
|
import im.vector.matrix.android.internal.task.TaskExecutor
|
||||||
import im.vector.matrix.android.internal.task.TaskThread
|
import im.vector.matrix.android.internal.task.TaskThread
|
||||||
import im.vector.matrix.android.internal.task.configureWith
|
import im.vector.matrix.android.internal.task.configureWith
|
||||||
|
import io.realm.RealmConfiguration
|
||||||
import io.realm.Sort
|
import io.realm.Sort
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
internal class UserEntityUpdater @Inject constructor(monarchy: Monarchy,
|
internal class UserEntityUpdater @Inject constructor(@SessionDatabase realmConfiguration: RealmConfiguration,
|
||||||
private val updateUserTask: UpdateUserTask,
|
private val updateUserTask: UpdateUserTask,
|
||||||
private val taskExecutor: TaskExecutor)
|
private val taskExecutor: TaskExecutor)
|
||||||
: RealmLiveEntityObserver<EventEntity>(monarchy) {
|
: RealmLiveEntityObserver<EventEntity>(realmConfiguration) {
|
||||||
|
|
||||||
override val query = Monarchy.Query<EventEntity> {
|
override val query = Monarchy.Query<EventEntity> {
|
||||||
EventEntity
|
EventEntity
|
||||||
|
@ -0,0 +1,29 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2019 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.util
|
||||||
|
|
||||||
|
import android.os.Handler
|
||||||
|
import android.os.HandlerThread
|
||||||
|
import android.os.Looper
|
||||||
|
|
||||||
|
fun createBackgroundHandler(name: String): Handler = Handler(
|
||||||
|
HandlerThread(name).apply { start() }.looper
|
||||||
|
)
|
||||||
|
|
||||||
|
fun createUIHandler(): Handler = Handler(
|
||||||
|
Looper.getMainLooper()
|
||||||
|
)
|
@ -18,6 +18,7 @@ package im.vector.riotx.core.utils
|
|||||||
|
|
||||||
import com.jakewharton.rxrelay2.BehaviorRelay
|
import com.jakewharton.rxrelay2.BehaviorRelay
|
||||||
import io.reactivex.Observable
|
import io.reactivex.Observable
|
||||||
|
import io.reactivex.schedulers.Schedulers
|
||||||
|
|
||||||
open class RxStore<T>(defaultValue: T? = null) {
|
open class RxStore<T>(defaultValue: T? = null) {
|
||||||
|
|
||||||
@ -28,7 +29,7 @@ open class RxStore<T>(defaultValue: T? = null) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun observe(): Observable<T> {
|
fun observe(): Observable<T> {
|
||||||
return storeSubject.hide().distinctUntilChanged()
|
return storeSubject.hide().observeOn(Schedulers.computation())
|
||||||
}
|
}
|
||||||
|
|
||||||
fun post(value: T) {
|
fun post(value: T) {
|
||||||
|
@ -24,6 +24,7 @@ import com.squareup.inject.assisted.AssistedInject
|
|||||||
import im.vector.matrix.android.api.session.Session
|
import im.vector.matrix.android.api.session.Session
|
||||||
import im.vector.matrix.rx.rx
|
import im.vector.matrix.rx.rx
|
||||||
import im.vector.riotx.core.platform.VectorViewModel
|
import im.vector.riotx.core.platform.VectorViewModel
|
||||||
|
import io.reactivex.schedulers.Schedulers
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* View model used to update the home bottom bar notification counts
|
* View model used to update the home bottom bar notification counts
|
||||||
@ -68,6 +69,7 @@ class HomeDetailViewModel @AssistedInject constructor(@Assisted initialState: Ho
|
|||||||
private fun observeRoomSummaries() {
|
private fun observeRoomSummaries() {
|
||||||
homeRoomListStore
|
homeRoomListStore
|
||||||
.observe()
|
.observe()
|
||||||
|
.observeOn(Schedulers.computation())
|
||||||
.subscribe { list ->
|
.subscribe { list ->
|
||||||
list.let { summaries ->
|
list.let { summaries ->
|
||||||
val peopleNotifications = summaries
|
val peopleNotifications = summaries
|
||||||
|
@ -21,18 +21,9 @@ import im.vector.riotx.core.utils.RxStore
|
|||||||
import im.vector.riotx.features.home.room.list.RoomListDisplayModeFilter
|
import im.vector.riotx.features.home.room.list.RoomListDisplayModeFilter
|
||||||
import im.vector.riotx.features.home.room.list.RoomListFragment
|
import im.vector.riotx.features.home.room.list.RoomListFragment
|
||||||
import io.reactivex.Observable
|
import io.reactivex.Observable
|
||||||
|
import io.reactivex.schedulers.Schedulers
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
class HomeRoomListObservableStore @Inject constructor() : RxStore<List<RoomSummary>>() {
|
class HomeRoomListObservableStore @Inject constructor() : RxStore<List<RoomSummary>>()
|
||||||
|
|
||||||
fun observeFilteredBy(displayMode: RoomListFragment.DisplayMode): Observable<List<RoomSummary>> {
|
|
||||||
return observe()
|
|
||||||
.flatMapSingle {
|
|
||||||
Observable.fromIterable(it).filter(RoomListDisplayModeFilter(displayMode)).toList()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
@ -23,6 +23,9 @@ import io.reactivex.functions.Predicate
|
|||||||
class RoomListDisplayModeFilter(private val displayMode: RoomListFragment.DisplayMode) : Predicate<RoomSummary> {
|
class RoomListDisplayModeFilter(private val displayMode: RoomListFragment.DisplayMode) : Predicate<RoomSummary> {
|
||||||
|
|
||||||
override fun test(roomSummary: RoomSummary): Boolean {
|
override fun test(roomSummary: RoomSummary): Boolean {
|
||||||
|
if (roomSummary.membership.isLeft()) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
return when (displayMode) {
|
return when (displayMode) {
|
||||||
RoomListFragment.DisplayMode.HOME -> roomSummary.notificationCount > 0 || roomSummary.membership == Membership.INVITE
|
RoomListFragment.DisplayMode.HOME -> roomSummary.notificationCount > 0 || roomSummary.membership == Membership.INVITE
|
||||||
RoomListFragment.DisplayMode.PEOPLE -> roomSummary.isDirect && roomSummary.membership == Membership.JOIN
|
RoomListFragment.DisplayMode.PEOPLE -> roomSummary.isDirect && roomSummary.membership == Membership.JOIN
|
||||||
|
@ -31,6 +31,7 @@ import im.vector.matrix.android.api.session.room.model.tag.RoomTag
|
|||||||
import im.vector.riotx.core.platform.VectorViewModel
|
import im.vector.riotx.core.platform.VectorViewModel
|
||||||
import im.vector.riotx.core.utils.LiveEvent
|
import im.vector.riotx.core.utils.LiveEvent
|
||||||
import im.vector.riotx.features.home.HomeRoomListObservableStore
|
import im.vector.riotx.features.home.HomeRoomListObservableStore
|
||||||
|
import io.reactivex.schedulers.Schedulers
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
|
|
||||||
class RoomListViewModel @AssistedInject constructor(@Assisted initialState: RoomListViewState,
|
class RoomListViewModel @AssistedInject constructor(@Assisted initialState: RoomListViewState,
|
||||||
@ -55,6 +56,7 @@ class RoomListViewModel @AssistedInject constructor(@Assisted initialState: Room
|
|||||||
}
|
}
|
||||||
|
|
||||||
private val displayMode = initialState.displayMode
|
private val displayMode = initialState.displayMode
|
||||||
|
private val roomListDisplayModeFilter = RoomListDisplayModeFilter(displayMode)
|
||||||
|
|
||||||
private val _openRoomLiveData = MutableLiveData<LiveEvent<String>>()
|
private val _openRoomLiveData = MutableLiveData<LiveEvent<String>>()
|
||||||
val openRoomLiveData: LiveData<LiveEvent<String>>
|
val openRoomLiveData: LiveData<LiveEvent<String>>
|
||||||
@ -95,7 +97,9 @@ class RoomListViewModel @AssistedInject constructor(@Assisted initialState: Room
|
|||||||
copy(asyncRooms = asyncRooms)
|
copy(asyncRooms = asyncRooms)
|
||||||
}
|
}
|
||||||
|
|
||||||
homeRoomListObservableSource.observeFilteredBy(displayMode)
|
homeRoomListObservableSource
|
||||||
|
.observe()
|
||||||
|
.observeOn(Schedulers.computation())
|
||||||
.map { buildRoomSummaries(it) }
|
.map { buildRoomSummaries(it) }
|
||||||
.execute { async ->
|
.execute { async ->
|
||||||
copy(asyncFilteredRooms = async)
|
copy(asyncFilteredRooms = async)
|
||||||
@ -182,23 +186,24 @@ class RoomListViewModel @AssistedInject constructor(@Assisted initialState: Room
|
|||||||
val lowPriorities = ArrayList<RoomSummary>()
|
val lowPriorities = ArrayList<RoomSummary>()
|
||||||
val serverNotices = ArrayList<RoomSummary>()
|
val serverNotices = ArrayList<RoomSummary>()
|
||||||
|
|
||||||
for (room in rooms) {
|
rooms
|
||||||
if (room.membership.isLeft()) continue
|
.filter { roomListDisplayModeFilter.test(it) }
|
||||||
val tags = room.tags.map { it.name }
|
.forEach { room ->
|
||||||
when {
|
val tags = room.tags.map { it.name }
|
||||||
room.membership == Membership.INVITE -> invites.add(room)
|
when {
|
||||||
tags.contains(RoomTag.ROOM_TAG_SERVER_NOTICE) -> serverNotices.add(room)
|
room.membership == Membership.INVITE -> invites.add(room)
|
||||||
tags.contains(RoomTag.ROOM_TAG_FAVOURITE) -> favourites.add(room)
|
tags.contains(RoomTag.ROOM_TAG_SERVER_NOTICE) -> serverNotices.add(room)
|
||||||
tags.contains(RoomTag.ROOM_TAG_LOW_PRIORITY) -> lowPriorities.add(room)
|
tags.contains(RoomTag.ROOM_TAG_FAVOURITE) -> favourites.add(room)
|
||||||
room.isDirect -> directChats.add(room)
|
tags.contains(RoomTag.ROOM_TAG_LOW_PRIORITY) -> lowPriorities.add(room)
|
||||||
else -> groupRooms.add(room)
|
room.isDirect -> directChats.add(room)
|
||||||
}
|
else -> groupRooms.add(room)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
val roomComparator = when (displayMode) {
|
val roomComparator = when (displayMode) {
|
||||||
RoomListFragment.DisplayMode.HOME -> chronologicalRoomComparator
|
RoomListFragment.DisplayMode.HOME -> chronologicalRoomComparator
|
||||||
RoomListFragment.DisplayMode.PEOPLE -> chronologicalRoomComparator
|
RoomListFragment.DisplayMode.PEOPLE -> chronologicalRoomComparator
|
||||||
RoomListFragment.DisplayMode.ROOMS -> alphabeticalRoomComparator
|
RoomListFragment.DisplayMode.ROOMS -> chronologicalRoomComparator
|
||||||
}
|
}
|
||||||
|
|
||||||
return RoomSummaries().apply {
|
return RoomSummaries().apply {
|
||||||
@ -210,6 +215,4 @@ class RoomListViewModel @AssistedInject constructor(@Assisted initialState: Room
|
|||||||
put(RoomCategory.SERVER_NOTICE, serverNotices.sortedWith(roomComparator))
|
put(RoomCategory.SERVER_NOTICE, serverNotices.sortedWith(roomComparator))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user