mirror of https://github.com/readrops/Readrops.git
Add top bar in AccountCredentialsScreen
This commit is contained in:
parent
f491a60ef6
commit
7f8d7aa87f
|
@ -12,13 +12,18 @@ import androidx.compose.foundation.layout.size
|
||||||
import androidx.compose.foundation.rememberScrollState
|
import androidx.compose.foundation.rememberScrollState
|
||||||
import androidx.compose.foundation.text.KeyboardOptions
|
import androidx.compose.foundation.text.KeyboardOptions
|
||||||
import androidx.compose.foundation.verticalScroll
|
import androidx.compose.foundation.verticalScroll
|
||||||
|
import androidx.compose.material.icons.Icons
|
||||||
|
import androidx.compose.material.icons.automirrored.filled.ArrowBack
|
||||||
import androidx.compose.material3.Button
|
import androidx.compose.material3.Button
|
||||||
import androidx.compose.material3.CircularProgressIndicator
|
import androidx.compose.material3.CircularProgressIndicator
|
||||||
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
import androidx.compose.material3.Icon
|
import androidx.compose.material3.Icon
|
||||||
import androidx.compose.material3.IconButton
|
import androidx.compose.material3.IconButton
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.material3.OutlinedTextField
|
import androidx.compose.material3.OutlinedTextField
|
||||||
|
import androidx.compose.material3.Scaffold
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.material3.TopAppBar
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
|
@ -39,8 +44,8 @@ import com.readrops.app.R
|
||||||
import com.readrops.app.home.HomeScreen
|
import com.readrops.app.home.HomeScreen
|
||||||
import com.readrops.app.util.ErrorMessage
|
import com.readrops.app.util.ErrorMessage
|
||||||
import com.readrops.app.util.components.AndroidScreen
|
import com.readrops.app.util.components.AndroidScreen
|
||||||
|
import com.readrops.app.util.theme.MediumSpacer
|
||||||
import com.readrops.app.util.theme.ShortSpacer
|
import com.readrops.app.util.theme.ShortSpacer
|
||||||
import com.readrops.app.util.theme.VeryLargeSpacer
|
|
||||||
import com.readrops.app.util.theme.spacing
|
import com.readrops.app.util.theme.spacing
|
||||||
import com.readrops.db.entities.account.Account
|
import com.readrops.db.entities.account.Account
|
||||||
import org.koin.core.parameter.parametersOf
|
import org.koin.core.parameter.parametersOf
|
||||||
|
@ -55,6 +60,7 @@ class AccountCredentialsScreen(
|
||||||
private val mode: AccountCredentialsScreenMode
|
private val mode: AccountCredentialsScreenMode
|
||||||
) : AndroidScreen() {
|
) : AndroidScreen() {
|
||||||
|
|
||||||
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
@Composable
|
@Composable
|
||||||
override fun Content() {
|
override fun Content() {
|
||||||
val navigator = LocalNavigator.currentOrThrow
|
val navigator = LocalNavigator.currentOrThrow
|
||||||
|
@ -71,128 +77,159 @@ class AccountCredentialsScreen(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Box(
|
Scaffold(
|
||||||
modifier = Modifier.imePadding()
|
topBar = {
|
||||||
) {
|
TopAppBar(
|
||||||
Column(
|
title = {
|
||||||
horizontalAlignment = Alignment.CenterHorizontally,
|
Text(
|
||||||
modifier = Modifier
|
text = if (mode == AccountCredentialsScreenMode.EDIT_CREDENTIALS)
|
||||||
.background(MaterialTheme.colorScheme.background)
|
stringResource(id = R.string.credentials)
|
||||||
.fillMaxSize()
|
else
|
||||||
.padding(MaterialTheme.spacing.largeSpacing)
|
stringResource(id = R.string.new_account)
|
||||||
.verticalScroll(rememberScrollState())
|
)
|
||||||
) {
|
},
|
||||||
Image(
|
navigationIcon = {
|
||||||
painter = painterResource(id = account.accountType!!.iconRes),
|
|
||||||
contentDescription = null,
|
|
||||||
modifier = Modifier.size(48.dp)
|
|
||||||
)
|
|
||||||
|
|
||||||
ShortSpacer()
|
|
||||||
|
|
||||||
Text(
|
|
||||||
text = stringResource(id = account.accountType!!.typeName),
|
|
||||||
style = MaterialTheme.typography.headlineMedium
|
|
||||||
)
|
|
||||||
|
|
||||||
VeryLargeSpacer()
|
|
||||||
|
|
||||||
OutlinedTextField(
|
|
||||||
value = state.name,
|
|
||||||
onValueChange = { screenModel.onEvent(Event.NameEvent(it)) },
|
|
||||||
label = { Text(text = stringResource(id = R.string.account_name)) },
|
|
||||||
singleLine = true,
|
|
||||||
isError = state.isNameError,
|
|
||||||
supportingText = { Text(text = state.nameError?.errorText().orEmpty()) },
|
|
||||||
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Next),
|
|
||||||
modifier = Modifier.fillMaxWidth()
|
|
||||||
)
|
|
||||||
|
|
||||||
ShortSpacer()
|
|
||||||
|
|
||||||
OutlinedTextField(
|
|
||||||
value = state.url,
|
|
||||||
onValueChange = { screenModel.onEvent(Event.URLEvent(it)) },
|
|
||||||
label = { Text(text = stringResource(id = R.string.account_url)) },
|
|
||||||
singleLine = true,
|
|
||||||
isError = state.isUrlError,
|
|
||||||
supportingText = { Text(text = state.urlError?.errorText().orEmpty()) },
|
|
||||||
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Next),
|
|
||||||
modifier = Modifier.fillMaxWidth()
|
|
||||||
)
|
|
||||||
|
|
||||||
ShortSpacer()
|
|
||||||
|
|
||||||
OutlinedTextField(
|
|
||||||
value = state.login,
|
|
||||||
onValueChange = { screenModel.onEvent(Event.LoginEvent(it)) },
|
|
||||||
label = { Text(text = stringResource(id = R.string.login)) },
|
|
||||||
singleLine = true,
|
|
||||||
isError = state.isLoginError,
|
|
||||||
supportingText = { Text(text = state.loginError?.errorText().orEmpty()) },
|
|
||||||
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Next),
|
|
||||||
modifier = Modifier.fillMaxWidth()
|
|
||||||
)
|
|
||||||
|
|
||||||
ShortSpacer()
|
|
||||||
|
|
||||||
OutlinedTextField(
|
|
||||||
value = state.password,
|
|
||||||
onValueChange = { screenModel.onEvent(Event.PasswordEvent(it)) },
|
|
||||||
label = { Text(text = stringResource(id = R.string.password)) },
|
|
||||||
trailingIcon = {
|
|
||||||
IconButton(
|
IconButton(
|
||||||
onClick = { screenModel.setPasswordVisibility(!state.isPasswordVisible) }
|
onClick = { navigator.pop() }
|
||||||
) {
|
) {
|
||||||
Icon(
|
Icon(
|
||||||
painter = painterResource(
|
imageVector = Icons.AutoMirrored.Default.ArrowBack,
|
||||||
id = if (state.isPasswordVisible) {
|
|
||||||
R.drawable.ic_visible_off
|
|
||||||
} else R.drawable.ic_visible
|
|
||||||
),
|
|
||||||
contentDescription = null
|
contentDescription = null
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
},
|
|
||||||
singleLine = true,
|
|
||||||
visualTransformation = if (state.isPasswordVisible)
|
|
||||||
VisualTransformation.None
|
|
||||||
else
|
|
||||||
PasswordVisualTransformation(),
|
|
||||||
isError = state.isPasswordError,
|
|
||||||
supportingText = { Text(text = state.passwordError?.errorText().orEmpty()) },
|
|
||||||
keyboardOptions = KeyboardOptions(
|
|
||||||
keyboardType = KeyboardType.Password,
|
|
||||||
imeAction = ImeAction.Done
|
|
||||||
),
|
|
||||||
modifier = Modifier.fillMaxWidth()
|
|
||||||
)
|
|
||||||
|
|
||||||
ShortSpacer()
|
|
||||||
|
|
||||||
Button(
|
|
||||||
onClick = { screenModel.login() },
|
|
||||||
modifier = Modifier.fillMaxWidth()
|
|
||||||
) {
|
|
||||||
if (state.isLoginOnGoing) {
|
|
||||||
CircularProgressIndicator(
|
|
||||||
color = MaterialTheme.colorScheme.onPrimary,
|
|
||||||
strokeWidth = 2.dp,
|
|
||||||
modifier = Modifier.size(16.dp)
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
Text(text = stringResource(id = R.string.validate))
|
|
||||||
}
|
}
|
||||||
}
|
)
|
||||||
|
}
|
||||||
|
) { paddingValues ->
|
||||||
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.padding(paddingValues)
|
||||||
|
.imePadding()
|
||||||
|
) {
|
||||||
|
Column(
|
||||||
|
horizontalAlignment = Alignment.CenterHorizontally,
|
||||||
|
modifier = Modifier
|
||||||
|
.background(MaterialTheme.colorScheme.background)
|
||||||
|
.fillMaxSize()
|
||||||
|
.padding(MaterialTheme.spacing.mediumSpacing)
|
||||||
|
.verticalScroll(rememberScrollState())
|
||||||
|
) {
|
||||||
|
Image(
|
||||||
|
painter = painterResource(id = account.accountType!!.iconRes),
|
||||||
|
contentDescription = null,
|
||||||
|
modifier = Modifier.size(48.dp)
|
||||||
|
)
|
||||||
|
|
||||||
if (state.loginException != null) {
|
|
||||||
ShortSpacer()
|
ShortSpacer()
|
||||||
|
|
||||||
Text(
|
Text(
|
||||||
text = ErrorMessage.get(state.loginException!!, LocalContext.current),
|
text = stringResource(id = account.accountType!!.typeName),
|
||||||
style = MaterialTheme.typography.labelMedium,
|
style = MaterialTheme.typography.headlineMedium
|
||||||
color = MaterialTheme.colorScheme.error
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
MediumSpacer()
|
||||||
|
|
||||||
|
OutlinedTextField(
|
||||||
|
value = state.name,
|
||||||
|
onValueChange = { screenModel.onEvent(Event.NameEvent(it)) },
|
||||||
|
label = { Text(text = stringResource(id = R.string.account_name)) },
|
||||||
|
singleLine = true,
|
||||||
|
isError = state.isNameError,
|
||||||
|
supportingText = { Text(text = state.nameError?.errorText().orEmpty()) },
|
||||||
|
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Next),
|
||||||
|
modifier = Modifier.fillMaxWidth()
|
||||||
|
)
|
||||||
|
|
||||||
|
ShortSpacer()
|
||||||
|
|
||||||
|
OutlinedTextField(
|
||||||
|
value = state.url,
|
||||||
|
onValueChange = { screenModel.onEvent(Event.URLEvent(it)) },
|
||||||
|
label = { Text(text = stringResource(id = R.string.account_url)) },
|
||||||
|
singleLine = true,
|
||||||
|
isError = state.isUrlError,
|
||||||
|
supportingText = { Text(text = state.urlError?.errorText().orEmpty()) },
|
||||||
|
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Next),
|
||||||
|
modifier = Modifier.fillMaxWidth()
|
||||||
|
)
|
||||||
|
|
||||||
|
ShortSpacer()
|
||||||
|
|
||||||
|
OutlinedTextField(
|
||||||
|
value = state.login,
|
||||||
|
onValueChange = { screenModel.onEvent(Event.LoginEvent(it)) },
|
||||||
|
label = { Text(text = stringResource(id = R.string.login)) },
|
||||||
|
singleLine = true,
|
||||||
|
isError = state.isLoginError,
|
||||||
|
supportingText = { Text(text = state.loginError?.errorText().orEmpty()) },
|
||||||
|
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Next),
|
||||||
|
modifier = Modifier.fillMaxWidth()
|
||||||
|
)
|
||||||
|
|
||||||
|
ShortSpacer()
|
||||||
|
|
||||||
|
OutlinedTextField(
|
||||||
|
value = state.password,
|
||||||
|
onValueChange = { screenModel.onEvent(Event.PasswordEvent(it)) },
|
||||||
|
label = { Text(text = stringResource(id = R.string.password)) },
|
||||||
|
trailingIcon = {
|
||||||
|
IconButton(
|
||||||
|
onClick = { screenModel.setPasswordVisibility(!state.isPasswordVisible) }
|
||||||
|
) {
|
||||||
|
Icon(
|
||||||
|
painter = painterResource(
|
||||||
|
id = if (state.isPasswordVisible) {
|
||||||
|
R.drawable.ic_visible_off
|
||||||
|
} else R.drawable.ic_visible
|
||||||
|
),
|
||||||
|
contentDescription = null
|
||||||
|
)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
singleLine = true,
|
||||||
|
visualTransformation = if (state.isPasswordVisible)
|
||||||
|
VisualTransformation.None
|
||||||
|
else
|
||||||
|
PasswordVisualTransformation(),
|
||||||
|
isError = state.isPasswordError,
|
||||||
|
supportingText = {
|
||||||
|
Text(
|
||||||
|
text = state.passwordError?.errorText().orEmpty()
|
||||||
|
)
|
||||||
|
},
|
||||||
|
keyboardOptions = KeyboardOptions(
|
||||||
|
keyboardType = KeyboardType.Password,
|
||||||
|
imeAction = ImeAction.Done
|
||||||
|
),
|
||||||
|
modifier = Modifier.fillMaxWidth()
|
||||||
|
)
|
||||||
|
|
||||||
|
ShortSpacer()
|
||||||
|
|
||||||
|
Button(
|
||||||
|
onClick = { screenModel.login() },
|
||||||
|
modifier = Modifier.fillMaxWidth()
|
||||||
|
) {
|
||||||
|
if (state.isLoginOnGoing) {
|
||||||
|
CircularProgressIndicator(
|
||||||
|
color = MaterialTheme.colorScheme.onPrimary,
|
||||||
|
strokeWidth = 2.dp,
|
||||||
|
modifier = Modifier.size(16.dp)
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
Text(text = stringResource(id = R.string.validate))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (state.loginException != null) {
|
||||||
|
ShortSpacer()
|
||||||
|
|
||||||
|
Text(
|
||||||
|
text = ErrorMessage.get(state.loginException!!, LocalContext.current),
|
||||||
|
style = MaterialTheme.typography.labelMedium,
|
||||||
|
color = MaterialTheme.colorScheme.error
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue