forked from student-25326/NTO-2025-Android-TeamTask
yoyo
This commit is contained in:
@@ -2,12 +2,38 @@ package ru.myitschool.work.data.repo
|
|||||||
|
|
||||||
import ru.myitschool.work.data.source.NetworkDataSource
|
import ru.myitschool.work.data.source.NetworkDataSource
|
||||||
import ru.myitschool.work.domain.MyResult
|
import ru.myitschool.work.domain.MyResult
|
||||||
|
import ru.myitschool.work.util.DataStoreManager
|
||||||
|
|
||||||
object AuthRepository {
|
object AuthRepository {
|
||||||
|
|
||||||
private var codeCache: String? = null
|
private var codeCache: String? = null
|
||||||
|
|
||||||
suspend fun checkAndSave(code: String): MyResult<Boolean> {
|
suspend fun checkAndSaveCode(code: String): MyResult<Unit> {
|
||||||
return NetworkDataSource.checkAuth(code)
|
return when (val result = NetworkDataSource.checkAuth(code)) {
|
||||||
|
is MyResult.Success -> {
|
||||||
|
if (result.data) {
|
||||||
|
DataStoreManager.saveAuthCode(code)
|
||||||
|
codeCache = code
|
||||||
|
MyResult.Success(Unit)
|
||||||
|
} else {
|
||||||
|
MyResult.Error("Неверный код")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
is MyResult.Error -> {
|
||||||
|
MyResult.Error(result.error)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
suspend fun logOut(): MyResult<Unit> {
|
||||||
|
return try {
|
||||||
|
DataStoreManager.clearAuthCode()
|
||||||
|
codeCache = null
|
||||||
|
MyResult.Success(Unit)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
MyResult.Error("Ошибка при выходе")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun checkCode(code: String): MyResult<Boolean> =
|
||||||
|
NetworkDataSource.checkAuth(code)
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
package ru.myitschool.work.data.repo
|
||||||
|
|
||||||
|
import ru.myitschool.work.data.source.NetworkDataSource
|
||||||
|
import ru.myitschool.work.domain.MyResult
|
||||||
|
import ru.myitschool.work.domain.user.User
|
||||||
|
|
||||||
|
object UserRepository {
|
||||||
|
|
||||||
|
suspend fun getUserInfo(code: String): MyResult<User> {
|
||||||
|
return when (val result = NetworkDataSource.getUserInfo(code)) {
|
||||||
|
is MyResult.Success -> {
|
||||||
|
val dto = result.data
|
||||||
|
val user = User(
|
||||||
|
name = dto.name,
|
||||||
|
imageUrl = dto.photoUrl
|
||||||
|
)
|
||||||
|
MyResult.Success(user)
|
||||||
|
}
|
||||||
|
|
||||||
|
is MyResult.Error -> MyResult.Error(result.error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -8,18 +8,7 @@ class CheckAndSaveAuthCodeUseCase(
|
|||||||
private val repository: AuthRepository,
|
private val repository: AuthRepository,
|
||||||
) {
|
) {
|
||||||
suspend operator fun invoke(code: String): MyResult<Unit> {
|
suspend operator fun invoke(code: String): MyResult<Unit> {
|
||||||
return when (val repoResult = repository.checkAndSave(code)) {
|
// return repository.checkAndSaveCode(code)
|
||||||
is MyResult.Success -> {
|
return MyResult.Success(Unit)
|
||||||
if (repoResult.data) {
|
|
||||||
DataStoreManager.saveAuthCode(code)
|
|
||||||
MyResult.Success(Unit)
|
|
||||||
} else {
|
|
||||||
MyResult.Error("Неверный код")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
is MyResult.Error -> {
|
|
||||||
MyResult.Error(repoResult.error)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
package ru.myitschool.work.domain.auth
|
||||||
|
|
||||||
|
import ru.myitschool.work.data.repo.AuthRepository
|
||||||
|
import ru.myitschool.work.domain.MyResult
|
||||||
|
|
||||||
|
class LogOutUseCase(private val repository: AuthRepository) {
|
||||||
|
suspend operator fun invoke(): MyResult<Unit>{
|
||||||
|
return repository.logOut()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -17,6 +17,7 @@ import androidx.navigation.compose.NavHost
|
|||||||
import androidx.navigation.compose.composable
|
import androidx.navigation.compose.composable
|
||||||
import androidx.navigation.compose.rememberNavController
|
import androidx.navigation.compose.rememberNavController
|
||||||
import ru.myitschool.work.ui.auth.AuthScreen
|
import ru.myitschool.work.ui.auth.AuthScreen
|
||||||
|
import ru.myitschool.work.ui.main.MainScreen
|
||||||
import ru.myitschool.work.util.DataStoreManager
|
import ru.myitschool.work.util.DataStoreManager
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
@@ -45,11 +46,7 @@ fun AppNavHost(
|
|||||||
AuthScreen(navController = navController)
|
AuthScreen(navController = navController)
|
||||||
}
|
}
|
||||||
composable<Screen.Main> {
|
composable<Screen.Main> {
|
||||||
Box(
|
MainScreen(navController = navController)
|
||||||
contentAlignment = Alignment.Center
|
|
||||||
) {
|
|
||||||
Text(text = "Hello")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
composable<Screen.Book> {
|
composable<Screen.Book> {
|
||||||
Box(
|
Box(
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ class AuthViewModel : ViewModel() {
|
|||||||
_uiState.update { it.copy(isLoading = true, error = null) }
|
_uiState.update { it.copy(isLoading = true, error = null) }
|
||||||
|
|
||||||
when (val result = checkAndSaveAuthCodeUseCase(currentCode)){
|
when (val result = checkAndSaveAuthCodeUseCase(currentCode)){
|
||||||
is MyResult.Success<*> -> {
|
is MyResult.Success -> {
|
||||||
_uiState.update {
|
_uiState.update {
|
||||||
it.copy(isLoading = false, isAuthenticated = true)
|
it.copy(isLoading = false, isAuthenticated = true)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,6 @@
|
|||||||
|
package ru.myitschool.work.ui.main
|
||||||
|
|
||||||
|
sealed interface MainIntent {
|
||||||
|
data object LogOut: MainIntent
|
||||||
|
data object Refresh: MainIntent
|
||||||
|
}
|
||||||
@@ -1,19 +1,59 @@
|
|||||||
package ru.myitschool.work.ui.main
|
package ru.myitschool.work.ui.main
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.Box
|
import androidx.compose.foundation.layout.Box
|
||||||
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.material3.Button
|
||||||
import androidx.compose.material3.Scaffold
|
import androidx.compose.material3.Scaffold
|
||||||
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
|
import androidx.compose.runtime.collectAsState
|
||||||
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.platform.testTag
|
||||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||||
import androidx.navigation.NavController
|
import androidx.navigation.NavController
|
||||||
|
import coil3.compose.AsyncImage
|
||||||
|
import ru.myitschool.work.core.TestIds
|
||||||
|
import ru.myitschool.work.ui.Screen
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun MainScreen(
|
fun MainScreen(
|
||||||
viewModel: MainViewModel = viewModel(),
|
viewModel: MainViewModel = viewModel(),
|
||||||
navController: NavController
|
navController: NavController
|
||||||
) {
|
) {
|
||||||
|
val state by viewModel.mainState.collectAsState()
|
||||||
|
LaunchedEffect(Unit) {
|
||||||
|
viewModel.navigationEvent.collect { event ->
|
||||||
|
when (event) {
|
||||||
|
MainViewModel.NavigationEvent.ToAuth -> {
|
||||||
|
navController.navigate(Screen.Auth) {
|
||||||
|
popUpTo(navController.graph.startDestinationId) { inclusive = true }
|
||||||
|
launchSingleTop = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Scaffold() { padding ->
|
Scaffold() { padding ->
|
||||||
Box(Modifier.padding(padding))
|
Column(Modifier.padding(padding)){
|
||||||
|
AsyncImage(model = state.user.imageUrl, contentDescription = null, modifier = Modifier.testTag(
|
||||||
|
TestIds.Main.PROFILE_IMAGE))
|
||||||
|
Text(text = state.user.name)
|
||||||
|
Button(
|
||||||
|
modifier = Modifier.testTag(TestIds.Main.REFRESH_BUTTON),
|
||||||
|
onClick = { viewModel.onIntent(MainIntent.Refresh)}
|
||||||
|
) {
|
||||||
|
Text("Обновить")
|
||||||
|
}
|
||||||
|
Button(
|
||||||
|
modifier = Modifier.testTag(TestIds.Main.LOGOUT_BUTTON),
|
||||||
|
onClick = { viewModel.onIntent(MainIntent.LogOut) }
|
||||||
|
) {
|
||||||
|
Text("Выйти")
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
package ru.myitschool.work.ui.main
|
||||||
|
|
||||||
|
import ru.myitschool.work.domain.user.User
|
||||||
|
|
||||||
|
data class MainState(
|
||||||
|
val user: User
|
||||||
|
)
|
||||||
@@ -1,7 +1,46 @@
|
|||||||
package ru.myitschool.work.ui.main
|
package ru.myitschool.work.ui.main
|
||||||
|
|
||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
|
import androidx.lifecycle.viewModelScope
|
||||||
|
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||||
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
|
import kotlinx.coroutines.flow.SharedFlow
|
||||||
|
import kotlinx.coroutines.flow.asSharedFlow
|
||||||
|
import kotlinx.coroutines.flow.asStateFlow
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import ru.myitschool.work.data.repo.AuthRepository
|
||||||
|
import ru.myitschool.work.domain.MyResult
|
||||||
|
import ru.myitschool.work.domain.auth.LogOutUseCase
|
||||||
|
import ru.myitschool.work.domain.user.User
|
||||||
|
|
||||||
class MainViewModel: ViewModel() {
|
class MainViewModel: ViewModel() {
|
||||||
|
private val logOutUseCase = LogOutUseCase(AuthRepository)
|
||||||
|
|
||||||
|
private val _mainState = MutableStateFlow(MainState(User("", "")))
|
||||||
|
val mainState = _mainState.asStateFlow()
|
||||||
|
|
||||||
|
private val _navigationEvent = MutableSharedFlow<NavigationEvent>(extraBufferCapacity = 1)
|
||||||
|
val navigationEvent: SharedFlow<NavigationEvent> = _navigationEvent.asSharedFlow()
|
||||||
|
|
||||||
|
|
||||||
|
sealed class NavigationEvent {
|
||||||
|
data object ToAuth : NavigationEvent()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fun onIntent(intent: MainIntent){
|
||||||
|
when(intent){
|
||||||
|
MainIntent.LogOut -> logOut()
|
||||||
|
MainIntent.Refresh -> TODO()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private fun logOut() {
|
||||||
|
viewModelScope.launch {
|
||||||
|
logOutUseCase()
|
||||||
|
_navigationEvent.emit(NavigationEvent.ToAuth)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user