Replace Feed with highlights, remove duplicate live shelf, drop Intel schedule
Feed tab: Replaced news/transaction feed with league-wide highlights and condensed game replays. FeedViewModel now fetches highlights from all games concurrently, splits into condensed games vs individual highlights. Cards show team color thumbnails with play button overlay. Today tab: Removed duplicate Live games shelf — LiveSituationBar already shows all live games at the top, so the shelf was redundant. Intel tab: Removed schedule section (already on Today tab). Updated header description and stat pills. Added division hydration to standings API call so division names display correctly instead of "Division". Focus: Added .platformFocusable() to standings cards and leaderboard cards so tvOS remote can scroll horizontally through them. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,112 +1,3 @@
|
||||
import SwiftUI
|
||||
|
||||
struct FeedItemView: View {
|
||||
let item: FeedItem
|
||||
|
||||
private var accentColor: Color {
|
||||
switch item.type {
|
||||
case .news: DS.Colors.interactive
|
||||
case .transaction: DS.Colors.positive
|
||||
case .scoring: DS.Colors.live
|
||||
}
|
||||
}
|
||||
|
||||
private var iconName: String {
|
||||
switch item.type {
|
||||
case .news: "newspaper.fill"
|
||||
case .transaction: "arrow.left.arrow.right"
|
||||
case .scoring: "sportscourt.fill"
|
||||
}
|
||||
}
|
||||
|
||||
private var typeLabel: String {
|
||||
switch item.type {
|
||||
case .news: "NEWS"
|
||||
case .transaction: "TRANSACTION"
|
||||
case .scoring: "SCORING"
|
||||
}
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
HStack(spacing: 0) {
|
||||
// Colored edge bar
|
||||
RoundedRectangle(cornerRadius: 1.5)
|
||||
.fill(accentColor)
|
||||
.frame(width: 3)
|
||||
.padding(.vertical, 8)
|
||||
|
||||
HStack(spacing: 12) {
|
||||
Image(systemName: iconName)
|
||||
.font(.system(size: iconSize, weight: .semibold))
|
||||
.foregroundStyle(accentColor)
|
||||
.frame(width: iconFrame, height: iconFrame)
|
||||
|
||||
VStack(alignment: .leading, spacing: 4) {
|
||||
HStack(spacing: 8) {
|
||||
Text(typeLabel)
|
||||
.font(DS.Fonts.caption)
|
||||
.foregroundStyle(accentColor)
|
||||
.kerning(1)
|
||||
|
||||
if let code = item.teamCode {
|
||||
HStack(spacing: 4) {
|
||||
RoundedRectangle(cornerRadius: 1)
|
||||
.fill(TeamAssets.color(for: code))
|
||||
.frame(width: 2, height: 10)
|
||||
Text(code)
|
||||
.font(DS.Fonts.caption)
|
||||
.foregroundStyle(DS.Colors.textTertiary)
|
||||
}
|
||||
}
|
||||
|
||||
Spacer()
|
||||
|
||||
Text(timeAgo(item.timestamp))
|
||||
.font(DS.Fonts.caption)
|
||||
.foregroundStyle(DS.Colors.textQuaternary)
|
||||
}
|
||||
|
||||
Text(item.title)
|
||||
.font(titleFont)
|
||||
.foregroundStyle(DS.Colors.textPrimary)
|
||||
.lineLimit(2)
|
||||
|
||||
if !item.subtitle.isEmpty {
|
||||
Text(item.subtitle)
|
||||
.font(subtitleFont)
|
||||
.foregroundStyle(DS.Colors.textTertiary)
|
||||
.lineLimit(1)
|
||||
}
|
||||
}
|
||||
}
|
||||
.padding(.horizontal, 14)
|
||||
.padding(.vertical, 12)
|
||||
}
|
||||
.background(DS.Colors.panelFill)
|
||||
.clipShape(RoundedRectangle(cornerRadius: DS.Radii.compact))
|
||||
.overlay(
|
||||
RoundedRectangle(cornerRadius: DS.Radii.compact)
|
||||
.strokeBorder(DS.Colors.panelStroke, lineWidth: 0.5)
|
||||
)
|
||||
}
|
||||
|
||||
private func timeAgo(_ date: Date) -> String {
|
||||
let interval = Date().timeIntervalSince(date)
|
||||
if interval < 60 { return "Just now" }
|
||||
if interval < 3600 { return "\(Int(interval / 60))m ago" }
|
||||
if interval < 86400 { return "\(Int(interval / 3600))h ago" }
|
||||
return "\(Int(interval / 86400))d ago"
|
||||
}
|
||||
|
||||
#if os(tvOS)
|
||||
private var iconSize: CGFloat { 18 }
|
||||
private var iconFrame: CGFloat { 36 }
|
||||
private var titleFont: Font { .system(size: 18, weight: .semibold) }
|
||||
private var subtitleFont: Font { DS.Fonts.bodySmall }
|
||||
#else
|
||||
private var iconSize: CGFloat { 14 }
|
||||
private var iconFrame: CGFloat { 28 }
|
||||
private var titleFont: Font { .system(size: 15, weight: .semibold) }
|
||||
private var subtitleFont: Font { .system(size: 12, weight: .medium) }
|
||||
#endif
|
||||
}
|
||||
// Placeholder — highlight cards are now inline in FeedView
|
||||
|
||||
Reference in New Issue
Block a user