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

그룹 검색 기능 일부 구현 #96

Merged
merged 2 commits into from
Mar 15, 2024
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
8 changes: 8 additions & 0 deletions data/src/main/java/org/gdsc/data/database/GroupPaging.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package org.gdsc.data.database

import org.gdsc.domain.model.GroupPreview

data class GroupPaging(
val groupList: List<GroupPreview>,
val page: Page
)
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
package org.gdsc.data.datasource

import org.gdsc.domain.model.GroupPreview
import org.gdsc.domain.model.response.Group


interface GroupDataSource {
suspend fun getMyGroups(): List<Group>

suspend fun selectGroup(groupId: Int): String

suspend fun searchGroup(keyword: String, limitCount: Int): List<GroupPreview>
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
package org.gdsc.data.datasource

import android.util.Log
import org.gdsc.data.database.GroupPaging
import org.gdsc.data.network.GroupAPI
import org.gdsc.domain.model.GroupPreview
import org.gdsc.domain.model.request.GroupSearchRequest
import org.gdsc.domain.model.response.Group
import javax.inject.Inject

Expand Down Expand Up @@ -29,4 +32,8 @@ class GroupDataSourceImpl @Inject constructor(
}
return ""
}

override suspend fun searchGroup(keyword: String, limitCount: Int): List<GroupPreview> {
return groupAPI.searchGroup(GroupSearchRequest(keyword)).data.groupList.take(limitCount)
}
}
7 changes: 7 additions & 0 deletions data/src/main/java/org/gdsc/data/network/GroupAPI.kt
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
package org.gdsc.data.network

import org.gdsc.data.database.GroupPaging
import org.gdsc.data.model.Response
import org.gdsc.domain.model.request.GroupSearchRequest
import org.gdsc.domain.model.response.Group
import retrofit2.http.Body
import retrofit2.http.GET
import retrofit2.http.POST
import retrofit2.http.Path
Expand All @@ -16,4 +19,8 @@ interface GroupAPI {
@Path("groupId") groupId: Int
): Response<String>

@POST("api/v1/group/search")
suspend fun searchGroup(
@Body groupSearchRequest: GroupSearchRequest
): Response<GroupPaging>
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package org.gdsc.data.repository

import org.gdsc.data.datasource.GroupDataSource
import org.gdsc.domain.model.GroupPreview
import org.gdsc.domain.model.response.Group
import org.gdsc.domain.repository.GroupRepository
import javax.inject.Inject
Expand All @@ -15,4 +16,8 @@ class GroupRepositoryImpl @Inject constructor(
override suspend fun selectGroup(groupId: Int): String {
return groupDataSource.selectGroup(groupId)
}

override suspend fun searchGroup(keyword: String, limitCount: Int): List<GroupPreview> {
return groupDataSource.searchGroup(keyword, limitCount)
}
}
9 changes: 9 additions & 0 deletions domain/src/main/java/org/gdsc/domain/model/GroupPreview.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package org.gdsc.domain.model

data class GroupPreview(
val groupId: Int,
val groupIntroduce: String,
val groupName: String,
val memberCnt: Int,
val restaurantCnt: Int
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package org.gdsc.domain.model.request

data class GroupSearchRequest(
val keyword: String
)
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
package org.gdsc.domain.repository

import org.gdsc.domain.model.GroupPreview
import org.gdsc.domain.model.response.Group

interface GroupRepository {
suspend fun getMyGroups(): List<Group>

suspend fun selectGroup(groupId: Int): String

suspend fun searchGroup(keyword: String, limitCount: Int): List<GroupPreview>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package org.gdsc.domain.usecase

import org.gdsc.domain.repository.GroupRepository
import javax.inject.Inject

class GetGroupBySearchWithLimitCountUseCase @Inject constructor(
private val groupRepository: GroupRepository
) {
suspend operator fun invoke(keyword: String, limitCount: Int) = groupRepository.searchGroup(keyword, limitCount)
}
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ class AllSearchFragment : Fragment() {
binding.cgRecentSearch.removeAllViews()
keywordList.forEach {
if (it.isNotBlank()) {
binding.tvRecentSearch.visibility = View.VISIBLE
binding.tvDelete.visibility = View.VISIBLE
binding.cgRecentSearch.addView(
newChip(it,
{ keyword ->
Expand All @@ -64,6 +66,9 @@ class AllSearchFragment : Fragment() {
navigateToResultPage()
}
)
} else {
binding.tvRecentSearch.visibility = View.GONE
binding.tvDelete.visibility = View.GONE
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,10 @@ import kotlinx.coroutines.launch
import org.gdsc.domain.DrinkPossibility
import org.gdsc.domain.FoodCategory
import org.gdsc.domain.SortType
import org.gdsc.domain.model.GroupPreview
import org.gdsc.domain.model.Location
import org.gdsc.domain.model.RegisteredRestaurant
import org.gdsc.domain.usecase.GetGroupBySearchWithLimitCountUseCase
import org.gdsc.domain.usecase.GetRestaurantBySearchUseCase
import org.gdsc.domain.usecase.GetRestaurantBySearchWithLimitCountUseCase
import org.gdsc.domain.usecase.user.DeleteSearchedKeywordUseCase
Expand All @@ -32,41 +34,12 @@ class AllSearchViewModel @Inject constructor(
private val updateSearchedKeywordUseCase: UpdateSearchedKeywordUseCase,
private val deleteSearchedKeywordUseCase: DeleteSearchedKeywordUseCase,
private val initSearchedKeywordUseCase: InitSearchedKeywordUseCase,
private val getRestaurantBySearchWithLimitCountUseCase: GetRestaurantBySearchWithLimitCountUseCase
private val getRestaurantBySearchWithLimitCountUseCase: GetRestaurantBySearchWithLimitCountUseCase,
private val getGroupBySearchWithLimitCountUseCase: GetGroupBySearchWithLimitCountUseCase
) : ViewModel() {

init {

viewModelScope.launch {
val location = locationManager.getCurrentLocation()

if (location == null) {
_searchedRestaurantPreviewState.value = emptyList()
} else {

val userLoc = Location(location.longitude.toString(), location.latitude.toString())

_searchedRestaurantPreviewState.value =
getRestaurantBySearchWithLimitCountUseCase(searchKeyword.value, userLoc, 3)
}

}

viewModelScope.launch {
val location = locationManager.getCurrentLocation()

if (location == null) {
_searchedRestaurantState.value = PagingData.empty()
} else {
val userLoc = Location(location.longitude.toString(), location.latitude.toString())

getRestaurantBySearchUseCase(searchKeyword.value, userLoc).distinctUntilChanged()
.collect {
_searchedRestaurantState.value = it
}
}
}

viewModelScope.launch {
val keywords = getSearchedKeywordsUseCase()
if (keywords.isNotEmpty()) {
Expand Down Expand Up @@ -101,6 +74,12 @@ class AllSearchViewModel @Inject constructor(
val searchedRestaurantPreviewState: StateFlow<List<RegisteredRestaurant>>
get() = _searchedRestaurantPreviewState

private var _searchedGroupPreviewState =
MutableStateFlow<List<GroupPreview>>(emptyList())

val searchedGroupPreviewState: StateFlow<List<GroupPreview>>
get() = _searchedGroupPreviewState


private var _searchedKeywordsState = MutableStateFlow<List<String>>(emptyList())
val searchedKeywordsState: StateFlow<List<String>>
Expand Down Expand Up @@ -140,5 +119,46 @@ class AllSearchViewModel @Inject constructor(
}
}

fun searchRestaurantPreviewWithKeyword() {
viewModelScope.launch {
val location = locationManager.getCurrentLocation()

if (location == null) {
_searchedRestaurantPreviewState.value = emptyList()
} else {

val userLoc = Location(location.longitude.toString(), location.latitude.toString())

_searchedRestaurantPreviewState.value =
getRestaurantBySearchWithLimitCountUseCase(searchKeyword.value, userLoc, 3)
}

}
}

fun searchRestaurantWithKeyword() {
viewModelScope.launch {
val location = locationManager.getCurrentLocation()

if (location == null) {
_searchedRestaurantState.value = PagingData.empty()
} else {
val userLoc = Location(location.longitude.toString(), location.latitude.toString())

getRestaurantBySearchUseCase(searchKeyword.value, userLoc).distinctUntilChanged()
.collect {
_searchedRestaurantState.value = it
}
}
}
}

fun searchGroupPreviewWithKeyword() {
viewModelScope.launch {
val result = getGroupBySearchWithLimitCountUseCase(searchKeyword.value, 3)
_searchedGroupPreviewState.value = result
}
}


}
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ class SearchCategoryAllFragment(
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)

viewModel.searchRestaurantPreviewWithKeyword()
viewModel.searchGroupPreviewWithKeyword()

binding.restaurantRecyclerView.adapter = searchCategoryRestaurantPreviewAdapter
binding.restaurantRecyclerView.layoutManager = LinearLayoutManager(requireContext())

Expand All @@ -68,44 +71,12 @@ class SearchCategoryAllFragment(
}
}

// Todo: Real APi
searchCategoryGroupPreviewAdapter.submitList(
listOf(
GroupInfo(
"https://avatars.githubusercontent.com/u/58663494?v=4",
1,
"햄버거 먹으러 갈 사람 여기여기 모여라",
"버거 대마왕",
"https://avatars.githubusercontent.com/u/58663494?v=4",
false,
(0 .. 500).shuffled().first(),
false,
(0 .. 500).shuffled().first()
),
GroupInfo(
"https://avatars.githubusercontent.com/u/58663494?v=4",
2,
"햄버거 먹으러 갈 사람 여기여기 모여라",
"버거 대마왕",
"https://avatars.githubusercontent.com/u/58663494?v=4",
false,
(0 .. 500).shuffled().first(),
false,
(0 .. 500).shuffled().first()
),
GroupInfo(
"https://avatars.githubusercontent.com/u/58663494?v=4",
3,
"햄버거 먹으러 갈 사람 여기여기 모여라",
"버거 대마왕",
"https://avatars.githubusercontent.com/u/58663494?v=4",
false,
(0 .. 500).shuffled().first(),
false,
(0 .. 500).shuffled().first()
),
)
)
repeatWhenUiStarted {
viewModel.searchedGroupPreviewState.collect {
searchCategoryGroupPreviewAdapter.submitList(it)
}
}

}

override fun onDestroyView() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,13 +42,15 @@ class SearchCategoryRestaurantFragment(
setSpinners()

viewModel.setSearchKeyword(searchKeyword)
viewModel.searchRestaurantWithKeyword()

binding.restaurantRecyclerView.adapter = searchCategoryRestaurantAdapter
binding.restaurantRecyclerView.layoutManager = LinearLayoutManager(requireContext())

}

private fun observeState() {

repeatWhenUiStarted {
viewModel.searchedRestaurantState.collect {
searchCategoryRestaurantAdapter.submitData(it)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,27 +6,27 @@ import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
import com.bumptech.glide.Glide
import org.gdsc.domain.model.GroupInfo
import org.gdsc.domain.model.GroupPreview
import org.gdsc.presentation.R
import org.gdsc.presentation.databinding.ItemSearchGroupBinding

class SearchCategoryGroupPreviewAdapter
: ListAdapter<GroupInfo, SearchCategoryGroupPreviewAdapter.GroupWithSearchPreviewViewHolder>(
: ListAdapter<GroupPreview, SearchCategoryGroupPreviewAdapter.GroupWithSearchPreviewViewHolder>(
diffCallback
) {

companion object {
val diffCallback = object : DiffUtil.ItemCallback<GroupInfo>() {
val diffCallback = object : DiffUtil.ItemCallback<GroupPreview>() {
override fun areItemsTheSame(
oldItem: GroupInfo,
newItem: GroupInfo
oldItem: GroupPreview,
newItem: GroupPreview
): Boolean {
return oldItem == newItem
}

override fun areContentsTheSame(
oldItem: GroupInfo,
newItem: GroupInfo
oldItem: GroupPreview,
newItem: GroupPreview
): Boolean {
return oldItem == newItem
}
Expand All @@ -36,10 +36,10 @@ class SearchCategoryGroupPreviewAdapter
class GroupWithSearchPreviewViewHolder(
private val binding: ItemSearchGroupBinding,
): RecyclerView.ViewHolder(binding.root) {
fun bind(item: GroupInfo) {
fun bind(item: GroupPreview) {
binding.run {
Glide.with(itemView.context)
.load(item.groupProfileImageUrl)
.load("https://picsum.photos/200")
.placeholder(R.drawable.base_profile_image)
.into(ivGroupImage)

Expand Down
Loading