Split developer settings into 2 screens to be able to access global settings when no logged in.

This commit is contained in:
Benoit Marty 2026-04-15 10:31:54 +02:00
parent b6188a7646
commit 1b03dd1dcb
26 changed files with 924 additions and 447 deletions

View file

@ -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) {

View file

@ -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,
)
}
}

View file

@ -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,

View file

@ -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,

View file

@ -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,

View file

@ -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 = {},