diff --git a/Core/Core/Data/Model/Data_Discovery.swift b/Core/Core/Data/Model/Data_Discovery.swift index e5e4d01d7..1d21e1b6d 100644 --- a/Core/Core/Data/Model/Data_Discovery.swift +++ b/Core/Core/Data/Model/Data_Discovery.swift @@ -116,6 +116,7 @@ public extension DataLayer.DiscoveryResponce { courseID: $0.courseID ?? "", numPages: pagination.numPages, coursesCount: pagination.count, + courseRawImage: $0.media.image?.raw, progressEarned: 0, progressPossible: 0) }) diff --git a/Core/Core/Data/Model/Data_Enrollments.swift b/Core/Core/Data/Model/Data_Enrollments.swift index 527a69daa..5b6f834b6 100644 --- a/Core/Core/Data/Model/Data_Enrollments.swift +++ b/Core/Core/Data/Model/Data_Enrollments.swift @@ -260,6 +260,7 @@ public extension DataLayer.CourseEnrollments { courseID: course.id, numPages: enrollments.numPages ?? 1, coursesCount: enrollments.count ?? 0, + courseRawImage: course.media.courseImage?.url, progressEarned: 0, progressPossible: 0 ) diff --git a/Core/Core/Data/Model/Data_PrimaryEnrollment.swift b/Core/Core/Data/Model/Data_PrimaryEnrollment.swift index cbf70fc81..16af30373 100644 --- a/Core/Core/Data/Model/Data_PrimaryEnrollment.swift +++ b/Core/Core/Data/Model/Data_PrimaryEnrollment.swift @@ -262,6 +262,7 @@ public extension DataLayer.PrimaryEnrollment { courseID: enrollment.course.id, numPages: numPages, coursesCount: count, + courseRawImage: enrollment.course.media.image?.raw, progressEarned: enrollment.progress?.assignmentsCompleted ?? 0, progressPossible: enrollment.progress?.totalAssignmentsCount ?? 0 ) diff --git a/Core/Core/Domain/Model/CourseItem.swift b/Core/Core/Domain/Model/CourseItem.swift index 67647e038..19bd1f612 100644 --- a/Core/Core/Domain/Model/CourseItem.swift +++ b/Core/Core/Domain/Model/CourseItem.swift @@ -20,6 +20,7 @@ public struct CourseItem: Hashable { public let courseID: String public let numPages: Int public let coursesCount: Int + public let courseRawImage: String? public let progressEarned: Int public let progressPossible: Int @@ -35,6 +36,7 @@ public struct CourseItem: Hashable { courseID: String, numPages: Int, coursesCount: Int, + courseRawImage: String?, progressEarned: Int, progressPossible: Int) { self.name = name @@ -49,6 +51,7 @@ public struct CourseItem: Hashable { self.courseID = courseID self.numPages = numPages self.coursesCount = coursesCount + self.courseRawImage = courseRawImage self.progressEarned = progressEarned self.progressPossible = progressPossible } diff --git a/Core/Core/View/Base/CourseCellView.swift b/Core/Core/View/Base/CourseCellView.swift index 35f0c5d61..37dada165 100644 --- a/Core/Core/View/Base/CourseCellView.swift +++ b/Core/Core/View/Base/CourseCellView.swift @@ -138,6 +138,7 @@ struct CourseCellView_Previews: PreviewProvider { courseID: "1", numPages: 1, coursesCount: 10, + courseRawImage: nil, progressEarned: 4, progressPossible: 10 ) diff --git a/Core/Core/View/Base/DynamicOffsetView.swift b/Core/Core/View/Base/DynamicOffsetView.swift index da1bdf984..1647af921 100644 --- a/Core/Core/View/Base/DynamicOffsetView.swift +++ b/Core/Core/View/Base/DynamicOffsetView.swift @@ -29,6 +29,7 @@ public struct DynamicOffsetView: View { @Environment(\.isHorizontal) private var isHorizontal + @State private var isOnTheScreen: Bool = false public init( coordinate: Binding, collapsed: Binding, @@ -45,6 +46,9 @@ public struct DynamicOffsetView: View { .frame(height: collapseHeight) .overlay( GeometryReader { geometry -> Color in + if !isOnTheScreen { + return .clear + } guard idiom != .pad else { return .clear } @@ -59,8 +63,12 @@ public struct DynamicOffsetView: View { } ) .onAppear { + isOnTheScreen = true changeCollapsedHeight(collapsed: collapsed, isHorizontal: isHorizontal) } + .onDisappear { + isOnTheScreen = false + } .onChange(of: collapsed) { collapsed in if !collapsed { changeCollapsedHeight(collapsed: collapsed, isHorizontal: isHorizontal) @@ -87,7 +95,7 @@ public struct DynamicOffsetView: View { collapseHeight = collapsedVerticalHeight } } else { - collapseHeight = 240 + collapseHeight = expandedHeight } viewHeight = collapseHeight } diff --git a/Course/Course/Data/Persistence/CourseCoreModel.xcdatamodeld/CourseCoreModel.xcdatamodel/contents b/Course/Course/Data/Persistence/CourseCoreModel.xcdatamodeld/CourseCoreModel.xcdatamodel/contents index cb4d84738..1c6c4c93f 100644 --- a/Course/Course/Data/Persistence/CourseCoreModel.xcdatamodeld/CourseCoreModel.xcdatamodel/contents +++ b/Course/Course/Data/Persistence/CourseCoreModel.xcdatamodeld/CourseCoreModel.xcdatamodel/contents @@ -1,5 +1,5 @@ - + @@ -68,6 +68,7 @@ + diff --git a/Course/Course/Presentation/Container/CourseContainerView.swift b/Course/Course/Presentation/Container/CourseContainerView.swift index 65ca348d2..725f98ace 100644 --- a/Course/Course/Presentation/Container/CourseContainerView.swift +++ b/Course/Course/Presentation/Container/CourseContainerView.swift @@ -10,6 +10,7 @@ import Core import Discussion import Swinject import Theme +@_spi(Advanced) import SwiftUIIntrospect public struct CourseContainerView: View { @@ -30,6 +31,7 @@ public struct CourseContainerView: View { private var idiom: UIUserInterfaceIdiom { UIDevice.current.userInterfaceIdiom } private let coordinateBoundaryLower: CGFloat = -115 + private let courseRawImage: String? private var coordinateBoundaryHigher: CGFloat { let topInset = UIApplication.shared.windowInsets.top @@ -52,7 +54,8 @@ public struct CourseContainerView: View { viewModel: CourseContainerViewModel, courseDatesViewModel: CourseDatesViewModel, courseID: String, - title: String + title: String, + courseRawImage: String? ) { self.viewModel = viewModel Task { @@ -68,6 +71,7 @@ public struct CourseContainerView: View { self.courseID = courseID self.title = title self.courseDatesViewModel = courseDatesViewModel + self.courseRawImage = courseRawImage } public var body: some View { @@ -108,22 +112,24 @@ public struct CourseContainerView: View { collapsed: $collapsed, containerWidth: proxy.size.width, animationNamespace: animationNamespace, - isAnimatingForTap: $isAnimatingForTap + isAnimatingForTap: $isAnimatingForTap, + courseRawImage: courseRawImage ) } .offset( y: ignoreOffset ? (collapsed ? coordinateBoundaryLower : .zero) : ((coordinateBoundaryLower...coordinateBoundaryHigher).contains(coordinate) - ? coordinate + ? (collapsed ? coordinateBoundaryLower : coordinate) : (collapsed ? coordinateBoundaryLower : .zero)) ) backButton(containerWidth: proxy.size.width) } - }.ignoresSafeArea(edges: idiom == .pad ? .leading : .top) - .onAppear { - self.collapsed = isHorizontal - } + } + .ignoresSafeArea(edges: idiom == .pad ? .leading : .top) + .onAppear { + self.collapsed = isHorizontal + } } } @@ -282,7 +288,7 @@ public struct CourseContainerView: View { } } .tabViewStyle(.page(indexDisplayMode: .never)) - .introspect(.scrollView, on: .iOS(.v15, .v16, .v17), customize: { tabView in + .introspect(.scrollView, on: .iOS(.v16...), customize: { tabView in tabView.isScrollEnabled = false }) .onFirstAppear { @@ -379,11 +385,12 @@ struct CourseScreensView_Previews: PreviewProvider { config: ConfigMock(), courseID: "1", courseName: "a", - analytics: CourseAnalyticsMock(), + analytics: CourseAnalyticsMock(), calendarManager: CalendarManagerMock() ), courseID: "", - title: "Title of Course" + title: "Title of Course", + courseRawImage: nil ) } } diff --git a/Course/Course/Presentation/Outline/ContinueWithView.swift b/Course/Course/Presentation/Outline/ContinueWithView.swift index e8345bbb0..9da8b7a6c 100644 --- a/Course/Course/Presentation/Outline/ContinueWithView.swift +++ b/Course/Course/Presentation/Outline/ContinueWithView.swift @@ -41,7 +41,6 @@ struct ContinueWithView: View { .frame(width: 200) } .padding(.horizontal, 24) - .padding(.top, 32) } else { VStack(alignment: .leading) { ContinueTitle(vertical: courseContinueUnit) diff --git a/Course/Course/Presentation/Outline/CourseOutlineView.swift b/Course/Course/Presentation/Outline/CourseOutlineView.swift index d20c4de00..37e14b589 100644 --- a/Course/Course/Presentation/Outline/CourseOutlineView.swift +++ b/Course/Course/Presentation/Outline/CourseOutlineView.swift @@ -61,79 +61,81 @@ public struct CourseOutlineView: View { GeometryReader { proxy in VStack(alignment: .center) { ScrollView { - DynamicOffsetView( - coordinate: $coordinate, - collapsed: $collapsed, - viewHeight: $viewHeight - ) - RefreshProgressView(isShowRefresh: $viewModel.isShowRefresh) - VStack(alignment: .leading) { - - if isVideo, - viewModel.isShowProgress == false { - downloadQualityBars(proxy: proxy) - } - certificateView - - if viewModel.courseStructure == nil, - viewModel.isShowProgress == false, - !isVideo { - FullScreenErrorView( - type: .noContent( - CourseLocalization.Error.coursewareUnavailable, - image: CoreAssets.information.swiftUIImage - ) - ) - .frame(maxWidth: .infinity) - .frame(height: proxy.size.height - viewHeight) - } else { - if let continueWith = viewModel.continueWith, - let courseStructure = viewModel.courseStructure, - !isVideo { - let chapter = courseStructure.childs[continueWith.chapterIndex] - let sequential = chapter.childs[continueWith.sequentialIndex] - let continueUnit = sequential.childs[continueWith.verticalIndex] - - ContinueWithView( - data: continueWith, - courseContinueUnit: continueUnit - ) { - viewModel.openLastVisitedBlock() - } + VStack(spacing: 0) { + DynamicOffsetView( + coordinate: $coordinate, + collapsed: $collapsed, + viewHeight: $viewHeight + ) + RefreshProgressView(isShowRefresh: $viewModel.isShowRefresh) + VStack(alignment: .leading) { + + if isVideo, + viewModel.isShowProgress == false { + downloadQualityBars(proxy: proxy) } + certificateView - if let course = isVideo - ? viewModel.courseVideosStructure - : viewModel.courseStructure { - - if !isVideo, - let progress = course.courseProgress, - progress.totalAssignmentsCount != 0 { - CourseProgressView(progress: progress) - .padding(.horizontal, 24) - .padding(.top, 16) - .padding(.bottom, 8) - } - - // MARK: - Sections - CustomDisclosureGroup( - isVideo: isVideo, - course: course, - proxy: proxy, - viewModel: viewModel + if viewModel.courseStructure == nil, + viewModel.isShowProgress == false, + !isVideo { + FullScreenErrorView( + type: .noContent( + CourseLocalization.Error.coursewareUnavailable, + image: CoreAssets.information.swiftUIImage + ) ) + .frame(maxWidth: .infinity) + .frame(height: proxy.size.height - viewHeight) } else { - if let courseStart = viewModel.courseStart { - Text(courseStart > Date() ? CourseLocalization.Outline.courseHasntStarted : "") - .frame(maxWidth: .infinity) - .frame(maxHeight: .infinity) - .padding(.top, 100) + if let continueWith = viewModel.continueWith, + let courseStructure = viewModel.courseStructure, + !isVideo { + let chapter = courseStructure.childs[continueWith.chapterIndex] + let sequential = chapter.childs[continueWith.sequentialIndex] + let continueUnit = sequential.childs[continueWith.verticalIndex] + + ContinueWithView( + data: continueWith, + courseContinueUnit: continueUnit + ) { + viewModel.openLastVisitedBlock() + } + } + + if let course = isVideo + ? viewModel.courseVideosStructure + : viewModel.courseStructure { + + if !isVideo, + let progress = course.courseProgress, + progress.totalAssignmentsCount != 0 { + CourseProgressView(progress: progress) + .padding(.horizontal, 24) + .padding(.top, 16) + .padding(.bottom, 8) + } + + // MARK: - Sections + CustomDisclosureGroup( + isVideo: isVideo, + course: course, + proxy: proxy, + viewModel: viewModel + ) + } else { + if let courseStart = viewModel.courseStart { + Text(courseStart > Date() ? CourseLocalization.Outline.courseHasntStarted : "") + .frame(maxWidth: .infinity) + .frame(maxHeight: .infinity) + .padding(.top, 100) + } + Spacer(minLength: viewHeight < 200 ? 200 : viewHeight) } } - Spacer(minLength: 200) } + .frameLimit(width: proxy.size.width) } - .frameLimit(width: proxy.size.width) } .refreshable { Task { diff --git a/Course/Course/Presentation/Subviews/CourseHeaderView.swift b/Course/Course/Presentation/Subviews/CourseHeaderView.swift index 26e8ad38e..3f604e7df 100644 --- a/Course/Course/Presentation/Subviews/CourseHeaderView.swift +++ b/Course/Course/Presentation/Subviews/CourseHeaderView.swift @@ -24,6 +24,7 @@ struct CourseHeaderView: View { private let collapsedVerticalHeight: CGFloat = 260 private let expandedHeight: CGFloat = 300 + private let courseRawImage: String? private enum GeometryName { case backButton case topTabBar @@ -38,7 +39,8 @@ struct CourseHeaderView: View { collapsed: Binding, containerWidth: CGFloat, animationNamespace: Namespace.ID, - isAnimatingForTap: Binding + isAnimatingForTap: Binding, + courseRawImage: String? ) { self.viewModel = viewModel self.title = title @@ -46,14 +48,15 @@ struct CourseHeaderView: View { self.containerWidth = containerWidth self.animationNamespace = animationNamespace self._isAnimatingForTap = isAnimatingForTap + self.courseRawImage = courseRawImage } var body: some View { ZStack(alignment: .bottomLeading) { ScrollView { - if let banner = viewModel.courseStructure?.media.image.raw + if let banner = (courseRawImage ?? viewModel.courseStructure?.media.image.raw)? .addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) { - KFImage(URL(string: viewModel.config.baseURL.absoluteString + banner)) + KFImage(courseBannerURL(for: banner)) .onFailureImage(CoreAssets.noCourseImage.image) .resizable() .aspectRatio(contentMode: .fill) @@ -159,6 +162,13 @@ struct CourseHeaderView: View { .ignoresSafeArea(edges: .top) } + private func courseBannerURL(for path: String) -> URL? { + if path.contains("http://") || path.contains("https://") { + return URL(string: path) + } + return URL(string: viewModel.config.baseURL.absoluteString + path) + } + private func courseMenuBar(containerWidth: CGFloat) -> some View { ScrollSlidingTabBar( selection: $viewModel.selection, diff --git a/Dashboard/Dashboard/Data/DashboardRepository.swift b/Dashboard/Dashboard/Data/DashboardRepository.swift index 61f9e3f41..9487caab4 100644 --- a/Dashboard/Dashboard/Data/DashboardRepository.swift +++ b/Dashboard/Dashboard/Data/DashboardRepository.swift @@ -99,6 +99,7 @@ class DashboardRepositoryMock: DashboardRepositoryProtocol { courseID: "course_id_\(i)", numPages: 1, coursesCount: 0, + courseRawImage: nil, progressEarned: 0, progressPossible: 0 ) @@ -127,6 +128,7 @@ class DashboardRepositoryMock: DashboardRepositoryProtocol { courseID: "course_id_\(i)", numPages: 1, coursesCount: 0, + courseRawImage: nil, progressEarned: 4, progressPossible: 10 ) @@ -181,6 +183,7 @@ class DashboardRepositoryMock: DashboardRepositoryProtocol { courseID: "course_id_\(i)", numPages: 1, coursesCount: 0, + courseRawImage: nil, progressEarned: 4, progressPossible: 10 ) diff --git a/Dashboard/Dashboard/Data/Persistence/DashboardCoreModel.xcdatamodeld/DashboardCoreModel.xcdatamodel/contents b/Dashboard/Dashboard/Data/Persistence/DashboardCoreModel.xcdatamodeld/DashboardCoreModel.xcdatamodel/contents index 65dbea3a0..48a5a25c6 100644 --- a/Dashboard/Dashboard/Data/Persistence/DashboardCoreModel.xcdatamodeld/DashboardCoreModel.xcdatamodel/contents +++ b/Dashboard/Dashboard/Data/Persistence/DashboardCoreModel.xcdatamodeld/DashboardCoreModel.xcdatamodel/contents @@ -1,5 +1,5 @@ - + @@ -20,6 +20,7 @@ + diff --git a/Dashboard/Dashboard/Presentation/AllCoursesView.swift b/Dashboard/Dashboard/Presentation/AllCoursesView.swift index bdd6a6b77..f35299372 100644 --- a/Dashboard/Dashboard/Presentation/AllCoursesView.swift +++ b/Dashboard/Dashboard/Presentation/AllCoursesView.swift @@ -53,65 +53,68 @@ public struct AllCoursesView: View { learnTitleAndSearch() .frameLimit(width: proxy.size.width) ScrollView { - CategoryFilterView(selectedOption: $viewModel.selectedMenu) - .disabled(viewModel.fetchInProgress) - .frameLimit(width: proxy.size.width) - if let myEnrollments = viewModel.myEnrollments { - let useRelativeDates = viewModel.storage.useRelativeDates - LazyVGrid(columns: columns(), spacing: 15) { - ForEach( - Array(myEnrollments.courses.enumerated()), - id: \.offset - ) { index, course in - Button(action: { - viewModel.trackDashboardCourseClicked( - courseID: course.courseID, - courseName: course.name - ) - router.showCourseScreens( - courseID: course.courseID, - hasAccess: course.hasAccess, - courseStart: course.courseStart, - courseEnd: course.courseEnd, - enrollmentStart: course.enrollmentStart, - enrollmentEnd: course.enrollmentEnd, - title: course.name, - showDates: false, - lastVisitedBlockID: nil - ) - }, label: { - CourseCardView( - courseName: course.name, - courseImage: course.imageURL, - progressEarned: course.progressEarned, - progressPossible: course.progressPossible, - courseStartDate: course.courseStart, - courseEndDate: course.courseEnd, - hasAccess: course.hasAccess, - showProgress: true, - useRelativeDates: useRelativeDates - ).padding(8) - }) - .accessibilityIdentifier("course_item") - .onAppear { - Task { - await viewModel.getMyCoursesPagination(index: index) + VStack(spacing: 0) { + CategoryFilterView(selectedOption: $viewModel.selectedMenu) + .disabled(viewModel.fetchInProgress) + .frameLimit(width: proxy.size.width) + if let myEnrollments = viewModel.myEnrollments { + let useRelativeDates = viewModel.storage.useRelativeDates + LazyVGrid(columns: columns(), spacing: 15) { + ForEach( + Array(myEnrollments.courses.enumerated()), + id: \.offset + ) { index, course in + Button(action: { + viewModel.trackDashboardCourseClicked( + courseID: course.courseID, + courseName: course.name + ) + router.showCourseScreens( + courseID: course.courseID, + hasAccess: course.hasAccess, + courseStart: course.courseStart, + courseEnd: course.courseEnd, + enrollmentStart: course.enrollmentStart, + enrollmentEnd: course.enrollmentEnd, + title: course.name, + courseRawImage: course.imageURL, + showDates: false, + lastVisitedBlockID: nil + ) + }, label: { + CourseCardView( + courseName: course.name, + courseImage: course.imageURL, + progressEarned: course.progressEarned, + progressPossible: course.progressPossible, + courseStartDate: course.courseStart, + courseEndDate: course.courseEnd, + hasAccess: course.hasAccess, + showProgress: true, + useRelativeDates: useRelativeDates + ).padding(8) + }) + .accessibilityIdentifier("course_item") + .onAppear { + Task { + await viewModel.getMyCoursesPagination(index: index) + } } } + .padding(10) + .frameLimit(width: proxy.size.width) } } - .padding(10) - .frameLimit(width: proxy.size.width) - } - // MARK: - ProgressBar - if viewModel.nextPage <= viewModel.totalPages, !viewModel.refresh { - VStack(alignment: .center) { - ProgressBar(size: 40, lineWidth: 8) - .padding(.top, 20) - }.frame(maxWidth: .infinity, - maxHeight: .infinity) + // MARK: - ProgressBar + if viewModel.nextPage <= viewModel.totalPages, !viewModel.refresh { + VStack(alignment: .center) { + ProgressBar(size: 40, lineWidth: 8) + .padding(.top, 20) + }.frame(maxWidth: .infinity, + maxHeight: .infinity) + } + VStack {}.frame(height: 40) } - VStack {}.frame(height: 40) } .refreshable { Task { diff --git a/Dashboard/Dashboard/Presentation/DashboardRouter.swift b/Dashboard/Dashboard/Presentation/DashboardRouter.swift index 0e66ff2a8..0d38f3199 100644 --- a/Dashboard/Dashboard/Presentation/DashboardRouter.swift +++ b/Dashboard/Dashboard/Presentation/DashboardRouter.swift @@ -17,6 +17,7 @@ public protocol DashboardRouter: BaseRouter { enrollmentStart: Date?, enrollmentEnd: Date?, title: String, + courseRawImage: String?, showDates: Bool, lastVisitedBlockID: String?) @@ -41,6 +42,7 @@ public class DashboardRouterMock: BaseRouterMock, DashboardRouter { enrollmentStart: Date?, enrollmentEnd: Date?, title: String, + courseRawImage: String?, showDates: Bool, lastVisitedBlockID: String?) {} diff --git a/Dashboard/Dashboard/Presentation/ListDashboardView.swift b/Dashboard/Dashboard/Presentation/ListDashboardView.swift index d402ce41c..d5d925bd0 100644 --- a/Dashboard/Dashboard/Presentation/ListDashboardView.swift +++ b/Dashboard/Dashboard/Presentation/ListDashboardView.swift @@ -83,6 +83,7 @@ public struct ListDashboardView: View { enrollmentStart: course.enrollmentStart, enrollmentEnd: course.enrollmentEnd, title: course.name, + courseRawImage: course.courseRawImage, showDates: false, lastVisitedBlockID: nil ) diff --git a/Dashboard/Dashboard/Presentation/PrimaryCourseDashboardView.swift b/Dashboard/Dashboard/Presentation/PrimaryCourseDashboardView.swift index 718b0ceb5..e7af096b1 100644 --- a/Dashboard/Dashboard/Presentation/PrimaryCourseDashboardView.swift +++ b/Dashboard/Dashboard/Presentation/PrimaryCourseDashboardView.swift @@ -84,6 +84,7 @@ public struct PrimaryCourseDashboardView: View { enrollmentStart: nil, enrollmentEnd: nil, title: primary.name, + courseRawImage: primary.courseBanner, showDates: lastVisitedBlockID == nil, lastVisitedBlockID: lastVisitedBlockID ) @@ -97,6 +98,7 @@ public struct PrimaryCourseDashboardView: View { enrollmentStart: nil, enrollmentEnd: nil, title: primary.name, + courseRawImage: primary.courseBanner, showDates: false, lastVisitedBlockID: nil ) @@ -110,6 +112,7 @@ public struct PrimaryCourseDashboardView: View { enrollmentStart: nil, enrollmentEnd: nil, title: primary.name, + courseRawImage: primary.courseBanner, showDates: false, lastVisitedBlockID: primary.lastVisitedBlockID ) @@ -223,6 +226,7 @@ public struct PrimaryCourseDashboardView: View { enrollmentStart: course.enrollmentStart, enrollmentEnd: course.enrollmentEnd, title: course.name, + courseRawImage: course.imageURL, showDates: false, lastVisitedBlockID: nil ) diff --git a/Dashboard/DashboardTests/Presentation/AllCoursesViewModelTests.swift b/Dashboard/DashboardTests/Presentation/AllCoursesViewModelTests.swift index 625120e66..abd7c7e6e 100644 --- a/Dashboard/DashboardTests/Presentation/AllCoursesViewModelTests.swift +++ b/Dashboard/DashboardTests/Presentation/AllCoursesViewModelTests.swift @@ -58,6 +58,7 @@ final class AllCoursesViewModelTests: XCTestCase { courseID: "2", numPages: 1, coursesCount: 3, + courseRawImage: nil, progressEarned: 0, progressPossible: 2 ), @@ -74,6 +75,7 @@ final class AllCoursesViewModelTests: XCTestCase { courseID: "3", numPages: 1, coursesCount: 3, + courseRawImage: nil, progressEarned: 0, progressPossible: 2 ), @@ -90,6 +92,7 @@ final class AllCoursesViewModelTests: XCTestCase { courseID: "4", numPages: 1, coursesCount: 3, + courseRawImage: nil, progressEarned: 0, progressPossible: 2 ) diff --git a/Dashboard/DashboardTests/Presentation/DashboardViewModelTests.swift b/Dashboard/DashboardTests/Presentation/DashboardViewModelTests.swift index a5fb4e9b7..e053c19c7 100644 --- a/Dashboard/DashboardTests/Presentation/DashboardViewModelTests.swift +++ b/Dashboard/DashboardTests/Presentation/DashboardViewModelTests.swift @@ -38,6 +38,7 @@ final class ListDashboardViewModelTests: XCTestCase { courseID: "123", numPages: 2, coursesCount: 2, + courseRawImage: nil, progressEarned: 0, progressPossible: 0), CourseItem(name: "Test2", @@ -52,6 +53,7 @@ final class ListDashboardViewModelTests: XCTestCase { courseID: "1243", numPages: 1, coursesCount: 2, + courseRawImage: nil, progressEarned: 0, progressPossible: 0) ] @@ -92,6 +94,7 @@ final class ListDashboardViewModelTests: XCTestCase { courseID: "123", numPages: 2, coursesCount: 2, + courseRawImage: nil, progressEarned: 0, progressPossible: 0), CourseItem(name: "Test2", @@ -106,6 +109,7 @@ final class ListDashboardViewModelTests: XCTestCase { courseID: "1243", numPages: 1, coursesCount: 2, + courseRawImage: nil, progressEarned: 0, progressPossible: 0) ] diff --git a/Dashboard/DashboardTests/Presentation/PrimaryCourseDashboardViewModelTests.swift b/Dashboard/DashboardTests/Presentation/PrimaryCourseDashboardViewModelTests.swift index c4083e705..0f6aff8c5 100644 --- a/Dashboard/DashboardTests/Presentation/PrimaryCourseDashboardViewModelTests.swift +++ b/Dashboard/DashboardTests/Presentation/PrimaryCourseDashboardViewModelTests.swift @@ -61,6 +61,7 @@ final class PrimaryCourseDashboardViewModelTests: XCTestCase { courseID: "2", numPages: 1, coursesCount: 3, + courseRawImage: nil, progressEarned: 0, progressPossible: 2 ) diff --git a/Discovery/Discovery/Data/DiscoveryRepository.swift b/Discovery/Discovery/Data/DiscoveryRepository.swift index aa0b71978..d08571071 100644 --- a/Discovery/Discovery/Data/DiscoveryRepository.swift +++ b/Discovery/Discovery/Data/DiscoveryRepository.swift @@ -95,7 +95,8 @@ class DiscoveryRepositoryMock: DiscoveryRepositoryProtocol { isEnrolled: false, overviewHTML: "Course description

Lorem ipsum", courseBannerURL: "courseBannerURL", - courseVideoURL: nil + courseVideoURL: nil, + courseRawImage: nil ) } @@ -112,7 +113,8 @@ class DiscoveryRepositoryMock: DiscoveryRepositoryProtocol { isEnrolled: false, overviewHTML: "Course description

Lorem ipsum", courseBannerURL: "courseBannerURL", - courseVideoURL: nil + courseVideoURL: nil, + courseRawImage: nil ) } @@ -136,6 +138,7 @@ class DiscoveryRepositoryMock: DiscoveryRepositoryProtocol { enrollmentEnd: nil, courseID: "course_id_\(i)", numPages: 1, coursesCount: 10, + courseRawImage: nil, progressEarned: 0, progressPossible: 0 ) @@ -160,6 +163,7 @@ class DiscoveryRepositoryMock: DiscoveryRepositoryProtocol { enrollmentEnd: nil, courseID: "course_id_\(i)", numPages: 1, coursesCount: 10, + courseRawImage: nil, progressEarned: 0, progressPossible: 0 ) @@ -185,6 +189,7 @@ class DiscoveryRepositoryMock: DiscoveryRepositoryProtocol { courseID: "course_id_\(i)", numPages: 1, coursesCount: 10, + courseRawImage: nil, progressEarned: 0, progressPossible: 0 ) diff --git a/Discovery/Discovery/Data/Model/CourseDetails.swift b/Discovery/Discovery/Data/Model/CourseDetails.swift index 6769aff53..fb67340aa 100644 --- a/Discovery/Discovery/Data/Model/CourseDetails.swift +++ b/Discovery/Discovery/Data/Model/CourseDetails.swift @@ -20,6 +20,7 @@ public struct CourseDetails { public var overviewHTML: String public let courseBannerURL: String public let courseVideoURL: String? + public let courseRawImage: String? public init(courseID: String, org: String, @@ -32,7 +33,9 @@ public struct CourseDetails { isEnrolled: Bool, overviewHTML: String, courseBannerURL: String, - courseVideoURL: String?) { + courseVideoURL: String?, + courseRawImage: String? + ) { self.courseID = courseID self.org = org self.courseTitle = courseTitle @@ -45,5 +48,6 @@ public struct CourseDetails { self.overviewHTML = overviewHTML self.courseBannerURL = courseBannerURL self.courseVideoURL = courseVideoURL + self.courseRawImage = courseRawImage } } diff --git a/Discovery/Discovery/Data/Model/Data_CourseDetailsResponse.swift b/Discovery/Discovery/Data/Model/Data_CourseDetailsResponse.swift index 1047727e8..9b9e2522b 100644 --- a/Discovery/Discovery/Data/Model/Data_CourseDetailsResponse.swift +++ b/Discovery/Discovery/Data/Model/Data_CourseDetailsResponse.swift @@ -75,6 +75,8 @@ public extension DataLayer.CourseDetailsResponse { isEnrolled: isEnrolled, overviewHTML: overview, courseBannerURL: imageURL, - courseVideoURL: media.courseVideo?.url) + courseVideoURL: media.courseVideo?.url, + courseRawImage: media.image?.raw + ) } } diff --git a/Discovery/Discovery/Data/Persistence/DiscoveryCoreModel.xcdatamodeld/DiscoveryCoreModel.xcdatamodel/contents b/Discovery/Discovery/Data/Persistence/DiscoveryCoreModel.xcdatamodeld/DiscoveryCoreModel.xcdatamodel/contents index 2c838b0dd..f508a975a 100644 --- a/Discovery/Discovery/Data/Persistence/DiscoveryCoreModel.xcdatamodeld/DiscoveryCoreModel.xcdatamodel/contents +++ b/Discovery/Discovery/Data/Persistence/DiscoveryCoreModel.xcdatamodeld/DiscoveryCoreModel.xcdatamodel/contents @@ -1,10 +1,11 @@ - + + @@ -23,6 +24,7 @@ + diff --git a/Discovery/Discovery/Presentation/DiscoveryRouter.swift b/Discovery/Discovery/Presentation/DiscoveryRouter.swift index 4416d9659..6c9651c78 100644 --- a/Discovery/Discovery/Presentation/DiscoveryRouter.swift +++ b/Discovery/Discovery/Presentation/DiscoveryRouter.swift @@ -26,6 +26,7 @@ public protocol DiscoveryRouter: BaseRouter { enrollmentStart: Date?, enrollmentEnd: Date?, title: String, + courseRawImage: String?, showDates: Bool, lastVisitedBlockID: String? ) @@ -59,6 +60,7 @@ public class DiscoveryRouterMock: BaseRouterMock, DiscoveryRouter { enrollmentStart: Date?, enrollmentEnd: Date?, title: String, + courseRawImage: String?, showDates: Bool, lastVisitedBlockID: String? ) {} diff --git a/Discovery/Discovery/Presentation/NativeDiscovery/CourseDetailsView.swift b/Discovery/Discovery/Presentation/NativeDiscovery/CourseDetailsView.swift index 10c03ab40..092242d43 100644 --- a/Discovery/Discovery/Presentation/NativeDiscovery/CourseDetailsView.swift +++ b/Discovery/Discovery/Presentation/NativeDiscovery/CourseDetailsView.swift @@ -292,6 +292,7 @@ private struct CourseStateView: View { enrollmentStart: courseDetails.enrollmentStart, enrollmentEnd: courseDetails.enrollmentEnd, title: title, + courseRawImage: courseDetails.courseRawImage, showDates: false, lastVisitedBlockID: nil ) diff --git a/Discovery/Discovery/Presentation/WebDiscovery/DiscoveryWebviewViewModel.swift b/Discovery/Discovery/Presentation/WebDiscovery/DiscoveryWebviewViewModel.swift index df2330abf..8b9163dc1 100644 --- a/Discovery/Discovery/Presentation/WebDiscovery/DiscoveryWebviewViewModel.swift +++ b/Discovery/Discovery/Presentation/WebDiscovery/DiscoveryWebviewViewModel.swift @@ -228,6 +228,7 @@ extension DiscoveryWebviewViewModel: WebViewNavigationDelegate { enrollmentStart: courseDetails.enrollmentStart, enrollmentEnd: courseDetails.enrollmentEnd, title: courseDetails.courseTitle, + courseRawImage: courseDetails.courseRawImage, showDates: false, lastVisitedBlockID: nil ) diff --git a/Discovery/Discovery/Presentation/WebPrograms/ProgramWebviewViewModel.swift b/Discovery/Discovery/Presentation/WebPrograms/ProgramWebviewViewModel.swift index 34ad47de2..ed636378b 100644 --- a/Discovery/Discovery/Presentation/WebPrograms/ProgramWebviewViewModel.swift +++ b/Discovery/Discovery/Presentation/WebPrograms/ProgramWebviewViewModel.swift @@ -226,6 +226,7 @@ extension ProgramWebviewViewModel: WebViewNavigationDelegate { enrollmentStart: courseDetails.enrollmentStart, enrollmentEnd: courseDetails.enrollmentEnd, title: courseDetails.courseTitle, + courseRawImage: courseDetails.courseRawImage, showDates: false, lastVisitedBlockID: nil ) diff --git a/Discovery/DiscoveryTests/Presentation/CourseDetailsViewModelTests.swift b/Discovery/DiscoveryTests/Presentation/CourseDetailsViewModelTests.swift index ba30a66ce..35d61d57e 100644 --- a/Discovery/DiscoveryTests/Presentation/CourseDetailsViewModelTests.swift +++ b/Discovery/DiscoveryTests/Presentation/CourseDetailsViewModelTests.swift @@ -44,7 +44,8 @@ final class CourseDetailsViewModelTests: XCTestCase { isEnrolled: true, overviewHTML: "", courseBannerURL: "", - courseVideoURL: nil + courseVideoURL: nil, + courseRawImage: nil ) @@ -90,7 +91,8 @@ final class CourseDetailsViewModelTests: XCTestCase { isEnrolled: true, overviewHTML: "", courseBannerURL: "", - courseVideoURL: nil + courseVideoURL: nil, + courseRawImage: nil ) Given(interactor, .getLoadedCourseDetails(courseID: "123", diff --git a/Discovery/DiscoveryTests/Presentation/DiscoveryViewModelTests.swift b/Discovery/DiscoveryTests/Presentation/DiscoveryViewModelTests.swift index 241178b03..b41d901be 100644 --- a/Discovery/DiscoveryTests/Presentation/DiscoveryViewModelTests.swift +++ b/Discovery/DiscoveryTests/Presentation/DiscoveryViewModelTests.swift @@ -46,6 +46,7 @@ final class DiscoveryViewModelTests: XCTestCase { courseID: "123", numPages: 2, coursesCount: 2, + courseRawImage: nil, progressEarned: 0, progressPossible: 0), CourseItem(name: "Test2", @@ -60,6 +61,7 @@ final class DiscoveryViewModelTests: XCTestCase { courseID: "1243", numPages: 1, coursesCount: 2, + courseRawImage: nil, progressEarned: 0, progressPossible: 0) ] @@ -99,6 +101,7 @@ final class DiscoveryViewModelTests: XCTestCase { courseID: "123", numPages: 2, coursesCount: 0, + courseRawImage: nil, progressEarned: 0, progressPossible: 0), CourseItem(name: "Test2", @@ -113,6 +116,7 @@ final class DiscoveryViewModelTests: XCTestCase { courseID: "1243", numPages: 1, coursesCount: 0, + courseRawImage: nil, progressEarned: 0, progressPossible: 0) ] @@ -151,6 +155,7 @@ final class DiscoveryViewModelTests: XCTestCase { courseID: "123", numPages: 2, coursesCount: 2, + courseRawImage: nil, progressEarned: 0, progressPossible: 0), CourseItem(name: "Test2", @@ -165,6 +170,7 @@ final class DiscoveryViewModelTests: XCTestCase { courseID: "1243", numPages: 1, coursesCount: 2, + courseRawImage: nil, progressEarned: 0, progressPossible: 0) ] diff --git a/Discovery/DiscoveryTests/Presentation/SearchViewModelTests.swift b/Discovery/DiscoveryTests/Presentation/SearchViewModelTests.swift index 3aa8e9394..aac3408c5 100644 --- a/Discovery/DiscoveryTests/Presentation/SearchViewModelTests.swift +++ b/Discovery/DiscoveryTests/Presentation/SearchViewModelTests.swift @@ -49,6 +49,7 @@ final class SearchViewModelTests: XCTestCase { courseID: "123", numPages: 2, coursesCount: 0, + courseRawImage: nil, progressEarned: 0, progressPossible: 0), CourseItem(name: "Test2", @@ -63,6 +64,7 @@ final class SearchViewModelTests: XCTestCase { courseID: "1243", numPages: 1, coursesCount: 0, + courseRawImage: nil, progressEarned: 0, progressPossible: 0) ] diff --git a/Discussion/Discussion/Presentation/DiscussionTopics/DiscussionTopicsView.swift b/Discussion/Discussion/Presentation/DiscussionTopics/DiscussionTopicsView.swift index ee44d90d1..61106f87a 100644 --- a/Discussion/Discussion/Presentation/DiscussionTopics/DiscussionTopicsView.swift +++ b/Discussion/Discussion/Presentation/DiscussionTopics/DiscussionTopicsView.swift @@ -41,144 +41,146 @@ public struct DiscussionTopicsView: View { ZStack(alignment: .center) { VStack(alignment: .center) { ScrollView { - DynamicOffsetView( - coordinate: $coordinate, - collapsed: $collapsed, - viewHeight: $viewHeight - ) - RefreshProgressView(isShowRefresh: $viewModel.isShowRefresh) - // MARK: - Search fake field - if viewModel.isBlackedOut { - bannerDiscussionsDisabled - } - - if let topics = viewModel.discussionTopics, topics.count > 0 { - HStack(spacing: 11) { - Image(systemName: "magnifyingglass") - .foregroundColor(Theme.Colors.textInputTextColor) - .padding(.leading, 16) - .padding(.top, 1) - Text(DiscussionLocalization.Topics.search) - .foregroundColor(Theme.Colors.textInputTextColor) - .font(Theme.Fonts.bodyMedium) - Spacer() - } - .frame(minHeight: 48) - .background( - Theme.Shapes.textInputShape - .fill(Theme.Colors.textInputBackground) - ) - .overlay( - Theme.Shapes.textInputShape - .stroke(lineWidth: 1) - .fill(Theme.Colors.textInputUnfocusedStroke) + VStack(spacing: 0) { + DynamicOffsetView( + coordinate: $coordinate, + collapsed: $collapsed, + viewHeight: $viewHeight ) - .onTapGesture { - viewModel.router.showDiscussionsSearch( - courseID: courseID, - isBlackedOut: viewModel.isBlackedOut + RefreshProgressView(isShowRefresh: $viewModel.isShowRefresh) + // MARK: - Search fake field + if viewModel.isBlackedOut { + bannerDiscussionsDisabled + } + + if let topics = viewModel.discussionTopics, topics.count > 0 { + HStack(spacing: 11) { + Image(systemName: "magnifyingglass") + .foregroundColor(Theme.Colors.textInputTextColor) + .padding(.leading, 16) + .padding(.top, 1) + Text(DiscussionLocalization.Topics.search) + .foregroundColor(Theme.Colors.textInputTextColor) + .font(Theme.Fonts.bodyMedium) + Spacer() + } + .frame(minHeight: 48) + .background( + Theme.Shapes.textInputShape + .fill(Theme.Colors.textInputBackground) ) + .overlay( + Theme.Shapes.textInputShape + .stroke(lineWidth: 1) + .fill(Theme.Colors.textInputUnfocusedStroke) + ) + .onTapGesture { + viewModel.router.showDiscussionsSearch( + courseID: courseID, + isBlackedOut: viewModel.isBlackedOut + ) + } + .frameLimit(width: proxy.size.width) + .padding(.horizontal, 24) + .padding(.top, 10) + .accessibilityElement(children: .ignore) + .accessibilityLabel(DiscussionLocalization.Topics.search) } - .frameLimit(width: proxy.size.width) - .padding(.horizontal, 24) - .padding(.top, 10) - .accessibilityElement(children: .ignore) - .accessibilityLabel(DiscussionLocalization.Topics.search) - } - - // MARK: - Page Body - VStack { - ZStack(alignment: .top) { - VStack { - if let topics = viewModel.discussionTopics { - HStack { - Text(DiscussionLocalization.Topics.mainCategories) - .font(Theme.Fonts.titleMedium) - .foregroundColor(Theme.Colors.textSecondary) - .padding(.horizontal, 24) - .padding(.top, 10) - Spacer() - } - HStack(spacing: 8) { - if let allTopics = topics.first(where: { - $0.name == DiscussionLocalization.Topics.allPosts }) { - Button(action: { - allTopics.action() - }, label: { - VStack { - Spacer(minLength: 0) - CoreAssets.allPosts.swiftUIImage.renderingMode(.template) - .foregroundColor(Theme.Colors.textPrimary) - Text(allTopics.name) - .font(Theme.Fonts.titleSmall) - .foregroundColor(Theme.Colors.textPrimary) - Spacer(minLength: 0) - } - .frame(maxWidth: .infinity) - }).cardStyle(bgColor: Theme.Colors.textInputUnfocusedBackground) - .padding(.trailing, -20) + + // MARK: - Page Body + VStack { + ZStack(alignment: .top) { + VStack { + if let topics = viewModel.discussionTopics { + HStack { + Text(DiscussionLocalization.Topics.mainCategories) + .font(Theme.Fonts.titleMedium) + .foregroundColor(Theme.Colors.textSecondary) + .padding(.horizontal, 24) + .padding(.top, 10) + Spacer() } - if let followed = topics.first(where: { - $0.name == DiscussionLocalization.Topics.postImFollowing}) { - Button(action: { - followed.action() - }, label: { - VStack(alignment: .center) { - Spacer(minLength: 0) - CoreAssets.followed.swiftUIImage.renderingMode(.template) - .foregroundColor(Theme.Colors.textPrimary) - Text(followed.name) - .font(Theme.Fonts.titleSmall) - .foregroundColor(Theme.Colors.textPrimary) - Spacer(minLength: 0) + HStack(spacing: 8) { + if let allTopics = topics.first(where: { + $0.name == DiscussionLocalization.Topics.allPosts }) { + Button(action: { + allTopics.action() + }, label: { + VStack { + Spacer(minLength: 0) + CoreAssets.allPosts.swiftUIImage.renderingMode(.template) + .foregroundColor(Theme.Colors.textPrimary) + Text(allTopics.name) + .font(Theme.Fonts.titleSmall) + .foregroundColor(Theme.Colors.textPrimary) + Spacer(minLength: 0) + } + .frame(maxWidth: .infinity) + }).cardStyle(bgColor: Theme.Colors.textInputUnfocusedBackground) + .padding(.trailing, -20) + } + if let followed = topics.first(where: { + $0.name == DiscussionLocalization.Topics.postImFollowing}) { + Button(action: { + followed.action() + }, label: { + VStack(alignment: .center) { + Spacer(minLength: 0) + CoreAssets.followed.swiftUIImage.renderingMode(.template) + .foregroundColor(Theme.Colors.textPrimary) + Text(followed.name) + .font(Theme.Fonts.titleSmall) + .foregroundColor(Theme.Colors.textPrimary) + Spacer(minLength: 0) + } + .frame(maxWidth: .infinity) + }).cardStyle(bgColor: Theme.Colors.textInputUnfocusedBackground) + .padding(.leading, -20) + + } + }.padding(.bottom, 16) + ForEach(Array(topics.enumerated()), id: \.offset) { _, topic in + if topic.name != DiscussionLocalization.Topics.allPosts + && topic.name != DiscussionLocalization.Topics.postImFollowing { + + if topic.style == .title { + HStack { + Text("\(topic.name):") + .font(Theme.Fonts.titleMedium) + .foregroundColor(Theme.Colors.textSecondary) + Spacer() + }.padding(.top, 12) + .padding(.bottom, 8) + .padding(.horizontal, 24) + } else { + VStack { + TopicCell(topic: topic) + .padding(.vertical, 10) + Divider() + }.padding(.horizontal, 24) } - .frame(maxWidth: .infinity) - }).cardStyle(bgColor: Theme.Colors.textInputUnfocusedBackground) - .padding(.leading, -20) - - } - }.padding(.bottom, 16) - ForEach(Array(topics.enumerated()), id: \.offset) { _, topic in - if topic.name != DiscussionLocalization.Topics.allPosts - && topic.name != DiscussionLocalization.Topics.postImFollowing { - - if topic.style == .title { - HStack { - Text("\(topic.name):") - .font(Theme.Fonts.titleMedium) - .foregroundColor(Theme.Colors.textSecondary) - Spacer() - }.padding(.top, 12) - .padding(.bottom, 8) - .padding(.horizontal, 24) - } else { - VStack { - TopicCell(topic: topic) - .padding(.vertical, 10) - Divider() - }.padding(.horizontal, 24) } } - } - } else if viewModel.isShowProgress == false { - FullScreenErrorView( - type: .noContent( - DiscussionLocalization.Error.unableToLoadDiscussion, - image: CoreAssets.information.swiftUIImage + } else if viewModel.isShowProgress == false { + FullScreenErrorView( + type: .noContent( + DiscussionLocalization.Error.unableToLoadDiscussion, + image: CoreAssets.information.swiftUIImage + ) ) - ) - .frame(maxWidth: .infinity) - .frame(height: proxy.size.height - viewHeight) - Spacer(minLength: -200) + .frame(maxWidth: .infinity) + .frame(height: proxy.size.height - viewHeight) + Spacer(minLength: -200) + } + Spacer(minLength: 200) } - Spacer(minLength: 200) + .frameLimit(width: proxy.size.width) } - .frameLimit(width: proxy.size.width) - } - .onRightSwipeGesture { - router.back() + .onRightSwipeGesture { + router.back() + } + } - } }.frame(maxWidth: .infinity) .refreshable { diff --git a/OpenEdX/Data/CoursePersistence.swift b/OpenEdX/Data/CoursePersistence.swift index eaca47bb5..4115de9f2 100644 --- a/OpenEdX/Data/CoursePersistence.swift +++ b/OpenEdX/Data/CoursePersistence.swift @@ -34,6 +34,7 @@ public class CoursePersistence: CoursePersistenceProtocol { courseID: $0.courseID ?? "", numPages: Int($0.numPages), coursesCount: Int($0.courseCount), + courseRawImage: $0.courseRawImage, progressEarned: 0, progressPossible: 0) } diff --git a/OpenEdX/Data/DashboardPersistence.swift b/OpenEdX/Data/DashboardPersistence.swift index 0a55aeaf7..9cac9921b 100644 --- a/OpenEdX/Data/DashboardPersistence.swift +++ b/OpenEdX/Data/DashboardPersistence.swift @@ -33,6 +33,7 @@ public class DashboardPersistence: DashboardPersistenceProtocol { courseID: $0.courseID ?? "", numPages: Int($0.numPages), coursesCount: Int($0.courseCount), + courseRawImage: $0.courseRawImage, progressEarned: 0, progressPossible: 0)} if let result, !result.isEmpty { @@ -59,6 +60,7 @@ public class DashboardPersistence: DashboardPersistenceProtocol { newItem.enrollmentEnd = item.enrollmentEnd newItem.numPages = Int32(item.numPages) newItem.courseID = item.courseID + newItem.courseRawImage = item.courseRawImage do { try context.save() @@ -131,6 +133,7 @@ public class DashboardPersistence: DashboardPersistenceProtocol { courseID: cdCourse.courseID ?? "", numPages: Int(cdCourse.numPages), coursesCount: Int(cdCourse.courseCount), + courseRawImage: cdCourse.courseRawImage, progressEarned: Int(cdCourse.progressEarned), progressPossible: Int(cdCourse.progressPossible) ) diff --git a/OpenEdX/Data/DiscoveryPersistence.swift b/OpenEdX/Data/DiscoveryPersistence.swift index b36f58fad..282b107ee 100644 --- a/OpenEdX/Data/DiscoveryPersistence.swift +++ b/OpenEdX/Data/DiscoveryPersistence.swift @@ -33,6 +33,7 @@ public class DiscoveryPersistence: DiscoveryPersistenceProtocol { courseID: $0.courseID ?? "", numPages: Int($0.numPages), coursesCount: Int($0.courseCount), + courseRawImage: $0.courseRawImage, progressEarned: 0, progressPossible: 0)} if let result, !result.isEmpty { @@ -59,6 +60,7 @@ public class DiscoveryPersistence: DiscoveryPersistenceProtocol { newItem.enrollmentEnd = item.enrollmentEnd newItem.numPages = Int32(item.numPages) newItem.courseID = item.courseID + newItem.courseRawImage = item.courseRawImage do { try context.save() @@ -86,7 +88,8 @@ public class DiscoveryPersistence: DiscoveryPersistenceProtocol { isEnrolled: courseDetails.isEnrolled, overviewHTML: courseDetails.overviewHTML ?? "", courseBannerURL: courseDetails.courseBannerURL ?? "", - courseVideoURL: nil + courseVideoURL: nil, + courseRawImage: courseDetails.courseRawImage ) } } @@ -105,6 +108,7 @@ public class DiscoveryPersistence: DiscoveryPersistenceProtocol { newCourseDetails.isEnrolled = course.isEnrolled newCourseDetails.overviewHTML = course.overviewHTML newCourseDetails.courseBannerURL = course.courseBannerURL + newCourseDetails.courseRawImage = course.courseRawImage do { try context.save() diff --git a/OpenEdX/Managers/DeepLinkManager/DeepLinkRouter/DeepLinkRouter.swift b/OpenEdX/Managers/DeepLinkManager/DeepLinkRouter/DeepLinkRouter.swift index 259cc2171..c77b2d4db 100644 --- a/OpenEdX/Managers/DeepLinkManager/DeepLinkRouter/DeepLinkRouter.swift +++ b/OpenEdX/Managers/DeepLinkManager/DeepLinkRouter/DeepLinkRouter.swift @@ -113,6 +113,7 @@ extension Router: DeepLinkRouter { enrollmentStart: courseDetails.enrollmentStart, enrollmentEnd: courseDetails.enrollmentEnd, title: courseDetails.courseTitle, + courseRawImage: courseDetails.courseRawImage, showDates: false, lastVisitedBlockID: nil ) diff --git a/OpenEdX/Managers/PipManager.swift b/OpenEdX/Managers/PipManager.swift index 94895077d..6938ae9a2 100644 --- a/OpenEdX/Managers/PipManager.swift +++ b/OpenEdX/Managers/PipManager.swift @@ -188,6 +188,7 @@ public class PipManager: PipManagerProtocol { enrollmentStart: courseDetails.enrollmentStart, enrollmentEnd: courseDetails.enrollmentEnd, title: courseDetails.courseTitle, + courseRawImage: courseDetails.courseRawImage, showDates: false, lastVisitedBlockID: nil ) diff --git a/OpenEdX/Router.swift b/OpenEdX/Router.swift index 4302385d6..13f99ed02 100644 --- a/OpenEdX/Router.swift +++ b/OpenEdX/Router.swift @@ -365,6 +365,7 @@ public class Router: AuthorizationRouter, enrollmentStart: Date?, enrollmentEnd: Date?, title: String, + courseRawImage: String?, showDates: Bool, lastVisitedBlockID: String? ) { @@ -376,6 +377,7 @@ public class Router: AuthorizationRouter, enrollmentStart: enrollmentStart, enrollmentEnd: enrollmentEnd, title: title, + courseRawImage: courseRawImage, showDates: showDates, lastVisitedBlockID: lastVisitedBlockID ) @@ -394,6 +396,7 @@ public class Router: AuthorizationRouter, enrollmentStart: Date?, enrollmentEnd: Date?, title: String, + courseRawImage: String?, showDates: Bool, lastVisitedBlockID: String? ) -> UIHostingController { @@ -418,7 +421,8 @@ public class Router: AuthorizationRouter, viewModel: vm, courseDatesViewModel: datesVm, courseID: courseID, - title: title + title: title, + courseRawImage: courseRawImage ) return UIHostingController(rootView: screensView)