DetailViewModel.kt
package com.gyleedev.githubsearch.feature.detail
import android.os.Build
import androidx.annotation.RequiresExtension
import androidx.lifecycle.SavedStateHandle
import androidx.lifecycle.viewModelScope
import com.gyleedev.githubsearch.domain.model.RepositoryModel
import com.gyleedev.githubsearch.domain.model.UserModel
import com.gyleedev.githubsearch.domain.usecase.GetReposWithFlowUseCase
import com.gyleedev.githubsearch.domain.usecase.GetUserWithFlowUseCase
import com.gyleedev.githubsearch.domain.usecase.UpdateFavoriteStatusUseCase
import com.gyleedev.githubsearch.domain.usecase.UpdateUserFromGithubUseCase
import com.gyleedev.ui.BaseViewModel
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.FlowPreview
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.launch
import javax.inject.Inject
/*
1. user Flow로 받아오는 거
2. repos flow로 받아오는 거
3. user, repo 업데이트(싱크 맞추는 기능)
4. favoriteState 업데이트
*/
@HiltViewModel
class DetailViewModel @Inject constructor(
private val updateUserFromGithubUseCase: UpdateUserFromGithubUseCase,
private val getUserWithFlowUseCase: GetUserWithFlowUseCase,
private val getReposWithFlowUseCase: GetReposWithFlowUseCase,
private val updateFavoriteStatusUseCase: UpdateFavoriteStatusUseCase,
savedStateHandle: SavedStateHandle,
) : BaseViewModel() {
private val userId = MutableStateFlow("")
init {
val id = savedStateHandle.get<String>("id")
viewModelScope.launch {
if (!id.isNullOrBlank()) {
userId.emit(id)
updateUserFromGithubUseCase(id)
}
}
}
@OptIn(ExperimentalCoroutinesApi::class, FlowPreview::class)
val user: StateFlow<UserModel?> = userId
.flatMapLatest { query ->
if (query.isBlank()) {
flowOf(null)
} else {
getUserWithFlowUseCase(query)
}
}.stateIn(
scope = viewModelScope,
started = SharingStarted.WhileSubscribed(stopTimeoutMillis = 5000),
initialValue = null,
)
@OptIn(ExperimentalCoroutinesApi::class, FlowPreview::class)
val repo: StateFlow<List<RepositoryModel>> = userId
.flatMapLatest { query ->
if (query.isBlank()) {
flowOf(emptyList())
} else {
getReposWithFlowUseCase(query)
}
}.stateIn(
scope = viewModelScope,
started = SharingStarted.WhileSubscribed(stopTimeoutMillis = 5000),
initialValue = emptyList(),
)
@RequiresExtension(extension = Build.VERSION_CODES.S, version = 7)
fun updateFavoriteStatus() {
viewModelScope.launch(exceptionHandler) {
if (user.value != null) {
updateFavoriteStatusUseCase(user.value as UserModel)
}
}
}
}