Files
MatchLiveTv/native/ios/MatchLiveTv/UI/Wizard/MatchCoverSection.swift
T
eminuxandCursor 41d4235258 Aggiunge copertina sponsor custom solo Premium Full, con override in wizard e slate sui nodi di streaming.
Permette upload da portale e app con ereditarietà partita→squadra→società, generazione MP4 via ffmpeg e distribuzione su home lab e nodi CPX per pause e assenza segnale.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-19 23:47:17 +02:00

98 lines
3.7 KiB
Swift

import PhotosUI
import SwiftUI
struct MatchCoverSection: View {
let effectiveCoverUrl: String?
let coverSource: String
let customCoverEnabled: Bool
@Binding var localCoverImage: UIImage?
let hasMatchOverride: Bool
let onClearOverride: () -> Void
@State private var coverPickerItem: PhotosPickerItem?
private var sourceLabel: String {
switch coverSource {
case "match": return L10n.t("wizard.match.cover.source.match")
case "team": return L10n.t("wizard.match.cover.source.team")
case "club": return L10n.t("wizard.match.cover.source.club")
default: return L10n.t("wizard.match.cover.source.default")
}
}
var body: some View {
VStack(alignment: .leading, spacing: 0) {
Text(L10n.t("wizard.match.cover.title"))
.font(MatchTypography.labelLarge)
.foregroundStyle(MatchColors.textSecondary)
Text(L10n.t("wizard.match.cover.source.label", sourceLabel))
.font(MatchTypography.bodyMedium)
.foregroundStyle(MatchColors.textSecondary)
.padding(.top, 4)
Group {
if let localCoverImage {
Image(uiImage: localCoverImage)
.resizable()
.scaledToFill()
} else if let urlString = MediaUrl.resolve(effectiveCoverUrl), let url = URL(string: urlString) {
AsyncImage(url: url) { phase in
switch phase {
case .success(let image):
image.resizable().scaledToFill()
default:
Color.clear
}
}
} else {
Color.clear
}
}
.frame(maxWidth: .infinity)
.aspectRatio(16 / 9, contentMode: .fit)
.clipShape(RoundedRectangle(cornerRadius: 12))
.background(MatchColors.surface)
.padding(.top, 12)
Text(L10n.t("wizard.match.cover.hint"))
.font(MatchTypography.bodyMedium)
.foregroundStyle(MatchColors.textSecondary)
.padding(.top, 8)
if customCoverEnabled {
PhotosPicker(selection: $coverPickerItem, matching: .images) {
Text(L10n.t("wizard.match.cover.change"))
.font(MatchTypography.labelLarge)
.frame(maxWidth: .infinity)
.frame(height: 52)
.overlay(RoundedRectangle(cornerRadius: 8).stroke(MatchColors.outline, lineWidth: 1))
}
.buttonStyle(.plain)
.padding(.top, 12)
if hasMatchOverride || localCoverImage != nil {
MatchSecondaryButton(
label: L10n.t("wizard.match.cover.reset"),
action: onClearOverride
)
.padding(.top, 8)
}
} else {
Text(L10n.t("wizard.match.cover.premium.required"))
.font(MatchTypography.bodyMedium)
.foregroundStyle(MatchColors.textSecondary)
.padding(.top, 12)
}
}
.onChange(of: coverPickerItem) { item in
guard let item else { return }
Task {
if let data = try? await item.loadTransferable(type: Data.self),
let image = UIImage(data: data) {
await MainActor.run { localCoverImage = image }
}
}
}
}
}