Skip to content

Commit

Permalink
#23 [feat] 서버통신
Browse files Browse the repository at this point in the history
  • Loading branch information
wateralsie committed May 26, 2023
1 parent ec4acf8 commit 22b0de0
Show file tree
Hide file tree
Showing 10 changed files with 356 additions and 2 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@

import androidx.datastore.preferences.protobuf.Api
import com.jakewharton.retrofit2.converter.kotlinx.serialization.asConverterFactory
import com.sumin.android.carrot_aos.BuildConfig
import com.sumin.android.carrot_aos.data.service.ChatService
import com.sumin.android.carrot_aos.data.service.HomeService
import com.sumin.android.carrot_aos.data.service.ReviewService
import com.sumin.android.carrot_aos.data.service.HeartService
import com.sumin.android.carrot_aos.data.service.RecommendationService
Expand Down Expand Up @@ -42,6 +44,7 @@ object SaleServicePool {
}

object ServicePool {
val homeService = ApiFactory.create<HomeService>()
val chatService = ApiFactory.create<ChatService>()
val UserIdService = ApiFactory.create<UserIdService>()
val reviewService = ApiFactory.create<ReviewService>()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package com.sumin.android.carrot_aos.data.model.response

import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable

@Serializable
data class HomeResponse(
@SerialName("status")
val status: Int,
@SerialName("message")
val message: String,
@SerialName("data")
val data: List<HomeData>,
) {
@Serializable
data class HomeData(
@SerialName("saleId")
val saleId: Int,
@SerialName("title")
val title: String,
@SerialName("saleImgUrl")
val saleImgUrl: String,
@SerialName("location")
val location: String,
@SerialName("time")
val time: String,
@SerialName("isUpdated")
val isUpdated: Boolean,
@SerialName("price")
val price: Int,
@SerialName("isDiscount")
val isDiscount: Boolean,
@SerialName("likeCount")
val likeCount: Int,
@SerialName("isCheckLike")
val isCheckLike: Boolean
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.sumin.android.carrot_aos.data.service

import com.sumin.android.carrot_aos.data.model.response.HomeResponse
import retrofit2.Call
import retrofit2.http.GET

interface HomeService {
@GET("/sale")
fun getHomeList(): Call<HomeResponse>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.sumin.android.carrot_aos.presentation

sealed interface UiState {
object Success: UiState
object Failure: UiState
object Error: UiState
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
package com.sumin.android.carrot_aos.presentation.home

import android.annotation.SuppressLint
import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
import coil.load
import com.sumin.android.carrot_aos.data.model.response.HomeResponse
import com.sumin.android.carrot_aos.databinding.ItemHomeBinding
import java.text.DecimalFormat

class HomeAdapter(
private val navigateToSale: (Int, String) -> Unit,
context: Context
) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
private val inflater by lazy { LayoutInflater.from(context) }
private var homeList: List<HomeResponse.HomeData> = emptyList()

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
val binding = ItemHomeBinding.inflate(inflater, parent, false)
return HomeViewHolder(navigateToSale, binding)
}

override fun getItemCount() = homeList.size

override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
if (holder is HomeViewHolder) holder.onBind(homeList[position])
}

@SuppressLint("NotifyDataSetChanged")
fun setHomeList(list: List<HomeResponse.HomeData>) {
this.homeList = list.toList()
notifyDataSetChanged()
}
}

//class HomeAdapter(
// private val navigateToSale: (Int, String) -> Unit,
// context: Context
//) : ListAdapter<HomeResponse.HomeData, RecyclerView.ViewHolder>(diffUtil) {
// private val inflater by lazy { LayoutInflater.from(context) }
//
// override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
// val binding = ItemHomeBinding.inflate(inflater, parent, false)
// return HomeViewHolder(navigateToSale, binding)
// }
//
// override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
// if (holder is HomeViewHolder) holder.onBind(currentList[position])
// }
//
// companion object {
// val diffUtil = object : DiffUtil.ItemCallback<HomeResponse.HomeData>() {
// override fun areItemsTheSame(
// oldItem: HomeResponse.HomeData,
// newItem: HomeResponse.HomeData,
// ): Boolean {
// return oldItem.saleId == newItem.saleId
// }
//
// override fun areContentsTheSame(
// oldItem: HomeResponse.HomeData,
// newItem: HomeResponse.HomeData,
// ): Boolean {
// return oldItem == newItem
// }
// }
// }
//}

class HomeViewHolder(
private val navigateToSale: (Int, String) -> Unit,
private val binding: ItemHomeBinding,
) : RecyclerView.ViewHolder(binding.root) {
fun onBind(data: HomeResponse.HomeData) {
binding.ivHomeItem.load(data.saleImgUrl)
binding.tvHomeItemContent.text = data.title
binding.tvHomeItemWhere.text = data.location
binding.tvHomeItemReupload.visibility = toggleVisibility(data.isUpdated)
binding.tvHomeItemTime.text = data.time
binding.tvHomeItemPrice.text = formatPrice(data.price)
binding.ivHomeItemLike.visibility = toggleVisibility(data.likeCount == 0)
binding.ivHomeItemLike.isActivated = data.isCheckLike
binding.tvHomeItemLike.visibility = toggleVisibility(data.likeCount == 0)
binding.tvHomeItemLike.text = data.likeCount.toString()
binding.ivHomeItemDown.visibility = toggleVisibility(data.isDiscount)
binding.tvHomeItemDown.visibility = toggleVisibility(data.isDiscount)
binding.layoutHomeItem.setOnClickListener {
navigateToSale(data.saleId, formatPrice(data.price))
}
}

private fun toggleVisibility(status: Boolean): Int {
return when (status) {
true -> View.VISIBLE
else -> View.GONE
}
}

private fun formatPrice(price: Int): String {
val priceFormat = DecimalFormat("#,###")
return "${priceFormat.format(price)}"
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,48 @@
package com.sumin.android.carrot_aos.presentation.home

import android.content.Intent
import android.os.Bundle
import android.view.View
import androidx.fragment.app.viewModels
import com.sumin.android.carrot_aos.R
import com.sumin.android.carrot_aos.databinding.FragmentHomeBinding
import com.sumin.android.carrot_aos.presentation.UiState
import com.sumin.android.carrot_aos.presentation.base.BindingFragment
import com.sumin.android.carrot_aos.presentation.sale.SaleActivity
import com.sumin.android.carrot_aos.util.extension.showSnackbar

class HomeFragment : BindingFragment<FragmentHomeBinding>(R.layout.fragment_home) {
private val viewModel by viewModels<HomeViewModel>()

}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
initRecyclerView()
}

private fun initRecyclerView() {
val adapter = HomeAdapter(::navigateToSaleWith, requireContext())
binding.rvHome.adapter = adapter
adapter.setHomeList(viewModel.homeList)
}

// private fun addObservers(adapter: HomeAdapter) {
// viewModel.homeResult.observe(viewLifecycleOwner) {
// adapter.submitList(it.data)
// }
// viewModel.result.observe(viewLifecycleOwner) {
// when(it) {
// UiState.Success -> binding.root.showSnackbar("성공")
// UiState.Failure -> binding.root.showSnackbar("실패")
// UiState.Error -> binding.root.showSnackbar("에러")
// }
// }
// }

private fun navigateToSaleWith(id: Int, price: String) {
val intent = Intent(requireContext(), SaleActivity::class.java).apply {
putExtra("itemId", id)
putExtra("itemPrice", price)
}
startActivity(intent)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
package com.sumin.android.carrot_aos.presentation.home

import androidx.lifecycle.ViewModel
import com.sumin.android.carrot_aos.data.model.response.HomeResponse

class HomeViewModel : ViewModel() {
val homeList = listOf(
HomeResponse.HomeData(
saleId = 1,
title = "동교동 이웃 dd님에게만 보이는 순간이동 포털이 열렸어요",
saleImgUrl = "https://carrotbucket32.s3.ap-northeast-2.amazonaws.com/e47bd937-6831-4561-b7fa-042399477606-sale1.webp",
location = "서강동",
time = "2023. 5. 19. 오후 2:52:58",
isUpdated = false,
price = 10000,
isDiscount = true,
likeCount = 0,
isCheckLike = false
),
HomeResponse.HomeData(
saleId = 2,
title = "동교동 이웃 dd님에게만 보이는 순간이동 포털이 열렸어요",
saleImgUrl = "https://carrotbucket32.s3.ap-northeast-2.amazonaws.com/e47bd937-6831-4561-b7fa-042399477606-sale1.webp",
location = "서강동",
time = "2023. 5. 19. 오후 2:52:58",
isUpdated = false,
price = 10000,
isDiscount = true,
likeCount = 0,
isCheckLike = false
),
HomeResponse.HomeData(
saleId = 3,
title = "동교동 이웃 dd님에게만 보이는 순간이동 포털이 열렸어요",
saleImgUrl = "https://carrotbucket32.s3.ap-northeast-2.amazonaws.com/e47bd937-6831-4561-b7fa-042399477606-sale1.webp",
location = "서강동",
time = "2023. 5. 19. 오후 2:52:58",
isUpdated = false,
price = 10000,
isDiscount = true,
likeCount = 0,
isCheckLike = false
),
HomeResponse.HomeData(
saleId = 4,
title = "동교동 이웃 dd님에게만 보이는 순간이동 포털이 열렸어요",
saleImgUrl = "https://carrotbucket32.s3.ap-northeast-2.amazonaws.com/e47bd937-6831-4561-b7fa-042399477606-sale1.webp",
location = "서강동",
time = "2023. 5. 19. 오후 2:52:58",
isUpdated = false,
price = 10000,
isDiscount = true,
likeCount = 0,
isCheckLike = false
),
HomeResponse.HomeData(
saleId = 5,
title = "동교동 이웃 dd님에게만 보이는 순간이동 포털이 열렸어요",
saleImgUrl = "https://carrotbucket32.s3.ap-northeast-2.amazonaws.com/e47bd937-6831-4561-b7fa-042399477606-sale1.webp",
location = "서강동",
time = "2023. 5. 19. 오후 2:52:58",
isUpdated = false,
price = 10000,
isDiscount = true,
likeCount = 0,
isCheckLike = false
),
HomeResponse.HomeData(
saleId = 6,
title = "동교동 이웃 dd님에게만 보이는 순간이동 포털이 열렸어요",
saleImgUrl = "https://carrotbucket32.s3.ap-northeast-2.amazonaws.com/e47bd937-6831-4561-b7fa-042399477606-sale1.webp",
location = "서강동",
time = "2023. 5. 19. 오후 2:52:58",
isUpdated = false,
price = 10000,
isDiscount = true,
likeCount = 0,
isCheckLike = false
),
HomeResponse.HomeData(
saleId = 7,
title = "동교동 이웃 dd님에게만 보이는 순간이동 포털이 열렸어요",
saleImgUrl = "https://carrotbucket32.s3.ap-northeast-2.amazonaws.com/e47bd937-6831-4561-b7fa-042399477606-sale1.webp",
location = "서강동",
time = "2023. 5. 19. 오후 2:52:58",
isUpdated = false,
price = 10000,
isDiscount = true,
likeCount = 0,
isCheckLike = false
),
HomeResponse.HomeData(
saleId = 8,
title = "동교동 이웃 dd님에게만 보이는 순간이동 포털이 열렸어요",
saleImgUrl = "https://carrotbucket32.s3.ap-northeast-2.amazonaws.com/e47bd937-6831-4561-b7fa-042399477606-sale1.webp",
location = "서강동",
time = "2023. 5. 19. 오후 2:52:58",
isUpdated = false,
price = 10000,
isDiscount = true,
likeCount = 0,
isCheckLike = false
),
)
// private val homeService = ServicePool.homeService
//
// private val _homeResult = MutableLiveData<HomeResponse>()
// val homeResult: LiveData<HomeResponse>
// get() = _homeResult
// private val _result = MutableLiveData<UiState>()
// val result: LiveData<UiState>
// get() = _result
//
// fun getHomeList() {
// homeService.getHomeList()
// .enqueue(object : Callback<HomeResponse> {
// override fun onResponse(
// call: Call<HomeResponse>,
// response: Response<HomeResponse>
// ) {
// if (response.isSuccessful) {
// _result.value = UiState.Success
// _homeResult.value = response.body()
// } else {
// _result.value = UiState.Failure
// }
// }
//
// override fun onFailure(call: Call<HomeResponse>, t: Throwable) {
// _result.value = UiState.Error
// }
//
// })
// }

}
5 changes: 5 additions & 0 deletions app/src/main/res/drawable/sel_home_item_like.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_activated="true" android:drawable="@drawable/ic_sale_heart_filled" />
<item android:state_activated="false" android:drawable="@drawable/ic_sale_heart_default" />
</selector>
7 changes: 7 additions & 0 deletions app/src/main/res/layout/fragment_home.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,13 @@
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">

<data>

<variable
name="vm"
type="com.sumin.android.carrot_aos.presentation.home.HomeViewModel" />
</data>

<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
Expand Down
Loading

0 comments on commit 22b0de0

Please sign in to comment.