import SwiftUI import Combine public struct AvatarPicker: View { @StateObject private var uploadManager = MediaUploadManager() @State private var showMediaPicker = false @State private var isUploading = false @State private var uploadedFileId: String? = nil @State private var uploadTask: AnyCancellable? @Binding var selectedImage: UIImage? @Binding var showUsername: Bool @Binding var isKeyboardVisible: Bool // 添加完成回调 var onFileUploaded: ((String) -> Void)? = nil public init(selectedImage: Binding, showUsername: Binding, isKeyboardVisible: Binding, onFileUploaded: ((String) -> Void)? = nil) { self._selectedImage = selectedImage self._showUsername = showUsername self._isKeyboardVisible = isKeyboardVisible self.onFileUploaded = onFileUploaded } public var body: some View { VStack(spacing: 20) { // Avatar Image Button(action: { showMediaPicker = true }) { ZStack { if let selectedImage = selectedImage { Image(uiImage: selectedImage) .resizable() .scaledToFill() .frame(width: isKeyboardVisible ? 125 : 225, height: isKeyboardVisible ? 125 : 225) .clipShape(RoundedRectangle(cornerRadius: 20)) } else { // Default SVG avatar SVGImage(svgName: "Avatar") .frame(width: isKeyboardVisible ? 125 : 225, height: isKeyboardVisible ? 125 : 225) .contentShape(Rectangle()) } if isUploading { ProgressView() .progressViewStyle(CircularProgressViewStyle()) .scaleEffect(1.5) } } } if !showUsername { // Upload button Button(action: { showMediaPicker = true }) { Text("Upload from Gallery") .font(Typography.font(for: .subtitle, family: .inter)) .fontWeight(.regular) .frame(maxWidth: .infinity) .padding() .foregroundColor(.black) .background( RoundedRectangle(cornerRadius: 16) .fill(Color.themePrimaryLight) ) } .frame(maxWidth: .infinity) } } .sheet(isPresented: $showMediaPicker) { MediaPicker( selectedMedia: $uploadManager.selectedMedia, imageSelectionLimit: 1, videoSelectionLimit: 0, allowedMediaTypes: .imagesOnly, selectionMode: .single, onDismiss: { showMediaPicker = false if !uploadManager.selectedMedia.isEmpty { isUploading = true uploadManager.startUpload() // 使用 Combine 监听上传状态变化 uploadTask = uploadManager.$uploadStatus .receive(on: DispatchQueue.main) .sink { _ in if uploadManager.isAllUploaded { isUploading = false if let firstResult = uploadManager.getUploadResults().values.first { self.uploadedFileId = firstResult self.onFileUploaded?(firstResult) } uploadTask?.cancel() } } } } ) } .onDisappear { uploadTask?.cancel() } .onChange(of: uploadManager.selectedMedia) { newMedia in if let firstMedia = newMedia.first, case .image(let image) = firstMedia { selectedImage = image } } } }