mirror of
https://github.com/LiveFastEatTrashRaccoon/RaccoonForLemmy.git
synced 2025-02-10 05:20:38 +01:00
parent
f75057335f
commit
ac9a55c964
@ -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,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -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,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -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,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user