Forza dirette unlisted sul sito (non YouTube), copertina di test e verifica che in pausa gli spettatori vedano la slate. Alza il numero di build oltre le 33–34 già su App Store Connect. Co-authored-by: Cursor <cursoragent@cursor.com>
150 lines
5.5 KiB
Swift
150 lines
5.5 KiB
Swift
import SwiftUI
|
|
|
|
struct StepTransmissionScreen: View {
|
|
@ObservedObject var container: AppContainer
|
|
let match: Match
|
|
let onBack: () -> Void
|
|
let onNext: () -> Void
|
|
let onError: (String) -> Void
|
|
|
|
@State private var team: Team?
|
|
@State private var platform = "matchlivetv"
|
|
@State private var privacy = ProcessInfo.processInfo.arguments.contains("--uitesting-reset") ? "unlisted" : "public"
|
|
@State private var creating = false
|
|
|
|
private var youtubeReady: Bool {
|
|
team?.isYoutubeReady == true
|
|
}
|
|
|
|
private var youtubeSubtitle: String {
|
|
guard let team else { return L10n.t("wizard.transmission.youtube.activating") }
|
|
if !team.canUseYoutube { return L10n.t("wizard.transmission.youtube.premium.required") }
|
|
if !team.isYoutubeReady { return L10n.t("wizard.transmission.youtube.activating") }
|
|
return team.youtubeDestinationLabel
|
|
}
|
|
|
|
var body: some View {
|
|
ScrollView {
|
|
VStack(alignment: .leading, spacing: 0) {
|
|
if let plan = team?.planName {
|
|
Text(L10n.t("wizard.transmission.plan.label", plan))
|
|
.font(MatchTypography.bodyMedium)
|
|
.foregroundStyle(MatchColors.textSecondary)
|
|
.padding(.bottom, 12)
|
|
}
|
|
|
|
Text(L10n.t("wizard.transmission.platform.title"))
|
|
.font(MatchTypography.headlineMedium)
|
|
|
|
WizardPlatformCard(
|
|
title: "Match Live TV",
|
|
subtitle: L10n.t("wizard.transmission.platform.site.subtitle"),
|
|
selected: platform == "matchlivetv",
|
|
onClick: { platform = "matchlivetv" }
|
|
)
|
|
.accessibilityIdentifier("wizard.platform.site")
|
|
.padding(.top, 12)
|
|
|
|
WizardPlatformCard(
|
|
title: "YouTube Live",
|
|
subtitle: youtubeSubtitle,
|
|
selected: platform == "youtube",
|
|
enabled: youtubeReady,
|
|
badge: team?.canUseYoutube == false ? L10n.t("wizard.transmission.youtube.badge") : nil,
|
|
onClick: selectYoutube
|
|
)
|
|
.padding(.top, 8)
|
|
|
|
Text(L10n.t("wizard.transmission.visibility.title"))
|
|
.font(MatchTypography.headlineMedium)
|
|
.padding(.top, 24)
|
|
|
|
HStack(spacing: 8) {
|
|
WizardChoiceButton(
|
|
label: L10n.t("wizard.transmission.public.label"),
|
|
selected: privacy == "public",
|
|
action: { privacy = "public" }
|
|
)
|
|
.frame(maxWidth: .infinity)
|
|
WizardChoiceButton(
|
|
label: L10n.t("wizard.transmission.unlisted.label"),
|
|
selected: privacy == "unlisted",
|
|
action: { privacy = "unlisted" }
|
|
)
|
|
.accessibilityIdentifier("wizard.privacy.unlisted")
|
|
.frame(maxWidth: .infinity)
|
|
}
|
|
.padding(.top, 12)
|
|
|
|
Text(visibilityDescription)
|
|
.font(MatchTypography.bodyMedium)
|
|
.foregroundStyle(MatchColors.textSecondary)
|
|
.fixedSize(horizontal: false, vertical: true)
|
|
.padding(.top, 8)
|
|
|
|
Text(L10n.t("wizard.transmission.backend.note"))
|
|
.font(MatchTypography.bodyMedium)
|
|
.foregroundStyle(MatchColors.textSecondary)
|
|
.fixedSize(horizontal: false, vertical: true)
|
|
.padding(.top, 6)
|
|
|
|
WizardFooterButtons(
|
|
onBack: onBack,
|
|
forwardLabel: L10n.t("wizard.action.next"),
|
|
forwardLoading: creating,
|
|
onForward: createSessionAndContinue
|
|
)
|
|
.padding(.top, 32)
|
|
}
|
|
.padding(.horizontal, 20)
|
|
.padding(.top, 12)
|
|
.padding(.bottom, 32)
|
|
}
|
|
.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .top)
|
|
.task {
|
|
if let cached = container.wizardSession.team {
|
|
team = cached
|
|
} else {
|
|
team = await container.matchRepository.fetchTeam(teamId: match.teamId)
|
|
container.wizardSession.team = team
|
|
}
|
|
}
|
|
}
|
|
|
|
private var visibilityDescription: String {
|
|
if privacy == "public" {
|
|
return L10n.t("wizard.transmission.public.desc")
|
|
}
|
|
return L10n.t("wizard.transmission.unlisted.desc")
|
|
}
|
|
|
|
private func selectYoutube() {
|
|
if youtubeReady {
|
|
platform = "youtube"
|
|
} else {
|
|
onError(L10n.t("wizard.error.youtube.unavailable"))
|
|
}
|
|
}
|
|
|
|
private func createSessionAndContinue() {
|
|
creating = true
|
|
Task {
|
|
do {
|
|
let session = try await container.sessionRepository.createSession(
|
|
matchId: match.id,
|
|
platform: platform,
|
|
privacyStatus: privacy,
|
|
youtubeChannel: platform == "youtube" ? team?.effectiveYoutubeChannel : nil
|
|
)
|
|
container.wizardSession.session = session
|
|
onNext()
|
|
} catch {
|
|
if let message = UserFacingError.message(for: error) {
|
|
onError(message)
|
|
}
|
|
}
|
|
creating = false
|
|
}
|
|
}
|
|
}
|