Skip to content

Commit

Permalink
feat: Dates Tab integration with Calendar
Browse files Browse the repository at this point in the history
  • Loading branch information
shafqat-muneer authored Mar 26, 2024
1 parent 513a883 commit d02b303
Show file tree
Hide file tree
Showing 44 changed files with 1,418 additions and 156 deletions.
46 changes: 24 additions & 22 deletions Authorization/AuthorizationTests/AuthorizationMock.generated.swift

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"images" : [
{
"filename" : "placeholder-icon.svg",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
},
"properties" : {
"template-rendering-intent" : "template"
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions Core/Core/Configuration/BaseRouter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ public protocol BaseRouter {
nextSectionTapped: @escaping () -> Void
)

func presentView(transitionStyle: UIModalTransitionStyle, view: any View)
func presentView(transitionStyle: UIModalTransitionStyle, view: any View, completion: (() -> Void)?)

func presentView(transitionStyle: UIModalTransitionStyle, animated: Bool, content: () -> any View)

Expand Down Expand Up @@ -121,7 +121,7 @@ open class BaseRouterMock: BaseRouter {
nextSectionTapped: @escaping () -> Void
) {}

public func presentView(transitionStyle: UIModalTransitionStyle, view: any View) {}
public func presentView(transitionStyle: UIModalTransitionStyle, view: any View, completion: (() -> Void)?) {}

public func presentView(transitionStyle: UIModalTransitionStyle, animated: Bool, content: () -> any View) {}

Expand Down
11 changes: 10 additions & 1 deletion Core/Core/Domain/Model/CourseBlockModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,13 @@ public struct CourseStructure: Equatable {
public func totalVideosSizeInGb(downloadQuality: DownloadQuality) -> Double {
Double(totalVideosSizeInBytes(downloadQuality: downloadQuality)) / 1024.0 / 1024.0 / 1024.0
}


public func blockWithID(courseBlockId: String) -> CourseBlock? {
let block = childs.flatMap {
$0.childs.flatMap { $0.childs.flatMap { $0.childs.compactMap { $0 } } }
}.filter { $0.id == courseBlockId }.first
return block
}
}

public struct CourseChapter: Identifiable {
Expand Down Expand Up @@ -185,6 +191,7 @@ public struct CourseBlock: Hashable, Identifiable {
public let type: BlockType
public let displayName: String
public let studentUrl: String
public let webUrl: String
public let subtitles: [SubtitleUrl]?
public let encodedVideo: CourseBlockEncodedVideo?
public let multiDevice: Bool?
Expand All @@ -203,6 +210,7 @@ public struct CourseBlock: Hashable, Identifiable {
type: BlockType,
displayName: String,
studentUrl: String,
webUrl: String,
subtitles: [SubtitleUrl]? = nil,
encodedVideo: CourseBlockEncodedVideo?,
multiDevice: Bool?
Expand All @@ -216,6 +224,7 @@ public struct CourseBlock: Hashable, Identifiable {
self.type = type
self.displayName = displayName
self.studentUrl = studentUrl
self.webUrl = webUrl
self.subtitles = subtitles
self.encodedVideo = encodedVideo
self.multiDevice = multiDevice
Expand Down
1 change: 1 addition & 0 deletions Core/Core/SwiftGen/Assets.swift
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ public enum CoreAssets {
public static let lockIcon = ImageAsset(name: "lock_icon")
public static let lockWithWatchIcon = ImageAsset(name: "lock_with_watch_icon")
public static let schoolCapIcon = ImageAsset(name: "school_cap_icon")
public static let syncToCalendar = ImageAsset(name: "sync_to_calendar")
public static let bookCircle = ImageAsset(name: "book.circle")
public static let bubbleLeftCircle = ImageAsset(name: "bubble.left.circle")
public static let docCircle = ImageAsset(name: "doc.circle")
Expand Down
10 changes: 10 additions & 0 deletions Core/Core/SwiftGen/Strings.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import Foundation
public enum CoreLocalization {
/// Done
public static let done = CoreLocalization.tr("Localizable", "DONE", fallback: "Done")
/// View in Safari
public static let openInBrowser = CoreLocalization.tr("Localizable", "OPEN_IN_BROWSER", fallback: "View in Safari")
/// The user canceled the sign-in flow.
public static let socialSignCanceled = CoreLocalization.tr("Localizable", "SOCIAL_SIGN_CANCELED", fallback: "The user canceled the sign-in flow.")
/// Tomorrow
Expand All @@ -23,6 +25,10 @@ public enum CoreLocalization {
public enum Alert {
/// ACCEPT
public static let accept = CoreLocalization.tr("Localizable", "ALERT.ACCEPT", fallback: "ACCEPT")
/// Add
public static let add = CoreLocalization.tr("Localizable", "ALERT.ADD", fallback: "Add")
/// Remove course calendar
public static let calendarShiftPromptRemoveCourseCalendar = CoreLocalization.tr("Localizable", "ALERT.CALENDAR_SHIFT_PROMPT_REMOVE_COURSE_CALENDAR", fallback: "Remove course calendar")
/// CANCEL
public static let cancel = CoreLocalization.tr("Localizable", "ALERT.CANCEL", fallback: "CANCEL")
/// DELETE
Expand All @@ -33,6 +39,8 @@ public enum CoreLocalization {
public static let leave = CoreLocalization.tr("Localizable", "ALERT.LEAVE", fallback: "Leave")
/// Log out
public static let logout = CoreLocalization.tr("Localizable", "ALERT.LOGOUT", fallback: "Log out")
/// Remove
public static let remove = CoreLocalization.tr("Localizable", "ALERT.REMOVE", fallback: "Remove")
}
public enum Courseware {
/// Back to outline
Expand All @@ -41,6 +49,8 @@ public enum CoreLocalization {
public static let `continue` = CoreLocalization.tr("Localizable", "COURSEWARE.CONTINUE", fallback: "Continue")
/// Course content
public static let courseContent = CoreLocalization.tr("Localizable", "COURSEWARE.COURSE_CONTENT", fallback: "Course content")
/// This interactive component isn't yet available on mobile.
public static let courseContentNotAvailable = CoreLocalization.tr("Localizable", "COURSEWARE.COURSE_CONTENT_NOT_AVAILABLE", fallback: "This interactive component isn't yet available on mobile.")
/// Course units
public static let courseUnits = CoreLocalization.tr("Localizable", "COURSEWARE.COURSE_UNITS", fallback: "Course units")
/// Finish
Expand Down
45 changes: 42 additions & 3 deletions Core/Core/View/Base/AlertView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,16 @@ public enum AlertViewType: Equatable {
case leaveProfile
case deleteVideo
case deepLink
case addCalendar
case removeCalendar
case updateCalendar
case calendarAdded

var contentPadding: CGFloat {
switch self {
case .`default`:
case .`default`, .calendarAdded:
return 16
case .action, .logOut, .leaveProfile, .deleteVideo, .deepLink:
case .action, .logOut, .leaveProfile, .deleteVideo, .deepLink, .addCalendar, .removeCalendar, .updateCalendar:
return 36
}
}
Expand All @@ -31,6 +35,7 @@ public struct AlertView: View {
private var alertTitle: String
private var alertMessage: String
private var nextSectionName: String?
private var positiveAction: String
private var onCloseTapped: (() -> Void) = {}
private var okTapped: (() -> Void) = {}
private var nextSectionTapped: (() -> Void) = {}
Expand All @@ -48,6 +53,7 @@ public struct AlertView: View {
) {
self.alertTitle = alertTitle
self.alertMessage = alertMessage
self.positiveAction = positiveAction
self.onCloseTapped = onCloseTapped
self.okTapped = okTapped
self.type = type
Expand All @@ -69,6 +75,7 @@ public struct AlertView: View {
self.nextSectionName = nextSectionName
self.okTapped = okTapped
self.nextSectionTapped = nextSectionTapped
self.positiveAction = ""
type = .action(mainAction, image)
}

Expand Down Expand Up @@ -147,12 +154,18 @@ public struct AlertView: View {
.multilineTextAlignment(.center)
.padding(.horizontal, 40)
.frame(maxWidth: 250)
case .leaveProfile, .deleteVideo, .deepLink:
case .leaveProfile, .deleteVideo, .deepLink, .addCalendar, .removeCalendar, .updateCalendar:
VStack(spacing: 20) {
switch type {
case .deleteVideo, .deepLink:
CoreAssets.warning.swiftUIImage
.padding(.top, isHorizontal ? 20 : 54)
case .addCalendar, .removeCalendar, .updateCalendar:
CoreAssets.syncToCalendar.swiftUIImage
.resizable()
.scaledToFit()
.frame(width: 50, height: 50)
.padding(.top, isHorizontal ? 20 : 54)
default:
CoreAssets.leaveProfile.swiftUIImage
.padding(.top, isHorizontal ? 20 : 54)
Expand Down Expand Up @@ -362,6 +375,32 @@ public struct AlertView: View {
primaryButtonTitle: CoreLocalization.view,
secondaryButtonTitle: CoreLocalization.Alert.cancel
)
case .addCalendar:
configure(
primaryButtonTitle: CoreLocalization.Alert.add,
secondaryButtonTitle: CoreLocalization.Alert.cancel
)
case .removeCalendar:
configure(
primaryButtonTitle: CoreLocalization.Alert.remove,
secondaryButtonTitle: CoreLocalization.Alert.cancel
)
case .updateCalendar:
configure(
primaryButtonTitle: positiveAction,
secondaryButtonTitle: CoreLocalization.Alert.calendarShiftPromptRemoveCourseCalendar
)
case .calendarAdded:
HStack {
StyledButton(positiveAction, action: { okTapped() })
.frame(maxWidth: 135)
StyledButton(CoreLocalization.done, action: { onCloseTapped() })
.frame(maxWidth: 135)
.saturation(0)
}
.padding(.leading, 10)
.padding(.trailing, 10)
.padding(.bottom, 10)
}
}
.padding(.top, 16)
Expand Down
6 changes: 6 additions & 0 deletions Core/Core/en.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
"ERROR.AUTHORIZATION_FAILED" = "Authorization failed.";

"COURSEWARE.COURSE_CONTENT" = "Course content";
"COURSEWARE.COURSE_CONTENT_NOT_AVAILABLE" = "This interactive component isn't yet available on mobile.";
"COURSEWARE.COURSE_UNITS" = "Course units";
"COURSEWARE.NEXT" = "Next";
"COURSEWARE.PREVIOUS" = "Prev";
Expand Down Expand Up @@ -52,6 +53,9 @@
"ALERT.LEAVE" = "Leave";
"ALERT.KEEP_EDITING" = "Keep editing";
"ALERT.DELETE" = "DELETE";
"ALERT.ADD" = "Add";
"ALERT.REMOVE" = "Remove";
"ALERT.CALENDAR_SHIFT_PROMPT_REMOVE_COURSE_CALENDAR"="Remove course calendar";

"NO_INTERNET.OFFLINE" = "Offline";
"NO_INTERNET.DISMISS" = "Dismiss";
Expand Down Expand Up @@ -106,3 +110,5 @@

"TOMORROW" = "Tomorrow";
"YESTERDAY" = "Yesterday";

"OPEN_IN_BROWSER"="View in Safari";
6 changes: 6 additions & 0 deletions Core/Core/uk.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
"ERROR.WIFI" = "Завантажувати файли можна лише через Wi-Fi. Ви можете змінити це в налаштуваннях.";

"COURSEWARE.COURSE_CONTENT" = "Зміст курсу";
"COURSEWARE.COURSE_CONTENT_NOT_AVAILABLE" = "This interactive component isn't yet available on mobile.";
"COURSEWARE.COURSE_UNITS" = "Модулі";
"COURSEWARE.NEXT" = "Далі";
"COURSEWARE.PREVIOUS" = "Назад";
Expand Down Expand Up @@ -50,6 +51,9 @@
"ALERT.LOGOUT" = "Вийти";
"ALERT.LEAVE" = "Покинути";
"ALERT.KEEP_EDITING" = "Залишитись";
"ALERT.ADD" = "Add";
"ALERT.REMOVE" = "Remove";
"ALERT.CALENDAR_SHIFT_PROMPT_REMOVE_COURSE_CALENDAR"="Remove course calendar";

"NO_INTERNET.OFFLINE" = "Офлайн режим";
"NO_INTERNET.DISMISS" = "Сховати";
Expand Down Expand Up @@ -105,3 +109,5 @@

"TOMORROW" = "Tomorrow";
"YESTERDAY" = "Yesterday";

"OPEN_IN_BROWSER"="View in Safari";
24 changes: 20 additions & 4 deletions Course/Course.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,10 @@
197FB8EA8F92F00A8F383D82 /* Pods_App_Course.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E5E795BD160CDA7D9C120DE6 /* Pods_App_Course.framework */; };
975F475E2B6151FD00E5B031 /* CourseDatesMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 975F475D2B6151FD00E5B031 /* CourseDatesMock.swift */; };
975F47602B615DA700E5B031 /* CourseStructureMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 975F475F2B615DA700E5B031 /* CourseStructureMock.swift */; };
97CA95252B875EE200A9EDEA /* DatesShiftedSuccessView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 97CA95242B875EE200A9EDEA /* DatesShiftedSuccessView.swift */; };
97C99C362B9A08FE004EEDE2 /* CalendarSyncProgressView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 97C99C352B9A08FE004EEDE2 /* CalendarSyncProgressView.swift */; };
97CA95252B875EE200A9EDEA /* DatesSuccessView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 97CA95242B875EE200A9EDEA /* DatesSuccessView.swift */; };
97E7DF0F2B7C852A00A2A09B /* DatesStatusInfoView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 97E7DF0E2B7C852A00A2A09B /* DatesStatusInfoView.swift */; };
97EA4D862B85034D00663F58 /* CalendarManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 97EA4D852B85034D00663F58 /* CalendarManager.swift */; };
B8F50317B6B830A0E520C954 /* Pods_App_Course_CourseTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 50E59D2B81E12610964282C5 /* Pods_App_Course_CourseTests.framework */; };
BA58CF5D2B3D804D005B102E /* CourseStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = BA58CF5C2B3D804D005B102E /* CourseStorage.swift */; };
BA58CF612B471041005B102E /* VideoDownloadQualityBarView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BA58CF602B471041005B102E /* VideoDownloadQualityBarView.swift */; };
Expand Down Expand Up @@ -171,8 +173,10 @@
831B08139890634968EDD44D /* Pods-App-Course-CourseTests.debugstage.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-App-Course-CourseTests.debugstage.xcconfig"; path = "Target Support Files/Pods-App-Course-CourseTests/Pods-App-Course-CourseTests.debugstage.xcconfig"; sourceTree = "<group>"; };
975F475D2B6151FD00E5B031 /* CourseDatesMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CourseDatesMock.swift; sourceTree = "<group>"; };
975F475F2B615DA700E5B031 /* CourseStructureMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CourseStructureMock.swift; sourceTree = "<group>"; };
97CA95242B875EE200A9EDEA /* DatesShiftedSuccessView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DatesShiftedSuccessView.swift; sourceTree = "<group>"; };
97C99C352B9A08FE004EEDE2 /* CalendarSyncProgressView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CalendarSyncProgressView.swift; sourceTree = "<group>"; };
97CA95242B875EE200A9EDEA /* DatesSuccessView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DatesSuccessView.swift; sourceTree = "<group>"; };
97E7DF0E2B7C852A00A2A09B /* DatesStatusInfoView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DatesStatusInfoView.swift; sourceTree = "<group>"; };
97EA4D852B85034D00663F58 /* CalendarManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CalendarManager.swift; sourceTree = "<group>"; };
99AEF08FD75F1509863D3302 /* Pods-App-CourseDetails.debugprod.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-App-CourseDetails.debugprod.xcconfig"; path = "Target Support Files/Pods-App-CourseDetails/Pods-App-CourseDetails.debugprod.xcconfig"; sourceTree = "<group>"; };
9B5D3D31A9CFA08B6C4347BD /* Pods-App-CourseDetails.releasedev.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-App-CourseDetails.releasedev.xcconfig"; path = "Target Support Files/Pods-App-CourseDetails/Pods-App-CourseDetails.releasedev.xcconfig"; sourceTree = "<group>"; };
A47C63D9EB0D866F303D4588 /* Pods-App-Course.releasestage.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-App-Course.releasestage.xcconfig"; path = "Target Support Files/Pods-App-Course/Pods-App-Course.releasestage.xcconfig"; sourceTree = "<group>"; };
Expand Down Expand Up @@ -288,6 +292,7 @@
02B6B3B828E1D12900232911 /* Data */,
02B6B3B528E1D10700232911 /* Domain */,
02EAE2CA28E1F0A700529644 /* Presentation */,
97EA4D822B84EFA900663F58 /* Managers */,
97CA95212B875EA200A9EDEA /* Views */,
02B6B3B428E1C49400232911 /* Localizable.strings */,
);
Expand Down Expand Up @@ -491,11 +496,20 @@
97CA95212B875EA200A9EDEA /* Views */ = {
isa = PBXGroup;
children = (
97CA95242B875EE200A9EDEA /* DatesShiftedSuccessView.swift */,
97C99C352B9A08FE004EEDE2 /* CalendarSyncProgressView.swift */,
97CA95242B875EE200A9EDEA /* DatesSuccessView.swift */,
);
path = Views;
sourceTree = "<group>";
};
97EA4D822B84EFA900663F58 /* Managers */ = {
isa = PBXGroup;
children = (
97EA4D852B85034D00663F58 /* CalendarManager.swift */,
);
path = Managers;
sourceTree = "<group>";
};
BA58CF622B471047005B102E /* VideoDownloadQualityBarView */ = {
isa = PBXGroup;
children = (
Expand Down Expand Up @@ -860,13 +874,15 @@
022C64D829ACEC48000F532B /* HandoutsView.swift in Sources */,
02454CA82A2619890043052A /* DiscussionView.swift in Sources */,
0265B4B728E2141D00E6EAFD /* Strings.swift in Sources */,
97C99C362B9A08FE004EEDE2 /* CalendarSyncProgressView.swift in Sources */,
BAC0E0D82B32EF03006B68A9 /* DownloadsView.swift in Sources */,
97CA95252B875EE200A9EDEA /* DatesShiftedSuccessView.swift in Sources */,
97CA95252B875EE200A9EDEA /* DatesSuccessView.swift in Sources */,
DB7D6EAC2ADFCAC50036BB13 /* CourseDatesView.swift in Sources */,
0766DFCC299AA7A600EBEF6A /* YouTubeVideoPlayer.swift in Sources */,
022F8E162A1DFBC6008EFAB9 /* YouTubeVideoPlayerViewModel.swift in Sources */,
02F175372A4DAFD20019CD70 /* CourseAnalytics.swift in Sources */,
02B6B3BE28E1D15C00232911 /* CourseEndpoint.swift in Sources */,
97EA4D862B85034D00663F58 /* CalendarManager.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down
2 changes: 2 additions & 0 deletions Course/Course/Data/CourseRepository.swift
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,7 @@ public class CourseRepository: CourseRepositoryProtocol {
type: BlockType(rawValue: block.type) ?? .unknown,
displayName: block.displayName,
studentUrl: block.studentUrl,
webUrl: block.webUrl,
subtitles: subtitles,
encodedVideo: .init(
fallback: parseVideo(encodedVideo: block.userViewData?.encodedVideo?.fallback),
Expand Down Expand Up @@ -420,6 +421,7 @@ And there are various ways of describing it-- call it oral poetry or
type: BlockType(rawValue: block.type) ?? .unknown,
displayName: block.displayName,
studentUrl: block.studentUrl,
webUrl: block.webUrl,
subtitles: subtitles,
encodedVideo: .init(
fallback: parseVideo(encodedVideo: block.userViewData?.encodedVideo?.fallback),
Expand Down
Loading

0 comments on commit d02b303

Please sign in to comment.