change (media preview config) : manage migration of local data
This commit is contained in:
@@ -41,6 +41,7 @@ import dagger.assisted.AssistedInject
|
||||
import im.vector.app.features.analytics.plan.JoinedRoom
|
||||
import io.element.android.anvilannotations.ContributesNode
|
||||
import io.element.android.appnav.loggedin.LoggedInNode
|
||||
import io.element.android.appnav.loggedin.MediaPreviewConfigMigration
|
||||
import io.element.android.appnav.loggedin.SendQueues
|
||||
import io.element.android.appnav.room.RoomFlowNode
|
||||
import io.element.android.appnav.room.RoomNavigationTarget
|
||||
@@ -114,6 +115,7 @@ class LoggedInFlowNode @AssistedInject constructor(
|
||||
private val sendingQueue: SendQueues,
|
||||
private val logoutEntryPoint: LogoutEntryPoint,
|
||||
private val incomingVerificationEntryPoint: IncomingVerificationEntryPoint,
|
||||
private val mediaPreviewConfigMigration: MediaPreviewConfigMigration,
|
||||
snackbarDispatcher: SnackbarDispatcher,
|
||||
) : BaseFlowNode<LoggedInFlowNode.NavTarget>(
|
||||
backstack = BackStack(
|
||||
@@ -179,6 +181,7 @@ class LoggedInFlowNode @AssistedInject constructor(
|
||||
appNavigationStateService.onNavigateToSpace(id, MAIN_SPACE)
|
||||
loggedInFlowProcessor.observeEvents(sessionCoroutineScope)
|
||||
matrixClient.sessionVerificationService().setListener(verificationListener)
|
||||
mediaPreviewConfigMigration()
|
||||
|
||||
ftueService.state
|
||||
.onEach { ftueState ->
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright 2025 New Vector Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
|
||||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
package io.element.android.appnav.loggedin
|
||||
|
||||
import io.element.android.libraries.di.annotations.SessionCoroutineScope
|
||||
import io.element.android.libraries.matrix.api.media.MediaPreviewService
|
||||
import io.element.android.libraries.preferences.api.store.AppPreferencesStore
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.flow.first
|
||||
import kotlinx.coroutines.launch
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
|
||||
/**
|
||||
* This migration is temporary, will be safe to remove after some time.
|
||||
* The goal is to set the server config if it's not set, and remove the local data.
|
||||
*/
|
||||
class MediaPreviewConfigMigration @Inject constructor(
|
||||
private val mediaPreviewService: MediaPreviewService,
|
||||
private val appPreferencesStore: AppPreferencesStore,
|
||||
@SessionCoroutineScope
|
||||
private val sessionCoroutineScope: CoroutineScope,
|
||||
) {
|
||||
operator fun invoke() = sessionCoroutineScope.launch {
|
||||
val hideInviteAvatars = appPreferencesStore.getHideInviteAvatarsFlow().first()
|
||||
val mediaPreviewValue = appPreferencesStore.getTimelineMediaPreviewValueFlow().first()
|
||||
if (hideInviteAvatars == null && mediaPreviewValue == null) {
|
||||
// No local data, abort.
|
||||
return@launch
|
||||
}
|
||||
mediaPreviewService
|
||||
.fetchMediaPreviewConfig()
|
||||
.onSuccess { config ->
|
||||
if (config != null) {
|
||||
appPreferencesStore.setHideInviteAvatars(null)
|
||||
appPreferencesStore.setTimelineMediaPreviewValue(null)
|
||||
} else {
|
||||
if (hideInviteAvatars != null) {
|
||||
mediaPreviewService.setHideInviteAvatars(hideInviteAvatars)
|
||||
appPreferencesStore.setHideInviteAvatars(null)
|
||||
}
|
||||
if (mediaPreviewValue != null) {
|
||||
mediaPreviewService.setMediaPreviewValue(mediaPreviewValue)
|
||||
appPreferencesStore.setTimelineMediaPreviewValue(null)
|
||||
}
|
||||
}
|
||||
}.onFailure {
|
||||
Timber.d("Couldn't perform migration, failed to fetch media preview config.")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -22,9 +22,10 @@ interface AppPreferencesStore {
|
||||
suspend fun setTheme(theme: String)
|
||||
fun getThemeFlow(): Flow<String?>
|
||||
|
||||
fun getHideInviteAvatarsFlow(): Flow<Boolean>
|
||||
|
||||
fun getTimelineMediaPreviewValueFlow(): Flow<MediaPreviewValue>
|
||||
suspend fun setHideInviteAvatars(hide: Boolean?)
|
||||
fun getHideInviteAvatarsFlow(): Flow<Boolean?>
|
||||
suspend fun setTimelineMediaPreviewValue(mediaPreviewValue: MediaPreviewValue?)
|
||||
fun getTimelineMediaPreviewValueFlow(): Flow<MediaPreviewValue?>
|
||||
|
||||
suspend fun setTracingLogLevel(logLevel: LogLevel)
|
||||
fun getTracingLogLevelFlow(): Flow<LogLevel>
|
||||
|
||||
@@ -85,15 +85,35 @@ class DefaultAppPreferencesStore @Inject constructor(
|
||||
}
|
||||
}
|
||||
|
||||
override fun getHideInviteAvatarsFlow(): Flow<Boolean> {
|
||||
override fun getHideInviteAvatarsFlow(): Flow<Boolean?> {
|
||||
return store.data.map { prefs ->
|
||||
prefs[hideInviteAvatarsKey] == true
|
||||
prefs[hideInviteAvatarsKey]
|
||||
}
|
||||
}
|
||||
|
||||
override fun getTimelineMediaPreviewValueFlow(): Flow<MediaPreviewValue> {
|
||||
override suspend fun setHideInviteAvatars(hide: Boolean?) {
|
||||
store.edit { prefs ->
|
||||
if (hide != null) {
|
||||
prefs[hideInviteAvatarsKey] = hide
|
||||
} else {
|
||||
prefs.remove(hideInviteAvatarsKey)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun setTimelineMediaPreviewValue(mediaPreviewValue: MediaPreviewValue?) {
|
||||
store.edit { prefs ->
|
||||
if (mediaPreviewValue != null) {
|
||||
prefs[timelineMediaPreviewValueKey] = mediaPreviewValue.name
|
||||
} else {
|
||||
prefs.remove(timelineMediaPreviewValueKey)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun getTimelineMediaPreviewValueFlow(): Flow<MediaPreviewValue?> {
|
||||
return store.data.map { prefs ->
|
||||
prefs[timelineMediaPreviewValueKey]?.let { MediaPreviewValue.valueOf(it) } ?: MediaPreviewValue.On
|
||||
prefs[timelineMediaPreviewValueKey]?.let { MediaPreviewValue.valueOf(it) }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -17,8 +17,8 @@ import kotlinx.coroutines.flow.MutableStateFlow
|
||||
class InMemoryAppPreferencesStore(
|
||||
isDeveloperModeEnabled: Boolean = false,
|
||||
customElementCallBaseUrl: String? = null,
|
||||
hideInviteAvatars: Boolean = false,
|
||||
timelineMediaPreviewValue: MediaPreviewValue = MediaPreviewValue.On,
|
||||
hideInviteAvatars: Boolean? = null,
|
||||
timelineMediaPreviewValue: MediaPreviewValue? = null,
|
||||
theme: String? = null,
|
||||
logLevel: LogLevel = LogLevel.INFO,
|
||||
traceLockPacks: Set<TraceLogPack> = emptySet(),
|
||||
@@ -55,14 +55,22 @@ class InMemoryAppPreferencesStore(
|
||||
return theme
|
||||
}
|
||||
|
||||
override fun getHideInviteAvatarsFlow(): Flow<Boolean> {
|
||||
override fun getHideInviteAvatarsFlow(): Flow<Boolean?> {
|
||||
return hideInviteAvatars
|
||||
}
|
||||
|
||||
override fun getTimelineMediaPreviewValueFlow(): Flow<MediaPreviewValue> {
|
||||
override fun getTimelineMediaPreviewValueFlow(): Flow<MediaPreviewValue?> {
|
||||
return timelineMediaPreviewValue
|
||||
}
|
||||
|
||||
override suspend fun setHideInviteAvatars(hide: Boolean?) {
|
||||
hideInviteAvatars.value = hide
|
||||
}
|
||||
|
||||
override suspend fun setTimelineMediaPreviewValue(mediaPreviewValue: MediaPreviewValue?) {
|
||||
timelineMediaPreviewValue.value = mediaPreviewValue
|
||||
}
|
||||
|
||||
override suspend fun setTracingLogLevel(logLevel: LogLevel) {
|
||||
this.logLevel.value = logLevel
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user