The app was crashing from memory pressure on tvOS. Three causes fixed: 1. Feed was rendering all 418 highlights at once — capped to 50 items. 2. FeaturedGameCard had 3 blur effects (radius 80-120) on large circles for team color glow — replaced with a single LinearGradient. Same visual effect, fraction of the GPU memory. 3. BroadcastBackground had 3 blurred circles (radius 120-140, 680-900px) rendering on every screen — replaced with RadialGradients which are composited by the GPU natively without offscreen render passes. Also fixed iOS build: replaced tvOS-only font refs (tvSectionTitle, tvBody) with cross-platform equivalents in DashboardView fallback state. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
78 lines
2.2 KiB
Swift
78 lines
2.2 KiB
Swift
import SwiftUI
|
|
|
|
enum DataPanelDensity {
|
|
case compact
|
|
case standard
|
|
case featured
|
|
|
|
var padding: CGFloat {
|
|
switch self {
|
|
case .compact: DS.Spacing.panelPadCompact
|
|
case .standard: DS.Spacing.panelPadStandard
|
|
case .featured: DS.Spacing.panelPadFeatured
|
|
}
|
|
}
|
|
|
|
var cornerRadius: CGFloat {
|
|
switch self {
|
|
case .compact: DS.Radii.compact
|
|
case .standard: DS.Radii.standard
|
|
case .featured: DS.Radii.featured
|
|
}
|
|
}
|
|
}
|
|
|
|
struct DataPanel<Content: View>: View {
|
|
let density: DataPanelDensity
|
|
var teamAccentCode: String? = nil
|
|
@ViewBuilder let content: () -> Content
|
|
|
|
var body: some View {
|
|
HStack(spacing: 0) {
|
|
if let code = teamAccentCode {
|
|
RoundedRectangle(cornerRadius: 1.5)
|
|
.fill(TeamAssets.color(for: code))
|
|
.frame(width: 4)
|
|
.padding(.vertical, 8)
|
|
.padding(.leading, 6)
|
|
}
|
|
|
|
VStack(alignment: .leading, spacing: 0) {
|
|
content()
|
|
}
|
|
.frame(maxWidth: .infinity, alignment: .leading)
|
|
.padding(density.padding)
|
|
}
|
|
.background {
|
|
RoundedRectangle(cornerRadius: density.cornerRadius, style: .continuous)
|
|
.fill(
|
|
LinearGradient(
|
|
colors: [
|
|
DS.Colors.panelFill,
|
|
DS.Colors.panelFillMuted,
|
|
],
|
|
startPoint: .topLeading,
|
|
endPoint: .bottomTrailing
|
|
)
|
|
)
|
|
.overlay {
|
|
RoundedRectangle(cornerRadius: density.cornerRadius, style: .continuous)
|
|
.strokeBorder(DS.Colors.panelStroke, lineWidth: 1)
|
|
}
|
|
.shadow(color: DS.Shadows.card, radius: DS.Shadows.cardRadius, y: DS.Shadows.cardY)
|
|
}
|
|
}
|
|
}
|
|
|
|
extension DataPanel {
|
|
init(
|
|
_ density: DataPanelDensity = .standard,
|
|
teamAccent: String? = nil,
|
|
@ViewBuilder content: @escaping () -> Content
|
|
) {
|
|
self.density = density
|
|
self.teamAccentCode = teamAccent
|
|
self.content = content
|
|
}
|
|
}
|