// // WiredTransferPhotoRow.swift // suixinkan // import Kingfisher import SwiftUI import UIKit /// 有线传图照片列表行。 struct WiredTransferPhotoRow: View { let photo: WiredTransferPhotoItem let selectUploadMode: Bool let selected: Bool let onToggleSelection: () -> Void let onPhotoClick: () -> Void let onRetry: () -> Void let onDelete: () -> Void private var canSelect: Bool { photo.canSelectForSpecifyUpload } private var canRetry: Bool { photo.status == .failed || photo.status == .pending } private var rowOpacity: Double { selectUploadMode && !canSelect ? 0.45 : 1 } private var showsProgress: Bool { photo.status == .transferring || photo.status == .uploading } var body: some View { HStack(alignment: .center, spacing: 8) { HStack(alignment: .center, spacing: 8) { if selectUploadMode { WiredTransferSelectIndicator(selected: selected, enabled: canSelect) } thumbnailView .frame(width: WiredTransferDesign.thumbnailSize, height: WiredTransferDesign.thumbnailSize) .clipShape(RoundedRectangle(cornerRadius: WiredTransferDesign.thumbnailCornerRadius)) .opacity(rowOpacity) VStack(alignment: .leading, spacing: 5) { HStack(spacing: 4) { Text(photo.fileName) .font(.system(size: 12, weight: .medium)) .foregroundStyle(WiredTransferDesign.text333.opacity(rowOpacity)) .lineLimit(1) Spacer(minLength: 0) WiredTransferStatusBadge(status: photo.status) .opacity(rowOpacity) } Text(metaText) .font(.system(size: 10)) .foregroundStyle(WiredTransferDesign.text999.opacity(rowOpacity)) .lineLimit(1) progressSlot } } .frame(maxWidth: .infinity, alignment: .leading) .contentShape(Rectangle()) .onTapGesture { if selectUploadMode { if canSelect { onToggleSelection() } } else { onPhotoClick() } } if !selectUploadMode { Menu { Button("重传") { onRetry() } .disabled(!canRetry) Button("删除", role: .destructive) { onDelete() } } label: { Image(systemName: "ellipsis") .font(.system(size: 16)) .foregroundStyle(WiredTransferDesign.text666) .frame(width: 32, height: 32) .rotationEffect(.degrees(90)) } } } .frame(height: WiredTransferDesign.photoRowHeight) .padding(.horizontal, 10) } private var metaText: String { if photo.resolutionText.isEmpty { return photo.fileSizeText } return "\(photo.fileSizeText) \(photo.resolutionText)" } private var progressSlot: some View { ProgressView(value: showsProgress ? Double(photo.progress) : 0, total: 100) .tint(AppDesign.primary) .opacity(showsProgress ? 1 : 0) .frame(height: WiredTransferDesign.progressBarHeight) } @ViewBuilder private var thumbnailView: some View { if let url = URL(string: photo.thumbnailURL), !photo.thumbnailURL.isEmpty { KFImage(url) .placeholder { thumbnailPlaceholder } .setProcessor( DownsamplingImageProcessor( size: CGSize( width: WiredTransferDesign.thumbnailSize, height: WiredTransferDesign.thumbnailSize ) ) ) .scaleFactor(UIScreen.main.scale) .resizable() .aspectRatio(contentMode: .fill) } else { thumbnailPlaceholder } } private var thumbnailPlaceholder: some View { WiredTransferDesign.pageBackground .overlay { Image(systemName: "photo") .foregroundStyle(WiredTransferDesign.text999) } } }