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
4 changes: 2 additions & 2 deletions Core/Core/Domain/Model/CourseBlockModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -449,10 +449,10 @@ public struct CourseBlockVideo: Equatable, Sendable {
}

public var isVideoURL: Bool {
[".mp4", ".m3u8"].contains(where: { url?.contains($0) == true })
[".mp4", ".m3u8", ".MP4"].contains(where: { url?.contains($0) == true })
}

public var isDownloadable: Bool {
[".mp4"].contains(where: { url?.contains($0) == true })
[".mp4", ".MP4"].contains(where: { url?.contains($0) == true })
}
}
4 changes: 4 additions & 0 deletions Course/Course.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@
A5A510A22E66E8D600553607 /* CourseVideoCarouselSlideView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5A510A12E66E8D600553607 /* CourseVideoCarouselSlideView.swift */; };
A5A510A42E6728AD00553607 /* CourseAssignmentsCarouselSlideView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5A510A32E6728AD00553607 /* CourseAssignmentsCarouselSlideView.swift */; };
A5A510A62E672E4A00553607 /* AssignmentCarouselDetailCardView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5A510A52E672E4A00553607 /* AssignmentCarouselDetailCardView.swift */; };
A59016D52E69B2E900076220 /* VideoNavigationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A59016D42E69B2E900076220 /* VideoNavigationView.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 @@ -281,6 +282,7 @@
A5A510A12E66E8D600553607 /* CourseVideoCarouselSlideView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CourseVideoCarouselSlideView.swift; sourceTree = "<group>"; };
A5A510A32E6728AD00553607 /* CourseAssignmentsCarouselSlideView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CourseAssignmentsCarouselSlideView.swift; sourceTree = "<group>"; };
A5A510A52E672E4A00553607 /* AssignmentCarouselDetailCardView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AssignmentCarouselDetailCardView.swift; sourceTree = "<group>"; };
A59016D42E69B2E900076220 /* VideoNavigationView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VideoNavigationView.swift; sourceTree = "<group>"; };
ADC2A1B8183A674705F5F7E2 /* Pods-App-Course.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-App-Course.debug.xcconfig"; path = "Target Support Files/Pods-App-Course/Pods-App-Course.debug.xcconfig"; sourceTree = "<group>"; };
B196A14555D0E006995A5683 /* Pods-App-CourseDetails.releaseprod.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-App-CourseDetails.releaseprod.xcconfig"; path = "Target Support Files/Pods-App-CourseDetails/Pods-App-CourseDetails.releaseprod.xcconfig"; sourceTree = "<group>"; };
BA58CF5C2B3D804D005B102E /* CourseStorage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CourseStorage.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -390,6 +392,7 @@
02454C9E2A2618D40043052A /* Subviews */ = {
isa = PBXGroup;
children = (
A59016D42E69B2E900076220 /* VideoNavigationView.swift */,
068DDA5A2B1E198700FF8CCB /* DropdownList */,
02454C9F2A2618E70043052A /* YouTubeView.swift */,
02454CA12A26190A0043052A /* EncodedVideoView.swift */,
Expand Down Expand Up @@ -1144,6 +1147,7 @@
975F475E2B6151FD00E5B031 /* CourseDatesMock.swift in Sources */,
02FF6FAA2C20D56A00E44DD8 /* TotalDownloadedProgressView.swift in Sources */,
975F47602B615DA700E5B031 /* CourseStructureMock.swift in Sources */,
A59016D52E69B2E900076220 /* VideoNavigationView.swift in Sources */,
02280F5E294B4FDA0032823A /* CourseCoreModel.xcdatamodeld in Sources */,
0766DFCE299AB26D00EBEF6A /* EncodedVideoPlayer.swift in Sources */,
A5A510A42E6728AD00553607 /* CourseAssignmentsCarouselSlideView.swift in Sources */,
Expand Down
16 changes: 15 additions & 1 deletion Course/Course/Domain/CourseInteractor.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ public protocol CourseInteractorProtocol: Sendable {
func enrichCourseStructureWithLocalProgress(_ structure: CourseStructure) async -> CourseStructure
func getCourseProgress(courseID: String) async throws -> CourseProgressDetails
func getCourseProgressOffline(courseID: String) async throws -> CourseProgressDetails
func getAllVideosForNavigation(structure course: CourseStructure) async throws -> [CourseBlock]
}

public actor CourseInteractor: CourseInteractorProtocol, CourseStructureManagerProtocol {
Expand Down Expand Up @@ -136,7 +137,20 @@ public actor CourseInteractor: CourseInteractorProtocol, CourseStructureManagerP
}
}
}


public func getAllVideosForNavigation(structure course: CourseStructure) -> [CourseBlock] {
var newChilds = [CourseChapter]()
for chapter in course.childs {
let newChapter = filterChapter(chapter: chapter)
if !newChapter.childs.isEmpty {
newChilds.append(newChapter)
}
}

let allVideos = getAllVideosFromStructure(childs: newChilds)
return allVideos
}

private func getAllAssignmentsFromStructure(childs: [CourseChapter]) -> [CourseBlock] {
return childs.flatMap { chapter in
chapter.childs.flatMap { sequential in
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,9 @@ public final class CourseContainerViewModel: BaseCourseViewModel {
verticalIndex: continueWith.verticalIndex,
chapters: courseStructure.childs,
chapterIndex: continueWith.chapterIndex,
sequentialIndex: continueWith.sequentialIndex
sequentialIndex: continueWith.sequentialIndex,
showVideoNavigation: false,
courseVideoStructure: nil
)
}

Expand Down Expand Up @@ -1181,7 +1183,7 @@ public final class CourseContainerViewModel: BaseCourseViewModel {
NotificationCenter.default.removeObserver(self)
}

func handleVideoTap(video: CourseBlock, chapter: CourseChapter) {
func handleVideoTap(video: CourseBlock, chapter: CourseChapter?) {
// Find indices for navigation using full course structure
guard let chapterIndex = findChapterIndexInFullStructure(video: video),
let sequentialIndex = findSequentialIndexInFullStructure(video: video),
Expand All @@ -1205,7 +1207,9 @@ public final class CourseContainerViewModel: BaseCourseViewModel {
verticalIndex: verticalIndex,
chapters: courseStructure.childs,
chapterIndex: chapterIndex,
sequentialIndex: sequentialIndex
sequentialIndex: sequentialIndex,
showVideoNavigation: true,
courseVideoStructure: courseStructure
)
}

Expand Down Expand Up @@ -1700,7 +1704,9 @@ public final class CourseContainerViewModel: BaseCourseViewModel {
verticalIndex: 0,
chapters: courseStructure.childs,
chapterIndex: chapterIndex,
sequentialIndex: sequentialIndex
sequentialIndex: sequentialIndex,
showVideoNavigation: false,
courseVideoStructure: nil
)
} else {
router.showCourseVerticalView(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ struct VideoSectionView: View {
let sectionData: VideoSectionData
let proxy: GeometryProxy
@Binding var isShowingCompletedVideos: Bool
let onVideoTap: (CourseBlock, CourseChapter) -> Void
let onVideoTap: (CourseBlock, CourseChapter?) -> Void
let onDownloadSectionTap: (CourseChapter, DownloadViewState) async -> Void

private var chapter: CourseChapter {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@ struct VideoThumbnailView: View {
if type == .continueWith {
thumbnailImageView()
.aspectRatio(16/9, contentMode: .fill)
.scaleEffect(y: 1.35, anchor: .center)
.clipped()
.cornerRadius(10)
// for future update
Expand Down Expand Up @@ -193,7 +194,7 @@ struct VideoThumbnailView: View {
.multilineTextAlignment(.leading)
.foregroundStyle(.white)
.padding(.horizontal, 11)
.padding(.top, 11)
.padding(.top, self.type == .navigationVideo ? 4 : 11)
.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .topLeading)

// MARK: - Play Button Overlay
Expand Down Expand Up @@ -227,7 +228,7 @@ struct VideoThumbnailView: View {
.clipped()
.overlay {
RoundedRectangle(cornerRadius: 10)
.stroke(lineWidth: isCurrentVideo ? 3 : (video.completion >= 1.0 ? 2 : 0))
.stroke(lineWidth: isCurrentVideo ? 4 : (video.completion >= 1.0 ? 2 : 0))
.foregroundStyle(isCurrentVideo ? Theme.Colors.accentColor : Theme.Colors.success)
}
}
Expand Down Expand Up @@ -376,8 +377,12 @@ struct VideoThumbnailView: View {
}

private func openVideo() {
if let chapter {
thumbnailData.onVideoTap(video, chapter)
if self.type == .navigationVideo {
thumbnailData.onVideoTap(video, nil)
} else {
if let chapter {
thumbnailData.onVideoTap(video, chapter)
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ struct VideoSectionData {

struct VideoThumbnailData {
let video: CourseBlock
let chapter: CourseChapter
var chapter: CourseChapter?
let courseStructure: CourseStructure?
let onVideoTap: (CourseBlock, CourseChapter) -> Void
let onVideoTap: (CourseBlock, CourseChapter?) -> Void?
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ struct VideosContentView: View {

let videoContentData: VideoContentData
private let proxy: GeometryProxy
private let onVideoTap: (CourseBlock, CourseChapter) -> Void
private let onVideoTap: (CourseBlock, CourseChapter?) -> Void
private let onDownloadSectionTap: (CourseChapter, DownloadViewState) async -> Void
private let onTabSelection: (Int) -> Void
private let onErrorDismiss: () -> Void
Expand All @@ -26,7 +26,7 @@ struct VideosContentView: View {
init(
videoContentData: VideoContentData,
proxy: GeometryProxy,
onVideoTap: @escaping (CourseBlock, CourseChapter) -> Void,
onVideoTap: @escaping (CourseBlock, CourseChapter?) -> Void,
onDownloadSectionTap: @escaping (CourseChapter, DownloadViewState) async -> Void,
onTabSelection: @escaping (Int) -> Void,
onErrorDismiss: @escaping () -> Void,
Expand Down
16 changes: 12 additions & 4 deletions Course/Course/Presentation/CourseRouter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@ public protocol CourseRouter: BaseRouter {
verticalIndex: Int,
chapters: [CourseChapter],
chapterIndex: Int,
sequentialIndex: Int
sequentialIndex: Int,
showVideoNavigation: Bool,
courseVideoStructure: CourseStructure?
)

func replaceCourseUnit(
Expand All @@ -31,7 +33,9 @@ public protocol CourseRouter: BaseRouter {
chapters: [CourseChapter],
chapterIndex: Int,
sequentialIndex: Int,
animated: Bool
animated: Bool,
showVideoNavigation: Bool,
courseVideoStructure: CourseStructure?
)

func showCourseVerticalView(
Expand Down Expand Up @@ -77,7 +81,9 @@ public class CourseRouterMock: BaseRouterMock, CourseRouter {
verticalIndex: Int,
chapters: [CourseChapter],
chapterIndex: Int,
sequentialIndex: Int
sequentialIndex: Int,
showVideoNavigation: Bool,
courseVideoStructure: CourseStructure?
) {}

public func replaceCourseUnit(
Expand All @@ -88,7 +94,9 @@ public class CourseRouterMock: BaseRouterMock, CourseRouter {
chapters: [CourseChapter],
chapterIndex: Int,
sequentialIndex: Int,
animated: Bool
animated: Bool,
showVideoNavigation: Bool,
courseVideoStructure: CourseStructure?
) {}

public func showCourseVerticalView(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,9 @@ public struct CourseVerticalView: View {
verticalIndex: index,
chapters: viewModel.chapters,
chapterIndex: viewModel.chapterIndex,
sequentialIndex: viewModel.sequentialIndex
sequentialIndex: viewModel.sequentialIndex,
showVideoNavigation: false,
courseVideoStructure: nil
)
}
}, label: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ public class CourseProgressViewModel: ObservableObject {

for chapter in courseStructure.childs {
for sequential in chapter.childs where sequential.sequentialProgress?.assignmentType == assignmentType {
total = chapter.childs.count
total += 1
if sequential.completion == 1 {
completed += 1
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,18 @@ struct AssignmentCarouselDetailCardView: View {
}) {
HStack {
VStack(alignment: .leading, spacing: 8) {
if detailData.subsectionUI.status != .completed && detailData.subsectionUI.date != nil {
HStack {
HStack {

if detailData.subsectionUI.status == .pastDue {
CoreAssets.icAssignmentPastDue.swiftUIImage
Text(detailData.subsectionUI.status == .pastDue ? "Past Due" : "Due Soon")
.font(Theme.Fonts.titleMedium)
.foregroundStyle(Theme.Colors.textPrimary)
}

Text(detailData.subsectionUI.status == .pastDue ? CoreLocalization.CourseDates.pastDue
: CourseLocalization.CourseCarousel.nextAssignments)
.font(Theme.Fonts.titleMedium)
.foregroundStyle(Theme.Colors.textPrimary)
}

HStack {
VStack(alignment: .leading) {
if detailData.subsectionUI.date != nil {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,14 +83,14 @@ struct CourseVideoCarouselSlideView: View {
private var videoBlock: CourseBlock? {
guard let chapter = courseChapter else { return nil }
let videos = getAllVideos(from: chapter)
if let partial = videos.first(
where: {
$0.localVideoProgress > 0 && $0.localVideoProgress < 1 && $0.completion < 1
}) {
if let partial = videos.first(where: {
$0.localVideoProgress > 0 && $0.localVideoProgress < 1
}) {
return partial
} else {
return videos.first(where: { $0.localVideoProgress == 0 })
return videos.first(where: { $0.localVideoProgress == 0 && $0.completion < 1 })
}

}

// MARK: - Body
Expand Down Expand Up @@ -129,7 +129,7 @@ struct CourseVideoCarouselSlideView: View {
viewModelContainer.selectedTab = .videos
viewModelContainer.trackCourseHomeViewAllVideosClicked()
}
.padding(.top, -20)
.padding(.top, allVideosCompleted ? -10 : -20)
.frame(maxWidth: .infinity)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,9 @@ struct CustomDisclosureGroup: View {
verticalIndex: 0,
chapters: course.childs,
chapterIndex: chapterIndex,
sequentialIndex: sequentialIndex
sequentialIndex: sequentialIndex,
showVideoNavigation: false,
courseVideoStructure: nil
)
} else {
viewModel.router.showCourseVerticalView(
Expand Down
Loading