Files
MatchLiveTv/native/ios/MatchLiveTv/Domain/Models.swift
Emiliano Frascaro 7d5d66840f Riduce reload MediaMTX in live e allinea ingest mobile al preset qualità.
Evita patch recording ripetute che distruggevano i muxer HLS (500 ops) e fa encoderare 1080p/720p con codec e bitrate coerenti al wizard.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-21 22:17:18 +02:00

139 lines
3.9 KiB
Swift

import Foundation
struct User: Codable, Equatable, Sendable {
let id: String
let email: String
let name: String
let role: String
}
struct AuthTokens: Sendable {
let accessToken: String
let refreshToken: String
}
struct SportOption: Identifiable, Equatable, Sendable {
var id: String { key }
let key: String
let label: String
let board: String
let overlay: String
let allowedOverlays: [String]
let defaultRules: [String: Int]
}
struct Team: Identifiable, Equatable, Sendable {
let id: String
let name: String
let sport: String
let sportKey: String
let boardType: String
let clubName: String?
let logoUrl: String?
let primaryColor: String?
let secondaryColor: String?
let canStream: Bool
let youtubeEnabled: Bool
let youtubeConnected: Bool
let youtubeSelectable: Bool
let youtubeChannelTitle: String?
let youtubeUsesPlatformChannel: Bool
let youtubeTeamChannelTitle: String?
let planName: String?
let recordingsEnabled: Bool
let phoneDownloadEnabled: Bool
let billingUrl: String?
let staffManageUrl: String?
var canUseYoutube: Bool { youtubeEnabled }
var isYoutubeReady: Bool { youtubeSelectable }
var effectiveYoutubeChannel: String? {
guard isYoutubeReady else { return nil }
return youtubeUsesPlatformChannel ? "platform" : "team"
}
var youtubeDestinationLabel: String {
if youtubeUsesPlatformChannel { return "Canale Match Live TV" }
let name = youtubeTeamChannelTitle?.trimmingCharacters(in: .whitespacesAndNewlines).nilIfEmpty
?? clubName?.trimmingCharacters(in: .whitespacesAndNewlines).nilIfEmpty
?? "società"
return "Canale società · \(name)"
}
}
struct ScoringRules: Equatable, Sendable {
var pointsPerSet: Int = 25
var pointsDecidingSet: Int = 15
var minPointLead: Int = 2
var periods: Int = 4
var periodDurationSecs: Int = 600
var overtimeDurationSecs: Int = 300
}
struct Match: Identifiable, Equatable, Sendable {
let id: String
let teamId: String
let teamName: String
let opponentName: String
let location: String?
let scheduledAt: String?
let sportKey: String
let sportLabel: String?
let boardType: String
let overlayKind: String?
let effectiveOverlayKind: String
let setsToWin: Int
let category: String?
let scoringRules: ScoringRules?
let activeSessionId: String?
let activeSessionStatus: String?
let streamCompleted: Bool
let coachHubVisible: Bool?
let homePrimaryColor: String?
let homeSecondaryColor: String?
let homeLogoUrl: String?
let opponentPrimaryColor: String?
let opponentLogoUrl: String?
var hasActiveSession: Bool { activeSessionId != nil }
var canResumeCamera: Bool {
guard let status = activeSessionStatus, activeSessionId != nil else { return false }
return ["connecting", "live", "reconnecting", "paused"].contains(status)
}
}
struct StreamSession: Identifiable, Equatable, Sendable {
let id: String
let matchId: String
let status: String
let platform: String
let rtmpIngestUrl: String?
let hlsPlaybackUrl: String?
let watchPageUrl: String?
let shareUrl: String?
let youtubeWatchUrl: String?
let youtubeReady: Bool
let privacyStatus: String
let targetBitrate: Int
let targetFps: Int
let qualityPreset: String
let startedAt: String?
let score: ScoreState?
var isLive: Bool { status == "live" || status == "reconnecting" }
var isPaused: Bool { status == "paused" }
func watchShareUrl() -> String? {
if platform == "youtube", let url = youtubeWatchUrl, !url.isEmpty { return url }
if let url = shareUrl, !url.isEmpty { return url }
if let url = watchPageUrl, !url.isEmpty { return url }
return nil
}
}
private extension String {
var nilIfEmpty: String? { isEmpty ? nil : self }
}