diff --git a/wake/View/Upload/MediaUploadView.swift b/wake/View/Upload/MediaUploadView.swift index 099c1fe..7f44090 100644 --- a/wake/View/Upload/MediaUploadView.swift +++ b/wake/View/Upload/MediaUploadView.swift @@ -98,15 +98,22 @@ struct MediaUploadView: View { selectedMedia: $uploadManager.selectedMedia, imageSelectionLimit: 20, videoSelectionLimit: 5, - onDismiss: handleMediaPickerDismiss, + onDismiss: { + // 只处理界面相关的逻辑 + showMediaPicker = false + }, onUploadProgress: { index, progress in - // 更新单个文件的上传进度 print("File \(index) upload progress: \(progress * 100)%") } ) } .onChange(of: uploadManager.selectedMedia) { newMedia in - handleMediaChange(newMedia) + print("onChange1111111", uploadManager.selectedMedia) + // 在这里处理媒体变化 + if !newMedia.isEmpty { + // 当有新的媒体时开始上传 + uploadManager.startUpload() + } } } @@ -114,6 +121,8 @@ struct MediaUploadView: View { private func handleMediaPickerDismiss() { self.uploadManager.startUpload() + print("handleMediaPickerDismiss1111111", uploadManager.selectedMedia) + // showMediaPicker = false // // 确保选择器完全关闭后再开始上传 @@ -174,28 +183,88 @@ struct MainUploadArea: View { .fontWeight(.bold) .foregroundColor(.black) .multilineTextAlignment(.center) - .frame(maxWidth: .infinity, alignment: .leading) - .padding() - - if let media = selectedMedia { - MediaPreview(media: media, uploadManager: uploadManager) - .frame(width: 225, height: 225) - .onTapGesture { showMediaPicker = true } - .padding(.bottom, 10) + .padding(.horizontal) + + if !uploadManager.selectedMedia.isEmpty { + // 显示媒体预览网格 + ScrollView { + LazyVGrid(columns: [ + GridItem(.flexible(), spacing: 16), + GridItem(.flexible(), spacing: 16) + ], spacing: 16) { + ForEach(0.. Void var body: some View { - Button(action: onTap) { - ZStack(alignment: .topTrailing) { + Button(action: onTap) { + ZStack(alignment: .topTrailing) { + // Main thumbnail content + ZStack { Group { if let thumbnail = media.thumbnail { Image(uiImage: thumbnail) @@ -297,34 +370,64 @@ struct ThumbnailView: View { .stroke(isSelected ? Color.themePrimary : Color.clear, lineWidth: 2) ) - // Selection checkmark - if isSelected && showCheckmark { - Image(systemName: "checkmark.circle.fill") - .font(.system(size: 20)) - .foregroundColor(.white) - .background(Circle().fill(Color.themePrimary)) - .offset(x: 6, y: -6) // Adjusted offset to ensure visibility - .zIndex(1) // Ensure checkmark is above video icon - } - - // Video icon - if media.isVideo { - Image(systemName: "video.fill") - .font(.caption) - .foregroundColor(.white) - .padding(4) - .background(Color.black.opacity(0.6)) - .clipShape(Circle()) - .padding(4) - .offset(x: -4, y: 4) // Slight adjustment for better positioning + // Upload progress border + if let uploadManager = uploadManager, + let index = uploadManager.selectedMedia.firstIndex(where: { $0 == media }) { + let status = uploadManager.uploadStatus["\(index)"] + if case .uploading(let progress) = status, progress > 0 && progress < 1 { + ZStack { + Circle() + .stroke( + Color.themePrimary.opacity(0.3), + style: StrokeStyle(lineWidth: 2, lineCap: .round) + ) + .rotationEffect(.degrees(-90)) + .padding(2) + + Circle() + .trim(from: 0, to: progress) + .stroke( + Color.themePrimary, + style: StrokeStyle(lineWidth: 2, lineCap: .round) + ) + .rotationEffect(.degrees(-90)) + .animation(.linear, value: progress) + .padding(2) + } + .frame(width: 20, height: 20) + .offset(x: 30, y: -30) + } } } - .frame(width: 80, height: 80) - .contentShape(Rectangle()) - .padding(4) // Add padding to prevent clipping + + // Selection checkmark + if isSelected && showCheckmark { + Image(systemName: "checkmark.circle.fill") + .font(.system(size: 20)) + .foregroundColor(.white) + .background(Circle().fill(Color.themePrimary)) + .offset(x: 6, y: -6) + .zIndex(1) + } + + // Video icon + if media.isVideo { + Image(systemName: "video.fill") + .font(.caption) + .foregroundColor(.white) + .padding(4) + .background(Color.black.opacity(0.6)) + .clipShape(Circle()) + .padding(4) + .offset(x: -4, y: 4) + } } - .buttonStyle(PlainButtonStyle()) + .frame(width: 80, height: 80) + .contentShape(Rectangle()) + .padding(4) } + .buttonStyle(PlainButtonStyle()) +} } // MARK: - Add More Button @@ -357,83 +460,46 @@ struct MediaPreview: View { @ObservedObject var uploadManager: MediaUploadManager private var uploadProgress: Double { - // Get the upload progress for this media item using its index - if let index = uploadManager.selectedMedia.firstIndex(where: { $0 == media }) { - let status = uploadManager.uploadStatus["\(index)"] - if case .uploading(let progress) = status { - return progress - } + guard let index = uploadManager.selectedMedia.firstIndex(where: { $0 == media }), + case .uploading(let progress) = uploadManager.uploadStatus["\(index)"] else { + return 0 } - return 0 - } - - private var isUploading: Bool { - if let index = uploadManager.selectedMedia.firstIndex(where: { $0 == media }) { - let status = uploadManager.uploadStatus["\(index)"] - if case .uploading = status { - return true - } - } - return false + return progress } var body: some View { ZStack { - // Main media content + // 媒体内容 Group { switch media { case .image(let uiImage): Image(uiImage: uiImage) .resizable() - .scaledToFit() - .cornerRadius(12) - .drawingGroup() + .scaledToFill() case .video(_, let thumbnail): if let thumbnail = thumbnail { Image(uiImage: thumbnail) .resizable() - .scaledToFit() + .scaledToFill() .overlay( Image(systemName: "play.circle.fill") - .font(.system(size: 48)) + .font(.system(size: 36)) .foregroundColor(.white) - .shadow(radius: 10) + .shadow(radius: 8) ) - .cornerRadius(12) - .drawingGroup() + } else { + Color.gray } } } - - // Upload progress border - if isUploading { - Circle() - .stroke( - Color.themePrimary.opacity(0.3), - style: StrokeStyle(lineWidth: 4, lineCap: .round) - ) - .rotationEffect(.degrees(-90)) - .padding(4) - - Circle() - .trim(from: 0, to: uploadProgress) - .stroke( - Color.themePrimary, - style: StrokeStyle(lineWidth: 4, lineCap: .round) - ) - .rotationEffect(.degrees(-90)) - .animation(.linear, value: uploadProgress) - .padding(4) - } + .aspectRatio(1, contentMode: .fill) + .clipped() + .cornerRadius(8) + .overlay( + RoundedRectangle(cornerRadius: 8) + .stroke(Color.themePrimary.opacity(0.3), lineWidth: 1) + ) } - .frame(maxWidth: .infinity, maxHeight: .infinity) - .background(Color.themeTextWhiteSecondary) - .cornerRadius(16) - .overlay( - RoundedRectangle(cornerRadius: 16) - .stroke(Color.themePrimary, lineWidth: 2) - ) - .contentShape(Rectangle()) } }