feat: 页面布局
This commit is contained in:
parent
2eee2486e1
commit
daf8476dd4
@ -9,7 +9,35 @@ struct MediaUploadView: View {
|
||||
@State private var selectedIndices: Set<Int> = []
|
||||
|
||||
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 {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user