Merge pull request #6587 from element-hq/feature/bma/flagsFromOnBoarding
Split developer settings into 2 screens to be able to access global settings when no logged in.
This commit is contained in:
commit
9699488ae5
46 changed files with 1035 additions and 469 deletions
|
|
@ -41,6 +41,7 @@ import io.element.android.features.login.impl.screens.createaccount.CreateAccoun
|
|||
import io.element.android.features.login.impl.screens.loginpassword.LoginPasswordNode
|
||||
import io.element.android.features.login.impl.screens.onboarding.OnBoardingNode
|
||||
import io.element.android.features.login.impl.screens.searchaccountprovider.SearchAccountProviderNode
|
||||
import io.element.android.features.preferences.api.PreferencesEntryPoint
|
||||
import io.element.android.libraries.androidutils.browser.openUrlInChromeCustomTab
|
||||
import io.element.android.libraries.architecture.BackstackView
|
||||
import io.element.android.libraries.architecture.BaseFlowNode
|
||||
|
|
@ -67,6 +68,7 @@ class LoginFlowNode(
|
|||
@AppCoroutineScope
|
||||
private val appCoroutineScope: CoroutineScope,
|
||||
private val elementClassicConnection: ElementClassicConnection,
|
||||
private val preferencesEntryPoint: PreferencesEntryPoint,
|
||||
) : BaseFlowNode<LoginFlowNode.NavTarget>(
|
||||
backstack = BackStack(
|
||||
initialElement = NavTarget.CheckClassicFlow,
|
||||
|
|
@ -117,6 +119,9 @@ class LoginFlowNode(
|
|||
@Parcelize
|
||||
data object QrCode : NavTarget
|
||||
|
||||
@Parcelize
|
||||
data object AppDeveloperSettings : NavTarget
|
||||
|
||||
@Parcelize
|
||||
data class ConfirmAccountProvider(
|
||||
val isAccountCreation: Boolean,
|
||||
|
|
@ -200,6 +205,10 @@ class LoginFlowNode(
|
|||
backstack.push(NavTarget.CreateAccount(url))
|
||||
}
|
||||
|
||||
override fun navigateToDeveloperSettings() {
|
||||
backstack.push(NavTarget.AppDeveloperSettings)
|
||||
}
|
||||
|
||||
override fun navigateToLoginPassword() {
|
||||
backstack.push(NavTarget.LoginPassword())
|
||||
}
|
||||
|
|
@ -220,6 +229,18 @@ class LoginFlowNode(
|
|||
)
|
||||
createNode<OnBoardingNode>(buildContext, listOf(callback, inputs))
|
||||
}
|
||||
NavTarget.AppDeveloperSettings -> {
|
||||
val callback = object : PreferencesEntryPoint.DeveloperSettingsCallback {
|
||||
override fun onDone() {
|
||||
backstack.pop()
|
||||
}
|
||||
}
|
||||
preferencesEntryPoint.createAppDeveloperSettingsNode(
|
||||
parentNode = this,
|
||||
buildContext = buildContext,
|
||||
callback = callback,
|
||||
)
|
||||
}
|
||||
NavTarget.ChooseAccountProvider -> {
|
||||
val callback = object : ChooseAccountProviderNode.Callback {
|
||||
override fun navigateToOidc(oidcDetails: OidcDetails) {
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@ class OnBoardingNode(
|
|||
fun navigateToLoginPassword()
|
||||
fun navigateToOidc(oidcDetails: OidcDetails)
|
||||
fun navigateToCreateAccount(url: String)
|
||||
fun navigateToDeveloperSettings()
|
||||
fun onDone()
|
||||
}
|
||||
|
||||
|
|
@ -75,6 +76,7 @@ class OnBoardingNode(
|
|||
onLearnMoreClick = { openLearnMorePage(context) },
|
||||
onCreateAccountContinue = callback::navigateToCreateAccount,
|
||||
onBackClick = callback::onDone,
|
||||
onDeveloperSettingsClick = callback::navigateToDeveloperSettings,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ import io.element.android.features.login.impl.login.LoginHelper
|
|||
import io.element.android.features.rageshake.api.RageshakeFeatureAvailability
|
||||
import io.element.android.libraries.architecture.Presenter
|
||||
import io.element.android.libraries.core.meta.BuildMeta
|
||||
import io.element.android.libraries.core.meta.BuildType
|
||||
import io.element.android.libraries.sessionstorage.api.SessionStore
|
||||
import io.element.android.libraries.ui.utils.MultipleTapToUnlock
|
||||
import kotlinx.coroutines.launch
|
||||
|
|
@ -125,6 +126,7 @@ class OnBoardingPresenter(
|
|||
return OnBoardingState(
|
||||
isAddingAccount = isAddingAccount,
|
||||
showBackButton = params.showBackButton,
|
||||
showDeveloperSettings = buildMeta.buildType != BuildType.RELEASE,
|
||||
productionApplicationName = buildMeta.productionApplicationName,
|
||||
defaultAccountProvider = defaultAccountProvider,
|
||||
mustChooseAccountProvider = mustChooseAccountProvider,
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ import io.element.android.libraries.architecture.AsyncData
|
|||
data class OnBoardingState(
|
||||
val isAddingAccount: Boolean,
|
||||
val showBackButton: Boolean,
|
||||
val showDeveloperSettings: Boolean,
|
||||
val productionApplicationName: String,
|
||||
val defaultAccountProvider: String?,
|
||||
val mustChooseAccountProvider: Boolean,
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ open class OnBoardingStateProvider : PreviewParameterProvider<OnBoardingState> {
|
|||
),
|
||||
anOnBoardingState(
|
||||
showBackButton = true,
|
||||
showDeveloperSettings = true,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
|
@ -38,6 +39,7 @@ open class OnBoardingStateProvider : PreviewParameterProvider<OnBoardingState> {
|
|||
fun anOnBoardingState(
|
||||
isAddingAccount: Boolean = false,
|
||||
showBackButton: Boolean = false,
|
||||
showDeveloperSettings: Boolean = false,
|
||||
productionApplicationName: String = "Element",
|
||||
defaultAccountProvider: String? = null,
|
||||
mustChooseAccountProvider: Boolean = false,
|
||||
|
|
@ -52,6 +54,7 @@ fun anOnBoardingState(
|
|||
) = OnBoardingState(
|
||||
isAddingAccount = isAddingAccount,
|
||||
showBackButton = showBackButton,
|
||||
showDeveloperSettings = showDeveloperSettings,
|
||||
productionApplicationName = productionApplicationName,
|
||||
defaultAccountProvider = defaultAccountProvider,
|
||||
mustChooseAccountProvider = mustChooseAccountProvider,
|
||||
|
|
|
|||
|
|
@ -64,6 +64,7 @@ import io.element.android.libraries.ui.strings.CommonStrings
|
|||
fun OnBoardingView(
|
||||
state: OnBoardingState,
|
||||
onBackClick: () -> Unit,
|
||||
onDeveloperSettingsClick: () -> Unit,
|
||||
onSignInWithQrCode: () -> Unit,
|
||||
onSignIn: (mustChooseAccountProvider: Boolean) -> Unit,
|
||||
onCreateAccount: () -> Unit,
|
||||
|
|
@ -110,6 +111,7 @@ fun OnBoardingView(
|
|||
loginView = loginView,
|
||||
buttons = buttons,
|
||||
onBackClick = onBackClick,
|
||||
onDeveloperSettingsClick = onDeveloperSettingsClick,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -120,6 +122,7 @@ private fun AddFirstAccountScaffold(
|
|||
loginView: @Composable () -> Unit,
|
||||
buttons: @Composable () -> Unit,
|
||||
onBackClick: () -> Unit,
|
||||
onDeveloperSettingsClick: () -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
OnBoardingPage(
|
||||
|
|
@ -136,6 +139,18 @@ private fun AddFirstAccountScaffold(
|
|||
} else {
|
||||
OnBoardingContent(state = state)
|
||||
}
|
||||
if (state.showDeveloperSettings) {
|
||||
IconButton(
|
||||
onClick = onDeveloperSettingsClick,
|
||||
modifier = Modifier
|
||||
.align(Alignment.TopStart),
|
||||
) {
|
||||
Icon(
|
||||
imageVector = CompoundIcons.SettingsSolid(),
|
||||
contentDescription = stringResource(CommonStrings.common_developer_options),
|
||||
)
|
||||
}
|
||||
}
|
||||
if (state.showBackButton) {
|
||||
// Add icon button to "navigate back"
|
||||
IconButton(
|
||||
|
|
@ -334,6 +349,7 @@ internal fun OnBoardingViewPreview(
|
|||
OnBoardingView(
|
||||
state = state,
|
||||
onBackClick = {},
|
||||
onDeveloperSettingsClick = {},
|
||||
onSignInWithQrCode = {},
|
||||
onSignIn = {},
|
||||
onCreateAccount = {},
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ import io.element.android.features.enterprise.test.FakeEnterpriseService
|
|||
import io.element.android.features.login.api.LoginEntryPoint
|
||||
import io.element.android.features.login.impl.accountprovider.AccountProviderDataSource
|
||||
import io.element.android.features.login.impl.classic.FakeElementClassicConnection
|
||||
import io.element.android.features.preferences.test.FakePreferencesEntryPoint
|
||||
import io.element.android.libraries.oidc.test.customtab.FakeOidcActionFlow
|
||||
import io.element.android.tests.testutils.lambda.lambdaError
|
||||
import io.element.android.tests.testutils.node.TestParentNode
|
||||
|
|
@ -41,6 +42,7 @@ class DefaultLoginEntryPointTest {
|
|||
oidcActionFlow = FakeOidcActionFlow(),
|
||||
appCoroutineScope = backgroundScope,
|
||||
elementClassicConnection = FakeElementClassicConnection(),
|
||||
preferencesEntryPoint = FakePreferencesEntryPoint(),
|
||||
)
|
||||
}
|
||||
val callback = object : LoginEntryPoint.Callback {
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ package io.element.android.features.login.impl.screens.onboarding
|
|||
import androidx.activity.ComponentActivity
|
||||
import androidx.compose.ui.test.junit4.AndroidComposeTestRule
|
||||
import androidx.compose.ui.test.junit4.createAndroidComposeRule
|
||||
import androidx.compose.ui.test.onNodeWithContentDescription
|
||||
import androidx.compose.ui.test.onNodeWithText
|
||||
import androidx.compose.ui.test.performClick
|
||||
import com.google.testing.junit.testparameterinjector.KotlinTestParameters.namedTestValues
|
||||
|
|
@ -46,11 +47,15 @@ class OnboardingViewTest {
|
|||
rule.setOnboardingView(
|
||||
state = anOnBoardingState(
|
||||
canCreateAccount = true,
|
||||
showDeveloperSettings = false,
|
||||
eventSink = eventSink,
|
||||
),
|
||||
onCreateAccount = callback,
|
||||
)
|
||||
rule.clickOn(R.string.screen_onboarding_sign_up)
|
||||
// Developer settings should not be shown
|
||||
val developerSettingsText = rule.activity.getString(CommonStrings.common_developer_options)
|
||||
rule.onNodeWithContentDescription(developerSettingsText).assertDoesNotExist()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -172,6 +177,22 @@ class OnboardingViewTest {
|
|||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clicking on settings calls the developer settings callback`() {
|
||||
val eventSink = EventsRecorder<OnBoardingEvents>(expectEvents = false)
|
||||
ensureCalledOnce { callback ->
|
||||
rule.setOnboardingView(
|
||||
state = anOnBoardingState(
|
||||
showDeveloperSettings = true,
|
||||
eventSink = eventSink,
|
||||
),
|
||||
onDeveloperSettingsClick = callback,
|
||||
)
|
||||
val text = rule.activity.getString(CommonStrings.common_developer_options)
|
||||
rule.onNodeWithContentDescription(text).performClick()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `cannot report a problem when the feature is disabled`() {
|
||||
val eventSink = EventsRecorder<OnBoardingEvents>(expectEvents = false)
|
||||
|
|
@ -235,6 +256,7 @@ class OnboardingViewTest {
|
|||
private fun <R : TestRule> AndroidComposeTestRule<R, ComponentActivity>.setOnboardingView(
|
||||
state: OnBoardingState,
|
||||
onBackClick: () -> Unit = EnsureNeverCalled(),
|
||||
onDeveloperSettingsClick: () -> Unit = EnsureNeverCalled(),
|
||||
onSignInWithQrCode: () -> Unit = EnsureNeverCalled(),
|
||||
onSignIn: (Boolean) -> Unit = EnsureNeverCalledWithParam(),
|
||||
onCreateAccount: () -> Unit = EnsureNeverCalled(),
|
||||
|
|
@ -248,6 +270,7 @@ class OnboardingViewTest {
|
|||
OnBoardingView(
|
||||
state = state,
|
||||
onBackClick = onBackClick,
|
||||
onDeveloperSettingsClick = onDeveloperSettingsClick,
|
||||
onSignInWithQrCode = onSignInWithQrCode,
|
||||
onSignIn = onSignIn,
|
||||
onCreateAccount = onCreateAccount,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue