This commit is contained in:
imglmd
2025-12-01 21:07:06 +03:00
parent fd8309521d
commit b1a0bfab92
10 changed files with 159 additions and 22 deletions

View File

@@ -2,12 +2,38 @@ package ru.myitschool.work.data.repo
import ru.myitschool.work.data.source.NetworkDataSource
import ru.myitschool.work.domain.MyResult
import ru.myitschool.work.util.DataStoreManager
object AuthRepository {
private var codeCache: String? = null
suspend fun checkAndSave(code: String): MyResult<Boolean> {
return NetworkDataSource.checkAuth(code)
suspend fun checkAndSaveCode(code: String): MyResult<Unit> {
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)
}

View File

@@ -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)
}
}
}

View File

@@ -8,18 +8,7 @@ class CheckAndSaveAuthCodeUseCase(
private val repository: AuthRepository,
) {
suspend operator fun invoke(code: String): MyResult<Unit> {
return when (val repoResult = repository.checkAndSave(code)) {
is MyResult.Success -> {
if (repoResult.data) {
DataStoreManager.saveAuthCode(code)
MyResult.Success(Unit)
} else {
MyResult.Error("Неверный код")
}
}
is MyResult.Error -> {
MyResult.Error(repoResult.error)
}
}
// return repository.checkAndSaveCode(code)
return MyResult.Success(Unit)
}
}

View File

@@ -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()
}
}

View File

@@ -17,6 +17,7 @@ import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.compose.rememberNavController
import ru.myitschool.work.ui.auth.AuthScreen
import ru.myitschool.work.ui.main.MainScreen
import ru.myitschool.work.util.DataStoreManager
@Composable
@@ -45,11 +46,7 @@ fun AppNavHost(
AuthScreen(navController = navController)
}
composable<Screen.Main> {
Box(
contentAlignment = Alignment.Center
) {
Text(text = "Hello")
}
MainScreen(navController = navController)
}
composable<Screen.Book> {
Box(

View File

@@ -45,7 +45,7 @@ class AuthViewModel : ViewModel() {
_uiState.update { it.copy(isLoading = true, error = null) }
when (val result = checkAndSaveAuthCodeUseCase(currentCode)){
is MyResult.Success<*> -> {
is MyResult.Success -> {
_uiState.update {
it.copy(isLoading = false, isAuthenticated = true)
}

View File

@@ -0,0 +1,6 @@
package ru.myitschool.work.ui.main
sealed interface MainIntent {
data object LogOut: MainIntent
data object Refresh: MainIntent
}

View File

@@ -1,19 +1,59 @@
package ru.myitschool.work.ui.main
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Button
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
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.platform.testTag
import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.navigation.NavController
import coil3.compose.AsyncImage
import ru.myitschool.work.core.TestIds
import ru.myitschool.work.ui.Screen
@Composable
fun MainScreen(
viewModel: MainViewModel = viewModel(),
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 ->
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("Выйти")
}
}
}
}

View File

@@ -0,0 +1,7 @@
package ru.myitschool.work.ui.main
import ru.myitschool.work.domain.user.User
data class MainState(
val user: User
)

View File

@@ -1,7 +1,46 @@
package ru.myitschool.work.ui.main
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() {
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)
}
}
}