improvements in ui

This commit is contained in:
2024-07-19 06:52:25 +03:00
parent 2b018add7c
commit ce306c995e
9 changed files with 156 additions and 57 deletions
@@ -1,12 +1,12 @@
package dev.meloda.fast.auth.login
import dev.meloda.fast.auth.login.model.AuthInfo
import dev.meloda.fast.data.State
import dev.meloda.fast.data.api.oauth.OAuthRepository
import dev.meloda.fast.network.OAuthErrorDomain
import dev.meloda.fast.network.ValidationType
import dev.meloda.fast.network.VkOAuthError
import dev.meloda.fast.network.VkOAuthErrorType
import dev.meloda.fast.auth.login.model.AuthInfo
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flow
@@ -94,6 +94,8 @@ class OAuthUseCaseImpl(
VkOAuthError.INVALID_REQUEST -> {
when (errorType) {
null -> State.Error.OAuthError(OAuthErrorDomain.UnknownError)
VkOAuthErrorType.WRONG_OTP -> {
State.Error.OAuthError(OAuthErrorDomain.WrongValidationCode)
}
@@ -106,7 +108,9 @@ class OAuthUseCaseImpl(
State.Error.OAuthError(OAuthErrorDomain.TooManyTriesError)
}
null -> State.Error.OAuthError(OAuthErrorDomain.UnknownError)
VkOAuthErrorType.USERNAME_OR_PASSWORD_IS_INCORRECT -> {
State.Error.OAuthError(OAuthErrorDomain.InvalidCredentialsError)
}
}
}
@@ -50,14 +50,6 @@ import androidx.compose.ui.text.input.TextFieldValue
import androidx.compose.ui.text.input.VisualTransformation
import androidx.compose.ui.unit.dp
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import dev.meloda.fast.ui.basic.autoFillRequestHandler
import dev.meloda.fast.ui.basic.connectNode
import dev.meloda.fast.ui.basic.defaultFocusChangeAutoFill
import dev.meloda.fast.ui.components.MaterialDialog
import dev.meloda.fast.ui.components.TextFieldErrorText
import dev.meloda.fast.ui.theme.LocalThemeConfig
import dev.meloda.fast.ui.util.handleEnterKey
import dev.meloda.fast.ui.util.handleTabKey
import dev.meloda.fast.auth.login.LoginViewModel
import dev.meloda.fast.auth.login.LoginViewModelImpl
import dev.meloda.fast.auth.login.model.CaptchaArguments
@@ -65,6 +57,14 @@ import dev.meloda.fast.auth.login.model.LoginError
import dev.meloda.fast.auth.login.model.LoginScreenState
import dev.meloda.fast.auth.login.model.LoginUserBannedArguments
import dev.meloda.fast.auth.login.model.LoginValidationArguments
import dev.meloda.fast.ui.basic.autoFillRequestHandler
import dev.meloda.fast.ui.basic.connectNode
import dev.meloda.fast.ui.basic.defaultFocusChangeAutoFill
import dev.meloda.fast.ui.components.MaterialDialog
import dev.meloda.fast.ui.components.TextFieldErrorText
import dev.meloda.fast.ui.theme.LocalSizeConfig
import dev.meloda.fast.ui.util.handleEnterKey
import dev.meloda.fast.ui.util.handleTabKey
import org.koin.androidx.compose.koinViewModel
import dev.meloda.fast.ui.R as UiR
@@ -156,7 +156,7 @@ fun LoginScreen(
onPasswordFieldGoAction: () -> Unit = {},
onSignInButtonClicked: () -> Unit = {}
) {
val currentTheme = LocalThemeConfig.current
val currentSize = LocalSizeConfig.current
val focusManager = LocalFocusManager.current
val (loginFocusable, passwordFocusable) = FocusRequester.createRefs()
@@ -182,19 +182,19 @@ fun LoginScreen(
}
)
val titleStyle = if (currentTheme.isDeviceCompact) {
MaterialTheme.typography.displaySmall
val titleStyle = if (currentSize.isWidthSmall) {
MaterialTheme.typography.displayMedium
} else {
MaterialTheme.typography.displayMedium
}
val titleSpacerSize = if (currentTheme.isDeviceCompact) {
val titleSpacerSize = if (currentSize.isHeightSmall) {
24.dp
} else {
58.dp
}
val bottomPadding = if (currentTheme.isDeviceCompact) {
val bottomPadding = if (currentSize.isHeightSmall) {
10.dp
} else {
30.dp
@@ -354,19 +354,27 @@ fun LoginScreen(
modifier = Modifier.align(Alignment.BottomCenter),
contentAlignment = Alignment.Center
) {
FloatingActionButton(
onClick = {
focusManager.clearFocus()
onSignInButtonClicked()
},
containerColor = MaterialTheme.colorScheme.secondaryContainer,
modifier = Modifier.testTag("sing_in_fab")
AnimatedVisibility(
visible = !screenState.isLoading,
enter = fadeIn(),
exit = fadeOut()
) {
Icon(
painter = painterResource(id = UiR.drawable.ic_arrow_end),
contentDescription = "Sign in icon",
tint = MaterialTheme.colorScheme.onSecondaryContainer
)
FloatingActionButton(
onClick = {
if (!screenState.isLoading) {
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,
@@ -1,6 +1,9 @@
package dev.meloda.fast.auth.login.presentation
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.core.animateDpAsState
import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.combinedClickable
import androidx.compose.foundation.interaction.MutableInteractionSource
@@ -14,6 +17,7 @@ import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.FloatingActionButton
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
@@ -34,13 +38,14 @@ import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.LayoutDirection
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import dev.meloda.fast.auth.login.BuildConfig
import dev.meloda.fast.auth.login.LoginViewModel
import dev.meloda.fast.auth.login.LoginViewModelImpl
import dev.meloda.fast.ui.components.ActionInvokeDismiss
import dev.meloda.fast.ui.components.MaterialDialog
import dev.meloda.fast.ui.theme.LocalThemeConfig
import dev.meloda.fast.ui.theme.LocalSizeConfig
import org.koin.androidx.compose.koinViewModel
import dev.meloda.fast.ui.R as UiR
@@ -50,6 +55,7 @@ fun LogoRoute(
onGoNextButtonClicked: () -> Unit,
viewModel: LoginViewModel = koinViewModel<LoginViewModelImpl>()
) {
val screenState by viewModel.screenState.collectAsStateWithLifecycle()
val isNeedToOpenMain by viewModel.isNeedToOpenMain.collectAsStateWithLifecycle()
val isNeedToShowSignInAlert by viewModel.isNeedToShowFastSignInAlert.collectAsStateWithLifecycle()
@@ -61,6 +67,7 @@ fun LogoRoute(
}
LogoScreen(
isLoading = screenState.isLoading,
onLogoLongClicked = viewModel::onLogoLongClicked,
onGoNextButtonClicked = onGoNextButtonClicked
)
@@ -76,10 +83,11 @@ fun LogoRoute(
@OptIn(ExperimentalFoundationApi::class)
@Composable
fun LogoScreen(
isLoading: Boolean,
onLogoLongClicked: () -> Unit = {},
onGoNextButtonClicked: () -> Unit = {}
) {
val currentTheme = LocalThemeConfig.current
val currentSize = LocalSizeConfig.current
Scaffold { padding ->
val topPadding by animateDpAsState(
@@ -100,19 +108,19 @@ fun LogoScreen(
label = "startPaddingAnimation"
)
val iconWidth = if (currentTheme.isDeviceCompact) {
100.dp
val iconWidth = if (currentSize.isWidthSmall) {
110.dp
} else {
134.dp
}
val appNameTextStyle = if (currentTheme.isDeviceCompact) {
MaterialTheme.typography.displaySmall
val appNameTextStyle = if (currentSize.isWidthSmall) {
MaterialTheme.typography.displayMedium.copy(fontSize = 40.sp)
} else {
MaterialTheme.typography.displayMedium
}
val bottomAdditionalPadding = if (currentTheme.isDeviceCompact) {
val bottomAdditionalPadding = if (currentSize.isHeightSmall) {
10.dp
} else {
30.dp
@@ -158,18 +166,34 @@ fun LogoScreen(
)
}
FloatingActionButton(
onClick = onGoNextButtonClicked,
containerColor = MaterialTheme.colorScheme.secondaryContainer,
modifier = Modifier
.align(Alignment.BottomCenter)
.testTag("go_next_fab")
AnimatedVisibility(
visible = !isLoading,
modifier = Modifier.align(Alignment.BottomCenter),
enter = fadeIn(),
exit = fadeOut()
) {
Icon(
painter = painterResource(id = UiR.drawable.ic_arrow_end),
contentDescription = "Go button",
tint = MaterialTheme.colorScheme.onSecondaryContainer
)
FloatingActionButton(
onClick = {
if (!isLoading) {
onGoNextButtonClicked()
}
},
containerColor = MaterialTheme.colorScheme.secondaryContainer,
modifier = Modifier.testTag("go_next_fab")
) {
Icon(
painter = painterResource(id = UiR.drawable.ic_arrow_end),
contentDescription = "Go button",
tint = MaterialTheme.colorScheme.onSecondaryContainer
)
}
}
AnimatedVisibility(
visible = isLoading,
modifier = Modifier.align(Alignment.BottomCenter)
) {
CircularProgressIndicator()
}
}
}