Skip to content

Commit

Permalink
[FEAT/#32] 서버 통신 코드 1차적 작성
Browse files Browse the repository at this point in the history
  • Loading branch information
0zlrlo committed Jun 28, 2023
1 parent 69429cf commit 833de04
Show file tree
Hide file tree
Showing 5 changed files with 123 additions and 70 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@ import com.release.keyneez.data.entity.response.wrapper.BaseResponse

interface ContentRepository {
suspend fun getSearch(keyword: String): Result<BaseResponse<List<ResponseGetSearchResultDto>>>
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,14 @@ import android.view.inputmethod.EditorInfo
import android.widget.TextView
import androidx.activity.viewModels
import com.release.keyneez.R
import com.release.keyneez.data.entity.response.ResponseGetSearchResultDto
import com.release.keyneez.databinding.ActivitySearchBinding
import com.release.keyneez.util.UiState
import com.release.keyneez.util.binding.BindingActivity
import com.release.keyneez.util.extension.hideKeyboard
import com.release.keyneez.util.extension.setOnSingleClickListener
import com.release.keyneez.util.extension.showSnackbar
import com.release.keyneez.util.extension.showToast
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Job
Expand All @@ -20,16 +25,56 @@ import kotlinx.coroutines.runBlocking

@AndroidEntryPoint
class SearchActivity : BindingActivity<ActivitySearchBinding>(R.layout.activity_search) {
private var searchAdapter: SearchAdapter? = null
private var searchAdapter: SearchAdapter?= null
private val viewModel: SearchViewModel by viewModels()

override fun onCreate(savedInstanceState: Bundle?) {
binding.vm = viewModel
super.onCreate(savedInstanceState)
binding.vm = viewModel
initSearchBtnClickListener()
initSearchAdapter()
initBackBtnClickListener()
initSearchBtnKeyListener()
initHideKeyboard()
setupSearchState()
}

private fun setupSearchState() {
viewModel.stateMessage.observe(this) {
when (it) {
is UiState.Success -> setupSearchActivityList()
is UiState.Failure -> showSnackbar(
binding.root,
getString(R.string.msg_search_null)
)

is UiState.Error -> showSnackbar(
binding.root,
getString(R.string.msg_server_error)
)
}
}
}

private fun initSearchAdapter() {
searchAdapter = SearchAdapter()
binding.rvSearchResultContent.adapter = searchAdapter
}

private fun setupSearchActivityList() {
viewModel.searchList.observe(this) { searchList ->
searchAdapter?.submitList(searchList)
binding.tvSearchCount.text = searchList.size.toString()
if (searchList.size == 0) {
showToast(getString(R.string.search_no_result))
}
}
}

private fun initHideKeyboard() {
binding.layoutSearch.setOnSingleClickListener {
hideKeyboard()
}
}

private fun initSearchBtnKeyListener() {
Expand All @@ -46,7 +91,7 @@ class SearchActivity : BindingActivity<ActivitySearchBinding>(R.layout.activity_
private fun initSearchBtnClickListener() {
binding.btnSearch.setOnSingleClickListener {
setupSearchActivityList()
viewModel.activityList
viewModel.getSearchPostData()
}
}

Expand Down Expand Up @@ -81,17 +126,6 @@ class SearchActivity : BindingActivity<ActivitySearchBinding>(R.layout.activity_
}
}

private fun initSearchAdapter() {
searchAdapter = SearchAdapter()
binding.rvSearchResultContent.adapter = searchAdapter
}

private fun setupSearchActivityList() {
viewModel.activityList.observe(this) { activityList ->
searchAdapter?.submitList(activityList)
}
}

private fun initBackBtnClickListener() {
binding.btnSearchCancel.setOnSingleClickListener {
finish()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,13 @@ import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
import coil.load
import com.release.keyneez.data.entity.response.ResponseGetSearchResultDto
import com.release.keyneez.databinding.ItemSearchContentBinding
import com.release.keyneez.domain.model.Activity
import com.release.keyneez.util.DiffCallback

class SearchAdapter : ListAdapter<Activity, RecyclerView.ViewHolder>(diffUtil) {
class SearchAdapter : ListAdapter<ResponseGetSearchResultDto, RecyclerView.ViewHolder>(diffUtil) {
var data = listOf<ResponseGetSearchResultDto>()
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
return SearchViewHolder(
ItemSearchContentBinding.inflate(
Expand All @@ -20,21 +21,19 @@ class SearchAdapter : ListAdapter<Activity, RecyclerView.ViewHolder>(diffUtil) {
)
}

override fun getItemCount(): Int = data.size
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
if (holder is SearchViewHolder) holder.bind(getItem(position))
if (holder is SearchViewHolder) holder.setSearch(getItem(position))
}

// override fun getItemCount(): Int = data.size
class SearchViewHolder(private val binding: ItemSearchContentBinding) :
RecyclerView.ViewHolder(binding.root) {
fun bind(item: Activity) {
with(binding) {
ivSearchBackground.load(item.background)
tvSearchCategory.text = item.category
tvSearchContentTitle.text = item.title
tvSearchDate.text = item.date
// TODO : root.setOnSingleClickListener 구현
}
fun setSearch(search: Activity) {
binding.data = search
}
// 여기 코드 더 적기
binding.root.setOnClickListener {
// 디테일뷰와 연결하기
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,53 +3,69 @@ package com.release.keyneez.presentation.main.search
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import com.release.keyneez.R
import com.release.keyneez.domain.model.Activity
import androidx.lifecycle.viewModelScope
import com.release.keyneez.data.entity.response.ResponseGetSearchResultDto
import com.release.keyneez.data.repository.ContentRepository
import com.release.keyneez.util.UiState
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.launch
import retrofit2.HttpException
import timber.log.Timber
import javax.inject.Inject

class SearchViewModel : ViewModel() {
private val _activityList = MutableLiveData<List<Activity>>()
val activityList: LiveData<List<Activity>>
get() = _activityList
@HiltViewModel
class SearchViewModel @Inject constructor(
private val contentRepository: ContentRepository
) : ViewModel() {
private val _searchList = MutableLiveData<List<ResponseGetSearchResultDto>>()
val searchList: LiveData<List<ResponseGetSearchResultDto>>
get() = _searchList

private val _stateMessage = MutableLiveData<UiState>()
val stateMessage: LiveData<UiState>
get() = _stateMessage

private val _saveState = MutableLiveData<Boolean>()
val saveState: LiveData<Boolean>
get() = _saveState

val key = MutableLiveData("")
init {
getSearchActivityList()
getSearchPostData()
}

fun getSearchPostData() {
viewModelScope.launch {
contentRepository.getSearch(key.value.toString()).onSuccess { response ->
if (response.data == null) {
Timber.d("GET SEARCH LIST IS NULL")
_stateMessage.value = UiState.Failure(SEARCH_NULL_CODE)
return@onSuccess
}
Timber.d("GET SEARCH LIST SUCCESS")
Timber.d("response : $response")

_searchList.value = response.data!!
_stateMessage.value = UiState.Success
}.onFailure {
Timber.e("GET SEARCH LIST SERVER ERROR")
Timber.e("message : ${it.message}")
if (it is HttpException) {
Timber.e("response : $it")
when (it.code()) {
SEARCH_NO_POST_CODE ->
_stateMessage.value =
UiState.Failure(SEARCH_NO_POST_CODE)

else -> _stateMessage.value = UiState.Error
}
} else _stateMessage.value = UiState.Error
}
}
}

private fun getSearchActivityList() {
val mainList = listOf(
Activity(
id = 1,
background = R.drawable.img_explore_background,
title = "행주산성\n맛집 투어",
category = "진로",
date = "%s-%s",
liked = true
),
Activity(
id = 1,
background = R.drawable.img_explore_background,
title = "행주산성\n맛집 투어",
category = "진로",
date = "%s-%s",
liked = true
),
Activity(
id = 1,
background = R.drawable.img_explore_background,
title = "행주산성\n맛집 투어",
category = "진로",
date = "%s-%s",
liked = true
),
Activity(
id = 1,
background = R.drawable.img_explore_background,
title = "행주산성\n맛집 투어",
category = "진로",
date = "%s-%s",
liked = true
)
)
_activityList.value = mainList
companion object {
const val SEARCH_NULL_CODE = 100
const val SEARCH_NO_POST_CODE = 404
}
}
4 changes: 4 additions & 0 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,10 @@
<string name="like_delete_btn">삭제하기</string>
<string name="like_delete_complete">삭제 완료</string>

<!-- uiState -->
<string name="msg_search_null">검색결과가 없습니다.</string>
<string name="msg_server_error">네트워크 연결에 실패했습니다.</string>

<!-- TODO: Remove or change this placeholder text -->
<string name="hello_blank_fragment">Hello blank fragment</string>

Expand Down

0 comments on commit 833de04

Please sign in to comment.