From dd742ce2453688d025d83db0c18c2152a33825e4 Mon Sep 17 00:00:00 2001 From: klaus Date: Tue, 23 Jun 2026 15:50:34 +0900 Subject: [PATCH] =?UTF-8?q?feat(content):=20=EC=B6=94=EC=B2=9C=20ViewModel?= =?UTF-8?q?=20DI=EB=A5=BC=20=EC=B6=94=EA=B0=80=ED=95=9C=EB=8B=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/kr/co/vividnext/sodalive/di/AppDI.kt | 7 ++ .../v2/main/content/ContentMainViewModel.kt | 70 +++++++++++++++++++ 2 files changed, 77 insertions(+) create mode 100644 app/src/main/java/kr/co/vividnext/sodalive/v2/main/content/ContentMainViewModel.kt diff --git a/app/src/main/java/kr/co/vividnext/sodalive/di/AppDI.kt b/app/src/main/java/kr/co/vividnext/sodalive/di/AppDI.kt index 18312eb4..92344a78 100644 --- a/app/src/main/java/kr/co/vividnext/sodalive/di/AppDI.kt +++ b/app/src/main/java/kr/co/vividnext/sodalive/di/AppDI.kt @@ -195,6 +195,9 @@ import kr.co.vividnext.sodalive.v2.main.chat.dm.DmChatRoomViewModel import kr.co.vividnext.sodalive.v2.main.chat.dm.data.DmChatApi import kr.co.vividnext.sodalive.v2.main.chat.dm.data.DmChatRepository import kr.co.vividnext.sodalive.v2.main.chat.dm.data.DmChatSocketClient +import kr.co.vividnext.sodalive.v2.main.content.ContentMainViewModel +import kr.co.vividnext.sodalive.v2.main.content.data.AudioRecommendationsApi +import kr.co.vividnext.sodalive.v2.main.content.data.AudioRecommendationsRepository import kr.co.vividnext.sodalive.v2.main.home.HomeCreatorRankingViewModel import kr.co.vividnext.sodalive.v2.main.home.HomeRecommendationViewModel import kr.co.vividnext.sodalive.v2.main.home.data.HomeCreatorRankingApi @@ -233,6 +236,7 @@ class AppDI(private val context: Context, isDebugMode: Boolean) { } else { logging.setLevel(HttpLoggingInterceptor.Level.NONE) } + logging.redactHeader("Authorization") OkHttpClient().newBuilder() .addInterceptor(logging) @@ -312,6 +316,7 @@ class AppDI(private val context: Context, isDebugMode: Boolean) { single { ApiBuilder().build(get(), HomeApi::class.java) } single { ApiBuilder().build(get(), ChatRoomApi::class.java) } single { ApiBuilder().build(get(), DmChatApi::class.java) } + single { ApiBuilder().build(get(), AudioRecommendationsApi::class.java) } single { ApiBuilder().build(get(), HomeCreatorRankingApi::class.java) } single { ApiBuilder().build(get(), HomeRecommendationApi::class.java) } single { ApiBuilder().build(get(), CreatorChannelApi::class.java) } @@ -414,6 +419,7 @@ class AppDI(private val context: Context, isDebugMode: Boolean) { viewModel { HomeViewModel(get(), get()) } viewModel { ChatMainViewModel(get()) } viewModel { DmChatRoomViewModel(get()) } + viewModel { ContentMainViewModel(get()) } viewModel { HomeCreatorRankingViewModel(get()) } viewModel { HomeRecommendationViewModel(get()) } viewModel { CreatorChannelHomeViewModel(get()) } @@ -475,6 +481,7 @@ class AppDI(private val context: Context, isDebugMode: Boolean) { factory { HomeRepository(get()) } factory { ChatRoomRepository(get()) } factory { DmChatRepository(api = get(), socketClient = get()) } + factory { AudioRecommendationsRepository(get()) } factory { HomeCreatorRankingRepository(get()) } factory { HomeRecommendationRepository(get()) } factory { diff --git a/app/src/main/java/kr/co/vividnext/sodalive/v2/main/content/ContentMainViewModel.kt b/app/src/main/java/kr/co/vividnext/sodalive/v2/main/content/ContentMainViewModel.kt new file mode 100644 index 00000000..4ba66360 --- /dev/null +++ b/app/src/main/java/kr/co/vividnext/sodalive/v2/main/content/ContentMainViewModel.kt @@ -0,0 +1,70 @@ +package kr.co.vividnext.sodalive.v2.main.content + +import androidx.lifecycle.LiveData +import androidx.lifecycle.MutableLiveData +import com.orhanobut.logger.Logger +import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers +import io.reactivex.rxjava3.schedulers.Schedulers +import kr.co.vividnext.sodalive.R +import kr.co.vividnext.sodalive.base.BaseViewModel +import kr.co.vividnext.sodalive.common.SharedPreferenceManager +import kr.co.vividnext.sodalive.common.ToastMessage +import kr.co.vividnext.sodalive.v2.main.content.data.AudioRecommendationsRepository +import kr.co.vividnext.sodalive.v2.main.content.model.AudioRecommendationsUiState +import kr.co.vividnext.sodalive.v2.main.content.model.toContent + +class ContentMainViewModel( + private val repository: AudioRecommendationsRepository +) : BaseViewModel() { + + private val _recommendationsStateLiveData = MutableLiveData() + val recommendationsStateLiveData: LiveData + get() = _recommendationsStateLiveData + + private val _toastLiveData = MutableLiveData() + val toastLiveData: LiveData + get() = _toastLiveData + + private val _isLoading = MutableLiveData(false) + val isLoading: LiveData + get() = _isLoading + + fun loadRecommendations() { + _isLoading.value = true + _recommendationsStateLiveData.value = AudioRecommendationsUiState.Loading + + compositeDisposable.add( + repository.getRecommendations(token = authToken()) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe( + { + _isLoading.value = false + val data = it.data + if (it.success && data != null) { + val content = data.toContent() + _recommendationsStateLiveData.value = if (content.isEmpty) { + AudioRecommendationsUiState.Empty + } else { + content + } + } else { + showUnknownError(it.message) + } + }, + { + _isLoading.value = false + it.message?.let { message -> Logger.e(message) } + showUnknownError(it.message) + } + ) + ) + } + + private fun showUnknownError(message: String?) { + _recommendationsStateLiveData.value = AudioRecommendationsUiState.Error(message = message) + _toastLiveData.postValue(ToastMessage(resId = R.string.common_error_unknown)) + } + + private fun authToken(): String = "Bearer ${SharedPreferenceManager.token}" +}