Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rememberFirstVisibleWeekAfterScroll #594

Open
akrulec opened this issue Nov 4, 2024 · 2 comments
Open

rememberFirstVisibleWeekAfterScroll #594

akrulec opened this issue Nov 4, 2024 · 2 comments

Comments

@akrulec
Copy link

akrulec commented Nov 4, 2024

fun rememberFirstVisibleWeekAfterScroll(state: WeekCalendarState): Week {

I've tried using this function the following way. The goal is that if the user scrolls the week calendar, we automatically select the same day in the week the user scrolled to. Then we update the screen below the week calendar.

val currentMonth = remember { YearMonth.of(currentDate.year, currentDate.month) }
    val startDate = remember { currentMonth.minusMonths(24).atStartOfMonth() }
    val endDate = remember { currentMonth.plusMonths(2).atEndOfMonth() }
    val firstDayOfWeek = remember { DayOfWeek.SUNDAY }

    val state = rememberWeekCalendarState(
        startDate = startDate,
        endDate = endDate,
        firstVisibleWeekDate = currentDate,
        firstDayOfWeek = firstDayOfWeek)
    val visibleWeek = rememberFirstVisibleWeekAfterScroll(state)
    // Remember this through UI changes, since the current date can be changed from a different
    // fragment.
    var firstDayOfTheWeek by rememberSaveable { mutableStateOf(currentDate) }

    LaunchedEffect(visibleWeek) {
        Timber.e("$currentDate visible week: $visibleWeek")
        visibleWeek.days.firstOrNull()?.date?.let { firstDateAfterScroll ->
            if (firstDateAfterScroll != firstDayOfTheWeek) {
                firstDayOfTheWeek = firstDateAfterScroll

                // Week changed, make sure to refresh data.
                visibleWeek.days.lastOrNull()?.date?.let { lastDate ->
                    onCalendarScroll(firstDateAfterScroll, lastDate)
                }

                // Select the same day in the new week, by updating the date.
                val dayOfWeek = (currentDate.dayOfWeek.value % NUM_DAYS_TO_SHOW)
                visibleWeek.days.getOrNull(dayOfWeek)?.date?.let { newDate ->
                    Timber.e("scroll new date: $newDate")
                    onDateSelected(newDate)
                }
            }
        }
    }

However, we also at some point show a full calendar, and when the user select the date there, we use scrollToWeek function to scroll the calendar to that week.

LaunchedEffect(currentDate) {
       // Update the state of the calendar if the date changes (by user clicking on a different
       // date in the week, or month calendar).
       state.scrollToWeek(currentDate)
   }

However, if the user scolls way back ( to like a year ago), and selects a date, the visibleWeek is not correct. Printing the values this is what I get:

selected date: 2023-11-01 
visible week: Week { first = WeekDay(date=2024-11-03, position=RangeDate), last = WeekDay(date=2024-11-09, position=RangeDate) } 

The side effect of this odd state seems to be the following. If the user clicks 'today' button, the visible week seems to be at some random date in 2021:

selected date: 2024-11-03 
visible week: Week { first = WeekDay(date=2021-10-31, position=InDate), last = WeekDay(date=2021-11-06, position=RangeDate) } 

Any idea what could be going on here? Is there something in the state that needs to be updated? I assume that if currentDate is updated, then rememberWeekCalendarState will refresh, but maybe not?

Thank you!

@kizitonwose
Copy link
Owner

How is currentDate being updated? There's an example in the sample app with month/week toggle and this seems to work fine. Can you reproduce it there?

@akrulec
Copy link
Author

akrulec commented Nov 26, 2024

How is currentDate being updated? There's an example in the sample app with month/week toggle and this seems to work fine. Can you reproduce it there?

Is there a specific case I should try to reproduce this on? I haven't found any examples that would keep the 'current date' state in the view model. Thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants