fast login with token
This commit is contained in:
@@ -3,6 +3,13 @@ package dev.meloda.fast.auth.login
|
||||
import android.util.Log
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import dev.meloda.fast.auth.login.model.CaptchaArguments
|
||||
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.auth.login.model.LoginValidationResult
|
||||
import dev.meloda.fast.auth.login.validation.LoginValidator
|
||||
import dev.meloda.fast.common.LongPollController
|
||||
import dev.meloda.fast.common.UserConfig
|
||||
import dev.meloda.fast.common.VkConstants
|
||||
@@ -17,13 +24,6 @@ import dev.meloda.fast.data.processState
|
||||
import dev.meloda.fast.datastore.AppSettings
|
||||
import dev.meloda.fast.model.database.AccountEntity
|
||||
import dev.meloda.fast.network.OAuthErrorDomain
|
||||
import dev.meloda.fast.auth.login.model.CaptchaArguments
|
||||
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.auth.login.model.LoginValidationResult
|
||||
import dev.meloda.fast.auth.login.validation.LoginValidator
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
@@ -44,6 +44,7 @@ interface LoginViewModel {
|
||||
val captchaArguments: StateFlow<CaptchaArguments?>
|
||||
val userBannedArguments: StateFlow<LoginUserBannedArguments?>
|
||||
val isNeedToOpenMain: StateFlow<Boolean>
|
||||
val isNeedToShowFastSignInAlert: StateFlow<Boolean>
|
||||
|
||||
fun onPasswordVisibilityButtonClicked()
|
||||
|
||||
@@ -63,6 +64,9 @@ interface LoginViewModel {
|
||||
fun onCaptchaCodeReceived(code: String)
|
||||
|
||||
fun onLogoLongClicked()
|
||||
|
||||
fun onFastLogInAlertDismissed()
|
||||
fun onFastLogInAlertConfirmClicked(token: String)
|
||||
}
|
||||
|
||||
class LoginViewModelImpl(
|
||||
@@ -82,6 +86,7 @@ class LoginViewModelImpl(
|
||||
override val captchaArguments = MutableStateFlow<CaptchaArguments?>(null)
|
||||
override val userBannedArguments = MutableStateFlow<LoginUserBannedArguments?>(null)
|
||||
override val isNeedToOpenMain = MutableStateFlow(false)
|
||||
override val isNeedToShowFastSignInAlert = MutableStateFlow(false)
|
||||
|
||||
private val validationState: StateFlow<List<LoginValidationResult>> =
|
||||
screenState.map(loginValidator::validate)
|
||||
@@ -145,9 +150,17 @@ class LoginViewModelImpl(
|
||||
}
|
||||
|
||||
override fun onLogoLongClicked() {
|
||||
val currentAccount = AccountEntity(
|
||||
userId = BuildConfig.debugUserId.toInt(),
|
||||
accessToken = BuildConfig.debugAccessToken,
|
||||
isNeedToShowFastSignInAlert.update { true }
|
||||
}
|
||||
|
||||
override fun onFastLogInAlertDismissed() {
|
||||
isNeedToShowFastSignInAlert.update { false }
|
||||
}
|
||||
|
||||
override fun onFastLogInAlertConfirmClicked(token: String) {
|
||||
var currentAccount = AccountEntity(
|
||||
userId = -1,
|
||||
accessToken = token,
|
||||
fastToken = null,
|
||||
trustedHash = null
|
||||
).also { account ->
|
||||
@@ -158,8 +171,6 @@ class LoginViewModelImpl(
|
||||
UserConfig.trustedHash = account.trustedHash
|
||||
}
|
||||
|
||||
startLongPoll()
|
||||
|
||||
usersUseCase.get(
|
||||
userIds = null,
|
||||
fields = VkConstants.USER_FIELDS,
|
||||
@@ -167,19 +178,29 @@ class LoginViewModelImpl(
|
||||
).listenValue { state ->
|
||||
state.processState(
|
||||
error = { error ->
|
||||
UserConfig.currentUserId = -1
|
||||
UserConfig.userId = -1
|
||||
UserConfig.accessToken = ""
|
||||
|
||||
// TODO: 19/07/2024, Danil Nikolaev: show error?
|
||||
},
|
||||
success = { response ->
|
||||
val actualUserId = response.first().id
|
||||
|
||||
currentAccount = currentAccount.copy(userId = actualUserId)
|
||||
|
||||
UserConfig.userId = actualUserId
|
||||
UserConfig.currentUserId = actualUserId
|
||||
|
||||
startLongPoll()
|
||||
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
accountsRepository.storeAccounts(listOf(currentAccount))
|
||||
|
||||
delay(350)
|
||||
|
||||
isNeedToOpenMain.update { true }
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
screenState.setValue { old -> old.copy(isLoading = state.isLoading()) }
|
||||
}
|
||||
}
|
||||
|
||||
+47
-1
@@ -17,12 +17,16 @@ import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.material3.FloatingActionButton
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.OutlinedTextField
|
||||
import androidx.compose.material3.Scaffold
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.saveable.rememberSaveable
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.testTag
|
||||
@@ -31,9 +35,12 @@ import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.unit.LayoutDirection
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import dev.meloda.fast.ui.theme.LocalThemeConfig
|
||||
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 org.koin.androidx.compose.koinViewModel
|
||||
import dev.meloda.fast.ui.R as UiR
|
||||
|
||||
@@ -44,6 +51,7 @@ fun LogoRoute(
|
||||
viewModel: LoginViewModel = koinViewModel<LoginViewModelImpl>()
|
||||
) {
|
||||
val isNeedToOpenMain by viewModel.isNeedToOpenMain.collectAsStateWithLifecycle()
|
||||
val isNeedToShowSignInAlert by viewModel.isNeedToShowFastSignInAlert.collectAsStateWithLifecycle()
|
||||
|
||||
LaunchedEffect(isNeedToOpenMain) {
|
||||
if (isNeedToOpenMain) {
|
||||
@@ -56,6 +64,13 @@ fun LogoRoute(
|
||||
onLogoLongClicked = viewModel::onLogoLongClicked,
|
||||
onGoNextButtonClicked = onGoNextButtonClicked
|
||||
)
|
||||
|
||||
if (isNeedToShowSignInAlert) {
|
||||
SignInAlert(
|
||||
onDismissRequest = viewModel::onFastLogInAlertDismissed,
|
||||
onConfirmClick = viewModel::onFastLogInAlertConfirmClicked,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalFoundationApi::class)
|
||||
@@ -159,3 +174,34 @@ fun LogoScreen(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun SignInAlert(
|
||||
onDismissRequest: () -> Unit,
|
||||
onConfirmClick: (token: String) -> Unit
|
||||
) {
|
||||
var tokenText by rememberSaveable {
|
||||
mutableStateOf(BuildConfig.debugAccessToken)
|
||||
}
|
||||
|
||||
val maxWidthModifier = Modifier.fillMaxWidth()
|
||||
|
||||
MaterialDialog(
|
||||
onDismissRequest = onDismissRequest,
|
||||
title = "Fast authorization",
|
||||
confirmText = stringResource(id = UiR.string.action_authorize),
|
||||
confirmAction = { onConfirmClick(tokenText) },
|
||||
cancelText = stringResource(id = UiR.string.cancel),
|
||||
actionInvokeDismiss = ActionInvokeDismiss.Always
|
||||
) {
|
||||
Column(modifier = maxWidthModifier) {
|
||||
OutlinedTextField(
|
||||
modifier = maxWidthModifier.padding(horizontal = 16.dp),
|
||||
value = tokenText,
|
||||
onValueChange = { tokenText = it },
|
||||
placeholder = { Text(text = "Access token") },
|
||||
label = { Text(text = "Access token") }
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user