Lifting debug overrides to their own abstraction (#5361)
* separating the debug overrides to their own abstraction - rather than sharing the user facing vector data store * inlining the debug flow getters and declarations - also replaces funs with vals as the references are immutable * adding changelog entry
This commit is contained in:
parent
1c94a7ddc7
commit
0c628905de
|
@ -0,0 +1 @@
|
||||||
|
Creates dedicated VectorOverrides for forcing behaviour for local testing/development
|
|
@ -23,8 +23,11 @@ import dagger.Provides
|
||||||
import dagger.hilt.InstallIn
|
import dagger.hilt.InstallIn
|
||||||
import dagger.hilt.components.SingletonComponent
|
import dagger.hilt.components.SingletonComponent
|
||||||
import im.vector.app.features.DefaultVectorFeatures
|
import im.vector.app.features.DefaultVectorFeatures
|
||||||
|
import im.vector.app.features.DefaultVectorOverrides
|
||||||
import im.vector.app.features.VectorFeatures
|
import im.vector.app.features.VectorFeatures
|
||||||
|
import im.vector.app.features.VectorOverrides
|
||||||
import im.vector.app.features.debug.features.DebugVectorFeatures
|
import im.vector.app.features.debug.features.DebugVectorFeatures
|
||||||
|
import im.vector.app.features.debug.features.DebugVectorOverrides
|
||||||
|
|
||||||
@InstallIn(SingletonComponent::class)
|
@InstallIn(SingletonComponent::class)
|
||||||
@Module
|
@Module
|
||||||
|
@ -33,6 +36,9 @@ interface FeaturesModule {
|
||||||
@Binds
|
@Binds
|
||||||
fun bindFeatures(debugFeatures: DebugVectorFeatures): VectorFeatures
|
fun bindFeatures(debugFeatures: DebugVectorFeatures): VectorFeatures
|
||||||
|
|
||||||
|
@Binds
|
||||||
|
fun bindOverrides(debugOverrides: DebugVectorOverrides): VectorOverrides
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
|
@ -44,5 +50,15 @@ interface FeaturesModule {
|
||||||
fun providesDebugVectorFeatures(context: Context, defaultVectorFeatures: DefaultVectorFeatures): DebugVectorFeatures {
|
fun providesDebugVectorFeatures(context: Context, defaultVectorFeatures: DefaultVectorFeatures): DebugVectorFeatures {
|
||||||
return DebugVectorFeatures(context, defaultVectorFeatures)
|
return DebugVectorFeatures(context, defaultVectorFeatures)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
fun providesDefaultVectorOverrides(): DefaultVectorOverrides {
|
||||||
|
return DefaultVectorOverrides()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
fun providesDebugVectorOverrides(context: Context): DebugVectorOverrides {
|
||||||
|
return DebugVectorOverrides(context)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,54 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2022 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.app.features.debug.features
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import androidx.datastore.core.DataStore
|
||||||
|
import androidx.datastore.preferences.core.Preferences
|
||||||
|
import androidx.datastore.preferences.core.booleanPreferencesKey
|
||||||
|
import androidx.datastore.preferences.core.edit
|
||||||
|
import androidx.datastore.preferences.preferencesDataStore
|
||||||
|
import im.vector.app.features.VectorOverrides
|
||||||
|
import kotlinx.coroutines.flow.map
|
||||||
|
import org.matrix.android.sdk.api.extensions.orFalse
|
||||||
|
|
||||||
|
private val Context.dataStore: DataStore<Preferences> by preferencesDataStore(name = "vector_overrides")
|
||||||
|
private val keyForceDialPadDisplay = booleanPreferencesKey("force_dial_pad_display")
|
||||||
|
private val keyForceLoginFallback = booleanPreferencesKey("force_login_fallback")
|
||||||
|
|
||||||
|
class DebugVectorOverrides(private val context: Context) : VectorOverrides {
|
||||||
|
|
||||||
|
override val forceDialPad = context.dataStore.data.map { preferences ->
|
||||||
|
preferences[keyForceDialPadDisplay].orFalse()
|
||||||
|
}
|
||||||
|
|
||||||
|
override val forceLoginFallback = context.dataStore.data.map { preferences ->
|
||||||
|
preferences[keyForceLoginFallback].orFalse()
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun setForceDialPadDisplay(force: Boolean) {
|
||||||
|
context.dataStore.edit { settings ->
|
||||||
|
settings[keyForceDialPadDisplay] = force
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun setForceLoginFallback(force: Boolean) {
|
||||||
|
context.dataStore.edit { settings ->
|
||||||
|
settings[keyForceLoginFallback] = force
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -24,12 +24,12 @@ import im.vector.app.core.di.MavericksAssistedViewModelFactory
|
||||||
import im.vector.app.core.di.hiltMavericksViewModelFactory
|
import im.vector.app.core.di.hiltMavericksViewModelFactory
|
||||||
import im.vector.app.core.platform.EmptyViewEvents
|
import im.vector.app.core.platform.EmptyViewEvents
|
||||||
import im.vector.app.core.platform.VectorViewModel
|
import im.vector.app.core.platform.VectorViewModel
|
||||||
import im.vector.app.features.settings.VectorDataStore
|
import im.vector.app.features.debug.features.DebugVectorOverrides
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
class DebugPrivateSettingsViewModel @AssistedInject constructor(
|
class DebugPrivateSettingsViewModel @AssistedInject constructor(
|
||||||
@Assisted initialState: DebugPrivateSettingsViewState,
|
@Assisted initialState: DebugPrivateSettingsViewState,
|
||||||
private val vectorDataStore: VectorDataStore
|
private val debugVectorOverrides: DebugVectorOverrides
|
||||||
) : VectorViewModel<DebugPrivateSettingsViewState, DebugPrivateSettingsViewActions, EmptyViewEvents>(initialState) {
|
) : VectorViewModel<DebugPrivateSettingsViewState, DebugPrivateSettingsViewActions, EmptyViewEvents>(initialState) {
|
||||||
|
|
||||||
@AssistedFactory
|
@AssistedFactory
|
||||||
|
@ -44,11 +44,12 @@ class DebugPrivateSettingsViewModel @AssistedInject constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun observeVectorDataStore() {
|
private fun observeVectorDataStore() {
|
||||||
vectorDataStore.forceDialPadDisplayFlow.setOnEach {
|
debugVectorOverrides.forceDialPad.setOnEach {
|
||||||
copy(dialPadVisible = it)
|
copy(
|
||||||
|
dialPadVisible = it
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
debugVectorOverrides.forceLoginFallback.setOnEach {
|
||||||
vectorDataStore.forceLoginFallbackFlow.setOnEach {
|
|
||||||
copy(forceLoginFallback = it)
|
copy(forceLoginFallback = it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -62,13 +63,13 @@ class DebugPrivateSettingsViewModel @AssistedInject constructor(
|
||||||
|
|
||||||
private fun handleSetDialPadVisibility(action: DebugPrivateSettingsViewActions.SetDialPadVisibility) {
|
private fun handleSetDialPadVisibility(action: DebugPrivateSettingsViewActions.SetDialPadVisibility) {
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
vectorDataStore.setForceDialPadDisplay(action.force)
|
debugVectorOverrides.setForceDialPadDisplay(action.force)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun handleSetForceLoginFallbackEnabled(action: DebugPrivateSettingsViewActions.SetForceLoginFallbackEnabled) {
|
private fun handleSetForceLoginFallbackEnabled(action: DebugPrivateSettingsViewActions.SetForceLoginFallbackEnabled) {
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
vectorDataStore.setForceLoginFallbackFlow(action.force)
|
debugVectorOverrides.setForceLoginFallback(action.force)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2022 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.app.features
|
||||||
|
|
||||||
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
import kotlinx.coroutines.flow.flowOf
|
||||||
|
|
||||||
|
interface VectorOverrides {
|
||||||
|
val forceDialPad: Flow<Boolean>
|
||||||
|
val forceLoginFallback: Flow<Boolean>
|
||||||
|
}
|
||||||
|
|
||||||
|
class DefaultVectorOverrides : VectorOverrides {
|
||||||
|
override val forceDialPad = flowOf(false)
|
||||||
|
override val forceLoginFallback = flowOf(false)
|
||||||
|
}
|
|
@ -28,6 +28,7 @@ import im.vector.app.core.di.MavericksAssistedViewModelFactory
|
||||||
import im.vector.app.core.di.hiltMavericksViewModelFactory
|
import im.vector.app.core.di.hiltMavericksViewModelFactory
|
||||||
import im.vector.app.core.extensions.singletonEntryPoint
|
import im.vector.app.core.extensions.singletonEntryPoint
|
||||||
import im.vector.app.core.platform.VectorViewModel
|
import im.vector.app.core.platform.VectorViewModel
|
||||||
|
import im.vector.app.features.VectorOverrides
|
||||||
import im.vector.app.features.call.dialpad.DialPadLookup
|
import im.vector.app.features.call.dialpad.DialPadLookup
|
||||||
import im.vector.app.features.call.lookup.CallProtocolsChecker
|
import im.vector.app.features.call.lookup.CallProtocolsChecker
|
||||||
import im.vector.app.features.call.webrtc.WebRtcCallManager
|
import im.vector.app.features.call.webrtc.WebRtcCallManager
|
||||||
|
@ -67,7 +68,8 @@ class HomeDetailViewModel @AssistedInject constructor(
|
||||||
private val callManager: WebRtcCallManager,
|
private val callManager: WebRtcCallManager,
|
||||||
private val directRoomHelper: DirectRoomHelper,
|
private val directRoomHelper: DirectRoomHelper,
|
||||||
private val appStateHandler: AppStateHandler,
|
private val appStateHandler: AppStateHandler,
|
||||||
private val autoAcceptInvites: AutoAcceptInvites
|
private val autoAcceptInvites: AutoAcceptInvites,
|
||||||
|
private val vectorOverrides: VectorOverrides
|
||||||
) : VectorViewModel<HomeDetailViewState, HomeDetailAction, HomeDetailViewEvents>(initialState),
|
) : VectorViewModel<HomeDetailViewState, HomeDetailAction, HomeDetailViewEvents>(initialState),
|
||||||
CallProtocolsChecker.Listener {
|
CallProtocolsChecker.Listener {
|
||||||
|
|
||||||
|
@ -106,8 +108,7 @@ class HomeDetailViewModel @AssistedInject constructor(
|
||||||
pushCounter = nbOfPush
|
pushCounter = nbOfPush
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
vectorOverrides.forceDialPad.setOnEach { force ->
|
||||||
vectorDataStore.forceDialPadDisplayFlow.setOnEach { force ->
|
|
||||||
copy(
|
copy(
|
||||||
forceDialPadTab = force
|
forceDialPadTab = force
|
||||||
)
|
)
|
||||||
|
|
|
@ -37,6 +37,7 @@ import im.vector.app.core.platform.VectorViewModel
|
||||||
import im.vector.app.core.resources.StringProvider
|
import im.vector.app.core.resources.StringProvider
|
||||||
import im.vector.app.core.utils.ensureTrailingSlash
|
import im.vector.app.core.utils.ensureTrailingSlash
|
||||||
import im.vector.app.features.VectorFeatures
|
import im.vector.app.features.VectorFeatures
|
||||||
|
import im.vector.app.features.VectorOverrides
|
||||||
import im.vector.app.features.analytics.AnalyticsTracker
|
import im.vector.app.features.analytics.AnalyticsTracker
|
||||||
import im.vector.app.features.analytics.extensions.toTrackingValue
|
import im.vector.app.features.analytics.extensions.toTrackingValue
|
||||||
import im.vector.app.features.analytics.plan.UserProperties
|
import im.vector.app.features.analytics.plan.UserProperties
|
||||||
|
@ -81,6 +82,7 @@ class OnboardingViewModel @AssistedInject constructor(
|
||||||
private val vectorFeatures: VectorFeatures,
|
private val vectorFeatures: VectorFeatures,
|
||||||
private val analyticsTracker: AnalyticsTracker,
|
private val analyticsTracker: AnalyticsTracker,
|
||||||
private val vectorDataStore: VectorDataStore,
|
private val vectorDataStore: VectorDataStore,
|
||||||
|
private val vectorOverrides: VectorOverrides
|
||||||
) : VectorViewModel<OnboardingViewState, OnboardingAction, OnboardingViewEvents>(initialState) {
|
) : VectorViewModel<OnboardingViewState, OnboardingAction, OnboardingViewEvents>(initialState) {
|
||||||
|
|
||||||
@AssistedFactory
|
@AssistedFactory
|
||||||
|
@ -102,7 +104,7 @@ class OnboardingViewModel @AssistedInject constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun observeDataStore() = viewModelScope.launch {
|
private fun observeDataStore() = viewModelScope.launch {
|
||||||
vectorDataStore.forceLoginFallbackFlow.setOnEach { isForceLoginFallbackEnabled ->
|
vectorOverrides.forceLoginFallback.setOnEach { isForceLoginFallbackEnabled ->
|
||||||
copy(isForceLoginFallbackEnabled = isForceLoginFallbackEnabled)
|
copy(isForceLoginFallbackEnabled = isForceLoginFallbackEnabled)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,13 +19,11 @@ package im.vector.app.features.settings
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import androidx.datastore.core.DataStore
|
import androidx.datastore.core.DataStore
|
||||||
import androidx.datastore.preferences.core.Preferences
|
import androidx.datastore.preferences.core.Preferences
|
||||||
import androidx.datastore.preferences.core.booleanPreferencesKey
|
|
||||||
import androidx.datastore.preferences.core.edit
|
import androidx.datastore.preferences.core.edit
|
||||||
import androidx.datastore.preferences.core.intPreferencesKey
|
import androidx.datastore.preferences.core.intPreferencesKey
|
||||||
import androidx.datastore.preferences.preferencesDataStore
|
import androidx.datastore.preferences.preferencesDataStore
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
import kotlinx.coroutines.flow.map
|
import kotlinx.coroutines.flow.map
|
||||||
import org.matrix.android.sdk.api.extensions.orFalse
|
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
private val Context.dataStore: DataStore<Preferences> by preferencesDataStore(name = "vector_settings")
|
private val Context.dataStore: DataStore<Preferences> by preferencesDataStore(name = "vector_settings")
|
||||||
|
@ -46,29 +44,4 @@ class VectorDataStore @Inject constructor(
|
||||||
settings[pushCounter] = currentCounterValue + 1
|
settings[pushCounter] = currentCounterValue + 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// For debug only
|
|
||||||
private val forceDialPadDisplay = booleanPreferencesKey("force_dial_pad_display")
|
|
||||||
|
|
||||||
val forceDialPadDisplayFlow: Flow<Boolean> = context.dataStore.data.map { preferences ->
|
|
||||||
preferences[forceDialPadDisplay].orFalse()
|
|
||||||
}
|
|
||||||
|
|
||||||
suspend fun setForceDialPadDisplay(force: Boolean) {
|
|
||||||
context.dataStore.edit { settings ->
|
|
||||||
settings[forceDialPadDisplay] = force
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private val forceLoginFallback = booleanPreferencesKey("force_login_fallback")
|
|
||||||
|
|
||||||
val forceLoginFallbackFlow: Flow<Boolean> = context.dataStore.data.map { preferences ->
|
|
||||||
preferences[forceLoginFallback].orFalse()
|
|
||||||
}
|
|
||||||
|
|
||||||
suspend fun setForceLoginFallbackFlow(force: Boolean) {
|
|
||||||
context.dataStore.edit { settings ->
|
|
||||||
settings[forceLoginFallback] = force
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,9 @@ import dagger.Provides
|
||||||
import dagger.hilt.InstallIn
|
import dagger.hilt.InstallIn
|
||||||
import dagger.hilt.components.SingletonComponent
|
import dagger.hilt.components.SingletonComponent
|
||||||
import im.vector.app.features.DefaultVectorFeatures
|
import im.vector.app.features.DefaultVectorFeatures
|
||||||
|
import im.vector.app.features.DefaultVectorOverrides
|
||||||
import im.vector.app.features.VectorFeatures
|
import im.vector.app.features.VectorFeatures
|
||||||
|
import im.vector.app.features.VectorOverrides
|
||||||
|
|
||||||
@InstallIn(SingletonComponent::class)
|
@InstallIn(SingletonComponent::class)
|
||||||
@Module
|
@Module
|
||||||
|
@ -31,4 +33,9 @@ object FeaturesModule {
|
||||||
fun providesFeatures(): VectorFeatures {
|
fun providesFeatures(): VectorFeatures {
|
||||||
return DefaultVectorFeatures()
|
return DefaultVectorFeatures()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
fun providesOverrides(): VectorOverrides {
|
||||||
|
return DefaultVectorOverrides()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue