feat: 反馈页面
This commit is contained in:
parent
85bd75b03a
commit
c5cb87b90b
@ -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()
|
||||
}
|
||||
|
||||
@ -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()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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)
|
||||
VStack(spacing: 16) {
|
||||
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: 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"
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user