Skip to content

Commit

Permalink
Backport minor changes from non-ose (#941)
Browse files Browse the repository at this point in the history
Login: correctly combine input flows for account details UI state (backport bitfireAT/davx5#575)
  • Loading branch information
rfc2822 authored Jul 26, 2024
1 parent 3423143 commit c3fe1b0
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 28 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.PopupProperties
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.lifecycle.viewmodel.compose.viewModel
import at.bitfire.davdroid.R
import at.bitfire.davdroid.ui.composable.Assistant
Expand All @@ -52,9 +53,8 @@ fun AccountDetailsPage(
onAccountCreated: (Account) -> Unit,
model: LoginScreenModel = viewModel()
) {
val uiState = model.accountDetailsUiState
if (uiState.createdAccount != null)
onAccountCreated(uiState.createdAccount)
val uiState by model.accountDetailsUiState.collectAsStateWithLifecycle()
uiState.createdAccount?.let(onAccountCreated)

val context = LocalContext.current
LaunchedEffect(uiState.couldNotCreateAccount) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ package at.bitfire.davdroid.ui.setup

import android.accounts.Account
import android.content.Context
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
Expand All @@ -24,9 +23,12 @@ import dagger.hilt.android.lifecycle.HiltViewModel
import dagger.hilt.android.qualifiers.ApplicationContext
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
import kotlinx.coroutines.runInterruptible
import kotlinx.coroutines.withContext
Expand Down Expand Up @@ -246,66 +248,75 @@ class LoginScreenModel @AssistedInject constructor(
else
null
}
.stateIn(viewModelScope, SharingStarted.Eagerly, null)

// backing field that is combined with dynamic content for the resulting UI State
private var _accountDetailsUiState by mutableStateOf(AccountDetailsUiState())
val accountDetailsUiState by derivedStateOf {
val method = forcedGroupMethod.value

private var _accountDetailsUiState = MutableStateFlow(AccountDetailsUiState())
val accountDetailsUiState = combine(_accountDetailsUiState, forcedGroupMethod) { uiState, method ->
// set group type to read-only if group method is forced
var combinedState = _accountDetailsUiState.copy(groupMethodReadOnly = method != null)
var combinedState = uiState.copy(groupMethodReadOnly = method != null)

// apply forced group method, if applicable
if (method != null)
combinedState = combinedState.copy(groupMethod = method)

combinedState
}
}.stateIn(viewModelScope, SharingStarted.Lazily, _accountDetailsUiState.value)

fun updateAccountName(accountName: String) {
_accountDetailsUiState = _accountDetailsUiState.copy(
accountName = accountName,
accountNameExists = accountRepository.exists(accountName)
)
_accountDetailsUiState.update { currentState ->
currentState.copy(
accountName = accountName,
accountNameExists = accountRepository.exists(accountName)
)
}
}

fun updateAccountNameAndEmails(accountName: String, emails: Set<String>) {
_accountDetailsUiState = _accountDetailsUiState.copy(
accountName = accountName,
accountNameExists = accountRepository.exists(accountName),
suggestedAccountNames = emails
)
_accountDetailsUiState.update { currentState ->
currentState.copy(
accountName = accountName,
accountNameExists = accountRepository.exists(accountName),
suggestedAccountNames = emails
)
}
}

fun updateGroupMethod(groupMethod: GroupMethod) {
_accountDetailsUiState = _accountDetailsUiState.copy(groupMethod = groupMethod)
_accountDetailsUiState.update { currentState ->
currentState.copy(groupMethod = groupMethod)
}
}

fun resetCouldNotCreateAccount() {
_accountDetailsUiState = _accountDetailsUiState.copy(couldNotCreateAccount = false)
_accountDetailsUiState.update { currentState ->
currentState.copy(couldNotCreateAccount = false)
}
}

fun createAccount() {
_accountDetailsUiState = _accountDetailsUiState.copy(creatingAccount = true)
_accountDetailsUiState.update { currentState ->
currentState.copy(creatingAccount = true)
}

viewModelScope.launch {
val account = withContext(Dispatchers.Default) {
accountRepository.create(
accountDetailsUiState.accountName,
accountDetailsUiState.value.accountName,
loginInfo.credentials,
foundConfig!!,
accountDetailsUiState.groupMethod
accountDetailsUiState.value.groupMethod
)
}

_accountDetailsUiState =
_accountDetailsUiState.update { currentState ->
if (account != null)
accountDetailsUiState.copy(createdAccount = account)
currentState.copy(createdAccount = account)
else
accountDetailsUiState.copy(
currentState.copy(
creatingAccount = false,
couldNotCreateAccount = true
)
}
}
}

Expand Down

0 comments on commit c3fe1b0

Please sign in to comment.