fix: bottom sheet IME padding (#437)

closes #436
This commit is contained in:
Diego Beraldin 2024-01-10 09:00:47 +01:00 committed by GitHub
parent f75057335f
commit ac9a55c964
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 461 additions and 473 deletions

View File

@ -85,100 +85,96 @@ class BanUserScreen(
}.launchIn(this) }.launchIn(this)
} }
Box( Column(
modifier = Modifier.imePadding(), modifier = Modifier.imePadding(),
contentAlignment = Alignment.BottomCenter, verticalArrangement = Arrangement.spacedBy(Spacing.s),
horizontalAlignment = Alignment.CenterHorizontally,
) { ) {
Column( Box(
verticalArrangement = Arrangement.spacedBy(Spacing.s), modifier = Modifier.fillMaxWidth().padding(top = Spacing.s),
horizontalAlignment = Alignment.CenterHorizontally,
) { ) {
Box( Column(
modifier = Modifier.fillMaxWidth().padding(top = Spacing.s), modifier = Modifier.align(Alignment.TopCenter),
verticalArrangement = Arrangement.spacedBy(Spacing.s),
horizontalAlignment = Alignment.CenterHorizontally
) { ) {
Column( BottomSheetHandle()
modifier = Modifier.align(Alignment.TopCenter), val title = if (newValue) {
verticalArrangement = Arrangement.spacedBy(Spacing.s), stringResource(MR.strings.mod_action_ban)
horizontalAlignment = Alignment.CenterHorizontally } else {
) { stringResource(MR.strings.mod_action_allow)
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,
)
} }
IconButton( Text(
modifier = Modifier.align(Alignment.TopEnd), text = title,
content = { style = MaterialTheme.typography.titleLarge,
Icon( color = MaterialTheme.colorScheme.onBackground,
imageVector = Icons.Default.Send,
contentDescription = null,
tint = MaterialTheme.colorScheme.onBackground,
)
},
onClick = {
model.reduce(BanUserMviModel.Intent.Submit)
},
) )
} }
IconButton(
val commentFocusRequester = remember { FocusRequester() } modifier = Modifier.align(Alignment.TopEnd),
TextField( content = {
modifier = Modifier Icon(
.focusRequester(commentFocusRequester) imageVector = Icons.Default.Send,
.heightIn(min = 300.dp, max = 500.dp) contentDescription = null,
.fillMaxWidth(), tint = MaterialTheme.colorScheme.onBackground,
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, onClick = {
value = uiState.text, model.reduce(BanUserMviModel.Intent.Submit)
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))
} }
if (uiState.loading) { val commentFocusRequester = remember { FocusRequester() }
ProgressHud() 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( if (uiState.loading) {
modifier = Modifier.padding(bottom = Spacing.xxxl), ProgressHud()
hostState = snackbarHostState }
) { data ->
Snackbar( SnackbarHost(
containerColor = MaterialTheme.colorScheme.surfaceVariant, modifier = Modifier.padding(bottom = Spacing.xxxl),
contentColor = MaterialTheme.colorScheme.onSurfaceVariant, hostState = snackbarHostState
snackbarData = data, ) { data ->
) Snackbar(
} containerColor = MaterialTheme.colorScheme.surfaceVariant,
contentColor = MaterialTheme.colorScheme.onSurfaceVariant,
snackbarData = data,
)
} }
} }
} }

View File

@ -79,99 +79,95 @@ class CreateReportScreen(
}.launchIn(this) }.launchIn(this)
} }
Box( Column(
modifier = Modifier.imePadding(), modifier = Modifier.imePadding(),
contentAlignment = Alignment.BottomCenter, verticalArrangement = Arrangement.spacedBy(Spacing.s),
horizontalAlignment = Alignment.CenterHorizontally,
) { ) {
Column( Box(
verticalArrangement = Arrangement.spacedBy(Spacing.s), modifier = Modifier.fillMaxWidth().padding(top = Spacing.s),
horizontalAlignment = Alignment.CenterHorizontally,
) { ) {
Box( Column(
modifier = Modifier.fillMaxWidth().padding(top = Spacing.s), modifier = Modifier.align(Alignment.TopCenter),
verticalArrangement = Arrangement.spacedBy(Spacing.s),
horizontalAlignment = Alignment.CenterHorizontally,
) { ) {
Column( BottomSheetHandle()
modifier = Modifier.align(Alignment.TopCenter), val title = when {
verticalArrangement = Arrangement.spacedBy(Spacing.s), commentId != null -> stringResource(MR.strings.create_report_title_comment)
horizontalAlignment = Alignment.CenterHorizontally, else -> stringResource(MR.strings.create_report_title_post)
) {
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,
)
} }
IconButton( Text(
modifier = Modifier.align(Alignment.TopEnd), text = title,
content = { style = MaterialTheme.typography.titleLarge,
Icon( color = MaterialTheme.colorScheme.onBackground,
imageVector = Icons.Default.Send,
contentDescription = null,
tint = MaterialTheme.colorScheme.onBackground,
)
},
onClick = {
model.reduce(CreateReportMviModel.Intent.Send)
},
) )
} }
IconButton(
val commentFocusRequester = remember { FocusRequester() } modifier = Modifier.align(Alignment.TopEnd),
TextField( content = {
modifier = Modifier Icon(
.focusRequester(commentFocusRequester) imageVector = Icons.Default.Send,
.heightIn(min = 300.dp, max = 500.dp) contentDescription = null,
.fillMaxWidth(), tint = MaterialTheme.colorScheme.onBackground,
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, onClick = {
value = uiState.text, model.reduce(CreateReportMviModel.Intent.Send)
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))
} }
if (uiState.loading) { val commentFocusRequester = remember { FocusRequester() }
ProgressHud() 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( if (uiState.loading) {
modifier = Modifier.padding(bottom = Spacing.xxxl), ProgressHud()
hostState = snackbarHostState }
) { data ->
Snackbar( SnackbarHost(
containerColor = MaterialTheme.colorScheme.surfaceVariant, modifier = Modifier.padding(bottom = Spacing.xxxl),
contentColor = MaterialTheme.colorScheme.onSurfaceVariant, hostState = snackbarHostState
snackbarData = data, ) { data ->
) Snackbar(
} containerColor = MaterialTheme.colorScheme.surfaceVariant,
contentColor = MaterialTheme.colorScheme.onSurfaceVariant,
snackbarData = data,
)
} }
} }
} }

View File

@ -11,8 +11,10 @@ import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.imePadding import androidx.compose.foundation.layout.imePadding
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.size
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.text.KeyboardActions import androidx.compose.foundation.text.KeyboardActions
import androidx.compose.foundation.text.KeyboardOptions import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Clear import androidx.compose.material.icons.filled.Clear
import androidx.compose.material.icons.filled.HelpOutline import androidx.compose.material.icons.filled.HelpOutline
@ -98,254 +100,252 @@ class LoginBottomSheet : Screen {
val uriHandler = LocalUriHandler.current val uriHandler = LocalUriHandler.current
val settingsRepository = remember { getSettingsRepository() } val settingsRepository = remember { getSettingsRepository() }
Box( Column(
modifier = Modifier.imePadding(), modifier = Modifier
contentAlignment = Alignment.BottomCenter, .imePadding()
) { .verticalScroll(rememberScrollState())
Column( .padding(
modifier = Modifier.padding(
top = Spacing.s, top = Spacing.s,
start = Spacing.s, start = Spacing.s,
end = Spacing.s, end = Spacing.s,
bottom = Spacing.m, bottom = Spacing.m,
), ),
verticalArrangement = Arrangement.spacedBy(Spacing.s), verticalArrangement = Arrangement.spacedBy(Spacing.s),
horizontalAlignment = Alignment.CenterHorizontally, horizontalAlignment = Alignment.CenterHorizontally,
) { ) {
Box { Box {
Column( Column(
modifier = Modifier.fillMaxWidth(), modifier = Modifier.fillMaxWidth(),
horizontalAlignment = Alignment.CenterHorizontally, horizontalAlignment = Alignment.CenterHorizontally,
) { ) {
BottomSheetHandle() BottomSheetHandle()
Text( Text(
modifier = Modifier.padding(start = Spacing.s, top = Spacing.s), modifier = Modifier.padding(start = Spacing.s, top = Spacing.s),
text = stringResource(MR.strings.profile_button_login), text = stringResource(MR.strings.profile_button_login),
style = MaterialTheme.typography.titleLarge, style = MaterialTheme.typography.titleLarge,
color = MaterialTheme.colorScheme.onBackground, 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,
)
}
} }
IconButton(
val instanceFocusRequester = remember { FocusRequester() } modifier = Modifier.align(Alignment.TopEnd),
val usernameFocusRequester = remember { FocusRequester() } onClick = rememberCallback {
val passwordFocusRequester = remember { FocusRequester() } navigationCoordinator.hideBottomSheet()
val tokenFocusRequester = remember { FocusRequester() } navigationCoordinator.handleUrl(
url = HELP_URL,
// instance name openExternal = settingsRepository.currentSettings.value.openUrlsInExternalBrowser,
TextField( uriHandler = uriHandler,
modifier = Modifier.focusRequester(instanceFocusRequester), onOpenWeb = { url ->
label = { navigationCoordinator.pushScreen(WebViewScreen(url))
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( Icon(
horizontalArrangement = Arrangement.spacedBy(Spacing.s), imageVector = Icons.Default.HelpOutline,
verticalAlignment = Alignment.CenterVertically, contentDescription = null,
) { tint = MaterialTheme.colorScheme.onBackground,
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( val instanceFocusRequester = remember { FocusRequester() }
modifier = Modifier.padding(bottom = Spacing.xxxl), val usernameFocusRequester = remember { FocusRequester() }
hostState = snackbarHostState val passwordFocusRequester = remember { FocusRequester() }
) { data -> val tokenFocusRequester = remember { FocusRequester() }
Snackbar(
containerColor = MaterialTheme.colorScheme.surfaceVariant, // instance name
contentColor = MaterialTheme.colorScheme.onSurfaceVariant, TextField(
snackbarData = data, 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,
)
} }
} }
} }

View File

@ -79,95 +79,91 @@ class RemoveScreen(
}.launchIn(this) }.launchIn(this)
} }
Box( Column(
modifier = Modifier.imePadding(), modifier = Modifier.imePadding(),
contentAlignment = Alignment.BottomCenter, verticalArrangement = Arrangement.spacedBy(Spacing.s),
horizontalAlignment = Alignment.CenterHorizontally,
) { ) {
Column( Box(
verticalArrangement = Arrangement.spacedBy(Spacing.s), modifier = Modifier.fillMaxWidth().padding(top = Spacing.s),
horizontalAlignment = Alignment.CenterHorizontally,
) { ) {
Box( Column(
modifier = Modifier.fillMaxWidth().padding(top = Spacing.s), modifier = Modifier.align(Alignment.TopCenter),
verticalArrangement = Arrangement.spacedBy(Spacing.s),
horizontalAlignment = Alignment.CenterHorizontally
) { ) {
Column( BottomSheetHandle()
modifier = Modifier.align(Alignment.TopCenter), Text(
verticalArrangement = Arrangement.spacedBy(Spacing.s), text = stringResource(MR.strings.mod_action_remove),
horizontalAlignment = Alignment.CenterHorizontally style = MaterialTheme.typography.titleLarge,
) { color = MaterialTheme.colorScheme.onBackground,
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)
},
) )
} }
IconButton(
val commentFocusRequester = remember { FocusRequester() } modifier = Modifier.align(Alignment.TopEnd),
TextField( content = {
modifier = Modifier Icon(
.focusRequester(commentFocusRequester) imageVector = Icons.Default.Send,
.heightIn(min = 300.dp, max = 500.dp) contentDescription = null,
.fillMaxWidth(), tint = MaterialTheme.colorScheme.onBackground,
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, onClick = {
value = uiState.text, model.reduce(RemoveMviModel.Intent.Submit)
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))
} }
if (uiState.loading) { val commentFocusRequester = remember { FocusRequester() }
ProgressHud() 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( if (uiState.loading) {
modifier = Modifier.padding(bottom = Spacing.xxxl), ProgressHud()
hostState = snackbarHostState }
) { data ->
Snackbar( SnackbarHost(
containerColor = MaterialTheme.colorScheme.surfaceVariant, modifier = Modifier.padding(bottom = Spacing.xxxl),
contentColor = MaterialTheme.colorScheme.onSurfaceVariant, hostState = snackbarHostState
snackbarData = data, ) { data ->
) Snackbar(
} containerColor = MaterialTheme.colorScheme.surfaceVariant,
contentColor = MaterialTheme.colorScheme.onSurfaceVariant,
snackbarData = data,
)
} }
} }
} }