feat(character-comment): 캐릭터 댓글 리스트 등록/목록/신고 API 연동 및 DI 등록
fix(character-comment): 캐릭터 댓글 리스트 무한 스크롤에서 cursor null 시 추가 호출 방지 - CharacterCommentApi/Repository 추가 - AppDI에 API/Repository 등록 - CharacterCommentListFragment: 등록 버튼 클릭 시 API 호출로 전환, 커서 페이징 목록 로드 적용, 신고 API 연동 - 로딩/에러 처리 및 중복 로드 방지 플래그 추가 - 스크롤 리스너에 canLoadMore 조건 추가(초기 또는 cursor 존재 시에만 호출) - loadMore()에 종료 가드 추가(adapter 비어있지 않고 cursor null이면 반환) - 댓글 1개인 경우 동일 내용 반복 로딩 문제 해결
This commit is contained in:
		@@ -0,0 +1,60 @@
 | 
			
		||||
package kr.co.vividnext.sodalive.chat.character.comment
 | 
			
		||||
 | 
			
		||||
import io.reactivex.rxjava3.core.Single
 | 
			
		||||
import kr.co.vividnext.sodalive.common.ApiResponse
 | 
			
		||||
import retrofit2.http.Body
 | 
			
		||||
import retrofit2.http.DELETE
 | 
			
		||||
import retrofit2.http.GET
 | 
			
		||||
import retrofit2.http.Header
 | 
			
		||||
import retrofit2.http.POST
 | 
			
		||||
import retrofit2.http.Path
 | 
			
		||||
import retrofit2.http.Query
 | 
			
		||||
 | 
			
		||||
interface CharacterCommentApi {
 | 
			
		||||
    @POST("/api/chat/character/{characterId}/comments")
 | 
			
		||||
    fun createComment(
 | 
			
		||||
        @Path("characterId") characterId: Long,
 | 
			
		||||
        @Body request: CreateCharacterCommentRequest,
 | 
			
		||||
        @Header("Authorization") authHeader: String
 | 
			
		||||
    ): Single<ApiResponse<Any>>
 | 
			
		||||
 | 
			
		||||
    @POST("/api/chat/character/{characterId}/comments/{commentId}/replies")
 | 
			
		||||
    fun createReply(
 | 
			
		||||
        @Path("characterId") characterId: Long,
 | 
			
		||||
        @Path("commentId") commentId: Long,
 | 
			
		||||
        @Body request: CreateCharacterCommentRequest,
 | 
			
		||||
        @Header("Authorization") authHeader: String
 | 
			
		||||
    ): Single<ApiResponse<Any>>
 | 
			
		||||
 | 
			
		||||
    @GET("/api/chat/character/{characterId}/comments")
 | 
			
		||||
    fun listComments(
 | 
			
		||||
        @Path("characterId") characterId: Long,
 | 
			
		||||
        @Query("limit") limit: Int = 20,
 | 
			
		||||
        @Query("cursor") cursor: Long?,
 | 
			
		||||
        @Header("Authorization") authHeader: String
 | 
			
		||||
    ): Single<ApiResponse<CharacterCommentListResponse>>
 | 
			
		||||
 | 
			
		||||
    @GET("/api/chat/character/{characterId}/comments/{commentId}/replies")
 | 
			
		||||
    fun listReplies(
 | 
			
		||||
        @Path("characterId") characterId: Long,
 | 
			
		||||
        @Path("commentId") commentId: Long,
 | 
			
		||||
        @Query("limit") limit: Int = 20,
 | 
			
		||||
        @Query("cursor") cursor: Long?,
 | 
			
		||||
        @Header("Authorization") authHeader: String
 | 
			
		||||
    ): Single<ApiResponse<CharacterCommentRepliesResponse>>
 | 
			
		||||
 | 
			
		||||
    @DELETE("/api/chat/character/{characterId}/comments/{commentId}")
 | 
			
		||||
    fun deleteComment(
 | 
			
		||||
        @Path("characterId") characterId: Long,
 | 
			
		||||
        @Path("commentId") commentId: Long,
 | 
			
		||||
        @Header("Authorization") authHeader: String
 | 
			
		||||
    ): Single<ApiResponse<Any>>
 | 
			
		||||
 | 
			
		||||
    @POST("/api/chat/character/{characterId}/comments/{commentId}/reports")
 | 
			
		||||
    fun reportComment(
 | 
			
		||||
        @Path("characterId") characterId: Long,
 | 
			
		||||
        @Path("commentId") commentId: Long,
 | 
			
		||||
        @Body request: ReportCharacterCommentRequest,
 | 
			
		||||
        @Header("Authorization") authHeader: String
 | 
			
		||||
    ): Single<ApiResponse<Any>>
 | 
			
		||||
}
 | 
			
		||||
@@ -14,17 +14,22 @@ import androidx.recyclerview.widget.RecyclerView
 | 
			
		||||
import coil.load
 | 
			
		||||
import coil.transform.CircleCropTransformation
 | 
			
		||||
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.base.BaseFragment
 | 
			
		||||
import kr.co.vividnext.sodalive.common.LoadingDialog
 | 
			
		||||
import kr.co.vividnext.sodalive.common.SharedPreferenceManager
 | 
			
		||||
import kr.co.vividnext.sodalive.databinding.FragmentCharacterCommentListBinding
 | 
			
		||||
import kr.co.vividnext.sodalive.extensions.dpToPx
 | 
			
		||||
import org.koin.android.ext.android.inject
 | 
			
		||||
 | 
			
		||||
class CharacterCommentListFragment : BaseFragment<FragmentCharacterCommentListBinding>(
 | 
			
		||||
    FragmentCharacterCommentListBinding::inflate
 | 
			
		||||
) {
 | 
			
		||||
 | 
			
		||||
    private val repository: CharacterCommentRepository by inject()
 | 
			
		||||
 | 
			
		||||
    private lateinit var imm: InputMethodManager
 | 
			
		||||
    private lateinit var loadingDialog: LoadingDialog
 | 
			
		||||
    private lateinit var adapter: CharacterCommentsAdapter
 | 
			
		||||
@@ -48,8 +53,8 @@ class CharacterCommentListFragment : BaseFragment<FragmentCharacterCommentListBi
 | 
			
		||||
 | 
			
		||||
        setupView()
 | 
			
		||||
        bindData()
 | 
			
		||||
        // 초기 로드 (스텁)
 | 
			
		||||
        loadMore()
 | 
			
		||||
        // 초기 로드
 | 
			
		||||
        resetAndLoad()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private fun hideDialog() {
 | 
			
		||||
@@ -70,21 +75,31 @@ class CharacterCommentListFragment : BaseFragment<FragmentCharacterCommentListBi
 | 
			
		||||
            hideKeyboard()
 | 
			
		||||
            val comment = binding.etComment.text.toString()
 | 
			
		||||
            if (comment.isBlank()) return@setOnClickListener
 | 
			
		||||
            // 스텁: 로컬에 즉시 추가 (CharacterCommentDto 기반)
 | 
			
		||||
            val me = CharacterCommentResponse(
 | 
			
		||||
                commentId = System.currentTimeMillis(),
 | 
			
		||||
                memberId = SharedPreferenceManager.userId,
 | 
			
		||||
                memberProfileImage = SharedPreferenceManager.profileImage,
 | 
			
		||||
                memberNickname = SharedPreferenceManager.nickname,
 | 
			
		||||
                createdAt = System.currentTimeMillis(),
 | 
			
		||||
                replyCount = 0,
 | 
			
		||||
                comment = comment
 | 
			
		||||
            )
 | 
			
		||||
            adapter.items.add(me)
 | 
			
		||||
            adapter.notifyItemInserted(adapter.items.size - 1)
 | 
			
		||||
            binding.rvComment.scrollToPosition(adapter.items.size - 1)
 | 
			
		||||
            binding.etComment.setText("")
 | 
			
		||||
            Toast.makeText(requireContext(), "등록되었습니다 (stub)", Toast.LENGTH_SHORT).show()
 | 
			
		||||
            val token = "Bearer ${SharedPreferenceManager.token}"
 | 
			
		||||
            loadingDialog.show(screenWidth)
 | 
			
		||||
            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(
 | 
			
		||||
@@ -92,11 +107,35 @@ class CharacterCommentListFragment : BaseFragment<FragmentCharacterCommentListBi
 | 
			
		||||
            onClickMore = { item, isOwner, anchor ->
 | 
			
		||||
                CharacterCommentMoreBottomSheet.newInstance(isOwner).apply {
 | 
			
		||||
                    onReport = {
 | 
			
		||||
                        // 더보기 닫히고 신고 BottomSheet 열림
 | 
			
		||||
                        val reportSheet = CharacterCommentReportBottomSheet.newInstance()
 | 
			
		||||
                        reportSheet.onSubmit = { reason ->
 | 
			
		||||
                            // 신고 API 스텁 호출 지점
 | 
			
		||||
                            Toast.makeText(requireContext(), "신고 접수: $reason (stub)", Toast.LENGTH_SHORT).show()
 | 
			
		||||
                            val token = "Bearer ${SharedPreferenceManager.token}"
 | 
			
		||||
                            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(childFragmentManager, "comment_report")
 | 
			
		||||
                    }
 | 
			
		||||
@@ -107,7 +146,8 @@ class CharacterCommentListFragment : BaseFragment<FragmentCharacterCommentListBi
 | 
			
		||||
                            .setMessage(getString(R.string.confirm_delete_message))
 | 
			
		||||
                            .setPositiveButton(getString(R.string.confirm)) { _, _ ->
 | 
			
		||||
                                // 삭제 API 스텁 호출 지점
 | 
			
		||||
                                val index = adapter.items.indexOfFirst { it.commentId == item.commentId }
 | 
			
		||||
                                val index =
 | 
			
		||||
                                    adapter.items.indexOfFirst { it.commentId == item.commentId }
 | 
			
		||||
                                if (index >= 0) {
 | 
			
		||||
                                    adapter.items.removeAt(index)
 | 
			
		||||
                                    adapter.notifyItemRemoved(index)
 | 
			
		||||
@@ -167,7 +207,9 @@ class CharacterCommentListFragment : BaseFragment<FragmentCharacterCommentListBi
 | 
			
		||||
                val lastVisible =
 | 
			
		||||
                    (recyclerView.layoutManager as LinearLayoutManager).findLastCompletelyVisibleItemPosition()
 | 
			
		||||
                val total = recyclerView.adapter?.itemCount ?: 0
 | 
			
		||||
                if (!recyclerView.canScrollVertically(1) && lastVisible == total - 1) {
 | 
			
		||||
                // 초기 진입(아이템 없음) 또는 다음 페이지가 존재할 때(cursor != null)에만 로드
 | 
			
		||||
                val canLoadMore = adapter.items.isEmpty() || cursor != null
 | 
			
		||||
                if (canLoadMore && !recyclerView.canScrollVertically(1) && lastVisible == total - 1) {
 | 
			
		||||
                    loadMore()
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
@@ -186,28 +228,47 @@ class CharacterCommentListFragment : BaseFragment<FragmentCharacterCommentListBi
 | 
			
		||||
        imm.hideSoftInputFromWindow(view?.windowToken, 0)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private var page = 1
 | 
			
		||||
    private var cursor: Long? = null
 | 
			
		||||
    private var isLoading = false
 | 
			
		||||
 | 
			
		||||
    private fun resetAndLoad() {
 | 
			
		||||
        cursor = null
 | 
			
		||||
        adapter.items.clear()
 | 
			
		||||
        adapter.notifyDataSetChanged()
 | 
			
		||||
        loadMore()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private fun loadMore() {
 | 
			
		||||
        // API 스텁: 더미 데이터 생성
 | 
			
		||||
        val newItems = (1..10).map { idx ->
 | 
			
		||||
            val id = page * 1000L + idx
 | 
			
		||||
            val writerId = if (idx % 5 == 0) SharedPreferenceManager.userId else -idx.toLong()
 | 
			
		||||
            CharacterCommentResponse(
 | 
			
		||||
                commentId = id,
 | 
			
		||||
                memberId = writerId,
 | 
			
		||||
                memberProfileImage = "",
 | 
			
		||||
                memberNickname = "게스트$id",
 | 
			
		||||
                createdAt = System.currentTimeMillis() - (idx * 60_000L * page),
 | 
			
		||||
                replyCount = (idx % 3),
 | 
			
		||||
                comment = "캐릭터 댓글 예시 텍스트 $id"
 | 
			
		||||
            )
 | 
			
		||||
        }
 | 
			
		||||
        if (page == 1) adapter.items.clear()
 | 
			
		||||
        val start = adapter.items.size
 | 
			
		||||
        adapter.items.addAll(newItems)
 | 
			
		||||
        adapter.notifyItemRangeInserted(start, newItems.size)
 | 
			
		||||
        binding.tvCommentCount.text = "${adapter.items.size}"
 | 
			
		||||
        page++
 | 
			
		||||
        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 = "${adapter.items.size}"
 | 
			
		||||
                    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 {
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,73 @@
 | 
			
		||||
package kr.co.vividnext.sodalive.chat.character.comment
 | 
			
		||||
 | 
			
		||||
class CharacterCommentRepository(private val api: CharacterCommentApi) {
 | 
			
		||||
    fun createComment(
 | 
			
		||||
        characterId: Long,
 | 
			
		||||
        comment: String,
 | 
			
		||||
        token: String
 | 
			
		||||
    ) = api.createComment(
 | 
			
		||||
        characterId = characterId,
 | 
			
		||||
        request = CreateCharacterCommentRequest(comment = comment),
 | 
			
		||||
        authHeader = token
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    fun createReply(
 | 
			
		||||
        characterId: Long,
 | 
			
		||||
        commentId: Long,
 | 
			
		||||
        comment: String,
 | 
			
		||||
        token: String
 | 
			
		||||
    ) = api.createReply(
 | 
			
		||||
        characterId = characterId,
 | 
			
		||||
        commentId = commentId,
 | 
			
		||||
        request = CreateCharacterCommentRequest(comment = comment),
 | 
			
		||||
        authHeader = token
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    fun listComments(
 | 
			
		||||
        characterId: Long,
 | 
			
		||||
        limit: Int,
 | 
			
		||||
        cursor: Long?,
 | 
			
		||||
        token: String
 | 
			
		||||
    ) = api.listComments(
 | 
			
		||||
        characterId = characterId,
 | 
			
		||||
        limit = limit,
 | 
			
		||||
        cursor = cursor,
 | 
			
		||||
        authHeader = token
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    fun listReplies(
 | 
			
		||||
        characterId: Long,
 | 
			
		||||
        commentId: Long,
 | 
			
		||||
        limit: Int,
 | 
			
		||||
        cursor: Long?,
 | 
			
		||||
        token: String
 | 
			
		||||
    ) = api.listReplies(
 | 
			
		||||
        characterId = characterId,
 | 
			
		||||
        commentId = commentId,
 | 
			
		||||
        limit = limit,
 | 
			
		||||
        cursor = cursor,
 | 
			
		||||
        authHeader = token
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    fun deleteComment(
 | 
			
		||||
        characterId: Long,
 | 
			
		||||
        commentId: Long,
 | 
			
		||||
        token: String
 | 
			
		||||
    ) = api.deleteComment(
 | 
			
		||||
        characterId = characterId,
 | 
			
		||||
        commentId = commentId,
 | 
			
		||||
        authHeader = token
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    fun reportComment(
 | 
			
		||||
        characterId: Long,
 | 
			
		||||
        commentId: Long,
 | 
			
		||||
        reason: String,
 | 
			
		||||
        token: String
 | 
			
		||||
    ) = api.reportComment(
 | 
			
		||||
        characterId = characterId,
 | 
			
		||||
        commentId = commentId,
 | 
			
		||||
        request = ReportCharacterCommentRequest(content = reason),
 | 
			
		||||
        authHeader = token
 | 
			
		||||
    )
 | 
			
		||||
}
 | 
			
		||||
@@ -20,11 +20,16 @@ import kr.co.vividnext.sodalive.common.SharedPreferenceManager
 | 
			
		||||
import kr.co.vividnext.sodalive.databinding.ActivityCharacterDetailBinding
 | 
			
		||||
import kr.co.vividnext.sodalive.extensions.dpToPx
 | 
			
		||||
import org.koin.androidx.viewmodel.ext.android.viewModel
 | 
			
		||||
import org.koin.android.ext.android.inject
 | 
			
		||||
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
 | 
			
		||||
import io.reactivex.rxjava3.schedulers.Schedulers
 | 
			
		||||
import kr.co.vividnext.sodalive.chat.character.comment.CharacterCommentRepository
 | 
			
		||||
 | 
			
		||||
class CharacterDetailActivity : BaseActivity<ActivityCharacterDetailBinding>(
 | 
			
		||||
    ActivityCharacterDetailBinding::inflate
 | 
			
		||||
) {
 | 
			
		||||
    private val viewModel: CharacterDetailViewModel by viewModel()
 | 
			
		||||
    private val commentRepository: CharacterCommentRepository by inject()
 | 
			
		||||
 | 
			
		||||
    private lateinit var loadingDialog: LoadingDialog
 | 
			
		||||
 | 
			
		||||
@@ -283,6 +288,35 @@ class CharacterDetailActivity : BaseActivity<ActivityCharacterDetailBinding>(
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                binding.ivSendComment.setOnClickListener {
 | 
			
		||||
                    val text = binding.etCommentInput.text?.toString()?.trim().orEmpty()
 | 
			
		||||
                    if (text.isBlank()) return@setOnClickListener
 | 
			
		||||
 | 
			
		||||
                    val idFromState = viewModel.uiState.value?.detail?.characterId ?: 0L
 | 
			
		||||
                    val idFromIntent = intent.getLongExtra(EXTRA_CHARACTER_ID, 0L)
 | 
			
		||||
                    val characterId = if (idFromState > 0) idFromState else idFromIntent
 | 
			
		||||
                    if (characterId <= 0) {
 | 
			
		||||
                        showToast("잘못된 접근 입니다.")
 | 
			
		||||
                        return@setOnClickListener
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    val token = "Bearer ${SharedPreferenceManager.token}"
 | 
			
		||||
                    loadingDialog.show(screenWidth)
 | 
			
		||||
                    val d = commentRepository.createComment(characterId, text, token)
 | 
			
		||||
                        .subscribeOn(Schedulers.io())
 | 
			
		||||
                        .observeOn(AndroidSchedulers.mainThread())
 | 
			
		||||
                        .doFinally { loadingDialog.dismiss() }
 | 
			
		||||
                        .subscribe({ resp ->
 | 
			
		||||
                            if (resp.success) {
 | 
			
		||||
                                binding.etCommentInput.setText("")
 | 
			
		||||
                                showToast("등록되었습니다.")
 | 
			
		||||
                                viewModel.load(characterId)
 | 
			
		||||
                            } else {
 | 
			
		||||
                                showToast(resp.message ?: "요청 중 오류가 발생했습니다")
 | 
			
		||||
                            }
 | 
			
		||||
                        }, { e ->
 | 
			
		||||
                            showToast(e.message ?: "요청 중 오류가 발생했습니다")
 | 
			
		||||
                        })
 | 
			
		||||
                    compositeDisposable.add(d)
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 
 | 
			
		||||
@@ -67,11 +67,14 @@ 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.chat.character.comment.CharacterCommentApi
 | 
			
		||||
import kr.co.vividnext.sodalive.chat.character.comment.CharacterCommentRepository
 | 
			
		||||
import kr.co.vividnext.sodalive.chat.character.detail.CharacterDetailRepository
 | 
			
		||||
import kr.co.vividnext.sodalive.chat.character.detail.CharacterDetailViewModel
 | 
			
		||||
import kr.co.vividnext.sodalive.chat.talk.TalkApi
 | 
			
		||||
import kr.co.vividnext.sodalive.chat.talk.TalkTabRepository
 | 
			
		||||
import kr.co.vividnext.sodalive.chat.talk.TalkTabViewModel
 | 
			
		||||
import kr.co.vividnext.sodalive.chat.talk.room.chatTalkRoomModule
 | 
			
		||||
import kr.co.vividnext.sodalive.common.ApiBuilder
 | 
			
		||||
import kr.co.vividnext.sodalive.common.ObjectBox
 | 
			
		||||
import kr.co.vividnext.sodalive.explorer.ExplorerApi
 | 
			
		||||
@@ -146,7 +149,6 @@ import kr.co.vividnext.sodalive.mypage.profile.tag.MemberTagApi
 | 
			
		||||
import kr.co.vividnext.sodalive.mypage.profile.tag.MemberTagRepository
 | 
			
		||||
import kr.co.vividnext.sodalive.mypage.profile.tag.MemberTagViewModel
 | 
			
		||||
import kr.co.vividnext.sodalive.mypage.recent.recentContentModule
 | 
			
		||||
import kr.co.vividnext.sodalive.chat.talk.room.chatTalkRoomModule
 | 
			
		||||
import kr.co.vividnext.sodalive.mypage.service_center.FaqApi
 | 
			
		||||
import kr.co.vividnext.sodalive.mypage.service_center.FaqRepository
 | 
			
		||||
import kr.co.vividnext.sodalive.mypage.service_center.ServiceCenterViewModel
 | 
			
		||||
@@ -256,6 +258,7 @@ class AppDI(private val context: Context, isDebugMode: Boolean) {
 | 
			
		||||
        single { ApiBuilder().build(get(), HomeApi::class.java) }
 | 
			
		||||
        single { ApiBuilder().build(get(), CharacterApi::class.java) }
 | 
			
		||||
        single { ApiBuilder().build(get(), TalkApi::class.java) }
 | 
			
		||||
        single { ApiBuilder().build(get(), CharacterCommentApi::class.java) }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private val viewModelModule = module {
 | 
			
		||||
@@ -403,6 +406,7 @@ class AppDI(private val context: Context, isDebugMode: Boolean) {
 | 
			
		||||
        factory { CharacterTabRepository(get()) }
 | 
			
		||||
        factory { CharacterDetailRepository(get(), get()) }
 | 
			
		||||
        factory { TalkTabRepository(get()) }
 | 
			
		||||
        factory { CharacterCommentRepository(get()) }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user