// // TravelAlbumDetailMaterialGridItem.swift // suixinkan // // 旅拍相册详情素材网格项,对齐 Android MaterialGridItem。 // import SwiftUI /// 旅拍相册详情素材网格单元。 struct TravelAlbumDetailMaterialGridItem: View { let material: TravelAlbumMaterial let isSelectionMode: Bool let isSelected: Bool let onSelect: () -> Void let onPreview: () -> Void var body: some View { VStack(alignment: .leading, spacing: 4) { thumbnailSection MiddleTruncatedText( text: material.fileName, font: .systemFont(ofSize: 11), textColor: UIColor(TravelAlbumDetailDesign.text333) ) .frame(maxWidth: .infinity, minHeight: 14, maxHeight: 14, alignment: .leading) Text(WiredTransferPhotoRecord.formatFileSize(Int64(material.fileSize))) .font(.system(size: 10)) .foregroundStyle(TravelAlbumDetailDesign.text999) .lineLimit(1) } .frame(maxWidth: .infinity, alignment: .leading) .contentShape(Rectangle()) .onTapGesture { if isSelectionMode { onSelect() } else { onPreview() } } } /// 1:1 缩略图区域,限制在网格单元宽度内避免重叠溢出。 private var thumbnailSection: some View { Color.clear .aspectRatio(1, contentMode: .fit) .overlay { RemoteImage( urlString: material.thumbnailURLString, contentMode: .fill ) { Color(hex: 0xE5E7EB) } .frame(maxWidth: .infinity, maxHeight: .infinity) } .clipShape(RoundedRectangle(cornerRadius: TravelAlbumDetailDesign.thumbnailCornerRadius)) .overlay(alignment: .topLeading) { if material.isPurchased { Text("已购买") .font(.system(size: 10)) .foregroundStyle(.white) .padding(.horizontal, 4) .padding(.vertical, 2) .background(AppDesign.primary) .clipShape(RoundedRectangle(cornerRadius: TravelAlbumDetailDesign.uploadedBadgeCornerRadius)) .padding(4) } } .overlay(alignment: .topTrailing) { if isSelectionMode { Image(systemName: isSelected ? "checkmark.circle.fill" : "circle") .font(.system(size: TravelAlbumDetailDesign.selectionCheckSize)) .foregroundStyle(isSelected ? AppDesign.primary : .white) .padding(4) .background(Color.black.opacity(0.4), in: Circle()) .padding(4) } } } }