feat(chat): 탭별 empty state를 표시한다

This commit is contained in:
2026-07-11 22:02:13 +09:00
parent 9925a954d1
commit c715c890b5
4 changed files with 74 additions and 9 deletions
@@ -6,6 +6,7 @@ import android.view.View
import android.widget.ImageView
import android.widget.LinearLayout
import android.widget.Toast
import androidx.core.view.isVisible
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import kr.co.vividnext.sodalive.R
@@ -21,6 +22,7 @@ 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.model.emptyMessageResId
import kr.co.vividnext.sodalive.v2.main.chat.ui.ChatRoomListAdapter
import org.koin.androidx.viewmodel.ext.android.viewModel
@@ -44,22 +46,25 @@ class ChatMainFragment : BaseFragment<FragmentV2MainChatBinding>(
private val viewModel: ChatMainViewModel by viewModel()
private val chatRoomListAdapter = ChatRoomListAdapter { onChatRoomClick(it) }
private lateinit var loadingDialog: LoadingDialog
private var selectedFilter: ChatRoomFilter = ChatRoomFilter.ALL
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
loadingDialog = LoadingDialog(requireActivity(), layoutInflater)
setupTitleBar()
val initialFilter = getInitialFilter()
setupFilterTabs(initialFilter ?: ChatRoomFilter.ALL)
val initialFilter = getInitialFilter() ?: ChatRoomFilter.ALL
selectedFilter = initialFilter
setupFilterTabs(initialFilter)
setupChatRooms()
bindViewModel()
binding.btnChatFloating.setOnClickListener { }
viewModel.loadFirstPage(initialFilter ?: ChatRoomFilter.ALL)
viewModel.loadFirstPage(initialFilter)
}
fun selectFilter(filter: ChatRoomFilter) {
selectedFilter = filter
selectFilterTab(filter)
viewModel.selectFilter(filter)
}
@@ -102,7 +107,9 @@ class ChatMainFragment : BaseFragment<FragmentV2MainChatBinding>(
selectedIndex = initialFilter.tabIndex
)
binding.viewChatFilterTabs.root.setOnTabSelectedListener { index ->
viewModel.selectFilter(ChatRoomFilter.fromTabIndex(index))
val filter = ChatRoomFilter.fromTabIndex(index)
selectedFilter = filter
viewModel.selectFilter(filter)
binding.rvChatRooms.scrollToPosition(0)
}
}
@@ -130,14 +137,14 @@ class ChatMainFragment : BaseFragment<FragmentV2MainChatBinding>(
viewModel.chatRoomStateLiveData.observe(viewLifecycleOwner) { state ->
when (state) {
is ChatRoomListUiState.Content -> {
chatRoomListAdapter.submitItems(state.items)
bindChatRooms(state.items, showEmpty = false)
if (!state.isAppending) {
binding.rvChatRooms.scrollToPosition(0)
}
}
ChatRoomListUiState.Empty -> chatRoomListAdapter.submitItems(emptyList())
is ChatRoomListUiState.Error -> chatRoomListAdapter.submitItems(emptyList())
ChatRoomListUiState.Loading -> Unit
ChatRoomListUiState.Empty -> bindChatRooms(emptyList(), showEmpty = true)
is ChatRoomListUiState.Error -> bindChatRooms(emptyList(), showEmpty = false)
ChatRoomListUiState.Loading -> binding.tvChatEmptyMessage.isVisible = false
}
}
viewModel.isLoading.observe(viewLifecycleOwner) {
@@ -155,6 +162,15 @@ class ChatMainFragment : BaseFragment<FragmentV2MainChatBinding>(
}
}
private fun bindChatRooms(items: List<ChatRoomListUiItem>, showEmpty: Boolean) {
chatRoomListAdapter.submitItems(items)
binding.rvChatRooms.isVisible = !showEmpty
binding.tvChatEmptyMessage.isVisible = showEmpty
if (showEmpty) {
binding.tvChatEmptyMessage.setText(selectedFilter.emptyMessageResId())
}
}
private fun onChatRoomClick(item: ChatRoomListUiItem) {
when (item.chatType) {
ChatRoomType.AI -> startActivity(ChatRoomActivity.newIntent(requireContext(), item.roomId))
@@ -1,5 +1,8 @@
package kr.co.vividnext.sodalive.v2.main.chat.model
import androidx.annotation.StringRes
import kr.co.vividnext.sodalive.R
enum class ChatRoomFilter(val apiValue: String, val tabIndex: Int) {
ALL("ALL", 0),
AI("AI", 1),
@@ -13,3 +16,10 @@ enum class ChatRoomFilter(val apiValue: String, val tabIndex: Int) {
}
}
}
@StringRes
fun ChatRoomFilter.emptyMessageResId(): Int = when (this) {
ChatRoomFilter.ALL -> R.string.screen_chat_empty_all
ChatRoomFilter.AI -> R.string.screen_chat_empty_ai
ChatRoomFilter.DM -> R.string.screen_chat_empty_dm
}
@@ -37,6 +37,20 @@
app:layout_constraintTop_toBottomOf="@id/view_chat_filter_tabs"
tools:listitem="@layout/item_v2_chat_room" />
<TextView
android:id="@+id/tv_chat_empty_message"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:gravity="center"
android:textColor="@color/color_777777"
android:textSize="14sp"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/view_chat_filter_tabs"
tools:text="아직 나눈 대화가 없어요.\n크리에이터와 이야기를 시작해 보세요." />
<ImageView
android:id="@+id/btn_chat_floating"
android:layout_width="@dimen/spacing_48"