-
Notifications
You must be signed in to change notification settings - Fork 1
Swiping on calendar days #176
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
base: main
Are you sure you want to change the base?
Changes from all commits
a98507d
3c66954
543529e
ca9437d
8a13542
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -67,12 +67,15 @@ struct RoomBookingsListView: View { | |
| } | ||
| .frame(height: hoursToDisplay * 40) | ||
| } | ||
| .frame(height: hoursToDisplay * 40) | ||
| .clipShape(RoundedRectangle(cornerRadius: 12)) | ||
| .onAppear { | ||
| let currentHour = max(dateComponent.hour ?? 0, 9) | ||
| withAnimation(.easeInOut(duration: 0.5)) { | ||
| proxy.scrollTo(currentHour, anchor: .top) | ||
| if Calendar.current.isDateInToday(dateSelect) { | ||
| let currentHour = max(dateComponent.hour ?? 0, 9) | ||
| withAnimation(.easeInOut(duration: 0.5)) { | ||
| proxy.scrollTo(currentHour, anchor: .top) | ||
| } | ||
| } else { | ||
| proxy.scrollTo(9, anchor: .top) | ||
|
Comment on lines
+73
to
+78
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. magic number |
||
| } | ||
| } | ||
| } | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -10,6 +10,8 @@ import RoomModels | |
| import RoomViewModels | ||
| import SwiftUI | ||
|
|
||
| // MARK: - RoomDetailsSheetView | ||
|
|
||
| struct RoomDetailsSheetView: View { | ||
|
|
||
| // MARK: Lifecycle | ||
|
|
@@ -23,13 +25,10 @@ struct RoomDetailsSheetView: View { | |
|
|
||
| // MARK: Internal | ||
|
|
||
| @State var dateSelect = Date() | ||
|
|
||
| let room: Room | ||
|
|
||
| var body: some View { | ||
| VStack(alignment: .leading, spacing: 10) { | ||
| // List { | ||
| // Booking informations | ||
| RoomBookingInformationView(room: room, currentRoomRating: roomViewModel.currentRoomRating) | ||
|
|
||
|
|
@@ -48,11 +47,34 @@ struct RoomDetailsSheetView: View { | |
| } | ||
|
|
||
| // Booking Grid | ||
| ScrollView { | ||
| RoomBookingsListView( | ||
| room: room, | ||
| roomViewModel: roomViewModel, | ||
| dateSelect: $dateSelect) | ||
| ScrollView(.horizontal, showsIndicators: false) { | ||
| LazyHStack(spacing: 0) { | ||
| ForEach(0..<Self.maxScrollID, id: \.self) { index in | ||
| RoomBookingsListView( | ||
| room: room, | ||
| roomViewModel: roomViewModel, | ||
| dateSelect: bindingFor(index: index)) | ||
| .id(index) | ||
| .containerRelativeFrame(.horizontal) | ||
| } | ||
| } | ||
| .scrollTargetLayout() | ||
| } | ||
| .scrollTargetBehavior(.paging) | ||
| .scrollPosition(id: $scrollID) | ||
| .onChange(of: scrollID) { oldValue, newValue in | ||
| if let newValue, let oldValue, abs(newValue - oldValue) == 1 { | ||
| dateSelect = baseDate + (Double(newValue - Self.middleIndex) * .day) | ||
| } | ||
| } | ||
| .onChange(of: dateSelect) { _, newValue in | ||
| let currentScroll = scrollID ?? Self.middleIndex | ||
| let expectedDate = baseDate + (Double(currentScroll - Self.middleIndex) * .day) | ||
|
|
||
| if abs(newValue.timeIntervalSince(expectedDate)) > 1 { | ||
| baseDate = newValue | ||
| scrollID = Self.middleIndex | ||
|
Comment on lines
+65
to
+76
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. logic in the view model so its testable |
||
| } | ||
| } | ||
| } | ||
| .padding() | ||
|
|
@@ -80,8 +102,24 @@ struct RoomDetailsSheetView: View { | |
| }) | ||
| } | ||
|
|
||
| func bindingFor(index: Int) -> Binding<Date> { | ||
| Binding( | ||
| get: { baseDate + (Double(index - Self.middleIndex) * .day) }, | ||
| set: { newDate in | ||
| baseDate = newDate + (Double(Self.middleIndex - index) * .day) | ||
| }) | ||
| } | ||
|
|
||
| // MARK: Private | ||
|
|
||
| // Paging is 0 <= page < middleindex * 2 | ||
| private static let maxScrollID = Self.middleIndex * 2 | ||
| private static let middleIndex = 500 | ||
|
|
||
| @State private var scrollID: Int? = middleIndex | ||
| @State private var baseDate = Date() | ||
| @State private var dateSelect = Date() | ||
|
Comment on lines
+119
to
+121
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Lets move all the states and logic to the view model instead, makes the view logic more testable and adhere to the architecture too |
||
|
|
||
| @Environment(Theme.self) private var theme | ||
|
|
||
| private let onDismiss: (() -> Void)? | ||
|
|
@@ -94,3 +132,13 @@ struct RoomDetailsSheetView: View { | |
| RoomDetailsSheetView(room: Room.exampleOne, roomViewModel: PreviewRoomViewModel()) | ||
| .defaultTheme() | ||
| } | ||
|
|
||
| extension Double { | ||
| static let day: Double = 86_400 | ||
| } | ||
|
Comment on lines
+136
to
+138
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this might be a reusable Double extension put it in a common file instead of this view file |
||
|
|
||
| extension Date { | ||
| static func +(lhs: Date, rhs: Double) -> Date { | ||
| lhs.addingTimeInterval(rhs) | ||
| } | ||
| } | ||
|
Comment on lines
+140
to
+144
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. if the extension is only being used in this file use fileprivate extension Date but if might be used in othe component define the extension in the model file |
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
move this to a onAppear function in the viewModel