@@ -14,6 +14,7 @@ import androidx.compose.foundation.layout.padding
1414import androidx.compose.foundation.layout.statusBarsPadding
1515import androidx.compose.foundation.lazy.LazyColumn
1616import androidx.compose.foundation.lazy.LazyListScope
17+ import androidx.compose.foundation.lazy.LazyListState
1718import androidx.compose.foundation.lazy.items
1819import androidx.compose.foundation.lazy.rememberLazyListState
1920import androidx.compose.foundation.shape.RoundedCornerShape
@@ -40,6 +41,7 @@ import androidx.compose.ui.unit.dp
4041import androidx.compose.ui.unit.sp
4142import androidx.hilt.navigation.compose.hiltViewModel
4243import com.cornellappdev.android.eatery.ui.components.general.CalendarWeekSelector
44+ import com.cornellappdev.android.eatery.ui.components.general.Filter
4345import com.cornellappdev.android.eatery.ui.components.general.FilterButton
4446import com.cornellappdev.android.eatery.ui.components.general.FilterRow
4547import com.cornellappdev.android.eatery.ui.components.general.MealFilter
@@ -56,6 +58,7 @@ import com.cornellappdev.android.eatery.util.AppStorePopupRepository
5658import com.cornellappdev.android.eatery.util.appStorePopupRepository
5759import com.valentinilk.shimmer.ShimmerBounds
5860import com.valentinilk.shimmer.rememberShimmer
61+ import kotlinx.coroutines.CoroutineScope
5962import kotlinx.coroutines.launch
6063import java.time.LocalDate
6164import java.time.format.DateTimeFormatter
@@ -106,76 +109,34 @@ fun UpcomingMenuScreen(
106109 },
107110 content = {
108111 val innerListState = rememberLazyListState()
112+ val filterRowState = rememberLazyListState()
109113 val isFirstVisible =
110114 remember { derivedStateOf { innerListState.firstVisibleItemIndex > 0 } }
111- val upcomingMenuHeader = @Composable {
112- UpcomingMenuHeader (isFirstVisible)
113- }
114- val calendarWeekSelector = @Composable {
115- Box (
116- modifier = Modifier .padding(start = 16 .dp, end = 16 .dp, top = 16 .dp)
117- ) {
118- CalendarWeekSelector (
119- dayNames = (0 until 7 ).map {
120- LocalDate .now().plusDays(it.toLong())
121- .format(DateTimeFormatter .ofPattern(" EEE" ))
122- },
123- currSelectedDay = viewState.selectedDay,
124- selectedDay = viewState.selectedDay,
125- days = (0 until 7 ).map {
126- LocalDate .now().plusDays(it.toLong()).dayOfMonth
115+ when (val menus = viewState.menus) {
116+ is EateryApiResponse .Success -> {
117+ UpcomingLazyColumn (
118+ innerListState = innerListState,
119+ upcomingMenuHeader = { UpcomingMenuHeader (isFirstVisible) },
120+ calendarWeekSelector = {
121+ CalendarWeekSelector (
122+ selectedDay = viewState.selectedDay,
123+ selectDayOffset = upcomingViewModel::selectDayOffset
124+ )
127125 },
128- onClick = upcomingViewModel::selectDayOffset,
129- closedDays = null
130- )
131- }
132- }
133- val filterRowState = rememberLazyListState()
134- val filterRow = @Composable {
135- FilterRow (
136- customItemsBefore = {
137- item {
138- FilterButton (
139- onFilterClicked = {
140- coroutineScope.launch {
141- modalBottomSheetState.show()
142- }
143- },
144- selected = true ,
145- text = when (viewState.mealFilter) {
146- MealFilter .LATE_DINNER -> " Late Dinner"
147- else -> viewState.mealFilter.text.first()
126+ filterRow = {
127+ UpcomingFilterRow (
128+ coroutineScope = coroutineScope,
129+ showModalBottomSheet = {
130+ modalBottomSheetState.show()
148131 },
149- icon = Icons .Default .ExpandMore
132+ mealFilter = viewState.mealFilter,
133+ upcomingMenuFilters = upcomingViewModel.upcomingMenuFilters,
134+ selectedFilters = viewState.selectedFilters,
135+ onToggleFilterClicked = upcomingViewModel::onToggleFilterClicked,
136+ filterRowState = filterRowState
150137 )
151138 }
152- },
153- filters = upcomingViewModel.upcomingMenuFilters,
154- currentFiltersSelected = viewState.selectedFilters,
155- onFilterClicked = upcomingViewModel::onToggleFilterClicked,
156- rowState = filterRowState
157- )
158- }
159- val upcomingLazyColumn: @Composable (LazyListScope .() -> Unit ) -> Unit =
160- { content ->
161- LazyColumn (
162- state = innerListState, modifier = Modifier .fillMaxSize()
163139 ) {
164- stickyHeader {
165- upcomingMenuHeader()
166- }
167- item {
168- calendarWeekSelector()
169- }
170- item {
171- filterRow()
172- }
173- content()
174- }
175- }
176- when (val menus = viewState.menus) {
177- is EateryApiResponse .Success -> {
178- upcomingLazyColumn {
179140 if (menus.data.isEmpty()) {
180141 item {
181142 Box (
@@ -219,7 +180,29 @@ fun UpcomingMenuScreen(
219180 }
220181
221182 is EateryApiResponse .Pending -> {
222- upcomingLazyColumn {
183+ UpcomingLazyColumn (
184+ innerListState = innerListState,
185+ upcomingMenuHeader = { UpcomingMenuHeader (isFirstVisible) },
186+ calendarWeekSelector = {
187+ CalendarWeekSelector (
188+ selectedDay = viewState.selectedDay,
189+ selectDayOffset = upcomingViewModel::selectDayOffset
190+ )
191+ },
192+ filterRow = {
193+ UpcomingFilterRow (
194+ coroutineScope = coroutineScope,
195+ showModalBottomSheet = {
196+ modalBottomSheetState.show()
197+ },
198+ mealFilter = viewState.mealFilter,
199+ upcomingMenuFilters = upcomingViewModel.upcomingMenuFilters,
200+ selectedFilters = viewState.selectedFilters,
201+ onToggleFilterClicked = upcomingViewModel::onToggleFilterClicked,
202+ filterRowState = filterRowState
203+ )
204+ }
205+ ) {
223206 items(UpcomingLoadingItem .upcomingItems) { item ->
224207 CreateUpcomingLoadingItem (
225208 item,
@@ -231,9 +214,22 @@ fun UpcomingMenuScreen(
231214
232215 is EateryApiResponse .Error -> {
233216 Column (modifier = Modifier .fillMaxSize()) {
234- upcomingMenuHeader()
235- calendarWeekSelector()
236- filterRow()
217+ UpcomingMenuHeader (isFirstVisible)
218+ CalendarWeekSelector (
219+ selectedDay = viewState.selectedDay,
220+ selectDayOffset = upcomingViewModel::selectDayOffset
221+ )
222+ UpcomingFilterRow (
223+ coroutineScope = coroutineScope,
224+ showModalBottomSheet = {
225+ modalBottomSheetState.show()
226+ },
227+ mealFilter = viewState.mealFilter,
228+ upcomingMenuFilters = upcomingViewModel.upcomingMenuFilters,
229+ selectedFilters = viewState.selectedFilters,
230+ onToggleFilterClicked = upcomingViewModel::onToggleFilterClicked,
231+ filterRowState = filterRowState
232+ )
237233 Box (
238234 modifier = Modifier .fillMaxSize(),
239235 contentAlignment = Alignment .Center
@@ -248,6 +244,90 @@ fun UpcomingMenuScreen(
248244 }
249245}
250246
247+ @Composable
248+ private fun CalendarWeekSelector (
249+ selectedDay : Int ,
250+ selectDayOffset : (Int ) -> Unit ,
251+ ) {
252+ Box (
253+ modifier = Modifier .padding(start = 16 .dp, end = 16 .dp, top = 16 .dp)
254+ ) {
255+ CalendarWeekSelector (
256+ dayNames = (0 until 7 ).map {
257+ LocalDate .now().plusDays(it.toLong())
258+ .format(DateTimeFormatter .ofPattern(" EEE" ))
259+ },
260+ currSelectedDay = selectedDay,
261+ selectedDay = selectedDay,
262+ days = (0 until 7 ).map {
263+ LocalDate .now().plusDays(it.toLong()).dayOfMonth
264+ },
265+ onClick = selectDayOffset,
266+ closedDays = null
267+ )
268+ }
269+ }
270+
271+ @Composable
272+ private fun UpcomingFilterRow (
273+ coroutineScope : CoroutineScope ,
274+ showModalBottomSheet : suspend () -> Unit ,
275+ mealFilter : MealFilter ,
276+ upcomingMenuFilters : List <Filter >,
277+ selectedFilters : List <Filter >,
278+ onToggleFilterClicked : (Filter ) -> Unit ,
279+ filterRowState : LazyListState ,
280+ ) {
281+ FilterRow (
282+ customItemsBefore = {
283+ item {
284+ FilterButton (
285+ onFilterClicked = {
286+ coroutineScope.launch {
287+ showModalBottomSheet()
288+ }
289+ },
290+ selected = true ,
291+ text = when (mealFilter) {
292+ MealFilter .LATE_DINNER -> " Late Dinner"
293+ else -> mealFilter.text.first()
294+ },
295+ icon = Icons .Default .ExpandMore
296+ )
297+ }
298+ },
299+ filters = upcomingMenuFilters,
300+ currentFiltersSelected = selectedFilters,
301+ onFilterClicked = onToggleFilterClicked,
302+ rowState = filterRowState
303+ )
304+ }
305+
306+ @OptIn(ExperimentalFoundationApi ::class )
307+ @Composable
308+ private fun UpcomingLazyColumn (
309+ innerListState : LazyListState ,
310+ upcomingMenuHeader : @Composable () -> Unit ,
311+ calendarWeekSelector : @Composable () -> Unit ,
312+ filterRow : @Composable () -> Unit ,
313+ content : LazyListScope .() -> Unit
314+ ) {
315+ LazyColumn (
316+ state = innerListState, modifier = Modifier .fillMaxSize()
317+ ) {
318+ stickyHeader {
319+ upcomingMenuHeader()
320+ }
321+ item {
322+ calendarWeekSelector()
323+ }
324+ item {
325+ filterRow()
326+ }
327+ content()
328+ }
329+ }
330+
251331@Composable
252332@OptIn(ExperimentalAnimationApi ::class )
253333private fun UpcomingMenuHeader (isFirstVisible : State <Boolean >) {
0 commit comments