import SwiftUI /// Compact track row for track lists. struct TrackRow: View { let track: Track var body: some View { HStack(spacing: 8) { // Album art placeholder / format badge ZStack { RoundedRectangle(cornerRadius: 4) .fill(trackColor.opacity(0.15)) .frame(width: 32, height: 32) Image(systemName: "music.note") .font(.caption) .foregroundStyle(trackColor) } VStack(alignment: .leading, spacing: 1) { HStack(spacing: 4) { Text(track.title) .lineLimit(1) .font(.body) trackStateIcon } if !track.artist.isEmpty { Text(track.artist) .lineLimit(1) .font(.caption) .foregroundStyle(.secondary) } } } } /// Priority-ordered state icon for upload/download/cloud status. @ViewBuilder private var trackStateIcon: some View { if track.uploadState == .uploading { Image(systemName: "arrow.up.circle.fill") .font(.system(size: 11)) .foregroundStyle(.orange) } else if track.uploadState == .error { Image(systemName: "exclamationmark.circle.fill") .font(.system(size: 11)) .foregroundStyle(.red) } else if track.isCloud && track.downloadState == .downloading { Image(systemName: "arrow.down.circle") .font(.system(size: 11)) .foregroundStyle(Color.accentColor) } else if track.isCloud && track.downloadState == .error { Image(systemName: "exclamationmark.circle.fill") .font(.system(size: 11)) .foregroundStyle(.red) } else if track.isCloud && (track.downloadState == .downloaded || track.localCachePath != nil) { Image(systemName: "arrow.down.circle.fill") .font(.system(size: 11)) .foregroundStyle(.green) } else if track.uploadState == .uploaded { Image(systemName: "arrow.up.circle.fill") .font(.system(size: 11)) .foregroundStyle(.green) } else if track.isCloud { Image(systemName: "cloud.fill") .font(.system(size: 11)) .foregroundStyle(Color.accentColor.opacity(0.85)) } } private var trackColor: Color { if let hex = track.color { return Color(hex: hex) ?? .accentColor } return .accentColor } }