← Back to index

ShowRowView

Spots
CodeWhat It DoesHow It Does It
▶ IMPORTS
import SwiftUIFramework importsImports SwiftUI.
struct ShowRowView: View { let entry: SpotEntry var showBell: Bool = true @State private var cachedImage: UIImage? /// "EEE, MMM d · h:mm a" e.g. "Sat, Mar 15 · 8:00 PM" private static let rowDateFormatter: DateFormatter = { let f = DateFormatter() f.dateFormat = "EEE, MMM d · h:mm a" return f }() /// Teal matching the Upcoming pin/button color private let showTeal = Color(red: 0/255, green: 150/255, blue: 136/255) var body: some View { HStack(spacing: 10) { VStack(alignment: .leading, spacing: 3) { // Show name + optional bell HStack(spacing: 5) { Text(verbatim: entry.playName) .font(.system(size: 15, weight: .medium)) .foregroundColor(.primary) if showBell && entry.remindersEnabled { Image(systemName: "bell.fill") .font(.system(size: 10)) .foregroundColor(.orange) } } // Date — only for committed (non-consider) entries if !entry.consider { Text(Self.rowDateFormatter.string(from: entry.dateTime)) .font(.system(size: 13)) .foregroundColor( entry.dateTime > Date() ? showTeal : Color.primary.opacity(0.65) ) } // Venue (stored in cuisine field) if !entry.cuisine.isEmpty { Text(entry.cuisine) .font(.system(size: 13)) .foregroundColor(Color.primary.opacity(0.65)) } // Row / Seat (stored in neighborhood field) if !entry.neighborhood.isEmpty { Text(entry.neighborhood) .font(.system(size: 12)) .foregroundColor(Color.primary.opacity(0.5)) } } Spacer() VStack(spacing: 3) { // Star rating (post-show) if entry.starRating > 0 { HStack(spacing: 2) { ForEach(1...entry.starRating, id: \.self) { _ in Image(systemName: "star.fill") .font(.system(size: 6)) .foregroundColor(.yellow) } } .frame(width: 50) } // Thumbnail if let uiImage = cachedImage { Image(uiImage: uiImage) .resizable() .scaledToFill() .frame(width: 50, height: 77) .clipped() .cornerRadius(4) } else { Rectangle() .fill(Color.gray.opacity(0.3)) .frame(width: 50, height: 77) .cornerRadius(4) } } } // Load downsampled thumbnail (50-pt × 3× = 150 px) .task(id: entry.id) { if let filename = entry.imageFilename, !filename.isEmpty { let image = await EntryStore.loadThumbnail(filename: filename, maxPixelSize: 150) await MainActor.run { cachedImage = image } } else if let data = entry.imageData { let image = await Task.detached(priority: .userInitiated) { let resized = EntryStore.resizedImageData(data, maxDimension: 150) guard let source = CGImageSourceCreateWithData(resized as CFData, nil), let cg = CGImageSourceCreateImageAtIndex(source, 0, nil) else { return UIImage?.none } return UIImage(cgImage: cg) }.value await MainActor.run { cachedImage = image } } } // Drop thumbnail when row scrolls off to avoid holding many UIImages in memory .onDisappear { cachedImage = nil } .onReceive(NotificationCenter.default.publisher( for: UIApplication.didReceiveMemoryWarningNotification)) { _ in cachedImage = nil } } }`ShowRowView` structDefines the `ShowRowView` struct. Conforms to View.