improve visuals for Logo & Login screens for compact devices

This commit is contained in:
2024-07-14 00:57:44 +03:00
parent 5f57d35ce5
commit c573803921
8 changed files with 254 additions and 182 deletions
+2
View File
@@ -181,4 +181,6 @@ dependencies {
implementation(libs.androidx.navigation.compose) implementation(libs.androidx.navigation.compose)
implementation(libs.kotlin.serialization) implementation(libs.kotlin.serialization)
implementation("androidx.compose.material3.adaptive:adaptive:1.0.0-beta04")
} }
@@ -15,6 +15,7 @@ import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge import androidx.activity.enableEdgeToEdge
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.app.AppCompatDelegate import androidx.appcompat.app.AppCompatDelegate
import androidx.compose.material3.adaptive.currentWindowAdaptiveInfo
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.LaunchedEffect
@@ -28,6 +29,7 @@ import androidx.core.content.ContextCompat
import androidx.core.os.LocaleListCompat import androidx.core.os.LocaleListCompat
import androidx.lifecycle.compose.LifecycleResumeEffect import androidx.lifecycle.compose.LifecycleResumeEffect
import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.window.core.layout.WindowWidthSizeClass
import com.google.accompanist.permissions.ExperimentalPermissionsApi import com.google.accompanist.permissions.ExperimentalPermissionsApi
import com.google.accompanist.permissions.rememberPermissionState import com.google.accompanist.permissions.rememberPermissionState
import com.meloda.app.fast.MainViewModel import com.meloda.app.fast.MainViewModel
@@ -57,7 +59,11 @@ class MainActivity : AppCompatActivity() {
val currentNightMode = resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK val currentNightMode = resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK
val systemBarStyle = when (currentNightMode) { val systemBarStyle = when (currentNightMode) {
Configuration.UI_MODE_NIGHT_NO -> SystemBarStyle.light(Color.Transparent.toArgb(), Color.Transparent.toArgb()) Configuration.UI_MODE_NIGHT_NO -> SystemBarStyle.light(
Color.Transparent.toArgb(),
Color.Transparent.toArgb()
)
Configuration.UI_MODE_NIGHT_YES -> SystemBarStyle.dark(Color.Transparent.toArgb()) Configuration.UI_MODE_NIGHT_YES -> SystemBarStyle.dark(Color.Transparent.toArgb())
else -> error("Illegal State, current mode is $currentNightMode") else -> error("Illegal State, current mode is $currentNightMode")
} }
@@ -104,6 +110,14 @@ class MainActivity : AppCompatActivity() {
} }
} }
val windowAdaptiveInfo = currentWindowAdaptiveInfo()
val isDeviceCompact by remember(windowAdaptiveInfo) {
derivedStateOf {
windowAdaptiveInfo.windowSizeClass.windowWidthSizeClass == WindowWidthSizeClass.COMPACT
}
}
val theme by userSettings.theme.collectAsStateWithLifecycle() val theme by userSettings.theme.collectAsStateWithLifecycle()
CompositionLocalProvider( CompositionLocalProvider(
LocalTheme provides ThemeConfig( LocalTheme provides ThemeConfig(
@@ -112,7 +126,8 @@ class MainActivity : AppCompatActivity() {
selectedColorScheme = theme.selectedColorScheme, selectedColorScheme = theme.selectedColorScheme,
usingAmoledBackground = theme.usingAmoledBackground, usingAmoledBackground = theme.usingAmoledBackground,
usingBlur = theme.usingBlur, usingBlur = theme.usingBlur,
multiline = theme.multiline multiline = theme.multiline,
isDeviceCompact = isDeviceCompact
) )
) { ) {
val currentTheme = LocalTheme.current val currentTheme = LocalTheme.current
@@ -40,7 +40,8 @@ class UserSettingsImpl(
selectedColorScheme = selectedColorScheme(), selectedColorScheme = selectedColorScheme(),
usingAmoledBackground = isUsingAmoledBackground(), usingAmoledBackground = isUsingAmoledBackground(),
usingBlur = isUsingBlur(), usingBlur = isUsingBlur(),
multiline = isMultiline() multiline = isMultiline(),
isDeviceCompact = false
) )
) )
@@ -7,5 +7,5 @@ data class ThemeConfig(
val usingAmoledBackground: Boolean, val usingAmoledBackground: Boolean,
val usingBlur: Boolean, val usingBlur: Boolean,
val multiline: Boolean, val multiline: Boolean,
val bubblesWithPinch: Boolean = true val isDeviceCompact: Boolean
) )
@@ -110,7 +110,8 @@ val LocalTheme = compositionLocalOf {
selectedColorScheme = 0, selectedColorScheme = 0,
usingAmoledBackground = false, usingAmoledBackground = false,
usingBlur = false, usingBlur = false,
multiline = false multiline = false,
isDeviceCompact = false
) )
} }
@@ -6,11 +6,13 @@ import androidx.compose.animation.fadeOut
import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.imePadding import androidx.compose.foundation.layout.ime
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.union
import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.text.KeyboardActions import androidx.compose.foundation.text.KeyboardActions
import androidx.compose.foundation.text.KeyboardOptions import androidx.compose.foundation.text.KeyboardOptions
@@ -20,6 +22,7 @@ import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Scaffold import androidx.compose.material3.Scaffold
import androidx.compose.material3.ScaffoldDefaults
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.material3.TextField import androidx.compose.material3.TextField
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
@@ -48,6 +51,7 @@ import androidx.compose.ui.text.input.VisualTransformation
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.meloda.app.fast.common.UiText import com.meloda.app.fast.common.UiText
import com.meloda.app.fast.designsystem.LocalTheme
import com.meloda.app.fast.designsystem.MaterialDialog import com.meloda.app.fast.designsystem.MaterialDialog
import com.meloda.app.fast.designsystem.TextFieldErrorText import com.meloda.app.fast.designsystem.TextFieldErrorText
import com.meloda.app.fast.designsystem.autoFillRequestHandler import com.meloda.app.fast.designsystem.autoFillRequestHandler
@@ -60,8 +64,8 @@ import com.meloda.fast.auth.login.LoginViewModelImpl
import com.meloda.fast.auth.login.model.CaptchaArguments import com.meloda.fast.auth.login.model.CaptchaArguments
import com.meloda.fast.auth.login.model.LoginError import com.meloda.fast.auth.login.model.LoginError
import com.meloda.fast.auth.login.model.LoginScreenState import com.meloda.fast.auth.login.model.LoginScreenState
import com.meloda.fast.auth.login.model.LoginValidationArguments
import com.meloda.fast.auth.login.model.LoginUserBannedArguments import com.meloda.fast.auth.login.model.LoginUserBannedArguments
import com.meloda.fast.auth.login.model.LoginValidationArguments
import org.koin.androidx.compose.koinViewModel import org.koin.androidx.compose.koinViewModel
import com.meloda.app.fast.designsystem.R as UiR import com.meloda.app.fast.designsystem.R as UiR
@@ -153,6 +157,7 @@ fun LoginScreen(
onPasswordFieldGoAction: () -> Unit = {}, onPasswordFieldGoAction: () -> Unit = {},
onSignInButtonClicked: () -> Unit = {} onSignInButtonClicked: () -> Unit = {}
) { ) {
val currentTheme = LocalTheme.current
val focusManager = LocalFocusManager.current val focusManager = LocalFocusManager.current
val (loginFocusable, passwordFocusable) = FocusRequester.createRefs() val (loginFocusable, passwordFocusable) = FocusRequester.createRefs()
@@ -181,183 +186,198 @@ fun LoginScreen(
} }
) )
Scaffold { padding -> val titleStyle = if (currentTheme.isDeviceCompact) {
MaterialTheme.typography.displaySmall
} else {
MaterialTheme.typography.displayMedium
}
val titleSpacerSize = if (currentTheme.isDeviceCompact) {
24.dp
} else {
58.dp
}
val bottomPadding = if (currentTheme.isDeviceCompact) {
10.dp
} else {
30.dp
}
Scaffold(
contentWindowInsets = ScaffoldDefaults.contentWindowInsets.union(WindowInsets.ime)
) { padding ->
Box( Box(
modifier = Modifier modifier = Modifier
.fillMaxSize() .fillMaxSize()
.padding(padding) .padding(padding)
.padding(top = 30.dp)
.padding(horizontal = 30.dp)
.padding(bottom = bottomPadding)
) { ) {
Box( Column(
modifier = Modifier modifier = Modifier
.fillMaxSize() .fillMaxWidth()
.padding(30.dp) .align(Alignment.Center)
.imePadding()
) { ) {
Column( Text(
text = stringResource(id = UiR.string.sign_in_to_vk),
color = MaterialTheme.colorScheme.onBackground,
style = titleStyle
)
Spacer(modifier = Modifier.height(titleSpacerSize))
TextField(
modifier = Modifier modifier = Modifier
.height(58.dp)
.fillMaxWidth() .fillMaxWidth()
.align(Alignment.Center) .clip(RoundedCornerShape(10.dp))
) { .handleEnterKey {
Text( passwordFocusable.requestFocus()
text = stringResource(id = UiR.string.sign_in_to_vk), true
color = MaterialTheme.colorScheme.onBackground, }
style = MaterialTheme.typography.displayMedium .handleTabKey {
) passwordFocusable.requestFocus()
true
}
.focusRequester(loginFocusable)
.connectNode(handler = autoFillEmailHandler)
.defaultFocusChangeAutoFill(handler = autoFillEmailHandler),
value = loginText,
onValueChange = { newText ->
val text = newText.text
if (text.isEmpty()) {
autoFillEmailHandler.requestVerifyManual()
}
Spacer(modifier = Modifier.height(58.dp)) loginText = newText
onLoginInputChanged(text)
TextField( },
modifier = Modifier label = { Text(text = stringResource(id = UiR.string.login_hint)) },
.height(58.dp) placeholder = { Text(text = stringResource(id = UiR.string.login_hint)) },
.fillMaxWidth() leadingIcon = {
.clip(RoundedCornerShape(10.dp)) Icon(
.handleEnterKey { painter = painterResource(id = UiR.drawable.ic_round_person_24),
passwordFocusable.requestFocus() contentDescription = "Login icon",
true tint = if (showLoginError) {
MaterialTheme.colorScheme.error
} else {
MaterialTheme.colorScheme.primary
} }
.handleTabKey { )
passwordFocusable.requestFocus() },
true keyboardOptions = KeyboardOptions.Default.copy(
} imeAction = ImeAction.Next,
.focusRequester(loginFocusable) keyboardType = KeyboardType.Email
.connectNode(handler = autoFillEmailHandler) ),
.defaultFocusChangeAutoFill(handler = autoFillEmailHandler), keyboardActions = KeyboardActions(onNext = { passwordFocusable.requestFocus() }),
value = loginText, isError = showLoginError,
onValueChange = { newText -> singleLine = true
val text = newText.text )
if (text.isEmpty()) { AnimatedVisibility(visible = showLoginError) {
autoFillEmailHandler.requestVerifyManual() TextFieldErrorText(text = stringResource(id = UiR.string.error_empty_field))
}
loginText = newText
onLoginInputChanged(text)
},
label = { Text(text = stringResource(id = UiR.string.login_hint)) },
placeholder = { Text(text = stringResource(id = UiR.string.login_hint)) },
leadingIcon = {
Icon(
painter = painterResource(id = UiR.drawable.ic_round_person_24),
contentDescription = "Login icon",
tint = if (showLoginError) {
MaterialTheme.colorScheme.error
} else {
MaterialTheme.colorScheme.primary
}
)
},
keyboardOptions = KeyboardOptions.Default.copy(
imeAction = ImeAction.Next,
keyboardType = KeyboardType.Email
),
keyboardActions = KeyboardActions(onNext = { passwordFocusable.requestFocus() }),
isError = showLoginError,
singleLine = true
)
AnimatedVisibility(visible = showLoginError) {
TextFieldErrorText(text = stringResource(id = UiR.string.error_empty_field))
}
Spacer(modifier = Modifier.height(16.dp))
TextField(
modifier = Modifier
.height(58.dp)
.fillMaxWidth()
.clip(RoundedCornerShape(10.dp))
.handleEnterKey {
focusManager.clearFocus()
onPasswordFieldEnterKeyClicked()
true
}
.focusRequester(passwordFocusable)
.connectNode(handler = autoFillPasswordHandler)
.defaultFocusChangeAutoFill(handler = autoFillPasswordHandler),
value = passwordText,
onValueChange = { newText ->
val text = newText.text
if (text.isEmpty()) {
autoFillPasswordHandler.requestVerifyManual()
}
passwordText = newText
onPasswordInputChanged(text)
},
label = { Text(text = stringResource(id = UiR.string.password_login_hint)) },
placeholder = { Text(text = stringResource(id = UiR.string.password_login_hint)) },
leadingIcon = {
Icon(
painter = painterResource(id = UiR.drawable.round_vpn_key_24),
contentDescription = "Password icon",
tint = if (showPasswordError) {
MaterialTheme.colorScheme.error
} else {
MaterialTheme.colorScheme.primary
}
)
},
trailingIcon = {
val imagePainter = painterResource(
id = if (screenState.passwordVisible) UiR.drawable.round_visibility_off_24
else UiR.drawable.round_visibility_24
)
IconButton(onClick = onPasswordVisibilityButtonClicked) {
Icon(
painter = imagePainter,
contentDescription = if (screenState.passwordVisible) "Password visible icon"
else "Password invisible icon"
)
}
},
keyboardOptions = KeyboardOptions.Default.copy(
imeAction = ImeAction.Go,
keyboardType = KeyboardType.Password
),
keyboardActions = KeyboardActions(
onGo = {
focusManager.clearFocus()
onPasswordFieldGoAction()
}
),
isError = showPasswordError,
visualTransformation = if (screenState.passwordVisible) {
VisualTransformation.None
} else {
PasswordVisualTransformation()
},
singleLine = true
)
AnimatedVisibility(visible = showPasswordError) {
TextFieldErrorText(text = stringResource(id = UiR.string.error_empty_field))
}
} }
Box( Spacer(modifier = Modifier.height(16.dp))
modifier = Modifier.align(Alignment.BottomCenter),
contentAlignment = Alignment.Center
) {
FloatingActionButton( TextField(
onClick = { modifier = Modifier
.height(58.dp)
.fillMaxWidth()
.clip(RoundedCornerShape(10.dp))
.handleEnterKey {
focusManager.clearFocus() focusManager.clearFocus()
onSignInButtonClicked() onPasswordFieldEnterKeyClicked()
}, true
containerColor = MaterialTheme.colorScheme.secondaryContainer, }
modifier = Modifier.testTag("sing_in_fab") .focusRequester(passwordFocusable)
) { .connectNode(handler = autoFillPasswordHandler)
.defaultFocusChangeAutoFill(handler = autoFillPasswordHandler),
value = passwordText,
onValueChange = { newText ->
val text = newText.text
if (text.isEmpty()) {
autoFillPasswordHandler.requestVerifyManual()
}
passwordText = newText
onPasswordInputChanged(text)
},
label = { Text(text = stringResource(id = UiR.string.password_login_hint)) },
placeholder = { Text(text = stringResource(id = UiR.string.password_login_hint)) },
leadingIcon = {
Icon( Icon(
painter = painterResource(id = UiR.drawable.ic_arrow_end), painter = painterResource(id = UiR.drawable.round_vpn_key_24),
contentDescription = "Sign in icon", contentDescription = "Password icon",
tint = MaterialTheme.colorScheme.onSecondaryContainer tint = if (showPasswordError) {
MaterialTheme.colorScheme.error
} else {
MaterialTheme.colorScheme.primary
}
) )
} },
AnimatedVisibility( trailingIcon = {
visible = screenState.isLoading, val imagePainter = painterResource(
enter = fadeIn(), id = if (screenState.passwordVisible) UiR.drawable.round_visibility_off_24
exit = fadeOut() else UiR.drawable.round_visibility_24
) { )
CircularProgressIndicator()
} IconButton(onClick = onPasswordVisibilityButtonClicked) {
Icon(
painter = imagePainter,
contentDescription = if (screenState.passwordVisible) "Password visible icon"
else "Password invisible icon"
)
}
},
keyboardOptions = KeyboardOptions.Default.copy(
imeAction = ImeAction.Go,
keyboardType = KeyboardType.Password
),
keyboardActions = KeyboardActions(
onGo = {
focusManager.clearFocus()
onPasswordFieldGoAction()
}
),
isError = showPasswordError,
visualTransformation = if (screenState.passwordVisible) {
VisualTransformation.None
} else {
PasswordVisualTransformation()
},
singleLine = true
)
AnimatedVisibility(visible = showPasswordError) {
TextFieldErrorText(text = stringResource(id = UiR.string.error_empty_field))
}
}
Box(
modifier = Modifier.align(Alignment.BottomCenter),
contentAlignment = Alignment.Center
) {
FloatingActionButton(
onClick = {
focusManager.clearFocus()
onSignInButtonClicked()
},
containerColor = MaterialTheme.colorScheme.secondaryContainer,
modifier = Modifier.testTag("sing_in_fab")
) {
Icon(
painter = painterResource(id = UiR.drawable.ic_arrow_end),
contentDescription = "Sign in icon",
tint = MaterialTheme.colorScheme.onSecondaryContainer
)
}
AnimatedVisibility(
visible = screenState.isLoading,
enter = fadeIn(),
exit = fadeOut()
) {
CircularProgressIndicator()
} }
} }
} }
@@ -13,6 +13,7 @@ import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.material3.FloatingActionButton import androidx.compose.material3.FloatingActionButton
import androidx.compose.material3.Icon import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
@@ -30,6 +31,7 @@ import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.LayoutDirection import androidx.compose.ui.unit.LayoutDirection
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.meloda.app.fast.designsystem.LocalTheme
import com.meloda.fast.auth.login.LoginViewModel import com.meloda.fast.auth.login.LoginViewModel
import com.meloda.fast.auth.login.LoginViewModelImpl import com.meloda.fast.auth.login.LoginViewModelImpl
import org.koin.androidx.compose.koinViewModel import org.koin.androidx.compose.koinViewModel
@@ -64,6 +66,8 @@ fun LogoScreen(
onLogoLongClicked: () -> Unit = {}, onLogoLongClicked: () -> Unit = {},
onGoNextButtonClicked: () -> Unit = {} onGoNextButtonClicked: () -> Unit = {}
) { ) {
val currentTheme = LocalTheme.current
Scaffold { padding -> Scaffold { padding ->
val topPadding by animateDpAsState( val topPadding by animateDpAsState(
targetValue = padding.calculateTopPadding(), targetValue = padding.calculateTopPadding(),
@@ -83,6 +87,24 @@ fun LogoScreen(
label = "startPaddingAnimation" label = "startPaddingAnimation"
) )
val iconWidth = if (currentTheme.isDeviceCompact) {
100.dp
} else {
134.dp
}
val appNameTextStyle = if (currentTheme.isDeviceCompact) {
MaterialTheme.typography.displaySmall
} else {
MaterialTheme.typography.displayMedium
}
val bottomAdditionalPadding = if (currentTheme.isDeviceCompact) {
10.dp
} else {
30.dp
}
Box( Box(
modifier = Modifier modifier = Modifier
.fillMaxSize() .fillMaxSize()
@@ -92,7 +114,9 @@ fun LogoScreen(
end = endPadding, end = endPadding,
bottom = bottomPadding bottom = bottomPadding
) )
.padding(30.dp) .padding(top = 30.dp)
.padding(horizontal = 30.dp)
.padding(bottom = bottomAdditionalPadding)
) { ) {
Column( Column(
modifier = Modifier modifier = Modifier
@@ -104,17 +128,19 @@ fun LogoScreen(
painter = painterResource(id = UiR.drawable.ic_logo_big), painter = painterResource(id = UiR.drawable.ic_logo_big),
contentDescription = "Application Logo", contentDescription = "Application Logo",
tint = MaterialTheme.colorScheme.primary, tint = MaterialTheme.colorScheme.primary,
modifier = Modifier.combinedClickable( modifier = Modifier
interactionSource = remember { MutableInteractionSource() }, .width(iconWidth)
indication = null, .combinedClickable(
onLongClick = onLogoLongClicked, interactionSource = remember { MutableInteractionSource() },
onClick = {} indication = null,
) onLongClick = onLogoLongClicked,
onClick = {}
)
) )
Spacer(modifier = Modifier.height(46.dp)) Spacer(modifier = Modifier.height(46.dp))
Text( Text(
text = stringResource(id = UiR.string.fast_messenger), text = stringResource(id = UiR.string.fast_messenger),
style = MaterialTheme.typography.displayMedium, style = appNameTextStyle,
color = MaterialTheme.colorScheme.onBackground color = MaterialTheme.colorScheme.onBackground
) )
} }
@@ -60,6 +60,7 @@ import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalView import androidx.compose.ui.platform.LocalView
import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.DpOffset import androidx.compose.ui.unit.DpOffset
import androidx.compose.ui.unit.LayoutDirection import androidx.compose.ui.unit.LayoutDirection
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
@@ -163,16 +164,16 @@ fun MessagesHistoryScreen(
) )
} }
val toolbarColorAlpha by animateFloatAsState(
targetValue = if (!listState.canScrollForward) 1f else 0f,
label = "toolbarColorAlpha",
animationSpec = tween(durationMillis = 50)
)
Scaffold( Scaffold(
modifier = Modifier.fillMaxSize(), modifier = Modifier.fillMaxSize(),
contentWindowInsets = WindowInsets.statusBars, contentWindowInsets = WindowInsets.statusBars,
topBar = { topBar = {
val toolbarColorAlpha by animateFloatAsState(
targetValue = if (!listState.canScrollForward) 1f else 0f,
label = "toolbarColorAlpha",
animationSpec = tween(durationMillis = 50)
)
Column(modifier = Modifier.fillMaxWidth()) { Column(modifier = Modifier.fillMaxWidth()) {
TopAppBar( TopAppBar(
modifier = Modifier modifier = Modifier
@@ -370,7 +371,13 @@ fun MessagesHistoryScreen(
unfocusedIndicatorColor = Color.Transparent, unfocusedIndicatorColor = Color.Transparent,
focusedIndicatorColor = Color.Transparent, focusedIndicatorColor = Color.Transparent,
), ),
placeholder = { Text(text = stringResource(id = UiR.string.message_input_hint)) } placeholder = {
Text(
text = stringResource(id = UiR.string.message_input_hint),
maxLines = 1,
overflow = TextOverflow.Ellipsis
)
}
) )
IconButton(onClick = onAttachmentButtonClicked) { IconButton(onClick = onAttachmentButtonClicked) {