Skip to content

Commit

Permalink
Merge pull request #349 from hyeeyoung/dev
Browse files Browse the repository at this point in the history
release 1.1.2
  • Loading branch information
youngjinc authored Nov 29, 2022
2 parents 52da9a8 + cbd7336 commit 6d17b1a
Show file tree
Hide file tree
Showing 13 changed files with 113 additions and 114 deletions.
2 changes: 1 addition & 1 deletion app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ android {
applicationId "com.hyeeyoung.wishboard"
minSdkVersion 22
targetSdkVersion 32
versionCode 13
versionCode 14
versionName "1.1.2"

testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.hyeeyoung.wishboard.data.model.noti

import com.google.gson.annotations.SerializedName
import com.hyeeyoung.wishboard.domain.entity.NotiItemInfo
import com.hyeeyoung.wishboard.presentation.noti.types.NotiType

data class NotiItem(
Expand All @@ -19,4 +20,14 @@ data class NotiItem(
val notiType: NotiType,
@SerializedName("item_notification_date")
val notiDate: String,
)
) {
fun toNotiItemInfo(noti: NotiItem) = NotiItemInfo(
noti.itemId,
noti.itemImg,
noti.itemName,
if (noti.itemUrl.isNullOrBlank()) null else noti.itemUrl,
noti.readState,
noti.notiType,
notiDate,
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.hyeeyoung.wishboard.domain.entity

import android.os.Parcelable
import com.google.gson.annotations.SerializedName
import com.hyeeyoung.wishboard.presentation.noti.types.NotiType
import kotlinx.parcelize.Parcelize

@Parcelize
data class NotiItemInfo( // TODO ๋„ค์ด๋ฐ ์ˆ˜์ • ํ•„์š”
val itemId: Long,
val itemImg: String? = null,
val itemName: String,
val itemUrl: String? = null,
var readState: Int,
val notiType: NotiType,
val notiDate: String,
) : Parcelable
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,12 @@ import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.hyeeyoung.wishboard.WishBoardApp
import com.hyeeyoung.wishboard.data.model.noti.NotiItem
import com.hyeeyoung.wishboard.data.services.AWSS3Service
import com.hyeeyoung.wishboard.domain.entity.NotiItemInfo
import com.hyeeyoung.wishboard.domain.repositories.NotiRepository
import com.hyeeyoung.wishboard.presentation.noti.adapters.NotiListAdapter
import com.hyeeyoung.wishboard.presentation.noti.types.NotiListViewType
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.joda.time.DateTime
import java.util.*
import javax.inject.Inject
Expand All @@ -24,8 +21,8 @@ class NotiViewModel @Inject constructor(
) : ViewModel() {
private val token = WishBoardApp.prefs.getUserToken()

private var notiList = MutableLiveData<List<NotiItem>?>(listOf())
private var selectedNotiList = MutableLiveData<List<NotiItem>?>(listOf())
private var notiList = MutableLiveData<List<NotiItemInfo>?>(listOf())
private var selectedNotiList = MutableLiveData<List<NotiItemInfo>?>(listOf())
private var notiDateList = MutableLiveData<List<String>?>(listOf())
private val notiListAdapter = NotiListAdapter(NotiListViewType.NOTI_TAB_VIEW_TYPE)
private val calendarNotiListAdapter = NotiListAdapter(NotiListViewType.CALENDAR_VIEW_TYPE)
Expand All @@ -39,36 +36,18 @@ class NotiViewModel @Inject constructor(
fun fetchPreviousNotiList() {
if (token == null) return
viewModelScope.launch {
var items: List<NotiItem>?
withContext(Dispatchers.IO) {
items = notiRepository.fetchPreviousNotiList(token)
items?.forEach { item ->
item.itemImg?.let { item.itemImageUrl = AWSS3Service().getImageUrl(it) }
}
}
withContext(Dispatchers.Main) {
notiList.postValue(items)
notiListAdapter.setData(items)
}
val items = notiRepository.fetchPreviousNotiList(token)?.map { it.toNotiItemInfo(it) }
notiList.value = items
notiListAdapter.setData(items)
}
}

fun fetchAllNotiList() {
if (token == null) return
viewModelScope.launch {
var items: List<NotiItem>?
withContext(Dispatchers.IO) {
items = notiRepository.fetchAllNotiList(token)
items?.forEach { item ->
item.itemImg?.let { item.itemImageUrl = AWSS3Service().getImageUrl(it) }
}
}
withContext(Dispatchers.Main) {
notiList.postValue(items)

// ์บ˜๋ฆฐ๋” ๋ทฐ ์•Œ๋ฆผ ๋‚ ์งœ ํ‘œ์‹œ๋ฅผ ์œ„ํ•œ notiDateList ๋งŒ๋“ค๊ธฐ
setNotiDateList(items)
}
val items = notiRepository.fetchAllNotiList(token)?.map { it.toNotiItemInfo(it) }
notiList.value = items
setNotiDateList(items) // ์บ˜๋ฆฐ๋” ๋ทฐ ์•Œ๋ฆผ ๋‚ ์งœ ํ‘œ์‹œ๋ฅผ ์œ„ํ•œ notiDateList ๋งŒ๋“ค๊ธฐ
}
}

Expand All @@ -89,7 +68,7 @@ class NotiViewModel @Inject constructor(
calendarNotiListAdapter.setData(items)
}

private fun setNotiDateList(notiList: List<NotiItem>?) {
private fun setNotiDateList(notiList: List<NotiItemInfo>?) {
notiDateList.value = notiList?.map {
it.notiDate.substring(0, 10)
}
Expand All @@ -100,15 +79,11 @@ class NotiViewModel @Inject constructor(
calendarMonthTitle.value = DateTime(millis).toString("MMMM yyyy", Locale("en"))
}

fun getNotiList(): LiveData<List<NotiItem>?> = notiList
fun getSelectedNotiList(): LiveData<List<NotiItem>?> = selectedNotiList
fun getNotiList(): LiveData<List<NotiItemInfo>?> = notiList
fun getSelectedNotiList(): LiveData<List<NotiItemInfo>?> = selectedNotiList
fun getNotiDateList(): LiveData<List<String>?> = notiDateList
fun getNotiListAdapter(): NotiListAdapter = notiListAdapter
fun getCalendarNotiListAdapter(): NotiListAdapter = calendarNotiListAdapter
fun getCalendarMonthTitle(): LiveData<String> = calendarMonthTitle
fun getSelectedDate(): LiveData<String> = selectedDate

companion object {
private const val TAG = "NotiViewModel"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,26 +5,24 @@ import android.view.ViewGroup
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
import coil.load
import com.bumptech.glide.Glide
import com.hyeeyoung.wishboard.data.model.noti.NotiItem
import com.hyeeyoung.wishboard.databinding.ItemCalendarNotiBinding
import com.hyeeyoung.wishboard.databinding.ItemNotiBinding
import com.hyeeyoung.wishboard.domain.entity.NotiItemInfo
import com.hyeeyoung.wishboard.presentation.noti.types.NotiListViewType
import com.hyeeyoung.wishboard.presentation.noti.types.ReadStateType

class NotiListAdapter(
private val notiListViewType: NotiListViewType,
) : ListAdapter<NotiItem, RecyclerView.ViewHolder>(diffCallback) {
private val dataSet = arrayListOf<NotiItem>()
) : ListAdapter<NotiItemInfo, RecyclerView.ViewHolder>(diffCallback) {
private val dataSet = arrayListOf<NotiItemInfo>()
private lateinit var listener: OnItemClickListener

init {
setHasStableIds(true)
}

interface OnItemClickListener {
fun onItemClick(position: Int, item: NotiItem)
fun onItemClick(position: Int, item: NotiItemInfo)
}

fun setOnItemClickListener(listener: OnItemClickListener) {
Expand All @@ -37,12 +35,6 @@ class NotiListAdapter(
val item = dataSet[position]
with(binding) {
this.item = item

itemImage.clipToOutline = true
item.itemImg?.let {
itemImage.load(it)
}

notiContainer.setOnClickListener {
listener.onItemClick(position, item)
}
Expand All @@ -56,12 +48,6 @@ class NotiListAdapter(
val item = dataSet[position]
with(binding) {
this.item = item

itemImage.clipToOutline = true
item.itemImageUrl?.let {
Glide.with(itemImage.context).load(it).into(itemImage)
}

notiContainer.setOnClickListener {
listener.onItemClick(position, item)
}
Expand Down Expand Up @@ -106,25 +92,24 @@ class NotiListAdapter(
notifyItemChanged(position)
}

fun setData(items: List<NotiItem>?) {
fun setData(items: List<NotiItemInfo>?) {
dataSet.clear()
items?.let { dataSet.addAll(it) }
notifyDataSetChanged()
}

companion object {
private const val TAG = "notiListAdapter"
private val diffCallback = object : DiffUtil.ItemCallback<NotiItem>() {
private val diffCallback = object : DiffUtil.ItemCallback<NotiItemInfo>() {
override fun areItemsTheSame(
oldItem: NotiItem,
newItem: NotiItem
oldItem: NotiItemInfo,
newItem: NotiItemInfo
): Boolean {
return oldItem.itemId == newItem.itemId
}

override fun areContentsTheSame(
oldItem: NotiItem,
newItem: NotiItem
oldItem: NotiItemInfo,
newItem: NotiItemInfo
): Boolean {
return oldItem == newItem
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import androidx.fragment.app.Fragment
import androidx.hilt.navigation.fragment.hiltNavGraphViewModels
import com.hyeeyoung.wishboard.R
import com.hyeeyoung.wishboard.databinding.FragmentNotiCalendarBinding
import com.hyeeyoung.wishboard.data.model.noti.NotiItem
import com.hyeeyoung.wishboard.domain.entity.NotiItemInfo
import com.hyeeyoung.wishboard.util.custom.CustomSnackbar
import com.hyeeyoung.wishboard.presentation.noti.adapters.CalendarAdapter
import com.hyeeyoung.wishboard.presentation.noti.adapters.NotiListAdapter
Expand Down Expand Up @@ -67,15 +67,11 @@ class NotiCalendarFragment : Fragment(), NotiListAdapter.OnItemClickListener {
}
}

override fun onItemClick(position: Int, item: NotiItem) {
override fun onItemClick(position: Int, item: NotiItemInfo) {
if (item.itemUrl == null) {
CustomSnackbar.make(binding.layout, getString(R.string.noti_item_url_snackbar_text)).show()
} else {
startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(item.itemUrl)))
}
}

companion object {
private const val TAG = "NotiCalendarFragment"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@ import androidx.fragment.app.Fragment
import androidx.fragment.app.viewModels
import com.hyeeyoung.wishboard.R
import com.hyeeyoung.wishboard.databinding.FragmentNotiBinding
import com.hyeeyoung.wishboard.data.model.noti.NotiItem
import com.hyeeyoung.wishboard.util.custom.CustomSnackbar
import com.hyeeyoung.wishboard.presentation.noti.adapters.NotiListAdapter
import com.hyeeyoung.wishboard.domain.entity.NotiItemInfo
import com.hyeeyoung.wishboard.presentation.noti.NotiViewModel
import com.hyeeyoung.wishboard.presentation.noti.adapters.NotiListAdapter
import com.hyeeyoung.wishboard.util.custom.CustomSnackbar
import dagger.hilt.android.AndroidEntryPoint

@AndroidEntryPoint
Expand Down Expand Up @@ -58,16 +58,12 @@ class NotiFragment : Fragment(), NotiListAdapter.OnItemClickListener {
}
}

override fun onItemClick(position: Int, item: NotiItem) {
override fun onItemClick(position: Int, item: NotiItemInfo) {
viewModel.updateNotiReadState(position, item.itemId)
if (item.itemUrl == null) {
CustomSnackbar.make(binding.layout, getString(R.string.noti_item_url_snackbar_text)).show()
} else {
startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(item.itemUrl)))
}
}

companion object {
private const val TAG = "NotiFragment"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,6 @@ class WishItemRegistrationViewModel @Inject constructor(
copyOriginItemInfo(value ?: return)
}

private var isEnabledSaveButton = MediatorLiveData<Boolean>()
private var isCompleteUpload = MutableLiveData<Boolean?>()
private var isCompleteFolderUpload = MutableLiveData<Boolean?>()
private var isExistFolderName = MutableLiveData<Boolean?>()
Expand All @@ -82,25 +81,38 @@ class WishItemRegistrationViewModel @Inject constructor(
private val folderListSquareAdapter =
FolderListAdapter(FolderListViewType.SQUARE_VIEW_TYPE)

val isEnabledUploadButton = MediatorLiveData<Boolean>().apply {
addSourceList(itemName, itemPrice) { checkValidItemInfoInput() }
private val _isEnabledSaveButton = MediatorLiveData<Boolean>().apply {
addSourceList(
itemName,
itemPrice,
itemImage,
selectedGalleryImageUri
) { combineEnabledSaveButton() }
}
val isEnabledSaveButton: LiveData<Boolean> get() = _isEnabledSaveButton

private fun checkValidItemInfoInput(): Boolean {
return !(itemName.value.isNullOrBlank() || itemPrice.value.isNullOrBlank() || token == null)
val isEnabledUploadButton = MediatorLiveData<Boolean>().apply {
addSourceList(itemName, itemPrice, itemImage) { checkValidItemInfoInput() }
}

init {
initEnabledSaveButton()
fetchFolderList()
}

private fun combineEnabledSaveButton() =
!(itemName.value.isNullOrBlank() || itemPrice.value.isNullOrBlank() || (itemImage.value.isNullOrBlank() && selectedGalleryImageUri.value == null))

private fun checkValidItemInfoInput(): Boolean {
return !(itemName.value.isNullOrBlank() || itemPrice.value.isNullOrBlank() || itemImage.value.isNullOrBlank() || token == null)
}

/** ์˜คํ”ˆ๊ทธ๋ž˜ํ”„ ๋ฉ”ํƒ€ํƒœ๊ทธ ํŒŒ์‹ฑ์„ ํ†ตํ•ด ์•„์ดํ…œ ์ •๋ณด ๊ฐ€์ ธ์˜ค๊ธฐ */
fun getWishItemInfo(url: String) {
viewModelScope.launch {
val result = wishRepository.getItemParsingInfo(url)
itemName.value = result?.first?.name
itemPrice.value = if (result?.first?.price == null || result.first?.price == "0") null else result.first?.price
itemPrice.value =
if (result?.first?.price == null || result.first?.price == "0") null else result.first?.price
itemImage.value = result?.first?.image
}
}
Expand Down Expand Up @@ -331,20 +343,6 @@ class WishItemRegistrationViewModel @Inject constructor(
return decimalFormat.format(numPrice.toInt())
}

private fun initEnabledSaveButton() {
isEnabledSaveButton.addSource(itemName) { name ->
combineEnabledSaveButton(name, itemPrice.value)
}

isEnabledSaveButton.addSource(itemPrice) { price ->
combineEnabledSaveButton(itemName.value, price)
}
}

private fun combineEnabledSaveButton(name: String?, price: String?) {
isEnabledSaveButton.value = !(name.isNullOrBlank() || price.isNullOrBlank())
}

fun removeWishItemImage() {
wishItemDetail?.apply {
this.image = null
Expand Down Expand Up @@ -511,8 +509,6 @@ class WishItemRegistrationViewModel @Inject constructor(
fun getFolderName(): LiveData<String?> = folderName

fun getFolderListSquareAdapter(): FolderListAdapter = folderListSquareAdapter

fun isEnabledSaveButton(): LiveData<Boolean> = isEnabledSaveButton
fun isCompleteUpload(): LiveData<Boolean?> = isCompleteUpload
fun isCompleteFolderUpload(): LiveData<Boolean?> = isCompleteFolderUpload

Expand Down
Loading

0 comments on commit 6d17b1a

Please sign in to comment.