mirror of
https://github.com/LiveFastEatTrashRaccoon/RaccoonForLemmy.git
synced 2025-02-09 10:08:45 +01:00
parent
f75057335f
commit
ac9a55c964
@ -85,100 +85,96 @@ class BanUserScreen(
|
||||
}.launchIn(this)
|
||||
}
|
||||
|
||||
Box(
|
||||
Column(
|
||||
modifier = Modifier.imePadding(),
|
||||
contentAlignment = Alignment.BottomCenter,
|
||||
verticalArrangement = Arrangement.spacedBy(Spacing.s),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
) {
|
||||
Column(
|
||||
verticalArrangement = Arrangement.spacedBy(Spacing.s),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
Box(
|
||||
modifier = Modifier.fillMaxWidth().padding(top = Spacing.s),
|
||||
) {
|
||||
Box(
|
||||
modifier = Modifier.fillMaxWidth().padding(top = Spacing.s),
|
||||
Column(
|
||||
modifier = Modifier.align(Alignment.TopCenter),
|
||||
verticalArrangement = Arrangement.spacedBy(Spacing.s),
|
||||
horizontalAlignment = Alignment.CenterHorizontally
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier.align(Alignment.TopCenter),
|
||||
verticalArrangement = Arrangement.spacedBy(Spacing.s),
|
||||
horizontalAlignment = Alignment.CenterHorizontally
|
||||
) {
|
||||
BottomSheetHandle()
|
||||
val title = if (newValue) {
|
||||
stringResource(MR.strings.mod_action_ban)
|
||||
} else {
|
||||
stringResource(MR.strings.mod_action_allow)
|
||||
}
|
||||
Text(
|
||||
text = title,
|
||||
style = MaterialTheme.typography.titleLarge,
|
||||
color = MaterialTheme.colorScheme.onBackground,
|
||||
)
|
||||
|
||||
BottomSheetHandle()
|
||||
val title = if (newValue) {
|
||||
stringResource(MR.strings.mod_action_ban)
|
||||
} else {
|
||||
stringResource(MR.strings.mod_action_allow)
|
||||
}
|
||||
IconButton(
|
||||
modifier = Modifier.align(Alignment.TopEnd),
|
||||
content = {
|
||||
Icon(
|
||||
imageVector = Icons.Default.Send,
|
||||
contentDescription = null,
|
||||
tint = MaterialTheme.colorScheme.onBackground,
|
||||
)
|
||||
},
|
||||
onClick = {
|
||||
model.reduce(BanUserMviModel.Intent.Submit)
|
||||
},
|
||||
Text(
|
||||
text = title,
|
||||
style = MaterialTheme.typography.titleLarge,
|
||||
color = MaterialTheme.colorScheme.onBackground,
|
||||
)
|
||||
|
||||
}
|
||||
|
||||
val commentFocusRequester = remember { FocusRequester() }
|
||||
TextField(
|
||||
modifier = Modifier
|
||||
.focusRequester(commentFocusRequester)
|
||||
.heightIn(min = 300.dp, max = 500.dp)
|
||||
.fillMaxWidth(),
|
||||
colors = TextFieldDefaults.colors(
|
||||
focusedContainerColor = Color.Transparent,
|
||||
unfocusedContainerColor = Color.Transparent,
|
||||
disabledContainerColor = Color.Transparent,
|
||||
),
|
||||
label = {
|
||||
Text(text = stringResource(MR.strings.create_report_placeholder))
|
||||
IconButton(
|
||||
modifier = Modifier.align(Alignment.TopEnd),
|
||||
content = {
|
||||
Icon(
|
||||
imageVector = Icons.Default.Send,
|
||||
contentDescription = null,
|
||||
tint = MaterialTheme.colorScheme.onBackground,
|
||||
)
|
||||
},
|
||||
textStyle = MaterialTheme.typography.bodyMedium,
|
||||
value = uiState.text,
|
||||
keyboardOptions = KeyboardOptions(
|
||||
keyboardType = KeyboardType.Text,
|
||||
autoCorrect = true,
|
||||
),
|
||||
onValueChange = { value ->
|
||||
model.reduce(BanUserMviModel.Intent.SetText(value))
|
||||
},
|
||||
isError = uiState.textError != null,
|
||||
supportingText = {
|
||||
if (uiState.textError != null) {
|
||||
Text(
|
||||
text = uiState.textError?.localized().orEmpty(),
|
||||
color = MaterialTheme.colorScheme.error,
|
||||
)
|
||||
}
|
||||
onClick = {
|
||||
model.reduce(BanUserMviModel.Intent.Submit)
|
||||
},
|
||||
)
|
||||
Spacer(Modifier.height(Spacing.xxl))
|
||||
}
|
||||
|
||||
if (uiState.loading) {
|
||||
ProgressHud()
|
||||
}
|
||||
val commentFocusRequester = remember { FocusRequester() }
|
||||
TextField(
|
||||
modifier = Modifier
|
||||
.focusRequester(commentFocusRequester)
|
||||
.heightIn(min = 300.dp, max = 500.dp)
|
||||
.fillMaxWidth(),
|
||||
colors = TextFieldDefaults.colors(
|
||||
focusedContainerColor = Color.Transparent,
|
||||
unfocusedContainerColor = Color.Transparent,
|
||||
disabledContainerColor = Color.Transparent,
|
||||
),
|
||||
label = {
|
||||
Text(text = stringResource(MR.strings.create_report_placeholder))
|
||||
},
|
||||
textStyle = MaterialTheme.typography.bodyMedium,
|
||||
value = uiState.text,
|
||||
keyboardOptions = KeyboardOptions(
|
||||
keyboardType = KeyboardType.Text,
|
||||
autoCorrect = true,
|
||||
),
|
||||
onValueChange = { value ->
|
||||
model.reduce(BanUserMviModel.Intent.SetText(value))
|
||||
},
|
||||
isError = uiState.textError != null,
|
||||
supportingText = {
|
||||
if (uiState.textError != null) {
|
||||
Text(
|
||||
text = uiState.textError?.localized().orEmpty(),
|
||||
color = MaterialTheme.colorScheme.error,
|
||||
)
|
||||
}
|
||||
},
|
||||
)
|
||||
Spacer(Modifier.height(Spacing.xxl))
|
||||
}
|
||||
|
||||
SnackbarHost(
|
||||
modifier = Modifier.padding(bottom = Spacing.xxxl),
|
||||
hostState = snackbarHostState
|
||||
) { data ->
|
||||
Snackbar(
|
||||
containerColor = MaterialTheme.colorScheme.surfaceVariant,
|
||||
contentColor = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
snackbarData = data,
|
||||
)
|
||||
}
|
||||
if (uiState.loading) {
|
||||
ProgressHud()
|
||||
}
|
||||
|
||||
SnackbarHost(
|
||||
modifier = Modifier.padding(bottom = Spacing.xxxl),
|
||||
hostState = snackbarHostState
|
||||
) { data ->
|
||||
Snackbar(
|
||||
containerColor = MaterialTheme.colorScheme.surfaceVariant,
|
||||
contentColor = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
snackbarData = data,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
@ -79,99 +79,95 @@ class CreateReportScreen(
|
||||
}.launchIn(this)
|
||||
}
|
||||
|
||||
Box(
|
||||
Column(
|
||||
modifier = Modifier.imePadding(),
|
||||
contentAlignment = Alignment.BottomCenter,
|
||||
verticalArrangement = Arrangement.spacedBy(Spacing.s),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
) {
|
||||
Column(
|
||||
verticalArrangement = Arrangement.spacedBy(Spacing.s),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
Box(
|
||||
modifier = Modifier.fillMaxWidth().padding(top = Spacing.s),
|
||||
) {
|
||||
Box(
|
||||
modifier = Modifier.fillMaxWidth().padding(top = Spacing.s),
|
||||
Column(
|
||||
modifier = Modifier.align(Alignment.TopCenter),
|
||||
verticalArrangement = Arrangement.spacedBy(Spacing.s),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier.align(Alignment.TopCenter),
|
||||
verticalArrangement = Arrangement.spacedBy(Spacing.s),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
) {
|
||||
BottomSheetHandle()
|
||||
val title = when {
|
||||
commentId != null -> stringResource(MR.strings.create_report_title_comment)
|
||||
else -> stringResource(MR.strings.create_report_title_post)
|
||||
}
|
||||
Text(
|
||||
text = title,
|
||||
style = MaterialTheme.typography.titleLarge,
|
||||
color = MaterialTheme.colorScheme.onBackground,
|
||||
)
|
||||
|
||||
BottomSheetHandle()
|
||||
val title = when {
|
||||
commentId != null -> stringResource(MR.strings.create_report_title_comment)
|
||||
else -> stringResource(MR.strings.create_report_title_post)
|
||||
}
|
||||
IconButton(
|
||||
modifier = Modifier.align(Alignment.TopEnd),
|
||||
content = {
|
||||
Icon(
|
||||
imageVector = Icons.Default.Send,
|
||||
contentDescription = null,
|
||||
tint = MaterialTheme.colorScheme.onBackground,
|
||||
)
|
||||
},
|
||||
onClick = {
|
||||
model.reduce(CreateReportMviModel.Intent.Send)
|
||||
},
|
||||
Text(
|
||||
text = title,
|
||||
style = MaterialTheme.typography.titleLarge,
|
||||
color = MaterialTheme.colorScheme.onBackground,
|
||||
)
|
||||
|
||||
}
|
||||
|
||||
val commentFocusRequester = remember { FocusRequester() }
|
||||
TextField(
|
||||
modifier = Modifier
|
||||
.focusRequester(commentFocusRequester)
|
||||
.heightIn(min = 300.dp, max = 500.dp)
|
||||
.fillMaxWidth(),
|
||||
colors = TextFieldDefaults.colors(
|
||||
focusedContainerColor = Color.Transparent,
|
||||
unfocusedContainerColor = Color.Transparent,
|
||||
disabledContainerColor = Color.Transparent,
|
||||
),
|
||||
label = {
|
||||
Text(text = stringResource(MR.strings.create_report_placeholder))
|
||||
IconButton(
|
||||
modifier = Modifier.align(Alignment.TopEnd),
|
||||
content = {
|
||||
Icon(
|
||||
imageVector = Icons.Default.Send,
|
||||
contentDescription = null,
|
||||
tint = MaterialTheme.colorScheme.onBackground,
|
||||
)
|
||||
},
|
||||
textStyle = MaterialTheme.typography.bodyMedium,
|
||||
value = uiState.text,
|
||||
keyboardOptions = KeyboardOptions(
|
||||
keyboardType = KeyboardType.Text,
|
||||
autoCorrect = true,
|
||||
),
|
||||
onValueChange = { value ->
|
||||
model.reduce(CreateReportMviModel.Intent.SetText(value))
|
||||
},
|
||||
isError = uiState.textError != null,
|
||||
supportingText = {
|
||||
if (uiState.textError != null) {
|
||||
Text(
|
||||
text = uiState.textError?.localized().orEmpty(),
|
||||
color = MaterialTheme.colorScheme.error,
|
||||
)
|
||||
}
|
||||
onClick = {
|
||||
model.reduce(CreateReportMviModel.Intent.Send)
|
||||
},
|
||||
)
|
||||
Spacer(Modifier.height(Spacing.xxl))
|
||||
}
|
||||
|
||||
if (uiState.loading) {
|
||||
ProgressHud()
|
||||
}
|
||||
val commentFocusRequester = remember { FocusRequester() }
|
||||
TextField(
|
||||
modifier = Modifier
|
||||
.focusRequester(commentFocusRequester)
|
||||
.heightIn(min = 300.dp, max = 500.dp)
|
||||
.fillMaxWidth(),
|
||||
colors = TextFieldDefaults.colors(
|
||||
focusedContainerColor = Color.Transparent,
|
||||
unfocusedContainerColor = Color.Transparent,
|
||||
disabledContainerColor = Color.Transparent,
|
||||
),
|
||||
label = {
|
||||
Text(text = stringResource(MR.strings.create_report_placeholder))
|
||||
},
|
||||
textStyle = MaterialTheme.typography.bodyMedium,
|
||||
value = uiState.text,
|
||||
keyboardOptions = KeyboardOptions(
|
||||
keyboardType = KeyboardType.Text,
|
||||
autoCorrect = true,
|
||||
),
|
||||
onValueChange = { value ->
|
||||
model.reduce(CreateReportMviModel.Intent.SetText(value))
|
||||
},
|
||||
isError = uiState.textError != null,
|
||||
supportingText = {
|
||||
if (uiState.textError != null) {
|
||||
Text(
|
||||
text = uiState.textError?.localized().orEmpty(),
|
||||
color = MaterialTheme.colorScheme.error,
|
||||
)
|
||||
}
|
||||
},
|
||||
)
|
||||
Spacer(Modifier.height(Spacing.xxl))
|
||||
}
|
||||
|
||||
SnackbarHost(
|
||||
modifier = Modifier.padding(bottom = Spacing.xxxl),
|
||||
hostState = snackbarHostState
|
||||
) { data ->
|
||||
Snackbar(
|
||||
containerColor = MaterialTheme.colorScheme.surfaceVariant,
|
||||
contentColor = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
snackbarData = data,
|
||||
)
|
||||
}
|
||||
if (uiState.loading) {
|
||||
ProgressHud()
|
||||
}
|
||||
|
||||
SnackbarHost(
|
||||
modifier = Modifier.padding(bottom = Spacing.xxxl),
|
||||
hostState = snackbarHostState
|
||||
) { data ->
|
||||
Snackbar(
|
||||
containerColor = MaterialTheme.colorScheme.surfaceVariant,
|
||||
contentColor = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
snackbarData = data,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
@ -11,8 +11,10 @@ import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.imePadding
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.foundation.text.KeyboardActions
|
||||
import androidx.compose.foundation.text.KeyboardOptions
|
||||
import androidx.compose.foundation.verticalScroll
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.Clear
|
||||
import androidx.compose.material.icons.filled.HelpOutline
|
||||
@ -98,254 +100,252 @@ class LoginBottomSheet : Screen {
|
||||
val uriHandler = LocalUriHandler.current
|
||||
val settingsRepository = remember { getSettingsRepository() }
|
||||
|
||||
Box(
|
||||
modifier = Modifier.imePadding(),
|
||||
contentAlignment = Alignment.BottomCenter,
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier.padding(
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.imePadding()
|
||||
.verticalScroll(rememberScrollState())
|
||||
.padding(
|
||||
top = Spacing.s,
|
||||
start = Spacing.s,
|
||||
end = Spacing.s,
|
||||
bottom = Spacing.m,
|
||||
),
|
||||
verticalArrangement = Arrangement.spacedBy(Spacing.s),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
) {
|
||||
Box {
|
||||
Column(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
) {
|
||||
BottomSheetHandle()
|
||||
Text(
|
||||
modifier = Modifier.padding(start = Spacing.s, top = Spacing.s),
|
||||
text = stringResource(MR.strings.profile_button_login),
|
||||
style = MaterialTheme.typography.titleLarge,
|
||||
color = MaterialTheme.colorScheme.onBackground,
|
||||
)
|
||||
}
|
||||
IconButton(
|
||||
modifier = Modifier.align(Alignment.TopEnd),
|
||||
onClick = rememberCallback {
|
||||
navigationCoordinator.hideBottomSheet()
|
||||
navigationCoordinator.handleUrl(
|
||||
url = HELP_URL,
|
||||
openExternal = settingsRepository.currentSettings.value.openUrlsInExternalBrowser,
|
||||
uriHandler = uriHandler,
|
||||
onOpenWeb = { url ->
|
||||
navigationCoordinator.pushScreen(WebViewScreen(url))
|
||||
}
|
||||
)
|
||||
},
|
||||
) {
|
||||
Icon(
|
||||
imageVector = Icons.Default.HelpOutline,
|
||||
contentDescription = null,
|
||||
tint = MaterialTheme.colorScheme.onBackground,
|
||||
)
|
||||
}
|
||||
verticalArrangement = Arrangement.spacedBy(Spacing.s),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
) {
|
||||
Box {
|
||||
Column(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
) {
|
||||
BottomSheetHandle()
|
||||
Text(
|
||||
modifier = Modifier.padding(start = Spacing.s, top = Spacing.s),
|
||||
text = stringResource(MR.strings.profile_button_login),
|
||||
style = MaterialTheme.typography.titleLarge,
|
||||
color = MaterialTheme.colorScheme.onBackground,
|
||||
)
|
||||
}
|
||||
|
||||
val instanceFocusRequester = remember { FocusRequester() }
|
||||
val usernameFocusRequester = remember { FocusRequester() }
|
||||
val passwordFocusRequester = remember { FocusRequester() }
|
||||
val tokenFocusRequester = remember { FocusRequester() }
|
||||
|
||||
// instance name
|
||||
TextField(
|
||||
modifier = Modifier.focusRequester(instanceFocusRequester),
|
||||
label = {
|
||||
Text(text = stringResource(MR.strings.login_field_instance_name))
|
||||
},
|
||||
singleLine = true,
|
||||
value = uiState.instanceName,
|
||||
isError = uiState.instanceNameError != null,
|
||||
keyboardActions = KeyboardActions(
|
||||
onNext = {
|
||||
usernameFocusRequester.requestFocus()
|
||||
},
|
||||
),
|
||||
keyboardOptions = KeyboardOptions(
|
||||
keyboardType = KeyboardType.Email,
|
||||
autoCorrect = false,
|
||||
imeAction = ImeAction.Next,
|
||||
),
|
||||
onValueChange = rememberCallbackArgs(model) { value ->
|
||||
model.reduce(LoginMviModel.Intent.SetInstanceName(value))
|
||||
},
|
||||
supportingText = {
|
||||
if (uiState.instanceNameError != null) {
|
||||
Text(
|
||||
text = uiState.instanceNameError?.localized().orEmpty(),
|
||||
color = MaterialTheme.colorScheme.error,
|
||||
)
|
||||
}
|
||||
},
|
||||
trailingIcon = {
|
||||
if (uiState.instanceName.isNotEmpty()) {
|
||||
Icon(
|
||||
modifier = Modifier.onClick(
|
||||
onClick = rememberCallback(model) {
|
||||
model.reduce(
|
||||
LoginMviModel.Intent.SetInstanceName("")
|
||||
)
|
||||
},
|
||||
),
|
||||
imageVector = Icons.Default.Clear,
|
||||
contentDescription = null,
|
||||
)
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
// user name
|
||||
TextField(
|
||||
modifier = Modifier.focusRequester(usernameFocusRequester),
|
||||
label = {
|
||||
Text(text = stringResource(MR.strings.login_field_user_name))
|
||||
},
|
||||
singleLine = true,
|
||||
value = uiState.username,
|
||||
isError = uiState.usernameError != null,
|
||||
keyboardActions = KeyboardActions(
|
||||
onNext = {
|
||||
passwordFocusRequester.requestFocus()
|
||||
},
|
||||
),
|
||||
keyboardOptions = KeyboardOptions(
|
||||
keyboardType = KeyboardType.Email,
|
||||
autoCorrect = false,
|
||||
imeAction = ImeAction.Next,
|
||||
),
|
||||
onValueChange = rememberCallbackArgs(model) { value ->
|
||||
model.reduce(LoginMviModel.Intent.SetUsername(value))
|
||||
},
|
||||
supportingText = {
|
||||
if (uiState.usernameError != null) {
|
||||
Text(
|
||||
text = uiState.usernameError?.localized().orEmpty(),
|
||||
color = MaterialTheme.colorScheme.error,
|
||||
)
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
// password
|
||||
var transformation: VisualTransformation by remember {
|
||||
mutableStateOf(PasswordVisualTransformation())
|
||||
}
|
||||
TextField(
|
||||
modifier = Modifier.focusRequester(passwordFocusRequester),
|
||||
label = {
|
||||
Text(text = stringResource(MR.strings.login_field_password))
|
||||
},
|
||||
singleLine = true,
|
||||
value = uiState.password,
|
||||
isError = uiState.passwordError != null,
|
||||
keyboardActions = KeyboardActions(
|
||||
onNext = {
|
||||
tokenFocusRequester.requestFocus()
|
||||
},
|
||||
),
|
||||
keyboardOptions = KeyboardOptions(
|
||||
keyboardType = KeyboardType.Password,
|
||||
imeAction = ImeAction.Next,
|
||||
),
|
||||
onValueChange = rememberCallbackArgs(model) { value ->
|
||||
model.reduce(LoginMviModel.Intent.SetPassword(value))
|
||||
},
|
||||
visualTransformation = transformation,
|
||||
trailingIcon = {
|
||||
Image(
|
||||
modifier = Modifier.onClick(
|
||||
onClick = rememberCallback {
|
||||
transformation =
|
||||
if (transformation == VisualTransformation.None) {
|
||||
PasswordVisualTransformation()
|
||||
} else {
|
||||
VisualTransformation.None
|
||||
}
|
||||
},
|
||||
),
|
||||
imageVector = if (transformation == VisualTransformation.None) {
|
||||
Icons.Default.VisibilityOff
|
||||
} else {
|
||||
Icons.Default.Visibility
|
||||
},
|
||||
contentDescription = null,
|
||||
colorFilter = ColorFilter.tint(color = MaterialTheme.colorScheme.onBackground),
|
||||
IconButton(
|
||||
modifier = Modifier.align(Alignment.TopEnd),
|
||||
onClick = rememberCallback {
|
||||
navigationCoordinator.hideBottomSheet()
|
||||
navigationCoordinator.handleUrl(
|
||||
url = HELP_URL,
|
||||
openExternal = settingsRepository.currentSettings.value.openUrlsInExternalBrowser,
|
||||
uriHandler = uriHandler,
|
||||
onOpenWeb = { url ->
|
||||
navigationCoordinator.pushScreen(WebViewScreen(url))
|
||||
}
|
||||
)
|
||||
},
|
||||
supportingText = {
|
||||
if (uiState.passwordError != null) {
|
||||
Text(
|
||||
text = uiState.passwordError?.localized().orEmpty(),
|
||||
color = MaterialTheme.colorScheme.error,
|
||||
)
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
// TOTP 2FA token
|
||||
TextField(
|
||||
modifier = Modifier.focusRequester(tokenFocusRequester),
|
||||
label = {
|
||||
Row(
|
||||
horizontalArrangement = Arrangement.spacedBy(Spacing.s),
|
||||
verticalAlignment = Alignment.Bottom,
|
||||
) {
|
||||
Text(text = stringResource(MR.strings.login_field_token))
|
||||
Text(
|
||||
text = stringResource(MR.strings.login_field_label_optional),
|
||||
style = MaterialTheme.typography.labelSmall,
|
||||
)
|
||||
}
|
||||
},
|
||||
singleLine = true,
|
||||
value = uiState.totp2faToken,
|
||||
keyboardOptions = KeyboardOptions(
|
||||
keyboardType = KeyboardType.Password,
|
||||
imeAction = ImeAction.Done,
|
||||
),
|
||||
onValueChange = rememberCallbackArgs(model) { value ->
|
||||
model.reduce(LoginMviModel.Intent.SetTotp2faToken(value))
|
||||
},
|
||||
visualTransformation = PasswordVisualTransformation(),
|
||||
)
|
||||
Spacer(modifier = Modifier.height(Spacing.m))
|
||||
Button(
|
||||
modifier = Modifier.align(Alignment.CenterHorizontally),
|
||||
onClick = rememberCallback(model) {
|
||||
model.reduce(LoginMviModel.Intent.Confirm)
|
||||
},
|
||||
) {
|
||||
Row(
|
||||
horizontalArrangement = Arrangement.spacedBy(Spacing.s),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
if (uiState.loading) {
|
||||
CircularProgressIndicator(
|
||||
modifier = Modifier.size(IconSize.s),
|
||||
color = MaterialTheme.colorScheme.onPrimary,
|
||||
)
|
||||
}
|
||||
Text(stringResource(MR.strings.button_confirm))
|
||||
}
|
||||
Icon(
|
||||
imageVector = Icons.Default.HelpOutline,
|
||||
contentDescription = null,
|
||||
tint = MaterialTheme.colorScheme.onBackground,
|
||||
)
|
||||
}
|
||||
Spacer(modifier = Modifier.height(Spacing.m))
|
||||
}
|
||||
|
||||
SnackbarHost(
|
||||
modifier = Modifier.padding(bottom = Spacing.xxxl),
|
||||
hostState = snackbarHostState
|
||||
) { data ->
|
||||
Snackbar(
|
||||
containerColor = MaterialTheme.colorScheme.surfaceVariant,
|
||||
contentColor = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
snackbarData = data,
|
||||
)
|
||||
val instanceFocusRequester = remember { FocusRequester() }
|
||||
val usernameFocusRequester = remember { FocusRequester() }
|
||||
val passwordFocusRequester = remember { FocusRequester() }
|
||||
val tokenFocusRequester = remember { FocusRequester() }
|
||||
|
||||
// instance name
|
||||
TextField(
|
||||
modifier = Modifier.focusRequester(instanceFocusRequester),
|
||||
label = {
|
||||
Text(text = stringResource(MR.strings.login_field_instance_name))
|
||||
},
|
||||
singleLine = true,
|
||||
value = uiState.instanceName,
|
||||
isError = uiState.instanceNameError != null,
|
||||
keyboardActions = KeyboardActions(
|
||||
onNext = {
|
||||
usernameFocusRequester.requestFocus()
|
||||
},
|
||||
),
|
||||
keyboardOptions = KeyboardOptions(
|
||||
keyboardType = KeyboardType.Email,
|
||||
autoCorrect = false,
|
||||
imeAction = ImeAction.Next,
|
||||
),
|
||||
onValueChange = rememberCallbackArgs(model) { value ->
|
||||
model.reduce(LoginMviModel.Intent.SetInstanceName(value))
|
||||
},
|
||||
supportingText = {
|
||||
if (uiState.instanceNameError != null) {
|
||||
Text(
|
||||
text = uiState.instanceNameError?.localized().orEmpty(),
|
||||
color = MaterialTheme.colorScheme.error,
|
||||
)
|
||||
}
|
||||
},
|
||||
trailingIcon = {
|
||||
if (uiState.instanceName.isNotEmpty()) {
|
||||
Icon(
|
||||
modifier = Modifier.onClick(
|
||||
onClick = rememberCallback(model) {
|
||||
model.reduce(
|
||||
LoginMviModel.Intent.SetInstanceName("")
|
||||
)
|
||||
},
|
||||
),
|
||||
imageVector = Icons.Default.Clear,
|
||||
contentDescription = null,
|
||||
)
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
// user name
|
||||
TextField(
|
||||
modifier = Modifier.focusRequester(usernameFocusRequester),
|
||||
label = {
|
||||
Text(text = stringResource(MR.strings.login_field_user_name))
|
||||
},
|
||||
singleLine = true,
|
||||
value = uiState.username,
|
||||
isError = uiState.usernameError != null,
|
||||
keyboardActions = KeyboardActions(
|
||||
onNext = {
|
||||
passwordFocusRequester.requestFocus()
|
||||
},
|
||||
),
|
||||
keyboardOptions = KeyboardOptions(
|
||||
keyboardType = KeyboardType.Email,
|
||||
autoCorrect = false,
|
||||
imeAction = ImeAction.Next,
|
||||
),
|
||||
onValueChange = rememberCallbackArgs(model) { value ->
|
||||
model.reduce(LoginMviModel.Intent.SetUsername(value))
|
||||
},
|
||||
supportingText = {
|
||||
if (uiState.usernameError != null) {
|
||||
Text(
|
||||
text = uiState.usernameError?.localized().orEmpty(),
|
||||
color = MaterialTheme.colorScheme.error,
|
||||
)
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
// password
|
||||
var transformation: VisualTransformation by remember {
|
||||
mutableStateOf(PasswordVisualTransformation())
|
||||
}
|
||||
TextField(
|
||||
modifier = Modifier.focusRequester(passwordFocusRequester),
|
||||
label = {
|
||||
Text(text = stringResource(MR.strings.login_field_password))
|
||||
},
|
||||
singleLine = true,
|
||||
value = uiState.password,
|
||||
isError = uiState.passwordError != null,
|
||||
keyboardActions = KeyboardActions(
|
||||
onNext = {
|
||||
tokenFocusRequester.requestFocus()
|
||||
},
|
||||
),
|
||||
keyboardOptions = KeyboardOptions(
|
||||
keyboardType = KeyboardType.Password,
|
||||
imeAction = ImeAction.Next,
|
||||
),
|
||||
onValueChange = rememberCallbackArgs(model) { value ->
|
||||
model.reduce(LoginMviModel.Intent.SetPassword(value))
|
||||
},
|
||||
visualTransformation = transformation,
|
||||
trailingIcon = {
|
||||
Image(
|
||||
modifier = Modifier.onClick(
|
||||
onClick = rememberCallback {
|
||||
transformation =
|
||||
if (transformation == VisualTransformation.None) {
|
||||
PasswordVisualTransformation()
|
||||
} else {
|
||||
VisualTransformation.None
|
||||
}
|
||||
},
|
||||
),
|
||||
imageVector = if (transformation == VisualTransformation.None) {
|
||||
Icons.Default.VisibilityOff
|
||||
} else {
|
||||
Icons.Default.Visibility
|
||||
},
|
||||
contentDescription = null,
|
||||
colorFilter = ColorFilter.tint(color = MaterialTheme.colorScheme.onBackground),
|
||||
)
|
||||
},
|
||||
supportingText = {
|
||||
if (uiState.passwordError != null) {
|
||||
Text(
|
||||
text = uiState.passwordError?.localized().orEmpty(),
|
||||
color = MaterialTheme.colorScheme.error,
|
||||
)
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
// TOTP 2FA token
|
||||
TextField(
|
||||
modifier = Modifier.focusRequester(tokenFocusRequester),
|
||||
label = {
|
||||
Row(
|
||||
horizontalArrangement = Arrangement.spacedBy(Spacing.s),
|
||||
verticalAlignment = Alignment.Bottom,
|
||||
) {
|
||||
Text(text = stringResource(MR.strings.login_field_token))
|
||||
Text(
|
||||
text = stringResource(MR.strings.login_field_label_optional),
|
||||
style = MaterialTheme.typography.labelSmall,
|
||||
)
|
||||
}
|
||||
},
|
||||
singleLine = true,
|
||||
value = uiState.totp2faToken,
|
||||
keyboardOptions = KeyboardOptions(
|
||||
keyboardType = KeyboardType.Password,
|
||||
imeAction = ImeAction.Done,
|
||||
),
|
||||
onValueChange = rememberCallbackArgs(model) { value ->
|
||||
model.reduce(LoginMviModel.Intent.SetTotp2faToken(value))
|
||||
},
|
||||
visualTransformation = PasswordVisualTransformation(),
|
||||
)
|
||||
Spacer(modifier = Modifier.height(Spacing.m))
|
||||
Button(
|
||||
modifier = Modifier.align(Alignment.CenterHorizontally),
|
||||
onClick = rememberCallback(model) {
|
||||
model.reduce(LoginMviModel.Intent.Confirm)
|
||||
},
|
||||
) {
|
||||
Row(
|
||||
horizontalArrangement = Arrangement.spacedBy(Spacing.s),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
if (uiState.loading) {
|
||||
CircularProgressIndicator(
|
||||
modifier = Modifier.size(IconSize.s),
|
||||
color = MaterialTheme.colorScheme.onPrimary,
|
||||
)
|
||||
}
|
||||
Text(stringResource(MR.strings.button_confirm))
|
||||
}
|
||||
}
|
||||
Spacer(modifier = Modifier.height(Spacing.m))
|
||||
}
|
||||
|
||||
SnackbarHost(
|
||||
modifier = Modifier.padding(bottom = Spacing.xxxl),
|
||||
hostState = snackbarHostState
|
||||
) { data ->
|
||||
Snackbar(
|
||||
containerColor = MaterialTheme.colorScheme.surfaceVariant,
|
||||
contentColor = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
snackbarData = data,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -79,95 +79,91 @@ class RemoveScreen(
|
||||
}.launchIn(this)
|
||||
}
|
||||
|
||||
Box(
|
||||
Column(
|
||||
modifier = Modifier.imePadding(),
|
||||
contentAlignment = Alignment.BottomCenter,
|
||||
verticalArrangement = Arrangement.spacedBy(Spacing.s),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
) {
|
||||
Column(
|
||||
verticalArrangement = Arrangement.spacedBy(Spacing.s),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
Box(
|
||||
modifier = Modifier.fillMaxWidth().padding(top = Spacing.s),
|
||||
) {
|
||||
Box(
|
||||
modifier = Modifier.fillMaxWidth().padding(top = Spacing.s),
|
||||
Column(
|
||||
modifier = Modifier.align(Alignment.TopCenter),
|
||||
verticalArrangement = Arrangement.spacedBy(Spacing.s),
|
||||
horizontalAlignment = Alignment.CenterHorizontally
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier.align(Alignment.TopCenter),
|
||||
verticalArrangement = Arrangement.spacedBy(Spacing.s),
|
||||
horizontalAlignment = Alignment.CenterHorizontally
|
||||
) {
|
||||
BottomSheetHandle()
|
||||
Text(
|
||||
text = stringResource(MR.strings.mod_action_remove),
|
||||
style = MaterialTheme.typography.titleLarge,
|
||||
color = MaterialTheme.colorScheme.onBackground,
|
||||
)
|
||||
|
||||
}
|
||||
IconButton(
|
||||
modifier = Modifier.align(Alignment.TopEnd),
|
||||
content = {
|
||||
Icon(
|
||||
imageVector = Icons.Default.Send,
|
||||
contentDescription = null,
|
||||
tint = MaterialTheme.colorScheme.onBackground,
|
||||
)
|
||||
},
|
||||
onClick = {
|
||||
model.reduce(RemoveMviModel.Intent.Submit)
|
||||
},
|
||||
BottomSheetHandle()
|
||||
Text(
|
||||
text = stringResource(MR.strings.mod_action_remove),
|
||||
style = MaterialTheme.typography.titleLarge,
|
||||
color = MaterialTheme.colorScheme.onBackground,
|
||||
)
|
||||
|
||||
}
|
||||
|
||||
val commentFocusRequester = remember { FocusRequester() }
|
||||
TextField(
|
||||
modifier = Modifier
|
||||
.focusRequester(commentFocusRequester)
|
||||
.heightIn(min = 300.dp, max = 500.dp)
|
||||
.fillMaxWidth(),
|
||||
colors = TextFieldDefaults.colors(
|
||||
focusedContainerColor = Color.Transparent,
|
||||
unfocusedContainerColor = Color.Transparent,
|
||||
disabledContainerColor = Color.Transparent,
|
||||
),
|
||||
label = {
|
||||
Text(text = stringResource(MR.strings.create_report_placeholder))
|
||||
IconButton(
|
||||
modifier = Modifier.align(Alignment.TopEnd),
|
||||
content = {
|
||||
Icon(
|
||||
imageVector = Icons.Default.Send,
|
||||
contentDescription = null,
|
||||
tint = MaterialTheme.colorScheme.onBackground,
|
||||
)
|
||||
},
|
||||
textStyle = MaterialTheme.typography.bodyMedium,
|
||||
value = uiState.text,
|
||||
keyboardOptions = KeyboardOptions(
|
||||
keyboardType = KeyboardType.Text,
|
||||
autoCorrect = true,
|
||||
),
|
||||
onValueChange = { value ->
|
||||
model.reduce(RemoveMviModel.Intent.SetText(value))
|
||||
},
|
||||
isError = uiState.textError != null,
|
||||
supportingText = {
|
||||
if (uiState.textError != null) {
|
||||
Text(
|
||||
text = uiState.textError?.localized().orEmpty(),
|
||||
color = MaterialTheme.colorScheme.error,
|
||||
)
|
||||
}
|
||||
onClick = {
|
||||
model.reduce(RemoveMviModel.Intent.Submit)
|
||||
},
|
||||
)
|
||||
Spacer(Modifier.height(Spacing.xxl))
|
||||
}
|
||||
|
||||
if (uiState.loading) {
|
||||
ProgressHud()
|
||||
}
|
||||
val commentFocusRequester = remember { FocusRequester() }
|
||||
TextField(
|
||||
modifier = Modifier
|
||||
.focusRequester(commentFocusRequester)
|
||||
.heightIn(min = 300.dp, max = 500.dp)
|
||||
.fillMaxWidth(),
|
||||
colors = TextFieldDefaults.colors(
|
||||
focusedContainerColor = Color.Transparent,
|
||||
unfocusedContainerColor = Color.Transparent,
|
||||
disabledContainerColor = Color.Transparent,
|
||||
),
|
||||
label = {
|
||||
Text(text = stringResource(MR.strings.create_report_placeholder))
|
||||
},
|
||||
textStyle = MaterialTheme.typography.bodyMedium,
|
||||
value = uiState.text,
|
||||
keyboardOptions = KeyboardOptions(
|
||||
keyboardType = KeyboardType.Text,
|
||||
autoCorrect = true,
|
||||
),
|
||||
onValueChange = { value ->
|
||||
model.reduce(RemoveMviModel.Intent.SetText(value))
|
||||
},
|
||||
isError = uiState.textError != null,
|
||||
supportingText = {
|
||||
if (uiState.textError != null) {
|
||||
Text(
|
||||
text = uiState.textError?.localized().orEmpty(),
|
||||
color = MaterialTheme.colorScheme.error,
|
||||
)
|
||||
}
|
||||
},
|
||||
)
|
||||
Spacer(Modifier.height(Spacing.xxl))
|
||||
}
|
||||
|
||||
SnackbarHost(
|
||||
modifier = Modifier.padding(bottom = Spacing.xxxl),
|
||||
hostState = snackbarHostState
|
||||
) { data ->
|
||||
Snackbar(
|
||||
containerColor = MaterialTheme.colorScheme.surfaceVariant,
|
||||
contentColor = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
snackbarData = data,
|
||||
)
|
||||
}
|
||||
if (uiState.loading) {
|
||||
ProgressHud()
|
||||
}
|
||||
|
||||
SnackbarHost(
|
||||
modifier = Modifier.padding(bottom = Spacing.xxxl),
|
||||
hostState = snackbarHostState
|
||||
) { data ->
|
||||
Snackbar(
|
||||
containerColor = MaterialTheme.colorScheme.surfaceVariant,
|
||||
contentColor = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
snackbarData = data,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user