Skip to content

Comments

POS Bookings: Address PR review feedback for date picker performance#16717

Open
staskus wants to merge 8 commits intotrunkfrom
woomob-2267-pos-bookings-date-picker-performance-2
Open

POS Bookings: Address PR review feedback for date picker performance#16717
staskus wants to merge 8 commits intotrunkfrom
woomob-2267-pos-bookings-date-picker-performance-2

Conversation

@staskus
Copy link
Contributor

@staskus staskus commented Feb 24, 2026

Description

Addresses code review feedback from #16701.

Changes:

  • Remove duplicated fetchLocalBookingsFromStorage function
  • Extract complex cache clear strategy ternary to a named function
  • Rename prefetchDateIfNeeded to prefetchDate (always re-fetches, only guards against duplicate in-flight requests)
  • Remove custom accessibility label from POSBookingRowView (combined children default is sufficient)
  • Move fetchLocalBookings() default from protocol extension to search strategy explicitly
  • Move syncBookings() call from POSBookingsModel init to POSBookingListController init
  • Improve readability: rename showsLoadingWithItems to showsCachedDataWhileLoading, restructure setLocalDataOrLoadingState() to showCachedBookingsOrLoadingIndicator(), add comments clarifying the sync-then-read and two-phase loading patterns
  • Pagination fixes:
    • Gate loadNextBookings() until first-page loading has finished and hasMoreItems is true. We need to wait since we need to know if there's actually anything to paginate.
    • Discard stale paginated results when strategy context changes mid-fetch.

Test Steps

  • Verify bookings list loads, date navigation works, prefetching works as before
  • Try paginate quickly after opening the view, switch dates while paginating
  • Verify search bookings flow still works

Pagination

Quick paginate while the first page is still loading

Quick.Case.mov

Pagination only after the first page has loaded

Slow.Case.mov

Pagination + Date switches

Switching.Case.mov

  • I have considered if this change warrants user-facing release notes and have added them to RELEASE-NOTES.txt if necessary.

Replace with the existing fetchLocalBookings() protocol method which
has the same implementation. Addresses PR review feedback.
Replace the complex ternary with a cacheClearStrategy(for:) method
that clearly documents the logic. Addresses PR review feedback.
The method always re-fetches data for the date (intentionally naive to
keep data fresh), so 'ifNeeded' was misleading. The only guard is
against duplicate in-flight requests. Addresses PR review feedback.
The combined children accessibility element already provides sufficient
context. The custom label was redundant and made announcements longer
without adding new information. Addresses PR review feedback.
Instead of providing a default empty implementation in the protocol
extension, add it explicitly to POSSearchBookingListFetchStrategy and
other conformers. This makes it clearer that search doesn't use local
storage, and forces new strategy implementations to consider this
method. Addresses PR review feedback.
Rename showsLoadingWithItems to showsCachedDataWhileLoading to clarify
that it controls whether cached data is displayed during a remote fetch.
Rename and restructure setLocalDataOrLoadingState() to
showCachedBookingsOrLoadingIndicator() with early returns and a doc
comment explaining the three branches. Add comments to the strategy's
sync-then-read pattern and the controller's two-phase loading flow.
Addresses PR review feedback about code intent being hard to follow.
@staskus staskus added this to the 24.2 milestone Feb 24, 2026
@staskus staskus added type: task An internally driven task. feature: POS labels Feb 24, 2026
@wpmobilebot
Copy link
Collaborator

wpmobilebot commented Feb 24, 2026

App Icon📲 You can test the changes from this Pull Request in WooCommerce iOS Prototype by scanning the QR code below to install the corresponding build.

App NameWooCommerce iOS Prototype
Build Numberpr16717-cb6153b
Version24.1
Bundle IDcom.automattic.alpha.woocommerce
Commitcb6153b
Installation URL3e08kci3lhf90
Automatticians: You can use our internal self-serve MC tool to give yourself access to those builds if needed.

@staskus staskus requested a review from joshheald February 24, 2026 15:30
@staskus staskus marked this pull request as ready for review February 24, 2026 15:31
Copy link
Contributor

@joshheald joshheald left a comment

Choose a reason for hiding this comment

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

Looks great, a few tiny things I spotted, but nothing very urgent. Thanks for the improvements.

Pagination – I noticed that if we scroll quickly to the bottom, the loading row doesn't show until we finish loading the first page. It does trigger the pagination without further scrolling, but it's difficult to spot.

WDYT about these two options:

  • Optimistically add the pagination row even if we're not actually loading it yet, or
  • Scroll to the loading row when we add it.

I prefer the first as we may mess up the user's scroll position with the second... but I recognise this is quite picky for our (probably) temporary solution, so no worries if the answer is "third, leave it as is."

func clearSearchBookings()
}

@MainActor
Copy link
Contributor

Choose a reason for hiding this comment

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

There are good arguments that any @Observable should be @MainActor.

guard paginationTracker.hasNextPage,
case .loaded(_, let hasMoreItems) = bookingsViewState, hasMoreItems else { return }

loadTask = Task {
Copy link
Contributor

Choose a reason for hiding this comment

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

Interesting, I didn't notice that we didn't put this in loadTask last time I reviewed. Was that just an error, previously, or is it to do with the pagination fixes?

InfiniteScrollView(
triggerDeterminer: infiniteScrollTriggerDeterminer,
loadMore: {
guard case .loaded(_, let hasMoreItems) = bookingsViewState, hasMoreItems else { return }
Copy link
Contributor

Choose a reason for hiding this comment

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

Didn't notice this before but definitely seems better to take this logic out of the view 👍

cacheClearStrategy: cacheClearStrategy
)
let bookings = await fetchLocalBookingsFromStorage()
guard let filters else { return PagedItems(items: [], hasMorePages: hasMorePages, totalItems: nil) }
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
guard let filters else { return PagedItems(items: [], hasMorePages: hasMorePages, totalItems: nil) }
guard let filters else {
return PagedItems(items: [], hasMorePages: hasMorePages, totalItems: nil)
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature: POS type: task An internally driven task.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants