Handle when AccountActivity is started without account (#1481)

* Pass new account as non-nullable

Signed-off-by: Sunik Kupfer <kupfer@bitfire.at>

* Move companion object

Signed-off-by: Sunik Kupfer <kupfer@bitfire.at>

* Handle missing account in intent by logging and redirecting to accounts overview

Signed-off-by: Sunik Kupfer <kupfer@bitfire.at>

* Fix deprecation

Signed-off-by: Sunik Kupfer <kupfer@bitfire.at>

* Also check account exists

Signed-off-by: Sunik Kupfer <kupfer@bitfire.at>

* Simplify toast message

Signed-off-by: Sunik Kupfer <kupfer@bitfire.at>

* Add account name to toast message

Signed-off-by: Sunik Kupfer <kupfer@bitfire.at>

* Don't check for invalid accounts in AccountActivity; handle InvalidAccountException in model

* Minor changes

---------

Signed-off-by: Sunik Kupfer <kupfer@bitfire.at>
Co-authored-by: Ricki Hirner <hirner@bitfire.at>
This commit is contained in:
Sunik Kupfer
2025-05-22 17:22:31 +02:00
committed by GitHub
parent 19f86670bf
commit a835557b35
5 changed files with 53 additions and 13 deletions

View File

@@ -10,20 +10,39 @@ import android.content.Intent
import android.os.Bundle
import androidx.activity.compose.setContent
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.IntentCompat
import at.bitfire.davdroid.R
import at.bitfire.davdroid.ui.AccountsActivity
import dagger.hilt.android.AndroidEntryPoint
import java.util.logging.Logger
import javax.inject.Inject
@AndroidEntryPoint
class AccountActivity : AppCompatActivity() {
companion object {
const val EXTRA_ACCOUNT = "account"
}
@Inject
lateinit var logger: Logger
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val account = intent.getParcelableExtra(EXTRA_ACCOUNT) as? Account
?: throw IllegalArgumentException("AccountActivity requires EXTRA_ACCOUNT")
val account =
IntentCompat.getParcelableExtra(intent, EXTRA_ACCOUNT, Account::class.java) ?:
intent.getStringExtra(EXTRA_ACCOUNT)?.let { Account(it, getString(R.string.account_type)) }
// If account is not passed, log warning and redirect to accounts overview
if (account == null) {
logger.warning("AccountActivity requires EXTRA_ACCOUNT")
// Redirect to accounts overview activity
val intent = Intent(this, AccountsActivity::class.java).apply {
// Create a new root activity, do not allow going back.
addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK)
}
startActivity(intent)
finish()
return
}
setContent {
AccountScreen(
@@ -55,4 +74,8 @@ class AccountActivity : AppCompatActivity() {
}
}
companion object {
const val EXTRA_ACCOUNT = "account"
}
}

View File

@@ -7,6 +7,7 @@ import android.Manifest
import android.accounts.Account
import android.content.Intent
import android.net.Uri
import android.widget.Toast
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxWidth
@@ -200,8 +201,12 @@ fun AccountScreen(
val context = LocalContext.current
val scope = rememberCoroutineScope()
if (invalidAccount)
onFinish()
LaunchedEffect(invalidAccount) {
if (invalidAccount) {
Toast.makeText(context, R.string.account_invalid_account, Toast.LENGTH_LONG).show()
onFinish()
}
}
val snackbarHostState = remember { SnackbarHostState() }
LaunchedEffect(error) {

View File

@@ -20,6 +20,7 @@ import at.bitfire.davdroid.servicedetection.RefreshCollectionsWorker
import at.bitfire.davdroid.settings.AccountSettings
import at.bitfire.davdroid.sync.SyncDataType
import at.bitfire.davdroid.sync.TasksAppManager
import at.bitfire.davdroid.sync.account.InvalidAccountException
import at.bitfire.davdroid.sync.worker.SyncWorkerManager
import dagger.Lazy
import dagger.assisted.Assisted
@@ -51,7 +52,7 @@ class AccountScreenModel @AssistedInject constructor(
getBindableHomesetsFromService: GetBindableHomeSetsFromServiceUseCase,
getServiceCollectionPager: GetServiceCollectionPagerUseCase,
private val logger: Logger,
private val serviceRepository: DavServiceRepository,
serviceRepository: DavServiceRepository,
private val syncWorkerManager: SyncWorkerManager,
tasksAppManager: TasksAppManager
): ViewModel() {
@@ -64,7 +65,13 @@ class AccountScreenModel @AssistedInject constructor(
/**
* Only acquire account settings on a worker thread!
*/
private val accountSettings by lazy { accountSettingsFactory.create(account) }
private val accountSettings: AccountSettings? by lazy {
try {
accountSettingsFactory.create(account)
} catch (_: InvalidAccountException) {
null
}
}
/** whether the account is invalid and the screen shall be closed */
val invalidAccount = accountRepository.getAllFlow().map { accounts ->
@@ -77,11 +84,13 @@ class AccountScreenModel @AssistedInject constructor(
private val _showOnlyPersonal = MutableStateFlow(false)
val showOnlyPersonal = _showOnlyPersonal.asStateFlow()
private suspend fun reloadShowOnlyPersonal() = withContext(Dispatchers.Default) {
_showOnlyPersonal.value = accountSettings.getShowOnlyPersonal()
accountSettings?.let {
_showOnlyPersonal.value = it.getShowOnlyPersonal()
}
}
fun setShowOnlyPersonal(showOnlyPersonal: Boolean) {
viewModelScope.launch {
accountSettings.setShowOnlyPersonal(showOnlyPersonal)
accountSettings?.setShowOnlyPersonal(showOnlyPersonal)
reloadShowOnlyPersonal()
}
}
@@ -92,7 +101,9 @@ class AccountScreenModel @AssistedInject constructor(
private var _showOnlyPersonalLocked = MutableStateFlow(false)
val showOnlyPersonalLocked = _showOnlyPersonalLocked.asStateFlow()
private suspend fun reloadShowOnlyPersonalLocked() = withContext(Dispatchers.Default) {
_showOnlyPersonalLocked.value = accountSettings.getShowOnlyPersonalLocked()
accountSettings?.let {
_showOnlyPersonalLocked.value = it.getShowOnlyPersonalLocked()
}
}
init {

View File

@@ -39,7 +39,7 @@ class LoginActivity @Inject constructor(): AppCompatActivity() {
onFinish = { newAccount ->
finish()
if (newAccount != null) {
newAccount?.let { newAccount ->
val intent = Intent(this, AccountActivity::class.java)
intent.putExtra(AccountActivity.EXTRA_ACCOUNT, newAccount)
startActivity(intent)

View File

@@ -238,6 +238,7 @@
<string name="app_settings_unifiedpush_encrypted">Push messages are always encrypted.</string>
<!-- AccountScreen -->
<string name="account_invalid_account">Account doesn\'t exist</string>
<string name="account_carddav">CardDAV</string>
<string name="account_caldav">CalDAV</string>
<string name="account_webcal">Webcal</string>