Fix hero image: use pitcher action photos instead of broken stadium URLs
Stadium venue URLs return 404. Switched to pitcher action hero photos from img.mlbstatic.com which return real high-res player photos — much more impactful than stadiums anyway (matches the cast photo aesthetic from the reference). Falls back to prominent team logos with rich team color gradients instead of washed-out gray circles. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -15,8 +15,19 @@ struct FeaturedGameCard: View {
|
|||||||
return parts.count > 1 ? parts.last : nil
|
return parts.count > 1 ? parts.last : nil
|
||||||
}
|
}
|
||||||
|
|
||||||
private var stadiumImageURL: URL? {
|
private var heroImageURL: URL? {
|
||||||
TeamAssets.stadiumURL(for: game.homeTeam.code)
|
// Prefer pitcher action hero photo — big, dramatic, like a cast photo
|
||||||
|
if let pitcherId = game.homePitcherId {
|
||||||
|
return URL(string: "https://img.mlbstatic.com/mlb-photos/image/upload/w_1200,q_auto:best/v1/people/\(pitcherId)/action/hero/current")
|
||||||
|
}
|
||||||
|
if let pitcherId = game.awayPitcherId {
|
||||||
|
return URL(string: "https://img.mlbstatic.com/mlb-photos/image/upload/w_1200,q_auto:best/v1/people/\(pitcherId)/action/hero/current")
|
||||||
|
}
|
||||||
|
// Fall back to large team logo
|
||||||
|
if let teamId = game.homeTeam.teamId {
|
||||||
|
return URL(string: "https://midfield.mlbstatic.com/v1/team/\(teamId)/spots/800")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
@@ -29,7 +40,7 @@ struct FeaturedGameCard: View {
|
|||||||
HStack(spacing: 0) {
|
HStack(spacing: 0) {
|
||||||
Spacer()
|
Spacer()
|
||||||
ZStack(alignment: .leading) {
|
ZStack(alignment: .leading) {
|
||||||
stadiumImage
|
heroImage
|
||||||
.frame(width: imageWidth)
|
.frame(width: imageWidth)
|
||||||
|
|
||||||
// White fade from left edge of image
|
// White fade from left edge of image
|
||||||
@@ -227,8 +238,8 @@ struct FeaturedGameCard: View {
|
|||||||
// MARK: - Stadium Image
|
// MARK: - Stadium Image
|
||||||
|
|
||||||
@ViewBuilder
|
@ViewBuilder
|
||||||
private var stadiumImage: some View {
|
private var heroImage: some View {
|
||||||
if let url = stadiumImageURL {
|
if let url = heroImageURL {
|
||||||
AsyncImage(url: url) { phase in
|
AsyncImage(url: url) { phase in
|
||||||
switch phase {
|
switch phase {
|
||||||
case .success(let image):
|
case .success(let image):
|
||||||
@@ -249,17 +260,25 @@ struct FeaturedGameCard: View {
|
|||||||
@ViewBuilder
|
@ViewBuilder
|
||||||
private var fallbackImage: some View {
|
private var fallbackImage: some View {
|
||||||
ZStack {
|
ZStack {
|
||||||
|
// Rich team color gradient
|
||||||
LinearGradient(
|
LinearGradient(
|
||||||
colors: [awayColor.opacity(0.15), homeColor.opacity(0.15)],
|
colors: [
|
||||||
startPoint: .leading,
|
awayColor.opacity(0.4),
|
||||||
endPoint: .trailing
|
homeColor.opacity(0.6),
|
||||||
|
],
|
||||||
|
startPoint: .topLeading,
|
||||||
|
endPoint: .bottomTrailing
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Large prominent team logos
|
||||||
HStack(spacing: fallbackLogoGap) {
|
HStack(spacing: fallbackLogoGap) {
|
||||||
TeamLogoView(team: game.awayTeam, size: fallbackLogoSize)
|
TeamLogoView(team: game.awayTeam, size: fallbackLogoSize)
|
||||||
.opacity(0.4)
|
.shadow(color: .black.opacity(0.2), radius: 12, y: 4)
|
||||||
|
Text("vs")
|
||||||
|
.font(.system(size: fallbackLogoSize * 0.3, weight: .light))
|
||||||
|
.foregroundStyle(.white.opacity(0.5))
|
||||||
TeamLogoView(team: game.homeTeam, size: fallbackLogoSize)
|
TeamLogoView(team: game.homeTeam, size: fallbackLogoSize)
|
||||||
.opacity(0.4)
|
.shadow(color: .black.opacity(0.2), radius: 12, y: 4)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user