mirror of
https://github.com/element-hq/element-android
synced 2024-11-23 18:05:36 +03:00
Migrate Threads and notify user
This commit is contained in:
parent
99b43fd771
commit
2ca3387ab3
12 changed files with 177 additions and 12 deletions
|
@ -60,7 +60,11 @@ data class MatrixConfiguration(
|
||||||
/**
|
/**
|
||||||
* RoomDisplayNameFallbackProvider to provide default room display name.
|
* RoomDisplayNameFallbackProvider to provide default room display name.
|
||||||
*/
|
*/
|
||||||
val roomDisplayNameFallbackProvider: RoomDisplayNameFallbackProvider
|
val roomDisplayNameFallbackProvider: RoomDisplayNameFallbackProvider,
|
||||||
|
/**
|
||||||
|
* Thread messages default enable/disabled value
|
||||||
|
*/
|
||||||
|
val threadMessagesEnabledDefault: Boolean = false,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -19,6 +19,7 @@ package org.matrix.android.sdk.internal.database.lightweight
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import androidx.core.content.edit
|
import androidx.core.content.edit
|
||||||
import androidx.preference.PreferenceManager
|
import androidx.preference.PreferenceManager
|
||||||
|
import org.matrix.android.sdk.api.MatrixConfiguration
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -27,7 +28,10 @@ import javax.inject.Inject
|
||||||
* not for large data sets
|
* not for large data sets
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class LightweightSettingsStorage @Inject constructor(context: Context) {
|
class LightweightSettingsStorage @Inject constructor(
|
||||||
|
context: Context,
|
||||||
|
val matrixConfiguration: MatrixConfiguration
|
||||||
|
) {
|
||||||
|
|
||||||
private val sdkDefaultPrefs = PreferenceManager.getDefaultSharedPreferences(context.applicationContext)
|
private val sdkDefaultPrefs = PreferenceManager.getDefaultSharedPreferences(context.applicationContext)
|
||||||
|
|
||||||
|
@ -38,7 +42,7 @@ class LightweightSettingsStorage @Inject constructor(context: Context) {
|
||||||
}
|
}
|
||||||
|
|
||||||
fun areThreadMessagesEnabled(): Boolean {
|
fun areThreadMessagesEnabled(): Boolean {
|
||||||
return sdkDefaultPrefs.getBoolean(MATRIX_SDK_SETTINGS_THREAD_MESSAGES_ENABLED, false)
|
return sdkDefaultPrefs.getBoolean(MATRIX_SDK_SETTINGS_THREAD_MESSAGES_ENABLED, matrixConfiguration.threadMessagesEnabledDefault)
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|
|
@ -75,7 +75,7 @@ internal class SyncResponseHandler @Inject constructor(
|
||||||
suspend fun handleResponse(syncResponse: SyncResponse,
|
suspend fun handleResponse(syncResponse: SyncResponse,
|
||||||
fromToken: String?,
|
fromToken: String?,
|
||||||
reporter: ProgressReporter?) {
|
reporter: ProgressReporter?) {
|
||||||
val isInitialSync = fromToken == null
|
var isInitialSync = fromToken == null
|
||||||
Timber.v("Start handling sync, is InitialSync: $isInitialSync")
|
Timber.v("Start handling sync, is InitialSync: $isInitialSync")
|
||||||
|
|
||||||
measureTimeMillis {
|
measureTimeMillis {
|
||||||
|
|
|
@ -36,8 +36,9 @@
|
||||||
<!-- Level 1: Security and Privacy -->
|
<!-- Level 1: Security and Privacy -->
|
||||||
|
|
||||||
<!-- Level 1: Labs -->
|
<!-- Level 1: Labs -->
|
||||||
|
<bool name="settings_labs_thread_messages_default">false</bool>
|
||||||
|
|
||||||
<!-- Level 1: Advcanced settings -->
|
<!-- Level 1: Advanced settings -->
|
||||||
|
|
||||||
<!-- Level 1: Help and about -->
|
<!-- Level 1: Help and about -->
|
||||||
|
|
||||||
|
|
|
@ -46,6 +46,7 @@ import im.vector.app.features.navigation.Navigator
|
||||||
import im.vector.app.features.pin.PinCodeStore
|
import im.vector.app.features.pin.PinCodeStore
|
||||||
import im.vector.app.features.pin.SharedPrefPinCodeStore
|
import im.vector.app.features.pin.SharedPrefPinCodeStore
|
||||||
import im.vector.app.features.room.VectorRoomDisplayNameFallbackProvider
|
import im.vector.app.features.room.VectorRoomDisplayNameFallbackProvider
|
||||||
|
import im.vector.app.features.settings.VectorPreferences
|
||||||
import im.vector.app.features.ui.SharedPreferencesUiStateRepository
|
import im.vector.app.features.ui.SharedPreferencesUiStateRepository
|
||||||
import im.vector.app.features.ui.UiStateRepository
|
import im.vector.app.features.ui.UiStateRepository
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
@ -113,10 +114,13 @@ object VectorStaticModule {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
fun providesMatrixConfiguration(vectorRoomDisplayNameFallbackProvider: VectorRoomDisplayNameFallbackProvider): MatrixConfiguration {
|
fun providesMatrixConfiguration(
|
||||||
|
vectorPreferences: VectorPreferences,
|
||||||
|
vectorRoomDisplayNameFallbackProvider: VectorRoomDisplayNameFallbackProvider): MatrixConfiguration {
|
||||||
return MatrixConfiguration(
|
return MatrixConfiguration(
|
||||||
applicationFlavor = BuildConfig.FLAVOR_DESCRIPTION,
|
applicationFlavor = BuildConfig.FLAVOR_DESCRIPTION,
|
||||||
roomDisplayNameFallbackProvider = vectorRoomDisplayNameFallbackProvider
|
roomDisplayNameFallbackProvider = vectorRoomDisplayNameFallbackProvider,
|
||||||
|
threadMessagesEnabledDefault = vectorPreferences.areThreadMessagesEnabled()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -241,7 +241,7 @@ class MainActivity : VectorBaseActivity<ActivityMainBinding>(), UnlockedActivity
|
||||||
// We have a session.
|
// We have a session.
|
||||||
// Check it can be opened
|
// Check it can be opened
|
||||||
if (sessionHolder.getActiveSession().isOpenable) {
|
if (sessionHolder.getActiveSession().isOpenable) {
|
||||||
HomeActivity.newIntent(this)
|
HomeActivity.newIntent(this, existingSession = true)
|
||||||
} else {
|
} else {
|
||||||
// The token is still invalid
|
// The token is still invalid
|
||||||
navigator.softLogout(this)
|
navigator.softLogout(this)
|
||||||
|
|
|
@ -90,6 +90,7 @@ import javax.inject.Inject
|
||||||
data class HomeActivityArgs(
|
data class HomeActivityArgs(
|
||||||
val clearNotification: Boolean,
|
val clearNotification: Boolean,
|
||||||
val accountCreation: Boolean,
|
val accountCreation: Boolean,
|
||||||
|
val existingSession: Boolean = false,
|
||||||
val inviteNotificationRoomId: String? = null
|
val inviteNotificationRoomId: String? = null
|
||||||
) : Parcelable
|
) : Parcelable
|
||||||
|
|
||||||
|
@ -253,6 +254,8 @@ class HomeActivity :
|
||||||
HomeActivityViewEvents.PromptToEnableSessionPush -> handlePromptToEnablePush()
|
HomeActivityViewEvents.PromptToEnableSessionPush -> handlePromptToEnablePush()
|
||||||
is HomeActivityViewEvents.OnCrossSignedInvalidated -> handleCrossSigningInvalidated(it)
|
is HomeActivityViewEvents.OnCrossSignedInvalidated -> handleCrossSigningInvalidated(it)
|
||||||
HomeActivityViewEvents.ShowAnalyticsOptIn -> handleShowAnalyticsOptIn()
|
HomeActivityViewEvents.ShowAnalyticsOptIn -> handleShowAnalyticsOptIn()
|
||||||
|
HomeActivityViewEvents.NotifyUserForThreadsMigration -> handleNotifyUserForThreadsMigration()
|
||||||
|
is HomeActivityViewEvents.MigrateThreads -> migrateThreadsIfNeeded(it.checkSession)
|
||||||
}.exhaustive
|
}.exhaustive
|
||||||
}
|
}
|
||||||
homeActivityViewModel.onEach { renderState(it) }
|
homeActivityViewModel.onEach { renderState(it) }
|
||||||
|
@ -269,6 +272,49 @@ class HomeActivity :
|
||||||
navigator.openAnalyticsOptIn(this)
|
navigator.openAnalyticsOptIn(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Migrating from old threads io.element.thread to new m.thread needs an initial sync to
|
||||||
|
* sync and display existing messages appropriately
|
||||||
|
*/
|
||||||
|
private fun migrateThreadsIfNeeded(checkSession: Boolean) {
|
||||||
|
|
||||||
|
if (checkSession) {
|
||||||
|
// We should check session to ensure we will only clear cache if needed
|
||||||
|
val args = intent.getParcelableExtra<HomeActivityArgs>(Mavericks.KEY_ARG)
|
||||||
|
if (args?.existingSession == true) {
|
||||||
|
// existingSession --> Will be true only if we came from an existing active session
|
||||||
|
Timber.i("----> Migrating threads from an existing session..")
|
||||||
|
handleThreadsMigration()
|
||||||
|
} else {
|
||||||
|
// We came from a new session and not an existing one,
|
||||||
|
// so there is no need to migrate threads while an initial synced performed
|
||||||
|
Timber.i("----> No thread migration needed, we are ok")
|
||||||
|
vectorPreferences.threadsMigrated()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Proceed with migration
|
||||||
|
handleThreadsMigration()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clear cache and restart to invoke an initial sync for threads migration
|
||||||
|
*/
|
||||||
|
private fun handleThreadsMigration() {
|
||||||
|
Timber.i("----> Threads Migration detected, clearing cache and sync...")
|
||||||
|
vectorPreferences.threadsMigrated()
|
||||||
|
MainActivity.restartApp(this, MainActivityArgs(clearCache = true))
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun handleNotifyUserForThreadsMigration() {
|
||||||
|
MaterialAlertDialogBuilder(this)
|
||||||
|
.setTitle("Threads, no longer experimental")
|
||||||
|
.setMessage("All \uD83C\uDF89 \uD83C\uDF89 threads created during experimental period will\n\n now be rendered as regular replies. This will be an one-off transition, as threads are now part of the matrix specification")
|
||||||
|
.setCancelable(true)
|
||||||
|
.setPositiveButton(R.string.ok) { _, _ -> }
|
||||||
|
.show()
|
||||||
|
}
|
||||||
|
|
||||||
private fun handleIntent(intent: Intent?) {
|
private fun handleIntent(intent: Intent?) {
|
||||||
intent?.dataString?.let { deepLink ->
|
intent?.dataString?.let { deepLink ->
|
||||||
val resolvedLink = when {
|
val resolvedLink = when {
|
||||||
|
@ -546,11 +592,13 @@ class HomeActivity :
|
||||||
fun newIntent(context: Context,
|
fun newIntent(context: Context,
|
||||||
clearNotification: Boolean = false,
|
clearNotification: Boolean = false,
|
||||||
accountCreation: Boolean = false,
|
accountCreation: Boolean = false,
|
||||||
|
existingSession: Boolean = false,
|
||||||
inviteNotificationRoomId: String? = null
|
inviteNotificationRoomId: String? = null
|
||||||
): Intent {
|
): Intent {
|
||||||
val args = HomeActivityArgs(
|
val args = HomeActivityArgs(
|
||||||
clearNotification = clearNotification,
|
clearNotification = clearNotification,
|
||||||
accountCreation = accountCreation,
|
accountCreation = accountCreation,
|
||||||
|
existingSession = existingSession,
|
||||||
inviteNotificationRoomId = inviteNotificationRoomId
|
inviteNotificationRoomId = inviteNotificationRoomId
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -25,4 +25,7 @@ sealed interface HomeActivityViewEvents : VectorViewEvents {
|
||||||
data class OnCrossSignedInvalidated(val userItem: MatrixItem.UserItem) : HomeActivityViewEvents
|
data class OnCrossSignedInvalidated(val userItem: MatrixItem.UserItem) : HomeActivityViewEvents
|
||||||
object PromptToEnableSessionPush : HomeActivityViewEvents
|
object PromptToEnableSessionPush : HomeActivityViewEvents
|
||||||
object ShowAnalyticsOptIn : HomeActivityViewEvents
|
object ShowAnalyticsOptIn : HomeActivityViewEvents
|
||||||
|
object NotifyUserForThreadsMigration : HomeActivityViewEvents
|
||||||
|
data class MigrateThreads(val checkSession: Boolean) : HomeActivityViewEvents
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,6 +51,7 @@ import org.matrix.android.sdk.api.util.toMatrixItem
|
||||||
import org.matrix.android.sdk.flow.flow
|
import org.matrix.android.sdk.flow.flow
|
||||||
import org.matrix.android.sdk.internal.crypto.model.CryptoDeviceInfo
|
import org.matrix.android.sdk.internal.crypto.model.CryptoDeviceInfo
|
||||||
import org.matrix.android.sdk.internal.crypto.model.MXUsersDevicesMap
|
import org.matrix.android.sdk.internal.crypto.model.MXUsersDevicesMap
|
||||||
|
import org.matrix.android.sdk.internal.database.lightweight.LightweightSettingsStorage
|
||||||
import org.matrix.android.sdk.internal.util.awaitCallback
|
import org.matrix.android.sdk.internal.util.awaitCallback
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import kotlin.coroutines.Continuation
|
import kotlin.coroutines.Continuation
|
||||||
|
@ -62,6 +63,7 @@ class HomeActivityViewModel @AssistedInject constructor(
|
||||||
private val activeSessionHolder: ActiveSessionHolder,
|
private val activeSessionHolder: ActiveSessionHolder,
|
||||||
private val reAuthHelper: ReAuthHelper,
|
private val reAuthHelper: ReAuthHelper,
|
||||||
private val analyticsStore: AnalyticsStore,
|
private val analyticsStore: AnalyticsStore,
|
||||||
|
private val lightweightSettingsStorage: LightweightSettingsStorage,
|
||||||
private val vectorPreferences: VectorPreferences
|
private val vectorPreferences: VectorPreferences
|
||||||
) : VectorViewModel<HomeActivityViewState, HomeActivityViewActions, HomeActivityViewEvents>(initialState) {
|
) : VectorViewModel<HomeActivityViewState, HomeActivityViewActions, HomeActivityViewEvents>(initialState) {
|
||||||
|
|
||||||
|
@ -84,6 +86,7 @@ class HomeActivityViewModel @AssistedInject constructor(
|
||||||
checkSessionPushIsOn()
|
checkSessionPushIsOn()
|
||||||
observeCrossSigningReset()
|
observeCrossSigningReset()
|
||||||
observeAnalytics()
|
observeAnalytics()
|
||||||
|
initThreadsMigration()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun observeAnalytics() {
|
private fun observeAnalytics() {
|
||||||
|
@ -130,6 +133,49 @@ class HomeActivityViewModel @AssistedInject constructor(
|
||||||
.launchIn(viewModelScope)
|
.launchIn(viewModelScope)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle threads migration. The migration includes:
|
||||||
|
* - Notify users that had io.element.thread enabled from labs
|
||||||
|
* - Re-Enable m.thread to those users (that they had enabled labs threads)
|
||||||
|
* - Handle migration when threads are enabled by default
|
||||||
|
*/
|
||||||
|
private fun initThreadsMigration() {
|
||||||
|
|
||||||
|
// Notify users
|
||||||
|
if (vectorPreferences.shouldNotifyUserAboutThreads() && vectorPreferences.areThreadMessagesEnabled()) {
|
||||||
|
Timber.i("----> Notify users about threads")
|
||||||
|
// Notify the user if needed that we migrated to support m.thread
|
||||||
|
// instead of io.element.thread so old thread messages will be displayed as normal timeline messages
|
||||||
|
_viewEvents.post(HomeActivityViewEvents.NotifyUserForThreadsMigration)
|
||||||
|
vectorPreferences.userNotifiedAboutThreads()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Migrate users with enabled lab settings
|
||||||
|
if (vectorPreferences.shouldNotifyUserAboutThreads() && vectorPreferences.shouldMigrateThreads()) {
|
||||||
|
Timber.i("----> Migrate threads with enabled labs")
|
||||||
|
// If user had io.element.thread enabled then enable the new thread support,
|
||||||
|
// clear cache to sync messages appropriately
|
||||||
|
vectorPreferences.setThreadMessagesEnabled()
|
||||||
|
lightweightSettingsStorage.setThreadMessagesEnabled(vectorPreferences.areThreadMessagesEnabled())
|
||||||
|
// Clear Cache
|
||||||
|
_viewEvents.post(HomeActivityViewEvents.MigrateThreads(checkSession = false))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// Enable all users
|
||||||
|
// When we would to enable threads for all
|
||||||
|
// if(vectorPreferences.shouldMigrateThreads) -->
|
||||||
|
// vectorPreferences.setThreadMessagesEnabled() &&
|
||||||
|
// lightweightSettingsStorage.setThreadMessagesEnabled(vectorPreferences.areThreadMessagesEnabled())
|
||||||
|
if(vectorPreferences.shouldMigrateThreads() && vectorPreferences.areThreadMessagesEnabled()){
|
||||||
|
Timber.i("----> Try to migrate threads")
|
||||||
|
_viewEvents.post(HomeActivityViewEvents.MigrateThreads(checkSession = true))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
private fun observeInitialSync() {
|
private fun observeInitialSync() {
|
||||||
val session = activeSessionHolder.getSafeActiveSession() ?: return
|
val session = activeSessionHolder.getSafeActiveSession() ?: return
|
||||||
|
|
||||||
|
|
|
@ -201,7 +201,13 @@ class VectorPreferences @Inject constructor(private val context: Context) {
|
||||||
private const val TAKE_PHOTO_VIDEO_MODE = "TAKE_PHOTO_VIDEO_MODE"
|
private const val TAKE_PHOTO_VIDEO_MODE = "TAKE_PHOTO_VIDEO_MODE"
|
||||||
|
|
||||||
private const val SETTINGS_LABS_RENDER_LOCATIONS_IN_TIMELINE = "SETTINGS_LABS_RENDER_LOCATIONS_IN_TIMELINE"
|
private const val SETTINGS_LABS_RENDER_LOCATIONS_IN_TIMELINE = "SETTINGS_LABS_RENDER_LOCATIONS_IN_TIMELINE"
|
||||||
const val SETTINGS_LABS_ENABLE_THREAD_MESSAGES = "SETTINGS_LABS_ENABLE_THREAD_MESSAGES"
|
|
||||||
|
// This key will be used to identify clients with the old thread support enabled io.element.thread
|
||||||
|
const val SETTINGS_LABS_ENABLE_THREAD_MESSAGES_OLD_CLIENTS = "SETTINGS_LABS_ENABLE_THREAD_MESSAGES"
|
||||||
|
|
||||||
|
// This key will be used to identify clients with the new thread support enabled m.thread
|
||||||
|
const val SETTINGS_LABS_ENABLE_THREAD_MESSAGES = "SETTINGS_LABS_ENABLE_THREAD_MESSAGES_FINAL"
|
||||||
|
const val SETTINGS_THREAD_MESSAGES_SYNCED = "SETTINGS_THREAD_MESSAGES_SYNCED"
|
||||||
|
|
||||||
// Possible values for TAKE_PHOTO_VIDEO_MODE
|
// Possible values for TAKE_PHOTO_VIDEO_MODE
|
||||||
const val TAKE_PHOTO_VIDEO_MODE_ALWAYS_ASK = 0
|
const val TAKE_PHOTO_VIDEO_MODE_ALWAYS_ASK = 0
|
||||||
|
@ -1006,7 +1012,55 @@ class VectorPreferences @Inject constructor(private val context: Context) {
|
||||||
return defaultPrefs.getBoolean(SETTINGS_LABS_RENDER_LOCATIONS_IN_TIMELINE, true)
|
return defaultPrefs.getBoolean(SETTINGS_LABS_RENDER_LOCATIONS_IN_TIMELINE, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates whether or not thread messages are enabled
|
||||||
|
*/
|
||||||
fun areThreadMessagesEnabled(): Boolean {
|
fun areThreadMessagesEnabled(): Boolean {
|
||||||
return defaultPrefs.getBoolean(SETTINGS_LABS_ENABLE_THREAD_MESSAGES, false)
|
return defaultPrefs.getBoolean(SETTINGS_LABS_ENABLE_THREAD_MESSAGES, getDefault(R.bool.settings_labs_thread_messages_default))
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Manually sets thread messages enabled, useful for migrating users from io.element.thread
|
||||||
|
*/
|
||||||
|
fun setThreadMessagesEnabled() {
|
||||||
|
defaultPrefs
|
||||||
|
.edit()
|
||||||
|
.putBoolean(SETTINGS_LABS_ENABLE_THREAD_MESSAGES, true)
|
||||||
|
.apply()
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Indicates whether or not the user will be notified about the new thread support
|
||||||
|
* We should notify the user only if he had old thread support enabled
|
||||||
|
*/
|
||||||
|
fun shouldNotifyUserAboutThreads(): Boolean {
|
||||||
|
return defaultPrefs.getBoolean(SETTINGS_LABS_ENABLE_THREAD_MESSAGES_OLD_CLIENTS, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates that the user have been notified about threads migration
|
||||||
|
*/
|
||||||
|
fun userNotifiedAboutThreads() {
|
||||||
|
defaultPrefs
|
||||||
|
.edit()
|
||||||
|
.putBoolean(SETTINGS_LABS_ENABLE_THREAD_MESSAGES_OLD_CLIENTS, false)
|
||||||
|
.apply()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates whether or not we should clear cache for threads migration.
|
||||||
|
* Default value is true, for fresh installs and updates
|
||||||
|
*/
|
||||||
|
fun shouldMigrateThreads(): Boolean {
|
||||||
|
return defaultPrefs.getBoolean(SETTINGS_THREAD_MESSAGES_SYNCED, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates that there no longer threads migration needed
|
||||||
|
*/
|
||||||
|
fun threadsMigrated() {
|
||||||
|
defaultPrefs
|
||||||
|
.edit()
|
||||||
|
.putBoolean(SETTINGS_THREAD_MESSAGES_SYNCED, false)
|
||||||
|
.apply()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,6 +42,7 @@ class VectorSettingsLabsFragment @Inject constructor(
|
||||||
// clear cache
|
// clear cache
|
||||||
findPreference<VectorSwitchPreference>(VectorPreferences.SETTINGS_LABS_ENABLE_THREAD_MESSAGES)?.let {
|
findPreference<VectorSwitchPreference>(VectorPreferences.SETTINGS_LABS_ENABLE_THREAD_MESSAGES)?.let {
|
||||||
it.onPreferenceClickListener = Preference.OnPreferenceClickListener {
|
it.onPreferenceClickListener = Preference.OnPreferenceClickListener {
|
||||||
|
vectorPreferences.threadsMigrated() // Manual actions should disable the ato enable mechanism
|
||||||
lightweightSettingsStorage.setThreadMessagesEnabled(vectorPreferences.areThreadMessagesEnabled())
|
lightweightSettingsStorage.setThreadMessagesEnabled(vectorPreferences.areThreadMessagesEnabled())
|
||||||
displayLoadingView()
|
displayLoadingView()
|
||||||
MainActivity.restartApp(requireActivity(), MainActivityArgs(clearCache = true))
|
MainActivity.restartApp(requireActivity(), MainActivityArgs(clearCache = true))
|
||||||
|
|
|
@ -52,8 +52,8 @@
|
||||||
<!--</im.vector.app.core.preference.VectorPreferenceCategory>-->
|
<!--</im.vector.app.core.preference.VectorPreferenceCategory>-->
|
||||||
|
|
||||||
<im.vector.app.core.preference.VectorSwitchPreference
|
<im.vector.app.core.preference.VectorSwitchPreference
|
||||||
android:defaultValue="false"
|
android:defaultValue="@bool/settings_labs_thread_messages_default"
|
||||||
android:key="SETTINGS_LABS_ENABLE_THREAD_MESSAGES"
|
android:key="SETTINGS_LABS_ENABLE_THREAD_MESSAGES_FINAL"
|
||||||
android:summary="@string/labs_enable_thread_messages_desc"
|
android:summary="@string/labs_enable_thread_messages_desc"
|
||||||
android:title="@string/labs_enable_thread_messages" />
|
android:title="@string/labs_enable_thread_messages" />
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue