Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,8 @@ private extension BookingListContainerView {
height: Layout.selectedTabIndicatorHeight)
.offset(x: tabIndicatorOffset(containerWidth: geometry.size.width,
tabCount: BookingListTab.allCases.count,
selectedIndex: viewModel.selectedTab.rawValue))
selectedIndex: viewModel.selectedTab.rawValue),
y: -Layout.selectedTabIndicatorHeight / 2)
Copy link
Contributor

Choose a reason for hiding this comment

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

Should it be + for the indicator Y? In my testing the - lifts the indicator even higher from the view bottom.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Nice catch! I'll fix this in the next PR #16211.

.animation(.easeInOut(duration: 0.3), value: viewModel.selectedTab.rawValue)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,13 @@ enum BookingListTab: Int, CaseIterable {
case upcoming
case all

static let utcTimeZone: TimeZone = {
guard let timeZone = TimeZone(identifier: "UTC") else {
fatalError("Unable to set up UTC time zone")
}
return timeZone
}()

var title: String {
switch self {
case .today: Localization.today
Expand All @@ -39,6 +46,21 @@ enum BookingListTab: Int, CaseIterable {
}
}

func startDateBefore(currentDate: Date) -> Date? {
switch self {
case .today: currentDate.endOfDay(timezone: Self.utcTimeZone).addingTimeInterval(1)
case .upcoming, .all: nil
}
}

func startDateAfter(currentDate: Date) -> Date? {
switch self {
case .today: currentDate.startOfDay(timezone: Self.utcTimeZone).addingTimeInterval(-1)
case .upcoming: currentDate.endOfDay(timezone: Self.utcTimeZone)
case .all: nil
}
}

private enum Localization {
static let today = NSLocalizedString(
"bookingListView.today",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,7 @@ struct BookingListView: View {
}
}
.task {
// Only load first page if no content is available.
if viewModel.bookings.isEmpty {
viewModel.loadBookings()
}
viewModel.loadBookings()
}
}
}
Expand Down Expand Up @@ -58,7 +55,9 @@ private extension BookingListView {
func bookingItem(_ booking: Booking) -> some View {
VStack(spacing: 0) {
VStack(alignment: .leading) {
Text(booking.startDate.formatted(date: .numeric, time: .shortened))
Text(booking.startDate.toString(dateStyle: .short,
timeStyle: .short,
timeZone: BookingListTab.utcTimeZone))
.font(.body)
.fontWeight(.medium)
.frame(maxWidth: .infinity, alignment: .leading)
Expand Down
39 changes: 27 additions & 12 deletions WooCommerce/Classes/Bookings/BookingList/BookingListViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ final class BookingListViewModel: ObservableObject {
private let type: BookingListTab
private let stores: StoresManager
private let storage: StorageManagerType
private let currentDate: Date

private static let refreshCacheReason = "refresh-cache"

/// Keeps track of the current state of the syncing
@Published private(set) var syncState: SyncState = .empty
Expand All @@ -24,22 +27,31 @@ final class BookingListViewModel: ObservableObject {

/// Booking ResultsController.
private lazy var resultsController: ResultsController<StorageBooking> = {
let predicate = NSPredicate(format: "siteID == %lld", siteID)
let sortDescriptorByDate = NSSortDescriptor(key: "dateCreated", ascending: false)
var predicates = [NSPredicate(format: "siteID == %lld", siteID)]
if let before = type.startDateBefore(currentDate: currentDate) {
predicates.append(NSPredicate(format: "startDate < %@", before as NSDate))
}
if let after = type.startDateAfter(currentDate: currentDate) {
predicates.append(NSPredicate(format: "startDate > %@", after as NSDate))
}
let combinedPredicate = NSCompoundPredicate(type: .and, subpredicates: predicates)
let sortDescriptorByDate = NSSortDescriptor(key: "startDate", ascending: false)
let resultsController = ResultsController<StorageBooking>(storageManager: storage,
matching: predicate,
matching: combinedPredicate,
sortedBy: [sortDescriptorByDate])
return resultsController
}()

init(siteID: Int64,
type: BookingListTab,
stores: StoresManager = ServiceLocator.stores,
storage: StorageManagerType = ServiceLocator.storageManager) {
storage: StorageManagerType = ServiceLocator.storageManager,
currentDate: Date = Date()) {
self.siteID = siteID
self.type = type
self.stores = stores
self.storage = storage
self.currentDate = currentDate
self.paginationTracker = PaginationTracker(pageFirstIndex: pageFirstIndex)

configureResultsController()
Expand All @@ -60,7 +72,7 @@ final class BookingListViewModel: ObservableObject {
@MainActor
func onRefreshAction() async {
await withCheckedContinuation { continuation in
paginationTracker.resync(reason: nil) {
paginationTracker.resync(reason: Self.refreshCacheReason) {
continuation.resume(returning: ())
}
}
Expand Down Expand Up @@ -92,20 +104,23 @@ private extension BookingListViewModel {

/// Updates row view models and sync state.
func updateResults() {
/// TODO: update logic for fetching bookings
if type == .all {
bookings = resultsController.fetchedObjects
} else {
bookings = []
}
bookings = resultsController.fetchedObjects
transitionToResultsUpdatedState()
}
}

extension BookingListViewModel: PaginationTrackerDelegate {
func sync(pageNumber: Int, pageSize: Int, reason: String?, onCompletion: SyncCompletion?) {
transitionToSyncingState()
let action = BookingAction.synchronizeBookings(siteID: siteID, pageNumber: pageNumber, pageSize: pageSize) { [weak self] result in
let shouldClearCache = reason == Self.refreshCacheReason
let action = BookingAction.synchronizeBookings(
siteID: siteID,
pageNumber: pageNumber,
pageSize: pageSize,
startDateBefore: type.startDateBefore(currentDate: currentDate)?.ISO8601Format(),
startDateAfter: type.startDateAfter(currentDate: currentDate)?.ISO8601Format(),
shouldClearCache: shouldClearCache
) { [weak self] result in
switch result {
case .success(let hasNextPage):
onCompletion?(.success(hasNextPage))
Expand Down
Loading