Open AccountCredentialsScreen from AccountTab to edit account credentials

This commit is contained in:
Shinokuni 2024-06-02 18:27:54 +02:00
parent 338e64eca8
commit 7a4d4d7225
5 changed files with 71 additions and 29 deletions

View File

@ -5,6 +5,7 @@ import androidx.security.crypto.MasterKey
import com.readrops.api.services.Credentials
import com.readrops.app.compose.account.AccountScreenModel
import com.readrops.app.compose.account.credentials.AccountCredentialsScreenModel
import com.readrops.app.compose.account.credentials.AccountCredentialsScreenMode
import com.readrops.app.compose.account.selection.AccountSelectionScreenModel
import com.readrops.app.compose.feeds.FeedScreenModel
import com.readrops.app.compose.item.ItemScreenModel
@ -31,7 +32,9 @@ val composeAppModule = module {
factory { (itemId: Int) -> ItemScreenModel(get(), itemId) }
factory { (accountType: AccountType) -> AccountCredentialsScreenModel(accountType, get(), androidContext()) }
factory { (accountType: Account, mode: AccountCredentialsScreenMode) ->
AccountCredentialsScreenModel(accountType, mode, get())
}
single { GetFoldersWithFeeds(get()) }

View File

@ -46,6 +46,7 @@ import cafe.adriel.voyager.navigator.tab.TabOptions
import com.readrops.api.utils.ApiUtils
import com.readrops.app.compose.R
import com.readrops.app.compose.account.credentials.AccountCredentialsScreen
import com.readrops.app.compose.account.credentials.AccountCredentialsScreenMode
import com.readrops.app.compose.account.selection.AccountSelectionDialog
import com.readrops.app.compose.account.selection.AccountSelectionScreen
import com.readrops.app.compose.account.selection.adaptiveIconPainterResource
@ -56,6 +57,7 @@ import com.readrops.app.compose.util.components.TwoChoicesDialog
import com.readrops.app.compose.util.theme.LargeSpacer
import com.readrops.app.compose.util.theme.MediumSpacer
import com.readrops.app.compose.util.theme.spacing
import com.readrops.db.entities.account.Account
object AccountTab : Tab {
@ -174,7 +176,12 @@ object AccountTab : Tab {
onDismiss = { screenModel.closeDialog() },
onValidate = { accountType ->
screenModel.closeDialog()
navigator.push(AccountCredentialsScreen(accountType))
val account = Account(
accountType = accountType,
accountName = context.resources.getString(accountType.typeName)
)
navigator.push(AccountCredentialsScreen(account, AccountCredentialsScreenMode.NEW_CREDENTIALS))
}
)
}
@ -279,7 +286,14 @@ object AccountTab : Tab {
style = MaterialTheme.typography.titleMedium,
spacing = MaterialTheme.spacing.mediumSpacing,
padding = MaterialTheme.spacing.mediumSpacing,
onClick = { }
onClick = {
navigator.push(
AccountCredentialsScreen(
state.account,
AccountCredentialsScreenMode.EDIT_CREDENTIALS
)
)
}
)
SelectableIconText(

View File

@ -42,23 +42,33 @@ import com.readrops.app.compose.util.components.AndroidScreen
import com.readrops.app.compose.util.theme.ShortSpacer
import com.readrops.app.compose.util.theme.VeryLargeSpacer
import com.readrops.app.compose.util.theme.spacing
import com.readrops.db.entities.account.AccountType
import com.readrops.db.entities.account.Account
import org.koin.core.parameter.parametersOf
enum class AccountCredentialsScreenMode {
NEW_CREDENTIALS,
EDIT_CREDENTIALS
}
class AccountCredentialsScreen(
private val accountType: AccountType
private val account: Account,
private val mode: AccountCredentialsScreenMode
) : AndroidScreen() {
@Composable
override fun Content() {
val navigator = LocalNavigator.currentOrThrow
val screenModel =
getScreenModel<AccountCredentialsScreenModel>(parameters = { parametersOf(accountType) })
getScreenModel<AccountCredentialsScreenModel>(parameters = { parametersOf(account, mode) })
val state by screenModel.state.collectAsStateWithLifecycle()
if (state.goToHomeScreen) {
navigator.replaceAll(HomeScreen())
if (state.exitScreen) {
if (mode == AccountCredentialsScreenMode.NEW_CREDENTIALS) {
navigator.replaceAll(HomeScreen())
} else {
navigator.pop()
}
}
Box(
@ -73,7 +83,7 @@ class AccountCredentialsScreen(
.verticalScroll(rememberScrollState())
) {
Image(
painter = painterResource(id = accountType.iconRes),
painter = painterResource(id = account.accountType!!.iconRes),
contentDescription = null,
modifier = Modifier.size(48.dp)
)
@ -81,7 +91,7 @@ class AccountCredentialsScreen(
ShortSpacer()
Text(
text = stringResource(id = accountType.typeName),
text = stringResource(id = account.accountType!!.typeName),
style = MaterialTheme.typography.headlineMedium
)

View File

@ -1,6 +1,5 @@
package com.readrops.app.compose.account.credentials
import android.content.Context
import android.content.SharedPreferences
import android.util.Patterns
import cafe.adriel.voyager.core.model.StateScreenModel
@ -9,7 +8,6 @@ import com.readrops.app.compose.repositories.BaseRepository
import com.readrops.app.compose.util.components.TextFieldError
import com.readrops.db.Database
import com.readrops.db.entities.account.Account
import com.readrops.db.entities.account.AccountType
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.update
@ -19,15 +17,25 @@ import org.koin.core.component.get
import org.koin.core.parameter.parametersOf
class AccountCredentialsScreenModel(
private val accountType: AccountType,
private val account: Account,
private val mode: AccountCredentialsScreenMode,
private val database: Database,
private val context: Context,
private val dispatcher: CoroutineDispatcher = Dispatchers.IO
) : StateScreenModel<AccountCredentialsState>(AccountCredentialsState(name = accountType.name)),
KoinComponent {
) : StateScreenModel<AccountCredentialsState>(AccountCredentialsState()), KoinComponent {
init {
mutableState.update { it.copy(name = context.resources.getString(accountType.typeName)) }
if (mode == AccountCredentialsScreenMode.EDIT_CREDENTIALS) {
mutableState.update {
it.copy(
name = account.accountName!!,
url = account.url!!,
login = account.login!!,
password = account.password!!
)
}
} else {
mutableState.update { it.copy(name = account.accountName!!) }
}
}
fun onEvent(event: Event): Unit = with(mutableState) {
@ -48,20 +56,20 @@ class AccountCredentialsScreenModel(
mutableState.update { it.copy(isLoginOnGoing = true) }
with(state.value) {
val account = Account(
val newAccount = account.copy(
url = url,
accountName = name,
login = login,
password = password,
accountType = accountType,
accountType = account.accountType,
isCurrentAccount = true
)
val repository = get<BaseRepository> { parametersOf(account) }
val repository = get<BaseRepository> { parametersOf(newAccount) }
screenModelScope.launch(dispatcher) {
try {
repository.login(account)
repository.login(newAccount)
} catch (e: Exception) {
mutableState.update {
it.copy(
@ -73,14 +81,18 @@ class AccountCredentialsScreenModel(
return@launch
}
account.id = database.newAccountDao().insert(account).toInt()
if (mode == AccountCredentialsScreenMode.NEW_CREDENTIALS) {
newAccount.id = database.newAccountDao().insert(newAccount).toInt()
get<SharedPreferences>().edit()
.putString(account.loginKey, account.login)
.putString(account.passwordKey, account.password)
.apply()
get<SharedPreferences>().edit()
.putString(newAccount.loginKey, newAccount.login)
.putString(newAccount.passwordKey, newAccount.password)
.apply()
} else {
database.newAccountDao().update(newAccount)
}
mutableState.update { it.copy(goToHomeScreen = true) }
mutableState.update { it.copy(exitScreen = true) }
}
}
}
@ -129,7 +141,7 @@ data class AccountCredentialsState(
val passwordError: TextFieldError? = null,
val isPasswordVisible: Boolean = false,
val isLoginOnGoing: Boolean = false,
val goToHomeScreen: Boolean = false,
val exitScreen: Boolean = false,
val loginException: Exception? = null
) {
val isUrlError = urlError != null

View File

@ -31,12 +31,14 @@ import cafe.adriel.voyager.navigator.LocalNavigator
import cafe.adriel.voyager.navigator.currentOrThrow
import com.readrops.app.compose.R
import com.readrops.app.compose.account.credentials.AccountCredentialsScreen
import com.readrops.app.compose.account.credentials.AccountCredentialsScreenMode
import com.readrops.app.compose.home.HomeScreen
import com.readrops.app.compose.util.components.AndroidScreen
import com.readrops.app.compose.util.components.SelectableImageText
import com.readrops.app.compose.util.theme.LargeSpacer
import com.readrops.app.compose.util.theme.ShortSpacer
import com.readrops.app.compose.util.theme.spacing
import com.readrops.db.entities.account.Account
import com.readrops.db.entities.account.AccountType
class AccountSelectionScreen : AndroidScreen() {
@ -56,8 +58,9 @@ class AccountSelectionScreen : AndroidScreen() {
is NavState.GoToAccountCredentialsScreen -> {
val accountType = (state as NavState.GoToAccountCredentialsScreen).accountType
val account = Account(accountType = accountType, accountName = stringResource(id = accountType.typeName))
navigator.push(AccountCredentialsScreen(accountType))
navigator.push(AccountCredentialsScreen(account, AccountCredentialsScreenMode.NEW_CREDENTIALS))
screenModel.resetNavState()
}