From daf8476dd4962ed4928e867a1eb00108ad445d4e Mon Sep 17 00:00:00 2001 From: jinyaqiu Date: Mon, 25 Aug 2025 14:09:15 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E9=A1=B5=E9=9D=A2=E5=B8=83=E5=B1=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- wake/View/Upload/MediaUploadView.swift | 127 ++++++++++++------------- 1 file changed, 62 insertions(+), 65 deletions(-) diff --git a/wake/View/Upload/MediaUploadView.swift b/wake/View/Upload/MediaUploadView.swift index 3a414da..da7d876 100644 --- a/wake/View/Upload/MediaUploadView.swift +++ b/wake/View/Upload/MediaUploadView.swift @@ -9,7 +9,35 @@ struct MediaUploadView: View { @State private var selectedIndices: Set = [] var body: some View { - VStack(spacing: 24) { + VStack() { + // 固定的顶部导航栏 + HStack { + Button(action: { + Router.shared.pop() + }) { + Image(systemName: "chevron.left") + .font(.system(size: 17, weight: .semibold)) + .foregroundColor(.themeTextMessageMain) + } + .padding(.leading, 16) + + Spacer() + + Text("Complete Your Profile") + .font(Typography.font(for: .title2, family: .quicksandBold)) + .foregroundColor(.themeTextMessageMain) + + Spacer() + + // 添加一个透明的占位视图来平衡布局 + Color.clear + .frame(width: 24, height: 24) + .padding(.trailing, 16) + } + .background(Color.themeTextWhiteSecondary) + .padding(.bottom, -24) + .zIndex(1) // 确保导航栏在最上层 + // 主体内容 HStack(spacing: 20) { Text("The upload process will take approximately 2 minutes. Thank you for your patience. ") .font(Typography.font(for: .caption)) @@ -28,64 +56,42 @@ struct MediaUploadView: View { ) ) } - .padding(10) + .padding() + Spacer() + .frame(height: 20) + MainUploadArea( uploadManager: uploadManager, showMediaPicker: $showMediaPicker, selectedMedia: $selectedMedia, selectedIndices: $selectedIndices ) + .padding() .id("mainUploadArea\(uploadManager.selectedMedia.count)") - + Spacer() - .frame(height: 40) // Navigation button Button(action: { - Router.shared.navigate(to: .avatarBox) + // Router.shared.navigate(to: .avatarBox) }) { Text("Continue") .font(.headline) - .foregroundColor(.white) + .foregroundColor(uploadManager.selectedMedia.isEmpty ? Color.themeTextMessage : Color.themeTextMessageMain) .frame(maxWidth: .infinity) .frame(height: 56) - .background(Theme.Colors.primary) + .background(uploadManager.selectedMedia.isEmpty ? Color.white : Color.themePrimary) .cornerRadius(28) .padding(.horizontal, 24) - .padding(.top, 16) } .buttonStyle(PlainButtonStyle()) - - if !uploadManager.selectedMedia.isEmpty { - ThumbnailScrollView( - uploadManager: uploadManager, - selectedIndices: $selectedIndices, - selectedMedia: $selectedMedia - ) - .id("thumbnailScroll\(uploadManager.selectedMedia.count)") - } - + Spacer() - - if !uploadManager.selectedMedia.isEmpty { - UploadButton(uploadManager: uploadManager) - .id("uploadButton\(uploadManager.selectedMedia.count)") - } } - .navigationTitle("Complete Your Profile") + .background(Color.themeTextWhiteSecondary) .navigationBarTitleDisplayMode(.inline) - .toolbar { - ToolbarItem(placement: .principal) { - Text("Complete Your Profile") - .font(Typography.font(for: .title2)) - } - ToolbarItem(placement: .navigationBarLeading) { - Button(action: {}) { - EmptyView() - } - } - } + .navigationBarBackButtonHidden(true) .sheet(isPresented: $showMediaPicker) { MediaPicker( selectedMedia: $uploadManager.selectedMedia, @@ -106,6 +112,8 @@ struct MediaUploadView: View { if !uploadManager.selectedMedia.isEmpty && selectedMedia == nil { selectedMedia = uploadManager.selectedMedia.first selectedIndices = [0] + // Start upload when media picker is dismissed with new media + uploadManager.startUpload() } } @@ -123,6 +131,11 @@ struct MediaUploadView: View { } else if let selectedIndex = selectedIndices.first, selectedIndex < newMedia.count { selectedMedia = newMedia[selectedIndex] } + + // Auto-upload when new media is added + if !newMedia.isEmpty && !uploadManager.isUploading { + uploadManager.startUpload() + } } } @@ -137,7 +150,7 @@ struct MainUploadArea: View { var body: some View { VStack(spacing: 16) { Text("Click to upload 20 images and 5 videos to generate your next blind box.") - .font(Typography.font(for: .body, family: .quicksandRegular)) + .font(Typography.font(for: .title2, family: .quicksandBold)) .fontWeight(.bold) .foregroundColor(.black) .multilineTextAlignment(.center) @@ -146,13 +159,20 @@ struct MainUploadArea: View { if let media = selectedMedia { MediaPreview(media: media) - .frame(height: 300) + .frame(width: 225, height: 225) .onTapGesture { showMediaPicker = true } } else { UploadPromptView(showMediaPicker: $showMediaPicker) } + if !uploadManager.selectedMedia.isEmpty { + ThumbnailScrollView( + uploadManager: uploadManager, + selectedIndices: $selectedIndices, + selectedMedia: $selectedMedia + ) + .id("thumbnailScroll\(uploadManager.selectedMedia.count)") + } } - .padding(.horizontal) .background(Color.white) .cornerRadius(16) } @@ -164,25 +184,22 @@ struct UploadPromptView: View { @Binding var showMediaPicker: Bool var body: some View { - VStack(spacing: 16) { + Button(action: { + showMediaPicker = true + }) { SVGImage(svgName: "IP") .frame(width: 225, height: 225) .contentShape(Rectangle()) .overlay( RoundedRectangle(cornerRadius: 20) .stroke(style: StrokeStyle( - lineWidth: 3, + lineWidth: 5, lineCap: .round, dash: [12, 8] )) .foregroundColor(Color.themePrimary) ) - .onTapGesture { - showMediaPicker = true - } } - .background(Color.white) - .cornerRadius(16) } } @@ -312,26 +329,6 @@ struct AddMoreButton: View { } } -// MARK: - Upload Button - -struct UploadButton: View { - @ObservedObject var uploadManager: MediaUploadManager - - var body: some View { - Button(action: uploadManager.startUpload) { - Text("上传") - .font(.headline) - .foregroundColor(.white) - .frame(maxWidth: .infinity) - .frame(height: 56) - .background(Color.themePrimary) - .cornerRadius(28) - .padding(.horizontal, 40) - .padding(.bottom, 24) - } - } -} - // MARK: - Media Preview struct MediaPreview: View {