Skip to content

Commit 1b59dff

Browse files
committed
Change eatery cache to a map flow
1 parent 7573887 commit 1b59dff

File tree

3 files changed

+35
-23
lines changed

3 files changed

+35
-23
lines changed

app/src/main/java/com/cornellappdev/android/eatery/data/repositories/EateryRepository.kt

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,12 @@ import com.cornellappdev.android.eatery.data.models.Event
77
import com.cornellappdev.android.eatery.ui.viewmodels.state.EateryApiResponse
88
import kotlinx.coroutines.CoroutineScope
99
import kotlinx.coroutines.Dispatchers
10+
import kotlinx.coroutines.flow.Flow
1011
import kotlinx.coroutines.flow.MutableStateFlow
1112
import kotlinx.coroutines.flow.StateFlow
1213
import kotlinx.coroutines.flow.asStateFlow
14+
import kotlinx.coroutines.flow.map
15+
import kotlinx.coroutines.flow.update
1316
import kotlinx.coroutines.launch
1417
import javax.inject.Inject
1518
import javax.inject.Singleton
@@ -95,8 +98,8 @@ class EateryRepository @Inject constructor(private val networkApi: NetworkApi) {
9598
/**
9699
* A map from eatery ids to the states representing their API loading calls.
97100
*/
98-
private val eateryApiCache: MutableMap<Int, MutableStateFlow<EateryApiResponse<Eatery>>> =
99-
mutableMapOf()
101+
private val eateryApiCache: MutableStateFlow<MutableMap<Int, EateryApiResponse<Eatery>>> =
102+
MutableStateFlow(mutableMapOf())
100103

101104
/**
102105
* Makes a new call to backend for the specified eatery. After calling,
@@ -105,31 +108,33 @@ class EateryRepository @Inject constructor(private val networkApi: NetworkApi) {
105108
*/
106109
private fun pingEatery(eateryId: Int) {
107110
// If first time calling, make new state.
108-
if (eateryApiCache[eateryId] == null) {
109-
eateryApiCache[eateryId] = MutableStateFlow(EateryApiResponse.Pending)
110-
}
111-
112-
eateryApiCache[eateryId]!!.value = EateryApiResponse.Pending
111+
updateCache(eateryId, EateryApiResponse.Pending)
113112

114113
CoroutineScope(Dispatchers.IO).launch {
115114
try {
116115
val eatery = getEatery(eateryId = eateryId)
117-
eateryApiCache[eateryId]!!.value = EateryApiResponse.Success(eatery)
116+
updateCache(eateryId, EateryApiResponse.Success(eatery))
118117
} catch (_: Exception) {
119-
eateryApiCache[eateryId]!!.value = EateryApiResponse.Error
118+
updateCache(eateryId, EateryApiResponse.Error)
120119
}
121120
}
122121
}
123122

123+
private fun updateCache(eateryId: Int, response: EateryApiResponse<Eatery>) {
124+
eateryApiCache.update {
125+
(it + (eateryId to response)).toMutableMap()
126+
}
127+
}
128+
124129
/**
125130
* Returns the [StateFlow] representing the API call for the specified eatery.
126131
* If ALL eateries are already loaded, then this simply instantly returns that.
127132
*/
128-
fun getEateryFlow(eateryId: Int): StateFlow<EateryApiResponse<Eatery>> {
133+
fun getEateryFlow(eateryId: Int): Flow<EateryApiResponse<Eatery>> {
129134
lastEateryId = eateryId
130-
if (!eateryApiCache.contains(eateryId)) {
135+
if (!eateryApiCache.value.contains(eateryId)) {
131136
pingEatery(eateryId)
132137
}
133-
return eateryApiCache[eateryId]!!
138+
return eateryApiCache.map { it[eateryId]!! }
134139
}
135140
}

app/src/main/java/com/cornellappdev/android/eatery/ui/screens/SearchScreen.kt

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,8 @@ fun SearchScreen(
109109
}
110110
}
111111

112-
ModalBottomSheetLayout(sheetState = modalBottomSheetState, sheetShape = RoundedCornerShape(
112+
ModalBottomSheetLayout(
113+
sheetState = modalBottomSheetState, sheetShape = RoundedCornerShape(
113114
bottomStart = 0.dp, bottomEnd = 0.dp, topStart = 12.dp, topEnd = 12.dp
114115
), sheetElevation = 8.dp, sheetContent = {
115116
PaymentMethodsBottomSheet(selectedFilters = selectedPaymentMethodFilters, hide = {
@@ -242,7 +243,10 @@ fun SearchScreen(
242243
)
243244

244245
recentSearches.forEach { eateryId ->
245-
val eateryResponse = searchViewModel.openEatery(eateryId).value
246+
val eateryResponse =
247+
searchViewModel.openEatery(eateryId).collectAsState(
248+
initial = EateryApiResponse.Pending
249+
).value
246250
if (eateryResponse is EateryApiResponse.Success) {
247251
Box(
248252
Modifier.padding(
@@ -280,7 +284,8 @@ fun SearchScreen(
280284
horizontal = 16.dp, vertical = 12.dp
281285
)
282286
) {
283-
EateryCard(eatery = eatery,
287+
EateryCard(
288+
eatery = eatery,
284289
isFavorite = favorites.any { favoriteEatery ->
285290
favoriteEatery.id == eatery.id
286291
},
@@ -309,14 +314,16 @@ fun SearchScreen(
309314
fun FavoriteItem(
310315
eatery: Eatery, onEateryClick: (eatery: Eatery) -> Unit
311316
) {
312-
Column(modifier = Modifier
313-
.width(96.dp)
314-
.clickable {
315-
onEateryClick(eatery)
316-
}) {
317+
Column(
318+
modifier = Modifier
319+
.width(96.dp)
320+
.clickable {
321+
onEateryClick(eatery)
322+
}) {
317323
// Use box to overlay the star over the eatery
318324
Box {
319-
GlideImage(imageModel = { eatery.imageUrl ?: "" },
325+
GlideImage(
326+
imageModel = { eatery.imageUrl ?: "" },
320327
modifier = Modifier
321328
.fillMaxWidth()
322329
.height(96.dp)

app/src/main/java/com/cornellappdev/android/eatery/ui/viewmodels/EateryDetailViewModel.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ import com.cornellappdev.android.eatery.ui.components.general.MenuItemViewState
1313
import com.cornellappdev.android.eatery.ui.viewmodels.state.EateryApiResponse
1414
import com.cornellappdev.android.eatery.util.fromOffsetToDayOfWeek
1515
import dagger.hilt.android.lifecycle.HiltViewModel
16+
import kotlinx.coroutines.flow.Flow
1617
import kotlinx.coroutines.flow.MutableStateFlow
17-
import kotlinx.coroutines.flow.StateFlow
1818
import kotlinx.coroutines.flow.asStateFlow
1919
import kotlinx.coroutines.flow.combine
2020
import kotlinx.coroutines.flow.launchIn
@@ -72,7 +72,7 @@ class EateryDetailViewModel @Inject constructor(
7272
/**
7373
* A flow emitting the loading status of the current eatery.
7474
*/
75-
private val eateryFlow: StateFlow<EateryApiResponse<Eatery>> =
75+
private val eateryFlow: Flow<EateryApiResponse<Eatery>> =
7676
eateryRepository.getEateryFlow(eateryId)
7777

7878
private val userSelectedMeal = MutableStateFlow<Event?>(null)

0 commit comments

Comments
 (0)