RoomSummary: don't fetch last event by default as it takes some time

This commit is contained in:
ganfra 2019-07-02 19:59:01 +02:00
parent 5b102485bc
commit 2f66321c2a
14 changed files with 42 additions and 45 deletions

View File

@ -24,8 +24,8 @@ import io.reactivex.Observable
class RxRoom(private val room: Room) { class RxRoom(private val room: Room) {
fun liveRoomSummary(): Observable<RoomSummary> { fun liveRoomSummary(fetchLastEvent: Boolean): Observable<RoomSummary> {
return room.liveRoomSummary.asObservable() return room.liveRoomSummary(fetchLastEvent).asObservable()
} }
fun liveRoomMemberIds(): Observable<List<String>> { fun liveRoomMemberIds(): Observable<List<String>> {

View File

@ -25,8 +25,8 @@ import io.reactivex.Observable
class RxSession(private val session: Session) { class RxSession(private val session: Session) {
fun liveRoomSummaries(): Observable<List<RoomSummary>> { fun liveRoomSummaries(fetchLastEvents: Boolean): Observable<List<RoomSummary>> {
return session.liveRoomSummaries().asObservable() return session.liveRoomSummaries(fetchLastEvents).asObservable()
} }
fun liveGroupSummaries(): Observable<List<GroupSummary>> { fun liveGroupSummaries(): Observable<List<GroupSummary>> {

View File

@ -47,8 +47,8 @@ interface Room :
* A live [RoomSummary] associated with the room * A live [RoomSummary] associated with the room
* You can observe this summary to get dynamic data from this room. * You can observe this summary to get dynamic data from this room.
*/ */
val liveRoomSummary: LiveData<RoomSummary> fun liveRoomSummary(fetchLastEvent: Boolean = false): LiveData<RoomSummary>
val roomSummary: RoomSummary? fun roomSummary(fetchLastEvent: Boolean = false): RoomSummary?
} }

View File

@ -43,6 +43,6 @@ interface RoomService {
* Get a live list of room summaries. This list is refreshed as soon as the data changes. * Get a live list of room summaries. This list is refreshed as soon as the data changes.
* @return the [LiveData] of [RoomSummary] * @return the [LiveData] of [RoomSummary]
*/ */
fun liveRoomSummaries(): LiveData<List<RoomSummary>> fun liveRoomSummaries(fetchLastEvents: Boolean = true): LiveData<List<RoomSummary>>
} }

View File

@ -16,29 +16,24 @@
package im.vector.matrix.android.internal.database.mapper package im.vector.matrix.android.internal.database.mapper
import com.zhuinden.monarchy.Monarchy
import im.vector.matrix.android.api.session.room.model.RoomSummary import im.vector.matrix.android.api.session.room.model.RoomSummary
import im.vector.matrix.android.api.session.room.model.tag.RoomTag import im.vector.matrix.android.api.session.room.model.tag.RoomTag
import im.vector.matrix.android.api.session.room.timeline.TimelineEvent
import im.vector.matrix.android.internal.database.model.RoomSummaryEntity import im.vector.matrix.android.internal.database.model.RoomSummaryEntity
import im.vector.matrix.android.internal.session.room.timeline.TimelineEventFactory import im.vector.matrix.android.internal.session.room.timeline.TimelineEventFactory
import javax.inject.Inject import javax.inject.Inject
internal class RoomSummaryMapper @Inject constructor(private val timelineEventFactory: TimelineEventFactory) {
internal class RoomSummaryMapper @Inject constructor( fun map(roomSummaryEntity: RoomSummaryEntity, getLatestEvent: Boolean = false): RoomSummary {
private val timelineEventFactory: TimelineEventFactory,
private val monarchy: Monarchy) {
fun map(roomSummaryEntity: RoomSummaryEntity): RoomSummary {
val tags = roomSummaryEntity.tags.map { val tags = roomSummaryEntity.tags.map {
RoomTag(it.tagName, it.tagOrder) RoomTag(it.tagName, it.tagOrder)
} }
val latestEvent = roomSummaryEntity.latestEvent?.let { val latestEvent = if (getLatestEvent) {
var ev: TimelineEvent? = null roomSummaryEntity.latestEvent?.let {
monarchy.doWithRealm { realm -> timelineEventFactory.create(it, it.realm)
ev = timelineEventFactory.create(it, realm)
} }
ev } else {
null
} }
return RoomSummary( return RoomSummary(
roomId = roomSummaryEntity.roomId, roomId = roomSummaryEntity.roomId,

View File

@ -34,6 +34,7 @@ import im.vector.matrix.android.internal.database.model.RoomSummaryEntity
import im.vector.matrix.android.internal.database.model.RoomSummaryEntityFields import im.vector.matrix.android.internal.database.model.RoomSummaryEntityFields
import im.vector.matrix.android.internal.database.query.where import im.vector.matrix.android.internal.database.query.where
import im.vector.matrix.android.internal.util.fetchCopied import im.vector.matrix.android.internal.util.fetchCopied
import im.vector.matrix.android.internal.util.fetchCopyMap
import javax.inject.Inject import javax.inject.Inject
internal class DefaultRoom @Inject constructor(override val roomId: String, internal class DefaultRoom @Inject constructor(override val roomId: String,
@ -47,19 +48,19 @@ internal class DefaultRoom @Inject constructor(override val roomId: String,
private val relationService: RelationService, private val relationService: RelationService,
private val roomMembersService: MembershipService private val roomMembersService: MembershipService
) : Room, ) : Room,
TimelineService by timelineService, TimelineService by timelineService,
SendService by sendService, SendService by sendService,
StateService by stateService, StateService by stateService,
ReadService by readService, ReadService by readService,
RelationService by relationService, RelationService by relationService,
MembershipService by roomMembersService { MembershipService by roomMembersService {
override val liveRoomSummary: LiveData<RoomSummary> by lazy { override fun liveRoomSummary(fetchLastEvent: Boolean): LiveData<RoomSummary> {
val liveRealmData = RealmLiveData<RoomSummaryEntity>(monarchy.realmConfiguration) { realm -> val liveRealmData = RealmLiveData<RoomSummaryEntity>(monarchy.realmConfiguration) { realm ->
RoomSummaryEntity.where(realm, roomId).isNotEmpty(RoomSummaryEntityFields.DISPLAY_NAME) RoomSummaryEntity.where(realm, roomId).isNotEmpty(RoomSummaryEntityFields.DISPLAY_NAME)
} }
Transformations.map(liveRealmData) { results -> return Transformations.map(liveRealmData) { results ->
val roomSummaries = results.map { roomSummaryMapper.map(it) } val roomSummaries = results.map { roomSummaryMapper.map(it, fetchLastEvent) }
if (roomSummaries.isEmpty()) { if (roomSummaries.isEmpty()) {
// Create a dummy RoomSummary to avoid Crash during Sign Out or clear cache // Create a dummy RoomSummary to avoid Crash during Sign Out or clear cache
@ -70,11 +71,12 @@ internal class DefaultRoom @Inject constructor(override val roomId: String,
} }
} }
override val roomSummary: RoomSummary? override fun roomSummary(fetchLastEvent: Boolean): RoomSummary? {
get() { return monarchy.fetchAllMappedSync(
var sum: RoomSummaryEntity? = monarchy.fetchCopied { RoomSummaryEntity.where(it, roomId).isNotEmpty(RoomSummaryEntityFields.DISPLAY_NAME).findFirst() } { realm -> RoomSummaryEntity.where(realm).isNotEmpty(RoomSummaryEntityFields.DISPLAY_NAME) },
return sum?.let { roomSummaryMapper.map(it) } { roomSummaryMapper.map(it, fetchLastEvent) }
} ).firstOrNull()
}
override fun isEncrypted(): Boolean { override fun isEncrypted(): Boolean {
return cryptoService.isRoomEncrypted(roomId) return cryptoService.isRoomEncrypted(roomId)

View File

@ -52,10 +52,10 @@ internal class DefaultRoomService @Inject constructor(private val monarchy: Mona
return roomFactory.create(roomId) return roomFactory.create(roomId)
} }
override fun liveRoomSummaries(): LiveData<List<RoomSummary>> { override fun liveRoomSummaries(fetchLastEvents: Boolean): LiveData<List<RoomSummary>> {
return monarchy.findAllMappedWithChanges( return monarchy.findAllMappedWithChanges(
{ realm -> RoomSummaryEntity.where(realm).isNotEmpty(RoomSummaryEntityFields.DISPLAY_NAME) }, { realm -> RoomSummaryEntity.where(realm).isNotEmpty(RoomSummaryEntityFields.DISPLAY_NAME) },
{ roomSummaryMapper.map(it) } { roomSummaryMapper.map(it, fetchLastEvents) }
) )
} }
} }

View File

@ -80,7 +80,7 @@ internal class SimpleTimelineEventFactory @Inject constructor(private val roomMe
val result = cryptoService.decryptEvent(event, UUID.randomUUID().toString()) val result = cryptoService.decryptEvent(event, UUID.randomUUID().toString())
event.setClearData(result) event.setClearData(result)
} catch (failure: Throwable) { } catch (failure: Throwable) {
Timber.e(failure, "Encrypted event: decryption failed") Timber.e("Encrypted event: decryption failed")
if (failure is MXDecryptionException) { if (failure is MXDecryptionException) {
event.setCryptoError(failure.cryptoError) event.setCryptoError(failure.cryptoError)
} }

View File

@ -73,7 +73,7 @@ class HomeActivityViewModel @AssistedInject constructor(@Assisted initialState:
private fun observeRoomAndGroup() { private fun observeRoomAndGroup() {
Observable Observable
.combineLatest<List<RoomSummary>, Option<GroupSummary>, List<RoomSummary>>( .combineLatest<List<RoomSummary>, Option<GroupSummary>, List<RoomSummary>>(
session.rx().liveRoomSummaries().throttleLast(300, TimeUnit.MILLISECONDS), session.rx().liveRoomSummaries(fetchLastEvents = true).throttleLast(300, TimeUnit.MILLISECONDS),
selectedGroupStore.observe(), selectedGroupStore.observe(),
BiFunction { rooms, selectedGroupOption -> BiFunction { rooms, selectedGroupOption ->
val selectedGroup = selectedGroupOption.orNull() val selectedGroup = selectedGroupOption.orNull()

View File

@ -498,7 +498,7 @@ class RoomDetailViewModel @AssistedInject constructor(@Assisted initialState: Ro
} }
private fun observeRoomSummary() { private fun observeRoomSummary() {
room.rx().liveRoomSummary() room.rx().liveRoomSummary(false)
.execute { async -> .execute { async ->
copy( copy(
asyncRoomSummary = async, asyncRoomSummary = async,

View File

@ -117,7 +117,7 @@ class NotifiableEventResolver @Inject constructor(private val stringProvider: St
val body = event.annotations?.editSummary?.aggregatedContent?.toModel<MessageContent>()?.body val body = event.annotations?.editSummary?.aggregatedContent?.toModel<MessageContent>()?.body
?: event.root.getClearContent().toModel<MessageContent>()?.body ?: event.root.getClearContent().toModel<MessageContent>()?.body
?: stringProvider.getString(R.string.notification_unknown_new_event) ?: stringProvider.getString(R.string.notification_unknown_new_event)
val roomName = room.roomSummary?.displayName ?: "" val roomName = room.roomSummary()?.displayName ?: ""
val senderDisplayName = event.senderName ?: event.root.senderId val senderDisplayName = event.senderName ?: event.root.senderId
val notifiableEvent = NotifiableMessageEvent( val notifiableEvent = NotifiableMessageEvent(
@ -129,7 +129,7 @@ class NotifiableEventResolver @Inject constructor(private val stringProvider: St
body = body, body = body,
roomId = event.root.roomId!!, roomId = event.root.roomId!!,
roomName = roomName, roomName = roomName,
roomIsDirect = room.roomSummary?.isDirect ?: false) roomIsDirect = room.roomSummary()?.isDirect ?: false)
notifiableEvent.matrixID = session.sessionParams.credentials.userId notifiableEvent.matrixID = session.sessionParams.credentials.userId
notifiableEvent.soundName = null notifiableEvent.soundName = null
@ -137,7 +137,7 @@ class NotifiableEventResolver @Inject constructor(private val stringProvider: St
// Get the avatars URL // Get the avatars URL
// TODO They will be not displayed the first time (known limitation) // TODO They will be not displayed the first time (known limitation)
notifiableEvent.roomAvatarPath = session.contentUrlResolver() notifiableEvent.roomAvatarPath = session.contentUrlResolver()
.resolveThumbnail(room.roomSummary?.avatarUrl, .resolveThumbnail(room.roomSummary()?.avatarUrl,
250, 250,
250, 250,
ContentUrlResolver.ThumbnailMethod.SCALE) ContentUrlResolver.ThumbnailMethod.SCALE)

View File

@ -100,8 +100,8 @@ class NotificationBroadcastReceiver : BroadcastReceiver() {
session.sessionParams.credentials.userId, session.sessionParams.credentials.userId,
message, message,
room.roomId, room.roomId,
room.roomSummary?.displayName ?: room.roomId, room.roomSummary()?.displayName ?: room.roomId,
room.roomSummary?.isDirect == true room.roomSummary()?.isDirect == true
) )
notifiableMessageEvent.outGoingMessage = true notifiableMessageEvent.outGoingMessage = true

View File

@ -86,7 +86,7 @@ class RoomDirectoryViewModel @AssistedInject constructor(@Assisted initialState:
private fun observeJoinedRooms() { private fun observeJoinedRooms() {
session session
.rx() .rx()
.liveRoomSummaries() .liveRoomSummaries(fetchLastEvents = false)
.subscribe { list -> .subscribe { list ->
val joinedRoomIds = list val joinedRoomIds = list
// Keep only joined room // Keep only joined room

View File

@ -54,7 +54,7 @@ class RoomPreviewViewModel @AssistedInject constructor(@Assisted initialState: R
private fun observeJoinedRooms() { private fun observeJoinedRooms() {
session session
.rx() .rx()
.liveRoomSummaries() .liveRoomSummaries(fetchLastEvents = false)
.subscribe { list -> .subscribe { list ->
withState { state -> withState { state ->
val isRoomJoined = list val isRoomJoined = list