fix: preserve login input during preference load
This commit is contained in:
@@ -80,7 +80,8 @@ fun LoginScreen(
|
||||
onSwitchProvider: () -> Unit,
|
||||
switchingProvider: Boolean = false,
|
||||
) {
|
||||
val navigationEnabled = !state.isSubmitting && !switchingProvider
|
||||
val formEnabled = !state.isSubmitting && !state.isLoadingPreferences
|
||||
val navigationEnabled = formEnabled && !switchingProvider
|
||||
BackHandler {
|
||||
if (navigationEnabled) onSwitchProvider()
|
||||
}
|
||||
@@ -140,7 +141,7 @@ fun LoginScreen(
|
||||
value = state.username,
|
||||
onValueChange = onUsernameChange,
|
||||
label = { Text(stringResource(R.string.login_username)) },
|
||||
enabled = !state.isSubmitting,
|
||||
enabled = formEnabled,
|
||||
singleLine = true,
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
)
|
||||
@@ -149,29 +150,31 @@ fun LoginScreen(
|
||||
onValueChange = onPasswordChange,
|
||||
label = { Text(stringResource(R.string.login_password)) },
|
||||
visualTransformation = PasswordVisualTransformation(),
|
||||
enabled = !state.isSubmitting,
|
||||
enabled = formEnabled,
|
||||
singleLine = true,
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
)
|
||||
ToggleRow(
|
||||
label = stringResource(R.string.login_remember_username),
|
||||
checked = state.rememberUsername,
|
||||
enabled = !state.isSubmitting,
|
||||
enabled = formEnabled,
|
||||
onCheckedChange = onRememberUsernameChange,
|
||||
)
|
||||
ToggleRow(
|
||||
label = stringResource(R.string.login_auto_login),
|
||||
checked = state.autoLogin,
|
||||
enabled = !state.isSubmitting,
|
||||
enabled = formEnabled,
|
||||
onCheckedChange = onAutoLoginChange,
|
||||
)
|
||||
state.errorMessage?.let { Text(it, color = MaterialTheme.colorScheme.error) }
|
||||
ABoxButton(
|
||||
onClick = onSubmit,
|
||||
enabled = !state.isSubmitting && !switchingProvider,
|
||||
enabled = formEnabled && !switchingProvider,
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
) {
|
||||
if (state.isSubmitting || switchingProvider) ABoxLoadingIndicator()
|
||||
if (state.isSubmitting || state.isLoadingPreferences || switchingProvider) {
|
||||
ABoxLoadingIndicator()
|
||||
}
|
||||
else Text(stringResource(R.string.action_login))
|
||||
}
|
||||
ABoxButton(
|
||||
|
||||
@@ -27,20 +27,39 @@ class LoginViewModel @Inject constructor(
|
||||
val uiState: StateFlow<LoginUiState> = _uiState.asStateFlow()
|
||||
private var profile: ProviderProfile? = null
|
||||
private var loadingJob: Job? = null
|
||||
private var usernameEdited = false
|
||||
private var rememberUsernameEdited = false
|
||||
private var autoLoginEdited = false
|
||||
|
||||
fun loadProfile(value: ProviderProfile) {
|
||||
val profileChanged = profile?.id != value.id
|
||||
if (!profileChanged && loadingJob != null) return
|
||||
loadingJob?.cancel()
|
||||
profile = value
|
||||
_uiState.value = LoginUiState()
|
||||
usernameEdited = false
|
||||
rememberUsernameEdited = false
|
||||
autoLoginEdited = false
|
||||
_uiState.value = LoginUiState(isLoadingPreferences = true)
|
||||
loadingJob = viewModelScope.launch {
|
||||
val preferences = profileStore.loginPreferences(value.id)
|
||||
if (profile?.id != value.id) return@launch
|
||||
_uiState.value = LoginUiState(
|
||||
username = preferences.rememberedUsername?.value.orEmpty(),
|
||||
rememberUsername = preferences.rememberUsername,
|
||||
autoLogin = preferences.autoLoginEnabled,
|
||||
_uiState.value = _uiState.value.copy(
|
||||
username = if (usernameEdited) {
|
||||
_uiState.value.username
|
||||
} else {
|
||||
preferences.rememberedUsername?.value.orEmpty()
|
||||
},
|
||||
rememberUsername = if (rememberUsernameEdited) {
|
||||
_uiState.value.rememberUsername
|
||||
} else {
|
||||
preferences.rememberUsername
|
||||
},
|
||||
autoLogin = if (autoLoginEdited) {
|
||||
_uiState.value.autoLogin
|
||||
} else {
|
||||
preferences.autoLoginEnabled
|
||||
},
|
||||
isLoadingPreferences = false,
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -49,10 +68,14 @@ class LoginViewModel @Inject constructor(
|
||||
loadingJob?.cancel()
|
||||
loadingJob = null
|
||||
profile = null
|
||||
usernameEdited = false
|
||||
rememberUsernameEdited = false
|
||||
autoLoginEdited = false
|
||||
_uiState.value = LoginUiState()
|
||||
}
|
||||
|
||||
fun setUsername(value: String) {
|
||||
usernameEdited = true
|
||||
_uiState.value = _uiState.value.copy(username = value, errorMessage = null)
|
||||
}
|
||||
|
||||
@@ -61,17 +84,23 @@ class LoginViewModel @Inject constructor(
|
||||
}
|
||||
|
||||
fun setRememberUsername(value: Boolean) {
|
||||
rememberUsernameEdited = true
|
||||
_uiState.value = _uiState.value.copy(rememberUsername = value)
|
||||
}
|
||||
|
||||
fun setAutoLogin(value: Boolean) {
|
||||
autoLoginEdited = true
|
||||
_uiState.value = _uiState.value.copy(autoLogin = value)
|
||||
}
|
||||
|
||||
fun submit() {
|
||||
val activeProfile = profile ?: return
|
||||
val state = _uiState.value
|
||||
if (state.username.isBlank() || state.password.isEmpty() || state.isSubmitting) {
|
||||
if (state.username.isBlank() ||
|
||||
state.password.isEmpty() ||
|
||||
state.isSubmitting ||
|
||||
state.isLoadingPreferences
|
||||
) {
|
||||
_uiState.value = state.copy(errorMessage = "Username and password are required")
|
||||
return
|
||||
}
|
||||
@@ -104,6 +133,7 @@ data class LoginUiState(
|
||||
val password: String = "",
|
||||
val rememberUsername: Boolean = false,
|
||||
val autoLogin: Boolean = false,
|
||||
val isLoadingPreferences: Boolean = false,
|
||||
val isSubmitting: Boolean = false,
|
||||
val errorMessage: String? = null,
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user