Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
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
7 changes: 6 additions & 1 deletion app/src/main/java/com/example/ssul/FavoritesFragment.kt
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,11 @@ class FavoritesFragment : Fragment() {
// 학과 클릭 로직 처리 + 즐겨찾기 가게 필터링 + 즐겨찾기 토글(아이템 삭제)
}

override fun onResume() {
super.onResume()

}

private fun setupViews(view: View) {
degreeTextView = view.findViewById(R.id.degree_text)
setDegreeButton = view.findViewById(R.id.set_degree_button)
Expand All @@ -325,7 +330,7 @@ class FavoritesFragment : Fragment() {

private fun setupAdapters() {
storeAdapter = StoreAdapter(
storeItems = storeViewModel.storeItems.value ?: mutableListOf(),
storeItems = storeViewModel.storeItems.value ?: emptyList(),
favoriteItems = favoriteViewModel.favoriteState.value ?: emptyList(),
onFavoriteClicked = { storeId ->
favoriteViewModel.toggleFavorite(storeId)
Expand Down
2 changes: 1 addition & 1 deletion app/src/main/java/com/example/ssul/HomeFragment.kt
Original file line number Diff line number Diff line change
Expand Up @@ -451,7 +451,7 @@ class HomeFragment : Fragment() {

private fun setupAdapters() {
storeAdapter = StoreAdapter(
storeItems = storeViewModel.storeItems.value ?: mutableListOf(),
storeItems = storeViewModel.storeItems.value ?: emptyList(),
favoriteItems = favoriteViewModel.favoriteState.value ?: emptyList(),
onFavoriteClicked = { storeId ->
favoriteViewModel.toggleFavorite(storeId)
Expand Down
26 changes: 13 additions & 13 deletions app/src/main/java/com/example/ssul/adapter/StoreAdapter.kt
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import com.example.ssul.model.FavoriteModel
import com.example.ssul.model.StoreModel

class StoreAdapter(
private var storeItems: MutableList<StoreModel>,
private var storeItems: List<StoreModel>,
private var favoriteItems: List<FavoriteModel>,
private val onFavoriteClicked: (Int) -> Unit,
private val onStoreClicked: (Int) -> Unit,
Expand Down Expand Up @@ -42,12 +42,10 @@ class StoreAdapter(
storeText.text = item.name
locationText.text = item.address

// 즐겨찾기 상태 조회
val isFavorite = favoriteItems.any { it.storeId == item.id && it.isFavorite }

// 즐겨찾기 가시성 조정
favoriteButton.setImageResource(
if (isFavorite) R.drawable.favorite_clicked else R.drawable.favorite_non_clicked
if (item.isFavorite) R.drawable.favorite_clicked else R.drawable.favorite_non_clicked
)

// 즐겨찾기 클릭 처리
Expand Down Expand Up @@ -101,24 +99,26 @@ class StoreAdapter(

// 가게 리스트 업데이트
fun updateItems(newItems: List<StoreModel>) {
storeItems = if (isFavoriteMode) { // FavoriteFragment
newItems.filter { store ->
favoriteItems.any { favorite -> favorite.storeId == store.id && favorite.isFavorite }
}.toMutableList()
} else { // HomeFragment
newItems.toMutableList()
storeItems = applyFavoritesToItems(newItems, favoriteItems)
if (isFavoriteMode) { // FavoriteFragment
storeItems = storeItems.filter { it.isFavorite }
}
notifyDataSetChanged()
}

// 즐겨찾기 상태 업데이트
fun updateFavorites(favorites: List<FavoriteModel>) {
favoriteItems = favorites
storeItems = applyFavoritesToItems(storeItems, favoriteItems)
if (isFavoriteMode) { // FavoriteFragment
storeItems = storeItems.filter { store ->
favoriteItems.any { favorite -> favorite.storeId == store.id && favorite.isFavorite }
}.toMutableList()
storeItems = storeItems.filter { it.isFavorite }
}
notifyDataSetChanged()
}

private fun applyFavoritesToItems(storeItems: List<StoreModel>, favoriteItems: List<FavoriteModel>): List<StoreModel> {
return storeItems.map { store ->
store.copy(isFavorite = favoriteItems.any { favorite -> favorite.storeId == store.id && favorite.isFavorite })
}
Copy link

@cometj03 cometj03 Mar 13, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isFavorite 필드를 매번 계산해주는 게 아니라 어딘가에 저장해두었다 재사용하면 더 효율적일 것 같아요!

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

조금 헷갈리는 부분이 있습니다..! 현재 isFavorite이 1. 가게 리스트가 변경될 때 2. 즐겨찾기 상태가 변경될 때 업데이트 되는 것으로 보이는데, 혹시 제가 놓친 부분이 있을까요?

해서, 지금은 storeItems.map 내부에서 favoriteItems.any로 isFavorite을 찾고 있는데,
favoriteItems를 Map으로 변환한 후 storeItems에서 isFavorite를 조회하는 건 어떨까요?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

음음 뭔가 제가 의도한 바가 잘 전달되지 않은 것 같네요..! 다음에 모각코 오시게 되면 설명드릴게욥

}
}
3 changes: 2 additions & 1 deletion app/src/main/java/com/example/ssul/model/StoreModel.kt
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ data class StoreModel(
val isFilterDateChecked: Boolean, // date 필터 선택 여부
val isFilterEfficiencyChecked: Boolean, // efficiency 필터 선택 여부
val imageUrl: String, // Store 이미지 리소스 ID
val isAssociated: Boolean // partner 필터 선택 여부
val isAssociated: Boolean, // partner 필터 선택 여부
val isFavorite: Boolean = false
)

data class StoreInfoModel(
Expand Down
52 changes: 17 additions & 35 deletions app/src/main/java/com/example/ssul/repository/StoreRepository.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package com.example.ssul.repository

import android.util.Log
import com.example.ssul.api.RetrofitClient
import com.example.ssul.api.collegeCodeMap
import com.example.ssul.api.degreeCodeMap
Expand All @@ -10,16 +9,17 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext

class StoreRepository {
suspend fun getStores(college: String, degree: String): MutableList<StoreModel> {
return withContext(Dispatchers.IO) {
try {
val collegeCode = collegeCodeMap[college] ?: throw IllegalArgumentException("Unknown college name: $college")
val degreeCode = degreeCodeMap[degree] ?: throw IllegalArgumentException("Unknown degree name: $degree")
suspend fun getStores(college: String, degree: String): Result<MutableList<StoreModel>> =
withContext(Dispatchers.IO) {
val collegeCode = collegeCodeMap[college]
?: return@withContext Result.failure(IllegalArgumentException("Unknown college name: $college"))
val degreeCode = degreeCodeMap[degree]
?: return@withContext Result.failure(IllegalArgumentException("Unknown degree name: $degree"))

runCatching {
val response = RetrofitClient.apiService.getStores(collegeCode, degreeCode).execute()
if (response.isSuccessful) {
val storeResponses = response.body() ?: emptyList()

storeResponses.map { storeResponse ->
StoreModel(
id = storeResponse.id,
Expand All @@ -33,32 +33,26 @@ class StoreRepository {
)
}.toMutableList()
} else {
mutableListOf()
throw Exception("Failed to fetch stores: ${response.errorBody()?.string()}")
}
} catch (e: Exception) {
e.printStackTrace()
mutableListOf()
}
}
}
}

class StoreInfoRepository {
suspend fun getStoreInfo(storeId: Int, college: String, degree: String): StoreInfoModel {
return withContext(Dispatchers.IO) {
try {
val collegeCode = collegeCodeMap[college] ?: throw IllegalArgumentException("Unknown college name: $college")
val degreeCode = degreeCodeMap[degree] ?: throw IllegalArgumentException("Unknown degree name: $degree")
suspend fun getStoreInfo(storeId: Int, college: String, degree: String): Result<StoreInfoModel> =
withContext(Dispatchers.IO) {
val collegeCode = collegeCodeMap[college]
?: return@withContext Result.failure(IllegalArgumentException("Unknown college name: $college"))
val degreeCode = degreeCodeMap[degree]
?: return@withContext Result.failure(IllegalArgumentException("Unknown degree name: $degree"))

runCatching {
val response = RetrofitClient.apiService.getStoreInfo(storeId, collegeCode, degreeCode).execute()
if (response.isSuccessful) {
val storeResponse = response.body() ?: throw java.lang.IllegalArgumentException("Invalid Store Response")
val storeResponse = response.body() ?: throw IllegalArgumentException("Invalid Store Response")
val associationTarget = collegeCodeMap.entries.find { it.value == storeResponse.associationInfo?.target }?.key
?: degreeCodeMap.entries.find { it.value == storeResponse.associationInfo?.target }?.key
?: "정보 없음"

Log.d("StoreInfo", "API Response: $storeResponse")

StoreInfoModel(
id = storeResponse.id,
name = storeResponse.name,
Expand All @@ -77,18 +71,6 @@ class StoreInfoRepository {
} else {
throw IllegalArgumentException("Failed to fetch store info: ${response.errorBody()?.string()}")
}
} catch (e: Exception) {
e.printStackTrace()
StoreInfoModel(
id = 0,
name = "",
isAssociated = false,
address = "정보 없음",
contact = "정보 없음",
associationInfo = "정보 없음" to "정보 없음",
menus = emptyList()
)
}
}
}
}
}
24 changes: 17 additions & 7 deletions app/src/main/java/com/example/ssul/viewmodel/StoreViewModel.kt
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,12 @@ import androidx.lifecycle.viewModelScope
import com.example.ssul.model.FilterModel
import com.example.ssul.model.StoreInfoModel
import com.example.ssul.model.StoreModel
import com.example.ssul.repository.StoreInfoRepository
import com.example.ssul.repository.StoreRepository
import kotlinx.coroutines.launch

class StoreViewModel(application: Application) : AndroidViewModel(application) {

private val storeRepository = StoreRepository()
private val storeInfoRepository = StoreInfoRepository()
private val _allStores = MutableLiveData<MutableList<StoreModel>>()
private val _filteredStores = MutableLiveData<MutableList<StoreModel>>()
val storeItems: LiveData<MutableList<StoreModel>> get() = _filteredStores
Expand All @@ -42,17 +40,29 @@ class StoreViewModel(application: Application) : AndroidViewModel(application) {
// 가게 데이터 불러오기
private fun loadStores() {
viewModelScope.launch {
val stores = storeRepository.getStores(college, degree)
_allStores.value = stores
_filteredStores.value = stores
storeRepository.getStores(college, degree)
.onSuccess { stores ->
_allStores.value = stores
_filteredStores.value = stores
}
.onFailure { error ->
error.printStackTrace()
_allStores.value = mutableListOf()
_filteredStores.value = mutableListOf()
}
}
}

// 가게 세부 데이터 불러오기
fun loadStoreInfo(storeId: Int) {
viewModelScope.launch {
val storeInfo = storeInfoRepository.getStoreInfo(storeId, college, degree)
_storeInfo.value = storeInfo
storeRepository.getStoreInfo(storeId, college, degree)
.onSuccess { info ->
_storeInfo.value = info
}
.onFailure { error ->
error.printStackTrace()
}
}
}

Expand Down