Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

카페 검색 검색어 여부에 따른 분기 처리 구현 #184

Merged
merged 3 commits into from
Dec 29, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import androidx.recyclerview.widget.RecyclerView
import androidx.viewbinding.ViewBinding

abstract class BaseRecyclerViewAdapter<T, VB : ViewBinding> : RecyclerView.Adapter<BaseViewHolder<T, VB>>() {
private val items = mutableListOf<T>()
protected val items = mutableListOf<T>()

override fun onBindViewHolder(holder: BaseViewHolder<T, VB>, position: Int) {
holder.bind(items[position])
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,5 @@ public interface PlaceLocalDataSource {

public suspend fun deleteRecentSearchPlace(placeEntity: PlaceEntity)

public fun getRecentSearchPlaceList(name: String?): Flow<PagingData<PlaceResponse>>
public fun getRecentSearchPlaceList(): Flow<PagingData<PlaceResponse>>
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public class PlaceLocalDataSourceImpl @Inject constructor(
placeSearchDatabase.placeSearchDao().deleteRecentSearchPlace(placeEntity.toModel())
}

override fun getRecentSearchPlaceList(name: String?): Flow<PagingData<PlaceResponse>> {
override fun getRecentSearchPlaceList(): Flow<PagingData<PlaceResponse>> {
val pagingSourceFactory = {
placeSearchDatabase.placeSearchDao().getRecentSearchPlaceList()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,8 @@ public class PlaceRepositoryImpl @Inject constructor(
localDataSource.deleteRecentSearchPlace(placeEntity)
}

override fun getRecentSearchPlaceList(name: String?): Flow<PagingData<PlaceEntity>> {
return localDataSource.getRecentSearchPlaceList(name).map { pagingData ->
override fun getRecentSearchPlaceList(): Flow<PagingData<PlaceEntity>> {
return localDataSource.getRecentSearchPlaceList().map { pagingData ->
pagingData.map { place ->
place.toEntity()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,6 @@ public interface PlaceRepository {

/**
* 최근 검색 장소 조회
*
* @param name 장소 이름
*/
public fun getRecentSearchPlaceList(name: String?): Flow<PagingData<PlaceEntity>>
public fun getRecentSearchPlaceList(): Flow<PagingData<PlaceEntity>>
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,28 @@ public class GetPlaceListUseCase @Inject constructor(
}
}

@Singleton
public class GetSearchPlaceListUseCase @Inject constructor(
private val repository: PlaceRepository,
) {
public operator fun invoke(query: String? = null): Flow<PagingData<PlaceEntity>> {
return if (query.isNullOrEmpty()) {
repository.getRecentSearchPlaceList()
} else {
repository.getPlaceList(search = query)
}
}
}

@Singleton
public class GetRecentSearchPlaceListUseCase @Inject constructor(
private val repository: PlaceRepository,
) {
public operator fun invoke(): Flow<PagingData<PlaceEntity>> {
return repository.getRecentSearchPlaceList()
}
}

@Singleton
public class UpsertPlaceUseCase @Inject constructor(
private val repository: PlaceRepository,
Expand Down Expand Up @@ -63,12 +85,3 @@ public class DeleteRecentSearchPlaceUseCase @Inject constructor(
repository.deleteRecentSearchPlace(placeEntity)
}
}

@Singleton
public class GetRecentSearchPlaceListUseCase @Inject constructor(
private val repository: PlaceRepository,
) {
public operator fun invoke(name: String? = null): Flow<PagingData<PlaceEntity>> {
return repository.getRecentSearchPlaceList(name)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ package us.wedemy.eggeum.android.main.ui.adapter
import android.view.ViewGroup
import us.wedemy.eggeum.android.common.extension.layoutInflater
import us.wedemy.eggeum.android.common.ui.BaseRecyclerViewAdapter
import us.wedemy.eggeum.android.common.ui.BaseViewHolder
import us.wedemy.eggeum.android.domain.model.place.PlaceEntity
import us.wedemy.eggeum.android.main.databinding.ItemNewCafeBinding
import us.wedemy.eggeum.android.main.ui.adapter.listener.SearchCafeClickListener
Expand All @@ -19,5 +20,13 @@ class NewCafeAdapter(private val clickListener: SearchCafeClickListener) :
BaseRecyclerViewAdapter<PlaceEntity, ItemNewCafeBinding>() {

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) =
NewCafeViewHolder(ItemNewCafeBinding.inflate(parent.context.layoutInflater, parent, false), clickListener)
NewCafeViewHolder(ItemNewCafeBinding.inflate(parent.context.layoutInflater, parent, false))

override fun onBindViewHolder(holder: BaseViewHolder<PlaceEntity, ItemNewCafeBinding>, position: Int) {
super.onBindViewHolder(holder, position)
val cafeItem = items[position]
holder.itemView.setOnClickListener {
clickListener.onItemClick(cafeItem)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,15 @@ class SearchCafeAdapter(private val clickListener: SearchCafeClickListener? = nu
PagingDataAdapter<PlaceEntity, SearchCafeViewHolder>(PlaceEntityDiffCallback) {

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) =
SearchCafeViewHolder(
ItemSearchCafeLocationBinding.inflate(LayoutInflater.from(parent.context), parent, false),
clickListener,
)
SearchCafeViewHolder(ItemSearchCafeLocationBinding.inflate(LayoutInflater.from(parent.context), parent, false))

override fun onBindViewHolder(holder: SearchCafeViewHolder, position: Int) {
val cafeItem = getItem(position)
cafeItem?.let { cafe ->
holder.bind(cafe)
holder.itemView.setOnClickListener {
clickListener?.onItemClick(cafeItem)
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@

package us.wedemy.eggeum.android.main.ui.adapter.listener

import us.wedemy.eggeum.android.domain.model.place.PlaceEntity

interface SearchCafeClickListener {
fun onItemClick(position: Int)
fun onItemClick(item: PlaceEntity)
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,8 @@ package us.wedemy.eggeum.android.main.ui.adapter.viewholder
import us.wedemy.eggeum.android.common.ui.BaseViewHolder
import us.wedemy.eggeum.android.domain.model.place.PlaceEntity
import us.wedemy.eggeum.android.main.databinding.ItemNewCafeBinding
import us.wedemy.eggeum.android.main.ui.adapter.listener.SearchCafeClickListener

class NewCafeViewHolder(
binding: ItemNewCafeBinding,
clickListener: SearchCafeClickListener? = null,
) : BaseViewHolder<PlaceEntity, ItemNewCafeBinding>(binding) {

init {
binding.root.setOnClickListener {
clickListener?.onItemClick(adapterPosition)
}
}
class NewCafeViewHolder(binding: ItemNewCafeBinding) : BaseViewHolder<PlaceEntity, ItemNewCafeBinding>(binding) {

override fun bind(item: PlaceEntity) {
binding.apply {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,9 @@ package us.wedemy.eggeum.android.main.ui.adapter.viewholder
import us.wedemy.eggeum.android.common.ui.BaseViewHolder
import us.wedemy.eggeum.android.domain.model.place.PlaceEntity
import us.wedemy.eggeum.android.main.databinding.ItemSearchCafeLocationBinding
import us.wedemy.eggeum.android.main.ui.adapter.listener.SearchCafeClickListener

class SearchCafeViewHolder(
binding: ItemSearchCafeLocationBinding,
clickListener: SearchCafeClickListener? = null,
) : BaseViewHolder<PlaceEntity, ItemSearchCafeLocationBinding>(binding) {

init {
binding.root.setOnClickListener {
clickListener?.onItemClick(adapterPosition)
}
}
class SearchCafeViewHolder(binding: ItemSearchCafeLocationBinding) :
BaseViewHolder<PlaceEntity, ItemSearchCafeLocationBinding>(binding) {

override fun bind(item: PlaceEntity) {
binding.tvCafeSearchLocation.text = item.name
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ package us.wedemy.eggeum.android.main.ui.home

import android.os.Bundle
import android.view.View
import android.widget.Toast
import androidx.fragment.app.viewModels
import androidx.paging.LoadState
import com.google.android.material.tabs.TabLayout
Expand All @@ -21,6 +22,7 @@ import us.wedemy.eggeum.android.common.extension.repeatOnStarted
import us.wedemy.eggeum.android.common.ui.BaseFragment
import us.wedemy.eggeum.android.common.util.HorizontalSpacingItemDecoration
import us.wedemy.eggeum.android.design.R
import us.wedemy.eggeum.android.domain.model.place.PlaceEntity
import us.wedemy.eggeum.android.main.databinding.FragmentHomeBinding
import us.wedemy.eggeum.android.main.ui.adapter.SearchCafeAdapter
import us.wedemy.eggeum.android.main.ui.adapter.NewCafeAdapter
Expand All @@ -40,8 +42,8 @@ class HomeFragment : BaseFragment<FragmentHomeBinding>() {
private val newCafeAdapter by lazy {
NewCafeAdapter(
object : SearchCafeClickListener {
override fun onItemClick(position: Int) {
// TODO 화면 전환 클릭 이벤트 리스터 구현
override fun onItemClick(item: PlaceEntity) {
Toast.makeText(requireContext(), "${item.name}을 선택했습니다.", Toast.LENGTH_SHORT).show()
}
},
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import android.os.Bundle
import android.view.View
import android.widget.Toast
import androidx.fragment.app.viewModels
import androidx.navigation.fragment.findNavController
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.launch
Expand All @@ -19,6 +20,7 @@ import us.wedemy.eggeum.android.common.extension.repeatOnStarted
import us.wedemy.eggeum.android.common.extension.textChangesAsFlow
import us.wedemy.eggeum.android.common.ui.BaseFragment
import us.wedemy.eggeum.android.design.R
import us.wedemy.eggeum.android.domain.model.place.PlaceEntity
import us.wedemy.eggeum.android.main.databinding.FragmentSearchCafeBinding
import us.wedemy.eggeum.android.main.ui.adapter.SearchCafeAdapter
import us.wedemy.eggeum.android.main.ui.adapter.listener.SearchCafeClickListener
Expand All @@ -33,8 +35,12 @@ class SearchCafeFragment : BaseFragment<FragmentSearchCafeBinding>() {
private val searchCafeAdapter by lazy {
SearchCafeAdapter(
object : SearchCafeClickListener {
override fun onItemClick(position: Int) {
Toast.makeText(requireContext(), "${position}번째 장소를 저장했습니다.", Toast.LENGTH_SHORT).show()
override fun onItemClick(item: PlaceEntity) {
Toast.makeText(requireContext(), "${item.name}을 저장했습니다.", Toast.LENGTH_SHORT).show()
viewModel.insertRecentSearchPlace(item)

// val action = SearchCafeFragmentDirections.actionFragmentSearchCafeToFragmentCafeDetail()
// findNavController().safeNavigate(action)
}
},
)
Expand All @@ -43,10 +49,8 @@ class SearchCafeFragment : BaseFragment<FragmentSearchCafeBinding>() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
initView()
initListener()
initObserver()

// val action = SearchCafeFragmentDirections.actionFragmentSearchCafeToFragmentCafeDetail()
// findNavController().safeNavigate(action)
}

private fun initView() {
Expand All @@ -57,6 +61,14 @@ class SearchCafeFragment : BaseFragment<FragmentSearchCafeBinding>() {
}
}

private fun initListener() {
binding.tilSearchCafe.setStartIconOnClickListener {
if (!findNavController().navigateUp()) {
requireActivity().finish()
}
}
}

private fun initObserver() {
repeatOnStarted {
launch {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,44 +19,36 @@ import kotlinx.coroutines.FlowPreview
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.debounce
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.filterNotNull
import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.launch
import us.wedemy.eggeum.android.common.util.SaveableMutableStateFlow
import us.wedemy.eggeum.android.common.util.getMutableStateFlow
import us.wedemy.eggeum.android.domain.model.place.PlaceEntity
import us.wedemy.eggeum.android.domain.usecase.DeleteRecentSearchPlaceUseCase
import us.wedemy.eggeum.android.domain.usecase.GetPlaceListUseCase
import us.wedemy.eggeum.android.domain.usecase.GetRecentSearchPlaceListUseCase
import us.wedemy.eggeum.android.domain.usecase.GetSearchPlaceListUseCase
import us.wedemy.eggeum.android.domain.usecase.InsertRecentSearchPlaceUseCase

@HiltViewModel
class SearchCafeViewModel @Inject constructor(
getPlaceListUseCase: GetPlaceListUseCase,
getRecentSearchPlaceListUseCase: GetRecentSearchPlaceListUseCase,
getSearchPlaceListUseCase: GetSearchPlaceListUseCase,
private val insertRecentSearchPlaceUseCase: InsertRecentSearchPlaceUseCase,
private val deleteRecentSearchPlaceUseCase: DeleteRecentSearchPlaceUseCase,
savedStateHandle: SavedStateHandle,
) : ViewModel() {
val recentSearchPlaceList = getRecentSearchPlaceListUseCase().cachedIn(viewModelScope)

private val _searchQuery: SaveableMutableStateFlow<String> =
savedStateHandle.getMutableStateFlow(KEY_CAFE_NAME, "")
val searchQuery = _searchQuery.asStateFlow()

@OptIn(FlowPreview::class)
val debouncedSearchQuery: Flow<String?> = searchQuery
.debounce(SEARCH_TIME_DELAY)
.filter { it.isNotEmpty() }
.distinctUntilChanged()

@OptIn(ExperimentalCoroutinesApi::class)
val searchPlaceList: Flow<PagingData<PlaceEntity>> =
debouncedSearchQuery.filterNotNull()
.flatMapLatest { query ->
getPlaceListUseCase(query)
}
debouncedSearchQuery.flatMapLatest { query ->
getSearchPlaceListUseCase(query)
}
.cachedIn(viewModelScope)

fun setSearchQuery(query: String) {
Expand Down