feat: Dates Tab integration with Calendar - #347
Conversation
|
Hey @shafqat-muneer, thanks, looks great! 🚀 RPReplay_Final1710750802.mp4 |
| <key>NSCalendarsUsageDescription</key> | ||
| <string>edX would like to use your calendar list to subscribe to your personalized edX calendar for this course.</string> | ||
| <key>NSCalendarsFullAccessUsageDescription</key> | ||
| <string>edX would like to use your calendar list to subscribe to your personalized edX calendar for this course.</string> |
There was a problem hiding this comment.
Could you please not hardcode the name of the edX app?
Ideally, we should use platformName or something similar from the config.yaml.
Hi @volodymyr-chekyrta, thanks for the review. |
Makes sense to me, thank you! 👍 |
| import Core | ||
| import BranchSDK | ||
|
|
||
| enum DeepLinkType: String { |
There was a problem hiding this comment.
@shafqat-muneer maybe we could re-use DeepLinkType and DeepLinkKeys defined in DeepLink class to avoid duplication?
Thank you
| courseID: courseID, | ||
| title: calendarName, | ||
| isOn: true, | ||
| modalPresented: false) |
There was a problem hiding this comment.
Could you move the bracket to the next line to respect the "parameter on its own line" style?
|
|
||
| if viewModel.dueDatesShifted { | ||
| DatesShiftedSuccessView(selectedTab: .dates, courseDatesViewModel: viewModel) | ||
| DatesSuccessView(title: CourseLocalization.CourseDates.toastSuccessTitle, |
There was a problem hiding this comment.
"parameter on its own line" style please
| CoreAssets.syncToCalendar.swiftUIImage | ||
| Toggle( | ||
| CourseLocalization.CourseDates.syncToCalendar, | ||
| isOn: $viewModel.isOn) |
There was a problem hiding this comment.
"parameter on its own line" style please
|
|
||
| if viewModel.dueDatesShifted && !isVideo { | ||
| DatesShiftedSuccessView(selectedTab: .course, courseContainerViewModel: viewModel) { | ||
| DatesSuccessView(title: CourseLocalization.CourseDates.toastSuccessTitle, |
There was a problem hiding this comment.
"parameter on its own line" style please
23b03dc to
9ad0c82
Compare
saeedbashir
left a comment
There was a problem hiding this comment.
- On adding the second calendar the
syncing calendarkeeps on screen and never goes away. - On selecting
cancelremove on remove calendar alert, the switch should turns back on.
| DatesSuccessView( | ||
| title: CourseLocalization.CourseDates.calendarEvents, | ||
| message: CourseLocalization.CourseDates.calendarEventsAdded, | ||
| selectedTab: .dates | ||
| ) { | ||
| Task { | ||
| await MainActor.run { | ||
| viewModel.calendarEventsAdded = false | ||
| } | ||
| } | ||
| } |
There was a problem hiding this comment.
This code is being shared between the following three conditions calendarEventsAdded, calendarEventsRemoved, and calendarEventsUpdated. How about moving it to a function and use that. Even that func can be used for dueDatesShifted with an additional param.
| @Published var calendarEventsAdded: Bool = false | ||
| @Published var calendarEventsRemoved: Bool = false | ||
| @Published var calendarEventsUpdated: Bool = false |
There was a problem hiding this comment.
Instead of using a boolean for each condition, how about using an enum for these cases?
| }, | ||
| okTapped: { | ||
| self.router.dismiss(animated: true) | ||
| self.removeCourseCalendar { [weak self] success in |
There was a problem hiding this comment.
success is unused here, so it can be replaced with _.
| positiveAction: CourseLocalization.CourseDates.calendarShiftPromptUpdateNow, | ||
| onCloseTapped: { | ||
| // Remove course calendar | ||
| self.router.dismiss(animated: true) |
There was a problem hiding this comment.
How about using weak self in closures? if so please update it for all alert functions.
| get { | ||
| if let calendarEntry = calendarEntry, | ||
| let localCalendar = localCalendar { | ||
| if calendarEntry.identifier == localCalendar.calendarIdentifier { |
There was a problem hiding this comment.
Is it possible to move this if condition to where clause of if let?
|
@saeedbashir I have made the recommended adjustments. Kindly review them. |
| } else { | ||
| if let localCalendar = localCalendar { |
There was a problem hiding this comment.
I guess else and il let can be merged like else if let
| ), | ||
| positiveAction: CoreLocalization.Alert.accept, | ||
| onCloseTapped: { [weak self] in | ||
| guard let self else { return } |
There was a problem hiding this comment.
It seems strong reference if self isn't required in this type of blocks because if the self will be nill, by using the optional self will not crash the app and following code will automatically be ignored.
|
@saeedbashir I have addressed requested changes. @volodymyr-chekyrta Please also review this pull request. Thank you. |
volodymyr-chekyrta
left a comment
There was a problem hiding this comment.
LGTM 👍
Just one question
| return DatesSuccessView( | ||
| title: title, | ||
| message: message, | ||
| selectedTab: .dates | ||
| ) { | ||
| Task { | ||
| await MainActor.run { | ||
| viewModel.eventState = CourseDatesViewModel.EventState.none | ||
| } | ||
| } | ||
| } |
There was a problem hiding this comment.
Can it be simplified just to something like this?
return DatesSuccessView(
title: title,
message: message,
selectedTab: .dates
) {
viewModel.eventState = CourseDatesViewModel.EventState.none
}
There was a problem hiding this comment.
This seems a bit odd. We switch to a Task only to switch back to the MainActor.
There was a problem hiding this comment.
@volodymyr-chekyrta Thank you for bringing that to my attention. I've streamlined the logic for simplification.
Explanation:
The DatesSuccessView struct was previously invoking action closures asynchronously on a background thread. Upon receiving the closure action, we had to switch back to the main thread to avoid warnings such as:
Publishing changes from background threads is not allowed; make sure to publish values from the main thread (via operators like receive(on:)) on model updates.
I've refactored this logic so that the action closures in DatesSuccessView are no longer asynchronous.
8363d7f
Jira Tickets:
Github Issues:
Demos
Light Mode: Sync and un-sync events in calendar application:
Simulator.Screen.Recording.-.iPhone.15.-.2024-03-15.at.12.42.44.mp4
Light Mode: Update out dated calendar:
Simulator.Screen.Recording.-.iPhone.15.-.2024-03-15.at.12.49.21.mp4
Light Mode: Deep Linking:
RPReplay_Final1710750802.mp4
Dark Mode: Sync and un-sync events in calendar application:
Simulator.Screen.Recording.-.iPhone.15.-.2024-03-15.at.12.43.27.mp4
Dark Mode: Update out dated calendar:
Simulator.Screen.Recording.-.iPhone.15.-.2024-03-15.at.12.50.38.mp4