Refactor power-level based display name color updates

Use similar mechanism as recently added for isDirect changes.

Change-Id: Ida304ae2cc2fbe85cc4b47cb32d6c343cd5e2bd6
This commit is contained in:
SpiritCroc 2021-09-09 12:35:39 +02:00
parent f4d8f78ac7
commit 4b241a00a3
7 changed files with 25 additions and 48 deletions

View File

@ -40,7 +40,6 @@ import im.vector.app.features.home.AvatarRenderer
import im.vector.app.features.home.CurrentSpaceSuggestedRoomListDataSource
import im.vector.app.features.home.room.detail.RoomDetailPendingActionStore
import im.vector.app.features.home.room.detail.timeline.helper.MatrixItemColorProvider
import im.vector.app.features.home.room.detail.timeline.helper.PowerLevelsHolder
import im.vector.app.features.html.EventHtmlRenderer
import im.vector.app.features.html.VectorHtmlCompressor
import im.vector.app.features.invite.AutoAcceptInvites
@ -168,8 +167,6 @@ interface VectorComponent {
fun jitsiActiveConferenceHolder(): JitsiActiveConferenceHolder
fun powerLevelsHolder(): PowerLevelsHolder
@Component.Factory
interface Factory {
fun create(@BindsInstance context: Context): VectorComponent

View File

@ -52,7 +52,6 @@ import im.vector.app.features.home.room.detail.composer.VoiceMessageHelper
import im.vector.app.features.home.room.detail.composer.rainbow.RainbowGenerator
import im.vector.app.features.home.room.detail.sticker.StickerPickerActionHandler
import im.vector.app.features.home.room.detail.timeline.factory.TimelineFactory
import im.vector.app.features.home.room.detail.timeline.helper.PowerLevelsHolder
import im.vector.app.features.home.room.detail.timeline.url.PreviewUrlRetriever
import im.vector.app.features.home.room.typing.TypingHelper
import im.vector.app.features.powerlevel.PowerLevelsObservableFactory
@ -118,7 +117,6 @@ class RoomDetailViewModel @AssistedInject constructor(
private val session: Session,
private val supportedVerificationMethodsProvider: SupportedVerificationMethodsProvider,
private val stickerPickerActionHandler: StickerPickerActionHandler,
private val powerLevelsHolder: PowerLevelsHolder,
private val typingHelper: TypingHelper,
private val callManager: WebRtcCallManager,
private val chatEffectManager: ChatEffectManager,
@ -175,7 +173,6 @@ class RoomDetailViewModel @AssistedInject constructor(
}
init {
powerLevelsHolder.clear(room.roomId)
timeline.start()
timeline.addListener(this)
observeRoomSummary()
@ -231,7 +228,6 @@ class RoomDetailViewModel @AssistedInject constructor(
PowerLevelsObservableFactory(room).createObservable()
.subscribe {
val powerLevelsHelper = PowerLevelsHelper(it)
powerLevelsHolder.set(room.roomId, powerLevelsHelper)
val canSendMessage = powerLevelsHelper.isUserAllowedToSend(session.myUserId, false, EventType.MESSAGE)
val canInvite = powerLevelsHelper.isUserAbleToInvite(session.myUserId)
val isAllowedToManageWidgets = session.widgetService().hasPermissionsToHandleWidgets(room.roomId)
@ -241,7 +237,8 @@ class RoomDetailViewModel @AssistedInject constructor(
canSendMessage = canSendMessage,
canInvite = canInvite,
isAllowedToManageWidgets = isAllowedToManageWidgets,
isAllowedToStartWebRTCCall = isAllowedToStartWebRTCCall
isAllowedToStartWebRTCCall = isAllowedToStartWebRTCCall,
powerLevelsHelper = powerLevelsHelper
)
}
}

View File

@ -24,6 +24,7 @@ import org.matrix.android.sdk.api.session.events.model.Event
import org.matrix.android.sdk.api.session.room.members.ChangeMembershipState
import org.matrix.android.sdk.api.session.room.model.RoomMemberSummary
import org.matrix.android.sdk.api.session.room.model.RoomSummary
import org.matrix.android.sdk.api.session.room.powerlevels.PowerLevelsHelper
import org.matrix.android.sdk.api.session.room.timeline.TimelineEvent
import org.matrix.android.sdk.api.session.sync.SyncState
import org.matrix.android.sdk.api.session.widgets.model.Widget
@ -71,6 +72,7 @@ data class RoomDetailViewState(
val myRoomMember: Async<RoomMemberSummary> = Uninitialized,
val asyncInviter: Async<RoomMemberSummary> = Uninitialized,
val asyncRoomSummary: Async<RoomSummary> = Uninitialized,
val powerLevelsHelper: PowerLevelsHelper? = null,
val activeRoomWidgets: Async<List<Widget>> = Uninitialized,
val typingMessage: String? = null,
val sendMode: SendMode = SendMode.REGULAR("", false),

View File

@ -43,6 +43,7 @@ import im.vector.app.features.home.room.detail.timeline.helper.TimelineEventsGro
import im.vector.app.features.home.room.detail.timeline.helper.ContentDownloadStateTrackerBinder
import im.vector.app.features.home.room.detail.timeline.helper.ContentUploadStateTrackerBinder
import im.vector.app.features.home.room.detail.timeline.helper.InvalidateTimelineEventDiffUtilCallback
import im.vector.app.features.home.room.detail.timeline.helper.MatrixItemColorProvider
import im.vector.app.features.home.room.detail.timeline.helper.TimelineControllerInterceptorHelper
import im.vector.app.features.home.room.detail.timeline.helper.TimelineEventDiffUtilCallback
import im.vector.app.features.home.room.detail.timeline.helper.TimelineEventVisibilityHelper
@ -69,6 +70,7 @@ import org.matrix.android.sdk.api.session.room.model.RoomSummary
import org.matrix.android.sdk.api.session.room.model.message.MessageAudioContent
import org.matrix.android.sdk.api.session.room.model.message.MessageImageInfoContent
import org.matrix.android.sdk.api.session.room.model.message.MessageVideoContent
import org.matrix.android.sdk.api.session.room.powerlevels.PowerLevelsHelper
import org.matrix.android.sdk.api.session.room.timeline.Timeline
import org.matrix.android.sdk.api.session.room.timeline.TimelineEvent
import javax.inject.Inject
@ -94,14 +96,16 @@ class TimelineEventController @Inject constructor(private val dateFormatter: Vec
val unreadState: UnreadState = UnreadState.Unknown,
val highlightedEventId: String? = null,
val jitsiState: JitsiState = JitsiState(),
val roomSummary: RoomSummary? = null
val roomSummary: RoomSummary? = null,
val powerLevelsHelper: PowerLevelsHelper? = null
) {
constructor(state: RoomDetailViewState) : this(
unreadState = state.unreadState,
highlightedEventId = state.highlightedEventId,
jitsiState = state.jitsiState,
roomSummary = state.asyncRoomSummary()
roomSummary = state.asyncRoomSummary(),
powerLevelsHelper = state.powerLevelsHelper,
)
}
@ -247,12 +251,23 @@ class TimelineEventController @Inject constructor(private val dateFormatter: Vec
fun update(viewState: RoomDetailViewState) = synchronized(modelCache) {
val newPartialState = PartialState(viewState)
// Full list rebuild if isDirect changed to apply new layout
if (partialState.roomSummary?.isDirect != newPartialState.roomSummary?.isDirect) {
partialState = newPartialState
invalidateFullTimeline()
// This already called requestModelBuild
return
}
// Full list rebuild if power levels changed and username colors depend on power levels
if (partialState.powerLevelsHelper != newPartialState.powerLevelsHelper) {
val coloringMode = vectorPreferences.userColorMode(newPartialState.roomSummary?.isDirect ?: false, newPartialState.roomSummary?.isPublic ?: false)
if (coloringMode == MatrixItemColorProvider.USER_COLORING_FROM_PL) {
partialState = newPartialState
invalidateFullTimeline()
// This already called requestModelBuild
return
}
}
if (partialState.highlightedEventId != newPartialState.highlightedEventId) {
// Clear cache to force a refresh
for (i in 0 until modelCache.size) {

View File

@ -99,9 +99,9 @@ class MatrixItemColorProvider @Inject constructor(
}
// Same values as in R.array.user_color_mode_values
private const val USER_COLORING_UNIFORM = "uniform"
private const val USER_COLORING_FROM_ID = "from-id"
private const val USER_COLORING_FROM_PL = "from-pl"
public const val USER_COLORING_UNIFORM = "uniform"
public const val USER_COLORING_FROM_ID = "from-id"
public const val USER_COLORING_FROM_PL = "from-pl"
const val USER_COLORING_DEFAULT = USER_COLORING_UNIFORM
}

View File

@ -55,7 +55,6 @@ 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
*/
class MessageInformationDataFactory @Inject constructor(private val session: Session,
private val powerLevelsHolder: PowerLevelsHolder,
private val dateFormatter: VectorDateFormatter,
private val context: Context,
private val visibilityHelper: TimelineEventVisibilityHelper,
@ -126,11 +125,7 @@ class MessageInformationDataFactory @Inject constructor(private val session: Ses
}
// Sender power level
/*
val powerLevelsHelper = session.getRoom(event.roomId)?.getStateEvent(EventType.STATE_ROOM_POWER_LEVELS, QueryStringValue.NoCondition)?.content.toModel<PowerLevelsContent>()?.let { PowerLevelsHelper(it) }
val senderPowerLevel = powerLevelsHelper?.getUserPowerLevelValue(event.senderInfo.userId)
*/
val senderPowerLevel = powerLevelsHolder.get(event.roomId)?.getUserPowerLevelValue(event.senderInfo.userId)
val senderPowerLevel = params.partialState.powerLevelsHelper?.getUserPowerLevelValue(event.senderInfo.userId)
return MessageInformationData(
eventId = eventId,

View File

@ -1,29 +0,0 @@
package im.vector.app.features.home.room.detail.timeline.helper
import org.matrix.android.sdk.api.session.room.powerlevels.PowerLevelsHelper
import javax.inject.Inject
import javax.inject.Singleton
/*
You can use this to share user power level helpers within the app.
You should probably use this only in the context of the timeline.
*/
@Singleton
class PowerLevelsHolder @Inject constructor() {
private var roomHelpers = HashMap<String, PowerLevelsHelper>()
fun set(roomId: String, powerLevelsHelper: PowerLevelsHelper) {
roomHelpers[roomId] = powerLevelsHelper
}
fun get(roomId: String) = roomHelpers[roomId]
fun clear() {
roomHelpers.clear()
}
fun clear(roomId: String) {
roomHelpers.remove(roomId)
}
}