Skip to content

Commit

Permalink
Merge branch 'dev-ose' into 699-last-synced-timestamp-is-only-applied…
Browse files Browse the repository at this point in the history
…-to-one-resource-if-there-are-multiple-collections-with-the-same-path
  • Loading branch information
rfc2822 committed Apr 8, 2024
2 parents 4341d35 + e638f5d commit d7e5906
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import androidx.compose.material.Icon
import androidx.compose.material.MaterialTheme
import androidx.compose.material.OutlinedTextField
import androidx.compose.material.RadioButton
import androidx.compose.material.SnackbarHostState
import androidx.compose.material.Text
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Email
Expand All @@ -29,9 +30,11 @@ import androidx.compose.runtime.getValue
import androidx.compose.runtime.livedata.observeAsState
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringArrayResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.input.KeyboardType
Expand All @@ -43,9 +46,11 @@ import at.bitfire.davdroid.servicedetection.DavResourceFinder
import at.bitfire.davdroid.ui.composable.Assistant
import at.bitfire.davdroid.ui.widget.ExceptionInfoDialog
import at.bitfire.vcard4android.GroupMethod
import kotlinx.coroutines.launch

@Composable
fun AccountDetailsPage(
snackbarHostState: SnackbarHostState,
loginInfo: LoginInfo,
foundConfig: DavResourceFinder.Configuration,
onBack: () -> Unit,
Expand All @@ -54,6 +59,9 @@ fun AccountDetailsPage(
) {
BackHandler(onBack = onBack)

val context = LocalContext.current
val scope = rememberCoroutineScope()

val resultOrNull by model.createAccountResult.observeAsState()
var showExceptionInfo by remember { mutableStateOf(false) }
LaunchedEffect(resultOrNull) {
Expand All @@ -73,9 +81,16 @@ fun AccountDetailsPage(
model.createAccountResult.value = null
}
)
// TODO else
}
else
scope.launch {
snackbarHostState.showSnackbar(context.getString(R.string.login_account_not_created))
}
}
else -> {}
}

// reset result
model.createAccountResult.value = null
}

val suggestedAccountNames = foundConfig.calDAV?.emails ?: emptyList()
Expand All @@ -86,6 +101,7 @@ fun AccountDetailsPage(
AccountDetailsPage_Content(
suggestedAccountNames = suggestedAccountNames,
accountName = accountName,
accountNameAlreadyExists = model.accountExists(accountName).observeAsState(false).value,
onUpdateAccountName = { accountName = it },
onCreateAccount = {
model.createAccount(
Expand All @@ -106,6 +122,7 @@ fun AccountDetailsPage(
fun AccountDetailsPage_Content(
suggestedAccountNames: List<String>,
accountName: String,
accountNameAlreadyExists: Boolean,
onUpdateAccountName: (String) -> Unit = {},
groupMethod: GroupMethod,
groupMethodReadOnly: Boolean,
Expand All @@ -114,18 +131,24 @@ fun AccountDetailsPage_Content(
) {
Assistant(
nextLabel = stringResource(R.string.login_create_account),
onNext = onCreateAccount
onNext = onCreateAccount,
nextEnabled = accountName.isNotBlank() && !accountNameAlreadyExists
) {
Column(Modifier.padding(8.dp)) {
var expanded by remember { mutableStateOf(false) }
ExposedDropdownMenuBox(
expanded = expanded,
onExpandedChange = { expanded = it }
) {
val accountNameLabel = if (accountNameAlreadyExists)
stringResource(R.string.login_account_name_already_taken)
else
stringResource(R.string.login_account_name)
OutlinedTextField(
value = accountName,
onValueChange = onUpdateAccountName,
label = { Text(stringResource(R.string.login_account_name)) },
label = { Text(accountNameLabel) },
isError = accountNameAlreadyExists,
singleLine = true,
keyboardOptions = KeyboardOptions(
keyboardType = KeyboardType.Email
Expand Down Expand Up @@ -227,6 +250,7 @@ fun AccountDetailsPage_Content_Preview() {
AccountDetailsPage_Content(
suggestedAccountNames = listOf("name1", "name2@example.com"),
accountName = "account@example.com",
accountNameAlreadyExists = false,
groupMethod = GroupMethod.GROUP_VCARDS,
groupMethodReadOnly = false
)
Expand All @@ -238,6 +262,7 @@ fun AccountDetailsPage_Content_Preview_With_Apostrophe() {
AccountDetailsPage_Content(
suggestedAccountNames = listOf("name1", "name2@example.com"),
accountName = "account'example.com",
accountNameAlreadyExists = true,
groupMethod = GroupMethod.CATEGORIES,
groupMethodReadOnly = true
)
Expand Down
16 changes: 16 additions & 0 deletions app/src/main/kotlin/at/bitfire/davdroid/ui/setup/LoginModel.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,15 @@
package at.bitfire.davdroid.ui.setup

import android.accounts.Account
import android.accounts.AccountManager
import android.app.Application
import android.content.ContentResolver
import android.provider.CalendarContract
import androidx.core.os.CancellationSignal
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.liveData
import androidx.lifecycle.map
import androidx.lifecycle.viewModelScope
import at.bitfire.davdroid.InvalidAccountException
Expand Down Expand Up @@ -77,6 +80,19 @@ class LoginModel @Inject constructor(
}


fun accountExists(accountName: String): LiveData<Boolean> = liveData {
val accountType = context.getString(R.string.account_type)
val exists =
if (accountName.isEmpty())
false
else
AccountManager.get(context)
.getAccountsByType(accountType)
.contains(Account(accountName, accountType))
emit(exists)
}


interface CreateAccountResult {
class Success(val account: Account): CreateAccountResult
class Error(val exception: Exception?): CreateAccountResult
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ fun LoginScreen(
foundConfig?.let {
val context = LocalContext.current
AccountDetailsPage(
snackbarHostState = snackbarHostState,
loginInfo = loginInfo,
foundConfig = it,
onBack = { phase = LoginActivity.Phase.LOGIN_TYPE },
Expand Down

0 comments on commit d7e5906

Please sign in to comment.