Timeline: add room summary holder to avoid fetching in item factory

This commit is contained in:
ganfra 2020-06-16 11:08:38 +02:00
parent 905fa7dd86
commit 8cef299878
3 changed files with 51 additions and 7 deletions

View File

@ -71,6 +71,7 @@ import im.vector.riotx.features.command.ParsedCommand
import im.vector.riotx.features.crypto.verification.SupportedVerificationMethodsProvider import im.vector.riotx.features.crypto.verification.SupportedVerificationMethodsProvider
import im.vector.riotx.features.home.room.detail.composer.rainbow.RainbowGenerator import im.vector.riotx.features.home.room.detail.composer.rainbow.RainbowGenerator
import im.vector.riotx.features.home.room.detail.sticker.StickerPickerActionHandler import im.vector.riotx.features.home.room.detail.sticker.StickerPickerActionHandler
import im.vector.riotx.features.home.room.detail.timeline.helper.RoomSummaryHolder
import im.vector.riotx.features.home.room.detail.timeline.helper.TimelineDisplayableEvents import im.vector.riotx.features.home.room.detail.timeline.helper.TimelineDisplayableEvents
import im.vector.riotx.features.home.room.typing.TypingHelper import im.vector.riotx.features.home.room.typing.TypingHelper
import im.vector.riotx.features.powerlevel.PowerLevelsObservableFactory import im.vector.riotx.features.powerlevel.PowerLevelsObservableFactory
@ -96,7 +97,8 @@ class RoomDetailViewModel @AssistedInject constructor(
private val rainbowGenerator: RainbowGenerator, private val rainbowGenerator: RainbowGenerator,
private val session: Session, private val session: Session,
private val supportedVerificationMethodsProvider: SupportedVerificationMethodsProvider, private val supportedVerificationMethodsProvider: SupportedVerificationMethodsProvider,
private val stickerPickerActionHandler: StickerPickerActionHandler private val stickerPickerActionHandler: StickerPickerActionHandler,
private val roomSummaryHolder: RoomSummaryHolder
) : VectorViewModel<RoomDetailViewState, RoomDetailAction, RoomDetailViewEvents>(initialState), Timeline.Listener { ) : VectorViewModel<RoomDetailViewState, RoomDetailAction, RoomDetailViewEvents>(initialState), Timeline.Listener {
private val room = session.getRoom(initialState.roomId)!! private val room = session.getRoom(initialState.roomId)!!
@ -1065,6 +1067,7 @@ class RoomDetailViewModel @AssistedInject constructor(
private fun observeSummaryState() { private fun observeSummaryState() {
asyncSubscribe(RoomDetailViewState::asyncRoomSummary) { summary -> asyncSubscribe(RoomDetailViewState::asyncRoomSummary) { summary ->
roomSummaryHolder.set(summary)
if (summary.membership == Membership.INVITE) { if (summary.membership == Membership.INVITE) {
summary.inviterId?.let { inviterId -> summary.inviterId?.let { inviterId ->
session.getUser(inviterId) session.getUser(inviterId)
@ -1094,6 +1097,7 @@ class RoomDetailViewModel @AssistedInject constructor(
} }
override fun onCleared() { override fun onCleared() {
roomSummaryHolder.clear()
timeline.dispose() timeline.dispose()
timeline.removeAllListeners() timeline.removeAllListeners()
if (vectorPreferences.sendTypingNotifs()) { if (vectorPreferences.sendTypingNotifs()) {

View File

@ -22,7 +22,6 @@ import im.vector.matrix.android.api.extensions.orFalse
import im.vector.matrix.android.api.session.Session import im.vector.matrix.android.api.session.Session
import im.vector.matrix.android.api.session.events.model.EventType import im.vector.matrix.android.api.session.events.model.EventType
import im.vector.matrix.android.api.session.events.model.toModel import im.vector.matrix.android.api.session.events.model.toModel
import im.vector.matrix.android.api.session.room.Room
import im.vector.matrix.android.api.session.room.model.ReferencesAggregatedContent import im.vector.matrix.android.api.session.room.model.ReferencesAggregatedContent
import im.vector.matrix.android.api.session.room.model.message.MessageVerificationRequestContent import im.vector.matrix.android.api.session.room.model.message.MessageVerificationRequestContent
import im.vector.matrix.android.api.session.room.send.SendState import im.vector.matrix.android.api.session.room.send.SendState
@ -49,6 +48,7 @@ import javax.inject.Inject
* This class compute if data of an event (such has avatar, display name, ...) should be displayed, depending on the previous event in the timeline * This class compute if data of an event (such has avatar, display name, ...) should be displayed, depending on the previous event in the timeline
*/ */
class MessageInformationDataFactory @Inject constructor(private val session: Session, class MessageInformationDataFactory @Inject constructor(private val session: Session,
private val roomSummaryHolder: RoomSummaryHolder,
private val dateFormatter: VectorDateFormatter, private val dateFormatter: VectorDateFormatter,
private val colorProvider: ColorProvider) { private val colorProvider: ColorProvider) {
@ -75,8 +75,7 @@ class MessageInformationDataFactory @Inject constructor(private val session: Ses
textColor = colorProvider.getColor(getColorFromUserId(event.root.senderId)) textColor = colorProvider.getColor(getColorFromUserId(event.root.senderId))
} }
val room = event.root.roomId?.let { session.getRoom(it) } val e2eDecoration = getE2EDecoration(event)
val e2eDecoration = getE2EDecoration(room, event)
return MessageInformationData( return MessageInformationData(
eventId = eventId, eventId = eventId,
senderId = event.root.senderId ?: "", senderId = event.root.senderId ?: "",
@ -121,13 +120,14 @@ class MessageInformationDataFactory @Inject constructor(private val session: Ses
) )
} }
private fun getE2EDecoration(room: Room?, event: TimelineEvent): E2EDecoration { private fun getE2EDecoration(event: TimelineEvent): E2EDecoration {
val roomSummary = roomSummaryHolder.roomSummary
return if ( return if (
event.root.sendState == SendState.SYNCED event.root.sendState == SendState.SYNCED
&& room?.isEncrypted() == true && roomSummary?.isEncrypted.orFalse()
// is user verified // is user verified
&& session.cryptoService().crossSigningService().getUserCrossSigningKeys(event.root.senderId ?: "")?.isTrusted() == true) { && session.cryptoService().crossSigningService().getUserCrossSigningKeys(event.root.senderId ?: "")?.isTrusted() == true) {
val ts = room.roomSummary()?.encryptionEventTs ?: 0 val ts = roomSummary?.encryptionEventTs ?: 0
val eventTs = event.root.originServerTs ?: 0 val eventTs = event.root.originServerTs ?: 0
if (event.isEncrypted()) { if (event.isEncrypted()) {
// Do not decorate failed to decrypt, or redaction (we lost sender device info) // Do not decorate failed to decrypt, or redaction (we lost sender device info)

View File

@ -0,0 +1,40 @@
/*
* 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.riotx.features.home.room.detail.timeline.helper
import im.vector.matrix.android.api.session.room.model.RoomSummary
import im.vector.riotx.core.di.ScreenScope
import javax.inject.Inject
/*
This holds an instance of the current room summary.
You should use this in the context of the timeline.
*/
@ScreenScope
class RoomSummaryHolder @Inject constructor() {
var roomSummary: RoomSummary? = null
private set
fun set(roomSummary: RoomSummary) {
this.roomSummary = roomSummary
}
fun clear() {
roomSummary = null
}
}