feat(chat): 채팅 탭 화면 동작을 연결한다

This commit is contained in:
2026-06-10 15:06:35 +09:00
parent 516e4a94bf
commit b38e58af9a
2 changed files with 186 additions and 1 deletions

View File

@@ -1,8 +1,123 @@
package kr.co.vividnext.sodalive.v2.main.chat
import android.os.Bundle
import android.view.View
import android.widget.ImageView
import android.widget.Toast
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import kr.co.vividnext.sodalive.R
import kr.co.vividnext.sodalive.base.BaseFragment
import kr.co.vividnext.sodalive.chat.talk.room.ChatRoomActivity
import kr.co.vividnext.sodalive.common.LoadingDialog
import kr.co.vividnext.sodalive.databinding.FragmentV2MainChatBinding
import kr.co.vividnext.sodalive.v2.main.chat.model.ChatRoomFilter
import kr.co.vividnext.sodalive.v2.main.chat.model.ChatRoomListUiItem
import kr.co.vividnext.sodalive.v2.main.chat.model.ChatRoomListUiState
import kr.co.vividnext.sodalive.v2.main.chat.model.ChatRoomType
import kr.co.vividnext.sodalive.v2.main.chat.ui.ChatRoomListAdapter
import org.koin.androidx.viewmodel.ext.android.viewModel
class ChatMainFragment : BaseFragment<FragmentV2MainChatBinding>(
FragmentV2MainChatBinding::inflate
)
) {
companion object {
private const val PAGINATION_THRESHOLD = 3
}
private val viewModel: ChatMainViewModel by viewModel()
private val chatRoomListAdapter = ChatRoomListAdapter { onChatRoomClick(it) }
private lateinit var loadingDialog: LoadingDialog
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
loadingDialog = LoadingDialog(requireActivity(), layoutInflater)
setupTitleBar()
setupFilterTabs()
setupChatRooms()
bindViewModel()
binding.btnChatFloating.setOnClickListener { }
viewModel.loadFirstPage()
}
private fun setupTitleBar() {
binding.viewChatTitleBar.tvTitleBarTitle.setText(R.string.tab_chat)
binding.viewChatTitleBar.ivTitleBarMenu.setImageResource(R.drawable.ic_bar_cash)
binding.viewChatTitleBar.llTitleBarActions.addView(
ImageView(requireContext()).apply {
setImageResource(R.drawable.ic_bar_search)
}
)
}
private fun setupFilterTabs() {
binding.viewChatFilterTabs.root.setMenus(
listOf(
getString(R.string.screen_chat_filter_all),
getString(R.string.screen_chat_filter_ai),
getString(R.string.screen_chat_filter_dm)
),
selectedIndex = 0
)
binding.viewChatFilterTabs.root.setOnTabSelectedListener { index ->
viewModel.selectFilter(ChatRoomFilter.fromTabIndex(index))
binding.rvChatRooms.scrollToPosition(0)
}
}
private fun setupChatRooms() {
val layoutManager = LinearLayoutManager(requireContext())
binding.rvChatRooms.layoutManager = layoutManager
binding.rvChatRooms.adapter = chatRoomListAdapter
binding.rvChatRooms.addOnScrollListener(object : RecyclerView.OnScrollListener() {
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
super.onScrolled(recyclerView, dx, dy)
if (dy <= 0) return
val lastVisiblePosition = layoutManager.findLastVisibleItemPosition()
val shouldLoadNext = lastVisiblePosition >=
chatRoomListAdapter.itemCount - PAGINATION_THRESHOLD
if (shouldLoadNext) {
viewModel.loadNextPage()
}
}
})
}
private fun bindViewModel() {
viewModel.chatRoomStateLiveData.observe(viewLifecycleOwner) { state ->
when (state) {
is ChatRoomListUiState.Content -> {
chatRoomListAdapter.submitItems(state.items)
if (!state.isAppending) {
binding.rvChatRooms.scrollToPosition(0)
}
}
ChatRoomListUiState.Empty -> chatRoomListAdapter.submitItems(emptyList())
is ChatRoomListUiState.Error -> chatRoomListAdapter.submitItems(emptyList())
ChatRoomListUiState.Loading -> Unit
}
}
viewModel.isLoading.observe(viewLifecycleOwner) {
if (it) {
loadingDialog.show(screenWidth)
} else {
loadingDialog.dismiss()
}
}
viewModel.toastLiveData.observe(viewLifecycleOwner) {
val text = it?.message ?: it?.resId?.let { resId -> getString(resId) }
if (!text.isNullOrBlank()) {
Toast.makeText(requireContext(), text, Toast.LENGTH_LONG).show()
}
}
}
private fun onChatRoomClick(item: ChatRoomListUiItem) {
if (item.chatType != ChatRoomType.AI) return
startActivity(ChatRoomActivity.newIntent(requireContext(), item.roomId))
}
}