refactor(chat/character): 댓글 리스트 화면에 ViewModel 도입 및 Fragment-Repository 직접 의존 제거
CharacterCommentListViewModel을 추가하여 댓글 조회/등록/삭제/신고 및 페이지네이션 로직을 ViewModel로 이전. Fragment는 UI 업데이트와 사용자 입력 처리에 집중하도록 리팩토링. Koin DI에 ViewModel 등록.
This commit is contained in:
@@ -8,14 +8,12 @@ import android.view.LayoutInflater
|
|||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import android.view.inputmethod.InputMethodManager
|
import android.view.inputmethod.InputMethodManager
|
||||||
import android.widget.Toast
|
import androidx.appcompat.app.AlertDialog
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import coil.load
|
import coil.load
|
||||||
import coil.transform.CircleCropTransformation
|
import coil.transform.CircleCropTransformation
|
||||||
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
|
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
|
||||||
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
|
|
||||||
import io.reactivex.rxjava3.schedulers.Schedulers
|
|
||||||
import kr.co.vividnext.sodalive.R
|
import kr.co.vividnext.sodalive.R
|
||||||
import kr.co.vividnext.sodalive.base.BaseFragment
|
import kr.co.vividnext.sodalive.base.BaseFragment
|
||||||
import kr.co.vividnext.sodalive.common.LoadingDialog
|
import kr.co.vividnext.sodalive.common.LoadingDialog
|
||||||
@@ -28,7 +26,7 @@ class CharacterCommentListFragment : BaseFragment<FragmentCharacterCommentListBi
|
|||||||
FragmentCharacterCommentListBinding::inflate
|
FragmentCharacterCommentListBinding::inflate
|
||||||
) {
|
) {
|
||||||
|
|
||||||
private val repository: CharacterCommentRepository by inject()
|
private val viewModel: CharacterCommentListViewModel by inject()
|
||||||
|
|
||||||
private lateinit var imm: InputMethodManager
|
private lateinit var imm: InputMethodManager
|
||||||
private lateinit var loadingDialog: LoadingDialog
|
private lateinit var loadingDialog: LoadingDialog
|
||||||
@@ -54,7 +52,7 @@ class CharacterCommentListFragment : BaseFragment<FragmentCharacterCommentListBi
|
|||||||
setupView()
|
setupView()
|
||||||
bindData()
|
bindData()
|
||||||
// 초기 로드
|
// 초기 로드
|
||||||
resetAndLoad()
|
viewModel.reset(characterId)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun hideDialog() {
|
private fun hideDialog() {
|
||||||
@@ -75,31 +73,8 @@ class CharacterCommentListFragment : BaseFragment<FragmentCharacterCommentListBi
|
|||||||
hideKeyboard()
|
hideKeyboard()
|
||||||
val comment = binding.etComment.text.toString()
|
val comment = binding.etComment.text.toString()
|
||||||
if (comment.isBlank()) return@setOnClickListener
|
if (comment.isBlank()) return@setOnClickListener
|
||||||
val token = "Bearer ${SharedPreferenceManager.token}"
|
viewModel.createComment(characterId, comment)
|
||||||
loadingDialog.show(screenWidth)
|
binding.etComment.setText("")
|
||||||
val d = repository.createComment(characterId, comment, token)
|
|
||||||
.subscribeOn(Schedulers.io())
|
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
|
||||||
.doFinally { loadingDialog.dismiss() }
|
|
||||||
.subscribe({ resp ->
|
|
||||||
if (resp.success) {
|
|
||||||
binding.etComment.setText("")
|
|
||||||
resetAndLoad()
|
|
||||||
} else {
|
|
||||||
Toast.makeText(
|
|
||||||
requireContext(),
|
|
||||||
resp.message ?: "요청 중 오류가 발생했습니다",
|
|
||||||
Toast.LENGTH_SHORT
|
|
||||||
).show()
|
|
||||||
}
|
|
||||||
}, { e ->
|
|
||||||
Toast.makeText(
|
|
||||||
requireContext(),
|
|
||||||
e.message ?: "요청 중 오류가 발생했습니다",
|
|
||||||
Toast.LENGTH_SHORT
|
|
||||||
).show()
|
|
||||||
})
|
|
||||||
compositeDisposable.add(d)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
adapter = CharacterCommentsAdapter(
|
adapter = CharacterCommentsAdapter(
|
||||||
@@ -109,74 +84,20 @@ class CharacterCommentListFragment : BaseFragment<FragmentCharacterCommentListBi
|
|||||||
onReport = {
|
onReport = {
|
||||||
val reportSheet = CharacterCommentReportBottomSheet.newInstance()
|
val reportSheet = CharacterCommentReportBottomSheet.newInstance()
|
||||||
reportSheet.onSubmit = { reason ->
|
reportSheet.onSubmit = { reason ->
|
||||||
val token = "Bearer ${SharedPreferenceManager.token}"
|
viewModel.reportComment(characterId, item.commentId, reason)
|
||||||
val d =
|
|
||||||
repository.reportComment(characterId, item.commentId, reason, token)
|
|
||||||
.subscribeOn(Schedulers.io())
|
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
|
||||||
.subscribe({ resp ->
|
|
||||||
if (resp.success) {
|
|
||||||
Toast.makeText(
|
|
||||||
requireContext(),
|
|
||||||
"신고가 접수되었습니다.",
|
|
||||||
Toast.LENGTH_SHORT
|
|
||||||
).show()
|
|
||||||
} else {
|
|
||||||
Toast.makeText(
|
|
||||||
requireContext(),
|
|
||||||
resp.message ?: "요청 중 오류가 발생했습니다",
|
|
||||||
Toast.LENGTH_SHORT
|
|
||||||
).show()
|
|
||||||
}
|
|
||||||
}, { e ->
|
|
||||||
Toast.makeText(
|
|
||||||
requireContext(),
|
|
||||||
e.message ?: "요청 중 오류가 발생했습니다",
|
|
||||||
Toast.LENGTH_SHORT
|
|
||||||
).show()
|
|
||||||
})
|
|
||||||
compositeDisposable.add(d)
|
|
||||||
}
|
}
|
||||||
reportSheet.show(parentFragmentManager, "comment_report")
|
reportSheet.show(parentFragmentManager, "comment_report")
|
||||||
}
|
}
|
||||||
onDelete = {
|
onDelete = {
|
||||||
// 삭제 확인 팝업
|
// 삭제 확인 팝업
|
||||||
androidx.appcompat.app.AlertDialog.Builder(requireContext())
|
AlertDialog.Builder(requireContext())
|
||||||
.setTitle(getString(R.string.confirm_delete_title))
|
.setTitle(getString(R.string.confirm_delete_title))
|
||||||
.setMessage(getString(R.string.confirm_delete_message))
|
.setMessage(getString(R.string.confirm_delete_message))
|
||||||
.setPositiveButton(getString(R.string.confirm)) { _, _ ->
|
.setPositiveButton(getString(R.string.confirm)) { _, _ ->
|
||||||
val token = "Bearer ${SharedPreferenceManager.token}"
|
viewModel.deleteComment(
|
||||||
loadingDialog.show(screenWidth)
|
|
||||||
val d = repository.deleteComment(
|
|
||||||
characterId = characterId,
|
characterId = characterId,
|
||||||
commentId = item.commentId,
|
commentId = item.commentId
|
||||||
token = token
|
|
||||||
)
|
)
|
||||||
.subscribeOn(Schedulers.io())
|
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
|
||||||
.doFinally { loadingDialog.dismiss() }
|
|
||||||
.subscribe({ resp ->
|
|
||||||
if (resp.success) {
|
|
||||||
val index = adapter.items.indexOfFirst { it.commentId == item.commentId }
|
|
||||||
if (index >= 0) {
|
|
||||||
adapter.items.removeAt(index)
|
|
||||||
adapter.notifyItemRemoved(index)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Toast.makeText(
|
|
||||||
requireContext(),
|
|
||||||
resp.message ?: "요청 중 오류가 발생했습니다",
|
|
||||||
Toast.LENGTH_SHORT
|
|
||||||
).show()
|
|
||||||
}
|
|
||||||
}, { e ->
|
|
||||||
Toast.makeText(
|
|
||||||
requireContext(),
|
|
||||||
e.message ?: "요청 중 오류가 발생했습니다",
|
|
||||||
Toast.LENGTH_SHORT
|
|
||||||
).show()
|
|
||||||
})
|
|
||||||
compositeDisposable.add(d)
|
|
||||||
}
|
}
|
||||||
.setNegativeButton(getString(R.string.cancel), null)
|
.setNegativeButton(getString(R.string.cancel), null)
|
||||||
.show()
|
.show()
|
||||||
@@ -229,13 +150,11 @@ class CharacterCommentListFragment : BaseFragment<FragmentCharacterCommentListBi
|
|||||||
recyclerView.addOnScrollListener(object : RecyclerView.OnScrollListener() {
|
recyclerView.addOnScrollListener(object : RecyclerView.OnScrollListener() {
|
||||||
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
|
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
|
||||||
super.onScrolled(recyclerView, dx, dy)
|
super.onScrolled(recyclerView, dx, dy)
|
||||||
val lastVisible =
|
val lastVisible = (recyclerView.layoutManager as LinearLayoutManager)
|
||||||
(recyclerView.layoutManager as LinearLayoutManager).findLastCompletelyVisibleItemPosition()
|
.findLastCompletelyVisibleItemPosition()
|
||||||
val total = recyclerView.adapter?.itemCount ?: 0
|
val total = recyclerView.adapter?.itemCount ?: 0
|
||||||
// 초기 진입(아이템 없음) 또는 다음 페이지가 존재할 때(cursor != null)에만 로드
|
if (!recyclerView.canScrollVertically(1) && lastVisible == total - 1) {
|
||||||
val canLoadMore = adapter.items.isEmpty() || cursor != null
|
viewModel.getCommentList(characterId)
|
||||||
if (canLoadMore && !recyclerView.canScrollVertically(1) && lastVisible == total - 1) {
|
|
||||||
loadMore()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -245,57 +164,37 @@ class CharacterCommentListFragment : BaseFragment<FragmentCharacterCommentListBi
|
|||||||
|
|
||||||
@SuppressLint("NotifyDataSetChanged")
|
@SuppressLint("NotifyDataSetChanged")
|
||||||
private fun bindData() {
|
private fun bindData() {
|
||||||
// total count 스텁: 어댑터 크기 사용
|
viewModel.isLoading.observe(viewLifecycleOwner) {
|
||||||
// 필요 시 ViewModel 도입 가능
|
if (it) {
|
||||||
|
loadingDialog.show(screenWidth)
|
||||||
|
} else {
|
||||||
|
loadingDialog.dismiss()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
viewModel.toastLiveData.observe(viewLifecycleOwner) { msg ->
|
||||||
|
|
||||||
|
msg?.let { showToast(it) }
|
||||||
|
}
|
||||||
|
|
||||||
|
viewModel.totalCommentCount.observe(viewLifecycleOwner) { count ->
|
||||||
|
binding.tvCommentCount.text = "$count"
|
||||||
|
}
|
||||||
|
|
||||||
|
viewModel.commentList.observe(viewLifecycleOwner) { items ->
|
||||||
|
if (viewModel.page - 1 == 1) {
|
||||||
|
adapter.items.clear()
|
||||||
|
binding.rvComment.scrollToPosition(0)
|
||||||
|
}
|
||||||
|
adapter.items.addAll(items)
|
||||||
|
adapter.notifyDataSetChanged()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun hideKeyboard() {
|
private fun hideKeyboard() {
|
||||||
imm.hideSoftInputFromWindow(view?.windowToken, 0)
|
imm.hideSoftInputFromWindow(view?.windowToken, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
private var cursor: Long? = null
|
|
||||||
private var isLoading = false
|
|
||||||
|
|
||||||
@SuppressLint("NotifyDataSetChanged")
|
|
||||||
private fun resetAndLoad() {
|
|
||||||
cursor = null
|
|
||||||
adapter.items.clear()
|
|
||||||
adapter.notifyDataSetChanged()
|
|
||||||
loadMore()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun loadMore() {
|
|
||||||
if (isLoading) return
|
|
||||||
// 초기 로드(아이템 없음)는 허용. 그 외에는 cursor가 null이면 더 이상 로드하지 않음
|
|
||||||
if (adapter.items.isNotEmpty() && cursor == null) return
|
|
||||||
val token = "Bearer ${SharedPreferenceManager.token}"
|
|
||||||
isLoading = true
|
|
||||||
val d = repository.listComments(characterId, 20, cursor, token)
|
|
||||||
.subscribeOn(Schedulers.io())
|
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
|
||||||
.doFinally { isLoading = false }
|
|
||||||
.subscribe({ resp ->
|
|
||||||
if (resp.success) {
|
|
||||||
val data = resp.data
|
|
||||||
val items = data?.comments ?: emptyList()
|
|
||||||
val start = adapter.items.size
|
|
||||||
adapter.items.addAll(items)
|
|
||||||
adapter.notifyItemRangeInserted(start, items.size)
|
|
||||||
binding.tvCommentCount.text = data?.totalCount?.toString() ?: "0"
|
|
||||||
cursor = data?.cursor
|
|
||||||
} else {
|
|
||||||
Toast.makeText(
|
|
||||||
requireContext(),
|
|
||||||
resp.message ?: "요청 중 오류가 발생했습니다",
|
|
||||||
Toast.LENGTH_SHORT
|
|
||||||
).show()
|
|
||||||
}
|
|
||||||
}, { e ->
|
|
||||||
Toast.makeText(requireContext(), e.message ?: "요청 중 오류가 발생했습니다", Toast.LENGTH_SHORT)
|
|
||||||
.show()
|
|
||||||
})
|
|
||||||
compositeDisposable.add(d)
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private const val EXTRA_CHARACTER_ID = "extra_character_id"
|
private const val EXTRA_CHARACTER_ID = "extra_character_id"
|
||||||
|
|||||||
@@ -0,0 +1,197 @@
|
|||||||
|
package kr.co.vividnext.sodalive.chat.character.comment
|
||||||
|
|
||||||
|
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 CharacterCommentListViewModel(
|
||||||
|
private val repository: CharacterCommentRepository
|
||||||
|
) : BaseViewModel() {
|
||||||
|
|
||||||
|
private val _toastLiveData = MutableLiveData<String?>()
|
||||||
|
val toastLiveData: LiveData<String?>
|
||||||
|
get() = _toastLiveData
|
||||||
|
|
||||||
|
private val _isLoading = MutableLiveData(false)
|
||||||
|
val isLoading: LiveData<Boolean>
|
||||||
|
get() = _isLoading
|
||||||
|
|
||||||
|
private val _commentList = MutableLiveData<List<CharacterCommentResponse>>()
|
||||||
|
val commentList: LiveData<List<CharacterCommentResponse>>
|
||||||
|
get() = _commentList
|
||||||
|
|
||||||
|
private val _totalCommentCount = MutableLiveData(0)
|
||||||
|
val totalCommentCount: LiveData<Int>
|
||||||
|
get() = _totalCommentCount
|
||||||
|
|
||||||
|
// 페이지네이션 상태 (cursor 기반이지만 UI에선 1페이지 초기화 판단을 위해 page 인덱스 유지)
|
||||||
|
var page: Int = 1
|
||||||
|
private set
|
||||||
|
private var isLast: Boolean = false
|
||||||
|
private val size: Int = 20
|
||||||
|
private var cursor: Long? = null
|
||||||
|
|
||||||
|
fun reset(characterId: Long) {
|
||||||
|
page = 1
|
||||||
|
isLast = false
|
||||||
|
cursor = null
|
||||||
|
getCommentList(characterId)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getCommentList(characterId: Long, onFailure: (() -> Unit)? = null) {
|
||||||
|
// 로딩 중이면 차단
|
||||||
|
if (_isLoading.value == true) return
|
||||||
|
// 이슈 요구사항: 초기 1회 로드 허용, 이후엔 cursor != null일 때만 추가 로드
|
||||||
|
if (page > 1 && cursor == null) return
|
||||||
|
// 이미 마지막이면 차단 (보조 안전장치)
|
||||||
|
if (isLast) return
|
||||||
|
|
||||||
|
_isLoading.value = true
|
||||||
|
|
||||||
|
val token = "Bearer ${SharedPreferenceManager.token}"
|
||||||
|
compositeDisposable.add(
|
||||||
|
repository.listComments(
|
||||||
|
characterId = characterId,
|
||||||
|
limit = size,
|
||||||
|
cursor = cursor,
|
||||||
|
token = token
|
||||||
|
)
|
||||||
|
.subscribeOn(Schedulers.io())
|
||||||
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
|
.subscribe({ resp ->
|
||||||
|
_isLoading.value = false
|
||||||
|
if (resp.success && resp.data != null) {
|
||||||
|
// total count 업데이트
|
||||||
|
_totalCommentCount.postValue(resp.data.totalCount)
|
||||||
|
|
||||||
|
// 다음 페이지 커서 및 마지막 여부 갱신
|
||||||
|
val nextCursor = resp.data.cursor
|
||||||
|
cursor = nextCursor
|
||||||
|
isLast = (nextCursor == null)
|
||||||
|
|
||||||
|
// 페이지 인덱스 증가 (UI에서 초기화 판단용)
|
||||||
|
page += 1
|
||||||
|
|
||||||
|
val items = resp.data.comments
|
||||||
|
// 응답 아이템 전달 (비어있어도 전달) — UI는 addAll 처리
|
||||||
|
_commentList.postValue(items)
|
||||||
|
} else {
|
||||||
|
val message = resp.message ?: "알 수 없는 오류가 발생했습니다. 다시 시도해 주세요."
|
||||||
|
_toastLiveData.postValue(message)
|
||||||
|
onFailure?.invoke()
|
||||||
|
}
|
||||||
|
}, { e ->
|
||||||
|
_isLoading.value = false
|
||||||
|
Logger.e(e, "Character comments load failed")
|
||||||
|
_toastLiveData.postValue("알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.")
|
||||||
|
onFailure?.invoke()
|
||||||
|
})
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun createComment(characterId: Long, comment: String) {
|
||||||
|
if (comment.isBlank()) {
|
||||||
|
_toastLiveData.postValue("내용을 입력하세요")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (_isLoading.value == true) return
|
||||||
|
_isLoading.value = true
|
||||||
|
|
||||||
|
val token = "Bearer ${SharedPreferenceManager.token}"
|
||||||
|
compositeDisposable.add(
|
||||||
|
repository.createComment(
|
||||||
|
characterId = characterId,
|
||||||
|
comment = comment,
|
||||||
|
token = token
|
||||||
|
)
|
||||||
|
.subscribeOn(Schedulers.io())
|
||||||
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
|
.subscribe({ resp ->
|
||||||
|
_isLoading.value = false
|
||||||
|
if (resp.success) {
|
||||||
|
// 목록 초기화 후 재조회
|
||||||
|
page = 1
|
||||||
|
isLast = false
|
||||||
|
cursor = null
|
||||||
|
getCommentList(characterId)
|
||||||
|
} else {
|
||||||
|
val message = resp.message ?: "알 수 없는 오류가 발생했습니다. 다시 시도해 주세요."
|
||||||
|
_toastLiveData.postValue(message)
|
||||||
|
}
|
||||||
|
}, { e ->
|
||||||
|
_isLoading.value = false
|
||||||
|
Logger.e(e, "Character comment create failed")
|
||||||
|
_toastLiveData.postValue("알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.")
|
||||||
|
})
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun deleteComment(characterId: Long, commentId: Long) {
|
||||||
|
if (_isLoading.value == true) return
|
||||||
|
_isLoading.value = true
|
||||||
|
val token = "Bearer ${SharedPreferenceManager.token}"
|
||||||
|
compositeDisposable.add(
|
||||||
|
repository.deleteComment(
|
||||||
|
characterId = characterId,
|
||||||
|
commentId = commentId,
|
||||||
|
token = token
|
||||||
|
)
|
||||||
|
.subscribeOn(Schedulers.io())
|
||||||
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
|
.subscribe({ resp ->
|
||||||
|
_isLoading.value = false
|
||||||
|
if (resp.success) {
|
||||||
|
// 간단하게 전체를 새로고침
|
||||||
|
page = 1
|
||||||
|
isLast = false
|
||||||
|
cursor = null
|
||||||
|
getCommentList(characterId)
|
||||||
|
} else {
|
||||||
|
val message = resp.message ?: "알 수 없는 오류가 발생했습니다. 다시 시도해 주세요."
|
||||||
|
_toastLiveData.postValue(message)
|
||||||
|
}
|
||||||
|
}, { e ->
|
||||||
|
_isLoading.value = false
|
||||||
|
Logger.e(e, "Character comment delete failed")
|
||||||
|
_toastLiveData.postValue("알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.")
|
||||||
|
})
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun reportComment(characterId: Long, commentId: Long, reason: String) {
|
||||||
|
if (reason.isBlank()) {
|
||||||
|
_toastLiveData.postValue("신고 사유를 입력하세요")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (_isLoading.value == true) return
|
||||||
|
_isLoading.value = true
|
||||||
|
val token = "Bearer ${SharedPreferenceManager.token}"
|
||||||
|
compositeDisposable.add(
|
||||||
|
repository.reportComment(
|
||||||
|
characterId = characterId,
|
||||||
|
commentId = commentId,
|
||||||
|
reason = reason,
|
||||||
|
token = token
|
||||||
|
)
|
||||||
|
.subscribeOn(Schedulers.io())
|
||||||
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
|
.subscribe({ resp ->
|
||||||
|
_isLoading.value = false
|
||||||
|
if (resp.success) {
|
||||||
|
_toastLiveData.postValue("신고가 접수되었습니다.")
|
||||||
|
} else {
|
||||||
|
val message = resp.message ?: "알 수 없는 오류가 발생했습니다. 다시 시도해 주세요."
|
||||||
|
_toastLiveData.postValue(message)
|
||||||
|
}
|
||||||
|
}, { e ->
|
||||||
|
_isLoading.value = false
|
||||||
|
Logger.e(e, "Character comment report failed")
|
||||||
|
_toastLiveData.postValue("알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.")
|
||||||
|
})
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -359,6 +359,7 @@ class AppDI(private val context: Context, isDebugMode: Boolean) {
|
|||||||
viewModel { CharacterTabViewModel(get()) }
|
viewModel { CharacterTabViewModel(get()) }
|
||||||
viewModel { CharacterDetailViewModel(get()) }
|
viewModel { CharacterDetailViewModel(get()) }
|
||||||
viewModel { TalkTabViewModel(get()) }
|
viewModel { TalkTabViewModel(get()) }
|
||||||
|
viewModel { kr.co.vividnext.sodalive.chat.character.comment.CharacterCommentListViewModel(get()) }
|
||||||
}
|
}
|
||||||
|
|
||||||
private val repositoryModule = module {
|
private val repositoryModule = module {
|
||||||
|
|||||||
Reference in New Issue
Block a user