From c2e7817cc0f7308658d84d63d0aaa74aecf29901 Mon Sep 17 00:00:00 2001 From: Eddie Date: Mon, 4 May 2026 16:27:49 -0400 Subject: [PATCH] fix: crop course details banner image Co-authored-by: Codex --- .../NativeDiscovery/CourseDetailsView.swift | 73 +++++++------------ Discovery/Discovery/SwiftGen/Strings.swift | 2 + .../Discovery/en.lproj/Localizable.strings | 1 + 3 files changed, 28 insertions(+), 48 deletions(-) diff --git a/Discovery/Discovery/Presentation/NativeDiscovery/CourseDetailsView.swift b/Discovery/Discovery/Presentation/NativeDiscovery/CourseDetailsView.swift index dbc2a35af..004e633df 100644 --- a/Discovery/Discovery/Presentation/NativeDiscovery/CourseDetailsView.swift +++ b/Discovery/Discovery/Presentation/NativeDiscovery/CourseDetailsView.swift @@ -76,18 +76,15 @@ public struct CourseDetailsView: View { // MARK: - Course Banner CourseBannerView( courseDetails: courseDetails, - proxy: proxy, - isHorisontal: viewModel.isHorisontal, onPlayButtonTap: { [weak viewModel] in viewModel?.showCourseVideo() } ) - }.aspectRatio(CGSize(width: 16, height: 8.5), contentMode: .fill) - .frame(maxHeight: 250) + .frame(width: 312, height: 312 * 8.5 / 16) .cornerRadius(12) .padding(.horizontal, 6) .padding(.top, 7) - + } } } else { // MARK: - iPhone @@ -95,16 +92,14 @@ public struct CourseDetailsView: View { // MARK: - Course Banner CourseBannerView( courseDetails: courseDetails, - proxy: proxy, - isHorisontal: viewModel.isHorisontal, onPlayButtonTap: { [weak viewModel] in viewModel?.showCourseVideo() }) - }.aspectRatio(CGSize(width: 16, height: 8.5), contentMode: .fill) + .aspectRatio(CGSize(width: 16, height: 8.5), contentMode: .fit) .cornerRadius(12) .padding(.horizontal, 6) .padding(.top, 7) - .fixedSize(horizontal: false, vertical: true) + } // MARK: - Course state button CourseStateView(title: title, @@ -376,58 +371,40 @@ private struct CourseTitleView: View { private struct CourseBannerView: View { @State private var animate = false - private var isHorisontal: Bool private let courseDetails: CourseDetails - private let idiom: UIUserInterfaceIdiom - private let proxy: GeometryProxy private let onPlayButtonTap: () -> Void init(courseDetails: CourseDetails, - proxy: GeometryProxy, - isHorisontal: Bool, onPlayButtonTap: @escaping () -> Void) { self.courseDetails = courseDetails - self.isHorisontal = isHorisontal - self.idiom = UIDevice.current.userInterfaceIdiom - self.proxy = proxy self.onPlayButtonTap = onPlayButtonTap } var body: some View { ZStack(alignment: .center) { - if !isHorisontal { - KFImage(URL(string: courseDetails.courseBannerURL)) - .onFailureImage(CoreAssets.noCourseImage.image) - .resizable() - .aspectRatio(16/9, contentMode: .fill) - .frame(width: idiom == .pad ? nil : proxy.size.width - 12) - .opacity(animate ? 1 : 0) - .onAppear { - withAnimation(.linear(duration: 0.5)) { - animate = true - } - } - .accessibilityIdentifier("course_image") - if courseDetails.courseVideoURL != nil { - PlayButton(action: onPlayButtonTap) - } - } else { - KFImage(URL(string: courseDetails.courseBannerURL)) - .onFailureImage(CoreAssets.noCourseImage.image) - .resizable() - .aspectRatio(16/9, contentMode: .fill) - .frame(width: 312) - .opacity(animate ? 1 : 0) - .onAppear { - withAnimation(.linear(duration: 0.5)) { - animate = true - } + bannerImage + if courseDetails.courseVideoURL != nil { + PlayButton(action: onPlayButtonTap) + } + } + } + + private var bannerImage: some View { + GeometryReader { proxy in + KFImage(URL(string: courseDetails.courseBannerURL)) + .onFailureImage(CoreAssets.noCourseImage.image) + .resizable() + .scaledToFill() + .frame(width: proxy.size.width, height: proxy.size.height) + .clipped() + .opacity(animate ? 1 : 0) + .onAppear { + withAnimation(.linear(duration: 0.5)) { + animate = true } - .accessibilityIdentifier("course_image") - if courseDetails.courseVideoURL != nil { - PlayButton(action: onPlayButtonTap) } - } + .accessibilityIdentifier("course_image") + .accessibilityLabel(DiscoveryLocalization.Details.courseBanner) } } } diff --git a/Discovery/Discovery/SwiftGen/Strings.swift b/Discovery/Discovery/SwiftGen/Strings.swift index 2e8c02fc5..3bc776d44 100644 --- a/Discovery/Discovery/SwiftGen/Strings.swift +++ b/Discovery/Discovery/SwiftGen/Strings.swift @@ -52,6 +52,8 @@ public enum DiscoveryLocalization { public static let pleaseEnterTheSystem = DiscoveryLocalization.tr("Localizable", "ALERT.PLEASE_ENTER_THE_SYSTEM", fallback: "Please enter the system to continue with course enrollment.") } public enum Details { + /// Course banner + public static let courseBanner = DiscoveryLocalization.tr("Localizable", "DETAILS.COURSE_BANNER", fallback: "Course banner") /// Enroll now public static let enrollNow = DiscoveryLocalization.tr("Localizable", "DETAILS.ENROLL_NOW", fallback: "Enroll now") /// You cannot enroll in this course because the enrollment date is over. diff --git a/Discovery/Discovery/en.lproj/Localizable.strings b/Discovery/Discovery/en.lproj/Localizable.strings index bb9877504..bda1428d0 100644 --- a/Discovery/Discovery/en.lproj/Localizable.strings +++ b/Discovery/Discovery/en.lproj/Localizable.strings @@ -35,6 +35,7 @@ "DETAILS.ENROLL_NOW" = "Enroll now"; "DETAILS.ENROLLMENT_DATE_IS_OVER" = "You cannot enroll in this course because the enrollment date is over."; "DETAILS.ENROLLMENT_NO_INTERNET" = "To enroll in this course, please make sure you are connected to the internet."; +"DETAILS.COURSE_BANNER" = "Course banner"; "ALERT.AUTHORIZATION" = "Authorization"; "ALERT.PLEASE_ENTER_THE_SYSTEM" = "Please enter the system to continue with course enrollment.";