feat(ui): viewmodel, repository, api 추가
This commit is contained in:
		@@ -0,0 +1,13 @@
 | 
				
			|||||||
 | 
					package kr.co.vividnext.sodalive.chat.character
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import io.reactivex.rxjava3.core.Single
 | 
				
			||||||
 | 
					import kr.co.vividnext.sodalive.common.ApiResponse
 | 
				
			||||||
 | 
					import retrofit2.http.GET
 | 
				
			||||||
 | 
					import retrofit2.http.Header
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					interface CharacterApi {
 | 
				
			||||||
 | 
					    @GET("/api/chat/character/main")
 | 
				
			||||||
 | 
					    fun getCharacterMain(
 | 
				
			||||||
 | 
					        @Header("Authorization") authHeader: String
 | 
				
			||||||
 | 
					    ): Single<ApiResponse<CharacterHomeResponse>>
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -0,0 +1,5 @@
 | 
				
			|||||||
 | 
					package kr.co.vividnext.sodalive.chat.character
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					data class CharacterHomeResponse(
 | 
				
			||||||
 | 
					    val id: Long
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
@@ -30,12 +30,15 @@ import kr.co.vividnext.sodalive.explorer.profile.UserProfileActivity
 | 
				
			|||||||
import kr.co.vividnext.sodalive.extensions.dpToPx
 | 
					import kr.co.vividnext.sodalive.extensions.dpToPx
 | 
				
			||||||
import kr.co.vividnext.sodalive.main.MainActivity
 | 
					import kr.co.vividnext.sodalive.main.MainActivity
 | 
				
			||||||
import kr.co.vividnext.sodalive.settings.event.EventDetailActivity
 | 
					import kr.co.vividnext.sodalive.settings.event.EventDetailActivity
 | 
				
			||||||
 | 
					import org.koin.android.ext.android.inject
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 캐릭터 탭 프래그먼트
 | 
					// 캐릭터 탭 프래그먼트
 | 
				
			||||||
@OptIn(UnstableApi::class)
 | 
					@OptIn(UnstableApi::class)
 | 
				
			||||||
class CharacterTabFragment : BaseFragment<FragmentCharacterTabBinding>(
 | 
					class CharacterTabFragment : BaseFragment<FragmentCharacterTabBinding>(
 | 
				
			||||||
    FragmentCharacterTabBinding::inflate
 | 
					    FragmentCharacterTabBinding::inflate
 | 
				
			||||||
) {
 | 
					) {
 | 
				
			||||||
 | 
					    private val viewModel: CharacterTabViewModel by inject()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private lateinit var contentBannerAdapter: AudioContentMainBannerAdapter
 | 
					    private lateinit var contentBannerAdapter: AudioContentMainBannerAdapter
 | 
				
			||||||
    private lateinit var recentCharacterAdapter: RecentCharacterAdapter
 | 
					    private lateinit var recentCharacterAdapter: RecentCharacterAdapter
 | 
				
			||||||
    private lateinit var popularCharacterAdapter: CharacterAdapter
 | 
					    private lateinit var popularCharacterAdapter: CharacterAdapter
 | 
				
			||||||
@@ -46,6 +49,8 @@ class CharacterTabFragment : BaseFragment<FragmentCharacterTabBinding>(
 | 
				
			|||||||
        super.onViewCreated(view, savedInstanceState)
 | 
					        super.onViewCreated(view, savedInstanceState)
 | 
				
			||||||
        setupView()
 | 
					        setupView()
 | 
				
			||||||
        loadData()
 | 
					        loadData()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        viewModel.fetchData()
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private fun setupView() {
 | 
					    private fun setupView() {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -0,0 +1,7 @@
 | 
				
			|||||||
 | 
					package kr.co.vividnext.sodalive.chat.character
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class CharacterTabRepository(private val api: CharacterApi) {
 | 
				
			||||||
 | 
					    fun getCharacterMain(
 | 
				
			||||||
 | 
					        token: String
 | 
				
			||||||
 | 
					    ) = api.getCharacterMain(authHeader = token)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -0,0 +1,45 @@
 | 
				
			|||||||
 | 
					package kr.co.vividnext.sodalive.chat.character
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					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.base.BaseViewModel
 | 
				
			||||||
 | 
					import kr.co.vividnext.sodalive.common.SharedPreferenceManager
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class CharacterTabViewModel(
 | 
				
			||||||
 | 
					    private val repository: CharacterTabRepository
 | 
				
			||||||
 | 
					) : BaseViewModel() {
 | 
				
			||||||
 | 
					    private var _isLoading = MutableLiveData(false)
 | 
				
			||||||
 | 
					    val isLoading: LiveData<Boolean>
 | 
				
			||||||
 | 
					        get() = _isLoading
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private val _toastLiveData = MutableLiveData<String?>()
 | 
				
			||||||
 | 
					    val toastLiveData: LiveData<String?>
 | 
				
			||||||
 | 
					        get() = _toastLiveData
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fun fetchData() {
 | 
				
			||||||
 | 
					        _isLoading.value = true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        compositeDisposable.add(
 | 
				
			||||||
 | 
					            repository.getCharacterMain(token = "Bearer ${SharedPreferenceManager.token}")
 | 
				
			||||||
 | 
					                .subscribeOn(Schedulers.io())
 | 
				
			||||||
 | 
					                .observeOn(AndroidSchedulers.mainThread())
 | 
				
			||||||
 | 
					                .subscribe(
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        _isLoading.value = false
 | 
				
			||||||
 | 
					                        val data = it.data
 | 
				
			||||||
 | 
					                        if (it.success && data != null) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                    },
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        _isLoading.value = false
 | 
				
			||||||
 | 
					                        it.message?.let { message -> Logger.e(message) }
 | 
				
			||||||
 | 
					                        _toastLiveData.postValue("알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.")
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                )
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -64,6 +64,9 @@ import kr.co.vividnext.sodalive.audition.AuditionRepository
 | 
				
			|||||||
import kr.co.vividnext.sodalive.audition.AuditionViewModel
 | 
					import kr.co.vividnext.sodalive.audition.AuditionViewModel
 | 
				
			||||||
import kr.co.vividnext.sodalive.audition.detail.AuditionDetailViewModel
 | 
					import kr.co.vividnext.sodalive.audition.detail.AuditionDetailViewModel
 | 
				
			||||||
import kr.co.vividnext.sodalive.audition.role.AuditionRoleDetailViewModel
 | 
					import kr.co.vividnext.sodalive.audition.role.AuditionRoleDetailViewModel
 | 
				
			||||||
 | 
					import kr.co.vividnext.sodalive.chat.character.CharacterApi
 | 
				
			||||||
 | 
					import kr.co.vividnext.sodalive.chat.character.CharacterTabRepository
 | 
				
			||||||
 | 
					import kr.co.vividnext.sodalive.chat.character.CharacterTabViewModel
 | 
				
			||||||
import kr.co.vividnext.sodalive.common.ApiBuilder
 | 
					import kr.co.vividnext.sodalive.common.ApiBuilder
 | 
				
			||||||
import kr.co.vividnext.sodalive.common.ObjectBox
 | 
					import kr.co.vividnext.sodalive.common.ObjectBox
 | 
				
			||||||
import kr.co.vividnext.sodalive.explorer.ExplorerApi
 | 
					import kr.co.vividnext.sodalive.explorer.ExplorerApi
 | 
				
			||||||
@@ -245,6 +248,7 @@ class AppDI(private val context: Context, isDebugMode: Boolean) {
 | 
				
			|||||||
        single { ApiBuilder().build(get(), SearchApi::class.java) }
 | 
					        single { ApiBuilder().build(get(), SearchApi::class.java) }
 | 
				
			||||||
        single { ApiBuilder().build(get(), PointStatusApi::class.java) }
 | 
					        single { ApiBuilder().build(get(), PointStatusApi::class.java) }
 | 
				
			||||||
        single { ApiBuilder().build(get(), HomeApi::class.java) }
 | 
					        single { ApiBuilder().build(get(), HomeApi::class.java) }
 | 
				
			||||||
 | 
					        single { ApiBuilder().build(get(), CharacterApi::class.java) }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private val viewModelModule = module {
 | 
					    private val viewModelModule = module {
 | 
				
			||||||
@@ -342,6 +346,7 @@ class AppDI(private val context: Context, isDebugMode: Boolean) {
 | 
				
			|||||||
        viewModel { SearchViewModel(get()) }
 | 
					        viewModel { SearchViewModel(get()) }
 | 
				
			||||||
        viewModel { PointStatusViewModel(get()) }
 | 
					        viewModel { PointStatusViewModel(get()) }
 | 
				
			||||||
        viewModel { HomeViewModel(get(), get()) }
 | 
					        viewModel { HomeViewModel(get(), get()) }
 | 
				
			||||||
 | 
					        viewModel { CharacterTabViewModel(get()) }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private val repositoryModule = module {
 | 
					    private val repositoryModule = module {
 | 
				
			||||||
@@ -386,6 +391,7 @@ class AppDI(private val context: Context, isDebugMode: Boolean) {
 | 
				
			|||||||
        factory { UserEventRepository(get()) }
 | 
					        factory { UserEventRepository(get()) }
 | 
				
			||||||
        factory { PointStatusRepository(get()) }
 | 
					        factory { PointStatusRepository(get()) }
 | 
				
			||||||
        factory { HomeRepository(get()) }
 | 
					        factory { HomeRepository(get()) }
 | 
				
			||||||
 | 
					        factory { CharacterTabRepository(get()) }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user