mirror of
https://github.com/Novaloop-AG/element-x-android.git
synced 2026-11-04 01:19:33 +00:00
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 im.vector.app.features.analytics.plan.JoinedRoom
|
||||||
import io.element.android.anvilannotations.ContributesNode
|
import io.element.android.anvilannotations.ContributesNode
|
||||||
import io.element.android.appnav.loggedin.LoggedInNode
|
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.loggedin.SendQueues
|
||||||
import io.element.android.appnav.room.RoomFlowNode
|
import io.element.android.appnav.room.RoomFlowNode
|
||||||
import io.element.android.appnav.room.RoomNavigationTarget
|
import io.element.android.appnav.room.RoomNavigationTarget
|
||||||
@@ -114,6 +115,7 @@ class LoggedInFlowNode @AssistedInject constructor(
|
|||||||
private val sendingQueue: SendQueues,
|
private val sendingQueue: SendQueues,
|
||||||
private val logoutEntryPoint: LogoutEntryPoint,
|
private val logoutEntryPoint: LogoutEntryPoint,
|
||||||
private val incomingVerificationEntryPoint: IncomingVerificationEntryPoint,
|
private val incomingVerificationEntryPoint: IncomingVerificationEntryPoint,
|
||||||
|
private val mediaPreviewConfigMigration: MediaPreviewConfigMigration,
|
||||||
snackbarDispatcher: SnackbarDispatcher,
|
snackbarDispatcher: SnackbarDispatcher,
|
||||||
) : BaseFlowNode<LoggedInFlowNode.NavTarget>(
|
) : BaseFlowNode<LoggedInFlowNode.NavTarget>(
|
||||||
backstack = BackStack(
|
backstack = BackStack(
|
||||||
@@ -179,6 +181,7 @@ class LoggedInFlowNode @AssistedInject constructor(
|
|||||||
appNavigationStateService.onNavigateToSpace(id, MAIN_SPACE)
|
appNavigationStateService.onNavigateToSpace(id, MAIN_SPACE)
|
||||||
loggedInFlowProcessor.observeEvents(sessionCoroutineScope)
|
loggedInFlowProcessor.observeEvents(sessionCoroutineScope)
|
||||||
matrixClient.sessionVerificationService().setListener(verificationListener)
|
matrixClient.sessionVerificationService().setListener(verificationListener)
|
||||||
|
mediaPreviewConfigMigration()
|
||||||
|
|
||||||
ftueService.state
|
ftueService.state
|
||||||
.onEach { ftueState ->
|
.onEach { ftueState ->
|
||||||
|
|||||||
+56
@@ -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.")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+4
-3
@@ -22,9 +22,10 @@ interface AppPreferencesStore {
|
|||||||
suspend fun setTheme(theme: String)
|
suspend fun setTheme(theme: String)
|
||||||
fun getThemeFlow(): Flow<String?>
|
fun getThemeFlow(): Flow<String?>
|
||||||
|
|
||||||
fun getHideInviteAvatarsFlow(): Flow<Boolean>
|
suspend fun setHideInviteAvatars(hide: Boolean?)
|
||||||
|
fun getHideInviteAvatarsFlow(): Flow<Boolean?>
|
||||||
fun getTimelineMediaPreviewValueFlow(): Flow<MediaPreviewValue>
|
suspend fun setTimelineMediaPreviewValue(mediaPreviewValue: MediaPreviewValue?)
|
||||||
|
fun getTimelineMediaPreviewValueFlow(): Flow<MediaPreviewValue?>
|
||||||
|
|
||||||
suspend fun setTracingLogLevel(logLevel: LogLevel)
|
suspend fun setTracingLogLevel(logLevel: LogLevel)
|
||||||
fun getTracingLogLevelFlow(): Flow<LogLevel>
|
fun getTracingLogLevelFlow(): Flow<LogLevel>
|
||||||
|
|||||||
+24
-4
@@ -85,15 +85,35 @@ class DefaultAppPreferencesStore @Inject constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getHideInviteAvatarsFlow(): Flow<Boolean> {
|
override fun getHideInviteAvatarsFlow(): Flow<Boolean?> {
|
||||||
return store.data.map { prefs ->
|
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 ->
|
return store.data.map { prefs ->
|
||||||
prefs[timelineMediaPreviewValueKey]?.let { MediaPreviewValue.valueOf(it) } ?: MediaPreviewValue.On
|
prefs[timelineMediaPreviewValueKey]?.let { MediaPreviewValue.valueOf(it) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+12
-4
@@ -17,8 +17,8 @@ import kotlinx.coroutines.flow.MutableStateFlow
|
|||||||
class InMemoryAppPreferencesStore(
|
class InMemoryAppPreferencesStore(
|
||||||
isDeveloperModeEnabled: Boolean = false,
|
isDeveloperModeEnabled: Boolean = false,
|
||||||
customElementCallBaseUrl: String? = null,
|
customElementCallBaseUrl: String? = null,
|
||||||
hideInviteAvatars: Boolean = false,
|
hideInviteAvatars: Boolean? = null,
|
||||||
timelineMediaPreviewValue: MediaPreviewValue = MediaPreviewValue.On,
|
timelineMediaPreviewValue: MediaPreviewValue? = null,
|
||||||
theme: String? = null,
|
theme: String? = null,
|
||||||
logLevel: LogLevel = LogLevel.INFO,
|
logLevel: LogLevel = LogLevel.INFO,
|
||||||
traceLockPacks: Set<TraceLogPack> = emptySet(),
|
traceLockPacks: Set<TraceLogPack> = emptySet(),
|
||||||
@@ -55,14 +55,22 @@ class InMemoryAppPreferencesStore(
|
|||||||
return theme
|
return theme
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getHideInviteAvatarsFlow(): Flow<Boolean> {
|
override fun getHideInviteAvatarsFlow(): Flow<Boolean?> {
|
||||||
return hideInviteAvatars
|
return hideInviteAvatars
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getTimelineMediaPreviewValueFlow(): Flow<MediaPreviewValue> {
|
override fun getTimelineMediaPreviewValueFlow(): Flow<MediaPreviewValue?> {
|
||||||
return timelineMediaPreviewValue
|
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) {
|
override suspend fun setTracingLogLevel(logLevel: LogLevel) {
|
||||||
this.logLevel.value = logLevel
|
this.logLevel.value = logLevel
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user