From c5cb87b90b59b59f69906b8e1cdf61527ade734c Mon Sep 17 00:00:00 2001 From: jinyaqiu Date: Mon, 1 Sep 2025 15:19:25 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=8F=8D=E9=A6=88=E9=A1=B5=E9=9D=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- wake/ContentView.swift | 10 +-- wake/Utils/Router.swift | 9 ++- wake/View/Blind/BlindOutCome.swift | 123 +++++++++++++++++++---------- wake/View/Feedback.swift | 12 +-- 4 files changed, 96 insertions(+), 58 deletions(-) diff --git a/wake/ContentView.swift b/wake/ContentView.swift index f6d2216..b6e7862 100644 --- a/wake/ContentView.swift +++ b/wake/ContentView.swift @@ -645,16 +645,14 @@ struct BlindBoxView: View { Button(action: { // 导航到BlindOutcomeView if mediaType == .video, !videoURL.isEmpty, let url = URL(string: videoURL) { - Router.shared.navigate(to: .blindOutcome(media: .video(url, nil))) + Router.shared.navigate(to: .blindOutcome(media: .video(url, nil), time: blindGenerate?.videoGenerateTime ?? "hhsdshjsjdhn", description:blindGenerate?.description ?? "informationinformationinformationinformationinformationinformation")) } else if mediaType == .image, let image = displayImage { - Router.shared.navigate(to: .blindOutcome(media: .image(image))) + Router.shared.navigate(to: .blindOutcome(media: .image(image), time: blindGenerate?.videoGenerateTime ?? "hhsdshjsjdhn", description:blindGenerate?.description ?? "informationinformationinformationinformationinformationinformation")) } }) { - Image(systemName: "chevron.left.circle.fill") - .font(.system(size: 36)) + Image(systemName: "chevron.left") + .font(.system(size: 24)) .foregroundColor(.black) - .padding(12) - .clipShape(Circle()) } Spacer() } diff --git a/wake/Utils/Router.swift b/wake/Utils/Router.swift index bef8ae3..6337967 100644 --- a/wake/Utils/Router.swift +++ b/wake/Utils/Router.swift @@ -8,13 +8,14 @@ enum AppRoute: Hashable { case feedbackDetail(type: FeedbackView.FeedbackType) case mediaUpload case blindBox(mediaType: BlindBoxView.BlindBoxMediaType) - case blindOutcome(media: MediaType) + case blindOutcome(media: MediaType, time: String? = nil, description: String? = nil) case memories case subscribe case userInfo case account case about case permissionManagement + case feedback @ViewBuilder var view: some View { @@ -31,8 +32,8 @@ enum AppRoute: Hashable { MediaUploadView() case .blindBox(let mediaType): BlindBoxView(mediaType: mediaType) - case .blindOutcome(let media): - BlindOutcomeView(media: media) + case .blindOutcome(let media, let time, let description): + BlindOutcomeView(media: media, time: time, description: description) case .memories: MemoriesView() case .subscribe: @@ -45,6 +46,8 @@ enum AppRoute: Hashable { AboutUsView() case .permissionManagement: PermissionManagementView() + case .feedback: + FeedbackView() } } } diff --git a/wake/View/Blind/BlindOutCome.swift b/wake/View/Blind/BlindOutCome.swift index 50c3f04..d0880e3 100644 --- a/wake/View/Blind/BlindOutCome.swift +++ b/wake/View/Blind/BlindOutCome.swift @@ -5,11 +5,19 @@ import os.log /// A view that displays either an image or a video with fullscreen support struct BlindOutcomeView: View { let media: MediaType + let time: String? + let description: String? @Environment(\.presentationMode) var presentationMode @State private var isFullscreen = false @State private var isPlaying = false @State private var showIPListModal = false + init(media: MediaType, time: String? = nil, description: String? = nil) { + self.media = media + self.time = time + self.description = description + } + var body: some View { NavigationView { ZStack { @@ -54,51 +62,72 @@ struct BlindOutcomeView: View { // Media content GeometryReader { geometry in - ZStack { - // 添加白色背景 - RoundedRectangle(cornerRadius: 12) - .fill(Color.white) - .shadow(color: Color.black.opacity(0.1), radius: 8, x: 0, y: 2) - - switch media { - case .image(let uiImage): - Image(uiImage: uiImage) - .resizable() - .scaledToFit() - .cornerRadius(10) - .padding(4) - .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .top) - .onTapGesture { - withAnimation { - isFullscreen.toggle() + VStack(spacing: 16) { + ZStack { + // 添加白色背景 + RoundedRectangle(cornerRadius: 12) + .fill(Color.white) + .shadow(color: Color.black.opacity(0.1), radius: 8, x: 0, y: 2) + + VStack(spacing: 0) { + switch media { + case .image(let uiImage): + Image(uiImage: uiImage) + .resizable() + .scaledToFit() + .cornerRadius(10) + .padding(4) + .onTapGesture { + withAnimation { + isFullscreen.toggle() + } + } + + case .video(let url, _): + // Create an AVPlayer with the video URL + let player = AVPlayer(url: url) + VideoPlayer(player: player) + .cornerRadius(10) + .padding(4) + .onAppear { + player.play() + isPlaying = true + } + .onDisappear { + player.pause() + isPlaying = false + } + } + + VStack(alignment: .leading, spacing: 8) { + + if let description = description, !description.isEmpty { + VStack(alignment: .leading, spacing: 2) { + Text("Description") + .font(Typography.font(for: .body, family: .quicksandBold)) + .foregroundColor(.themeTextMessageMain) + Text(description) + .font(.system(size: 12)) + .foregroundColor(Color.themeTextMessageMain) + .fixedSize(horizontal: false, vertical: true) + } + .padding(.horizontal, 12) + .padding(.bottom, 12) } } - - case .video(let url, _): - // Create an AVPlayer with the video URL - let player = AVPlayer(url: url) - VideoPlayer(player: player) - .cornerRadius(10) - .padding(4) - .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .top) - .onAppear { - player.play() - isPlaying = true - } - .onDisappear { - player.pause() - isPlaying = false - } + .frame(maxWidth: .infinity, alignment: .leading) + } + .padding(.top, 8) } } .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .top) .padding(.bottom, 20) } - .frame(height: UIScreen.main.bounds.height / 2) .padding(.horizontal) Spacer() - // Button below media - VStack(spacing: 16) { + // Button at bottom + VStack { + Spacer() Button(action: { // 如果携带的类型是video显示弹窗 if case .video = media { @@ -106,7 +135,7 @@ struct BlindOutcomeView: View { showIPListModal = true } } else { - Router.shared.navigate(to: .mediaUpload) + Router.shared.navigate(to: .feedbackView) } }) { Text("Continue") @@ -117,9 +146,9 @@ struct BlindOutcomeView: View { .background(Color.themePrimary) .cornerRadius(26) } - .padding() + .padding(.horizontal) } - .frame(maxWidth: .infinity, maxHeight: .infinity) + .padding(.bottom, 20) } } .navigationBarHidden(true) // 确保隐藏系统导航栏 @@ -350,12 +379,20 @@ private struct VideoControls: View { // MARK: - Preview struct BlindOutcomeView_Previews: PreviewProvider { static var previews: some View { - // Preview with image - BlindOutcomeView(media: .image(UIImage(systemName: "photo")!)) + // Preview with image and details + BlindOutcomeView( + media: .image(UIImage(systemName: "photo")!), + time: "2:30", + description: "This is a sample description for the preview. It shows how the text will wrap and display below the media content." + ) - // Preview with video + // Preview with video and details if let url = URL(string: "https://example.com/sample.mp4") { - BlindOutcomeView(media: .video(url, nil)) + BlindOutcomeView( + media: .video(url, nil), + time: "1:45", + description: "Video content with time and description" + ) } } } diff --git a/wake/View/Feedback.swift b/wake/View/Feedback.swift index 7c47243..18c62cd 100644 --- a/wake/View/Feedback.swift +++ b/wake/View/Feedback.swift @@ -58,7 +58,6 @@ struct FeedbackView: View { VStack(spacing: 24) { Text("How are you feeling?") .font(Typography.font(for: .title2, family: .quicksandBold)) - .fontWeight(.semibold) .multilineTextAlignment(.center) .frame(maxWidth: .infinity) .padding(.bottom, 50) @@ -100,7 +99,6 @@ struct FeedbackView: View { .padding(.vertical, 24) .background(Color.white) .cornerRadius(16) - .shadow(color: Color.black.opacity(0.2), radius: 12, x: 0, y: 4) .padding(.horizontal, 16) .frame(minHeight: geometry.size.height - 120) // Subtract navigation bar and bottom button height @@ -109,8 +107,8 @@ struct FeedbackView: View { } .frame(maxWidth: .infinity, minHeight: geometry.size.height - 44) // Subtract navigation bar height } - .background(Color.themeTextWhiteSecondary) } + .background(Color.themeTextWhiteSecondary) // Add background color to the GeometryReader // Continue Button @@ -119,18 +117,20 @@ struct FeedbackView: View { }) { Text("Continue") .font(.headline) - .foregroundColor(selectedFeedback != nil ? .white : .gray) + .foregroundColor(selectedFeedback != nil ? .themeTextMessageMain : .gray) .frame(maxWidth: .infinity) .frame(height: 56) .background( - RoundedRectangle(cornerRadius: 25) + RoundedRectangle(cornerRadius: 32) .fill(selectedFeedback != nil ? - Color.themePrimary : Color(.systemGray5)) + Color.themePrimary : Color.themeTextWhiteSecondary) ) } .disabled(selectedFeedback == nil) .padding() + .background(Color.themeTextWhiteSecondary) // Add background color to the button area } + .background(Color.themeTextWhiteSecondary) // Set the background for the entire view .navigationBarHidden(true) } }