You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
294 lines
10 KiB
294 lines
10 KiB
//
|
|
// BroadcastView.swift
|
|
// PadelClub
|
|
//
|
|
// Created by Razmig Sarkissian on 01/05/2024.
|
|
//
|
|
|
|
import SwiftUI
|
|
import CoreImage.CIFilterBuiltins
|
|
import LeStorage
|
|
import TipKit
|
|
|
|
extension String : Identifiable {
|
|
public var id: String { self }
|
|
}
|
|
|
|
struct BroadcastView: View {
|
|
@EnvironmentObject var dataStore: DataStore
|
|
@Environment(Tournament.self) var tournament: Tournament
|
|
let context = CIContext()
|
|
let filter = CIFilter.qrCodeGenerator()
|
|
@State private var urlToShow: String?
|
|
@State private var tvMode: Bool = false
|
|
@State private var pageLink: PageLink = .teams
|
|
|
|
let tournamentPublishingTip = TournamentPublishingTip()
|
|
let tournamentTVBroadcastTip = TournamentTVBroadcastTip()
|
|
|
|
var body: some View {
|
|
@Bindable var tournament = tournament
|
|
List {
|
|
Section {
|
|
TipView(tournamentPublishingTip) { action in
|
|
UIApplication.shared.open(URLs.main.url)
|
|
}
|
|
.tipStyle(tint: nil)
|
|
}
|
|
Section {
|
|
TipView(tournamentTVBroadcastTip)
|
|
.tipStyle(tint: nil)
|
|
}
|
|
|
|
if tournament.isPrivate == false {
|
|
Section {
|
|
LabeledContent {
|
|
if tournament.areTeamsPublished() {
|
|
Image(systemName:"checkmark").foregroundStyle(.green)
|
|
} else {
|
|
Text(tournament.publishedTeamsDate().formatted())
|
|
}
|
|
} label: {
|
|
if tournament.areTeamsPublished() {
|
|
Text("Publiée")
|
|
} else {
|
|
Text("Publication prévue")
|
|
}
|
|
}
|
|
|
|
Toggle(isOn: $tournament.hideTeamsWeight) {
|
|
Text("Masquer les poids des équipes")
|
|
}
|
|
} header: {
|
|
Text("Liste des équipes")
|
|
} footer: {
|
|
if Date() < tournament.publishedTeamsDate() {
|
|
HStack {
|
|
Spacer()
|
|
FooterButtonView(tournament.publishTeams ? "masquer sur le site" : "publier maintenant") {
|
|
tournament.publishTeams.toggle()
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
Section {
|
|
LabeledContent {
|
|
if tournament.areSummonsPublished() {
|
|
Image(systemName:"checkmark").foregroundStyle(.green)
|
|
} else {
|
|
Text(tournament.publishedTeamsDate().formatted())
|
|
}
|
|
} label: {
|
|
if tournament.areSummonsPublished() {
|
|
Text("Publiées")
|
|
} else {
|
|
Text("Publication prévue")
|
|
}
|
|
}
|
|
} header: {
|
|
Text("Convocations")
|
|
} footer: {
|
|
if Date() < tournament.publishedTeamsDate() {
|
|
HStack {
|
|
Spacer()
|
|
FooterButtonView(tournament.publishSummons ? "masquer sur le site" : "publier maintenant") {
|
|
tournament.publishSummons.toggle()
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if let publishedGroupStagesDate = tournament.publishedGroupStagesDate() {
|
|
Section {
|
|
let areGroupStagesPublished = tournament.areGroupStagesPublished()
|
|
LabeledContent {
|
|
if areGroupStagesPublished {
|
|
Image(systemName:"checkmark").foregroundStyle(.green)
|
|
} else {
|
|
Text(publishedGroupStagesDate.formatted())
|
|
}
|
|
} label: {
|
|
if areGroupStagesPublished {
|
|
Text("Publiées")
|
|
} else {
|
|
Text("Publication prévue")
|
|
}
|
|
}
|
|
} header: {
|
|
Text("Poules")
|
|
} footer: {
|
|
if Date() < publishedGroupStagesDate {
|
|
HStack {
|
|
Spacer()
|
|
FooterButtonView(tournament.publishGroupStages ? "masquer sur le site" : "publier maintenant") {
|
|
tournament.publishGroupStages.toggle()
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if let publishedBracketsDate = tournament.publishedBracketsDate() {
|
|
Section {
|
|
let areBracketsPublished = tournament.areBracketsPublished()
|
|
LabeledContent {
|
|
if areBracketsPublished {
|
|
Image(systemName:"checkmark").foregroundStyle(.green)
|
|
} else {
|
|
Text(publishedBracketsDate.formatted())
|
|
}
|
|
} label: {
|
|
if areBracketsPublished {
|
|
Text("Publié")
|
|
} else {
|
|
Text("Publication prévue")
|
|
}
|
|
}
|
|
} header: {
|
|
Text("Tableau")
|
|
} footer: {
|
|
if Date() < publishedBracketsDate {
|
|
HStack {
|
|
Spacer()
|
|
FooterButtonView(tournament.publishBrackets ? "masquer sur le site" : "publier maintenant") {
|
|
tournament.publishBrackets.toggle()
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//todo waitinglist & info
|
|
|
|
Section {
|
|
Toggle(isOn: $tournament.isPrivate) {
|
|
Text("Tournoi privé")
|
|
}
|
|
} footer: {
|
|
let footerString = "Le tournoi sera masqué sur le site [Padel Club](\(URLs.main.rawValue))"
|
|
Text(.init(footerString))
|
|
}
|
|
|
|
Section {
|
|
LabeledContent {
|
|
actionForURL(URLs.main.url)
|
|
} label: {
|
|
Text("Padel Club")
|
|
}
|
|
|
|
if let club = tournament.club(), let clubURL = club.shareURL() {
|
|
LabeledContent {
|
|
actionForURL(clubURL)
|
|
} label: {
|
|
Text("Club")
|
|
}
|
|
}
|
|
|
|
if let url = tournament.shareURL(pageLink) {
|
|
LabeledContent {
|
|
actionForURL(url)
|
|
} label: {
|
|
Text("Tournoi")
|
|
Text(pageLink.localizedLabel())
|
|
}
|
|
}
|
|
|
|
let links : [PageLink] = [.teams, .summons, .groupStages, .matches, .rankings]
|
|
Picker(selection: $pageLink) {
|
|
ForEach(links) { pageLink in
|
|
Text(pageLink.localizedLabel()).tag(pageLink)
|
|
}
|
|
} label: {
|
|
Text("Modifier la page du tournoi à partager")
|
|
}
|
|
.pickerStyle(.menu)
|
|
|
|
if let url = tournament.shareURL(.broadcast) {
|
|
LabeledContent {
|
|
actionForURL(url)
|
|
} label: {
|
|
Text("TV")
|
|
}
|
|
}
|
|
|
|
} header: {
|
|
Text("Liens à partager")
|
|
.textCase(nil)
|
|
}
|
|
|
|
}
|
|
.headerProminence(.increased)
|
|
.navigationTitle("Publication")
|
|
.navigationBarTitleDisplayMode(.inline)
|
|
.toolbarBackground(.visible, for: .navigationBar)
|
|
.sheet(item: $urlToShow) { urlToShow in
|
|
Image(uiImage: generateQRCode(from: urlToShow))
|
|
.interpolation(.none)
|
|
.resizable()
|
|
.scaledToFit()
|
|
.frame(width: 300, height: 300)
|
|
.onAppear {
|
|
UIPasteboard.general.string = urlToShow
|
|
}
|
|
}
|
|
.onChange(of: [tournament.hideTeamsWeight, tournament.isPrivate, tournament.publishTeams, tournament.publishSummons, tournament.publishBrackets, tournament.publishGroupStages]) {
|
|
_save()
|
|
}
|
|
}
|
|
|
|
private func _save() {
|
|
do {
|
|
try dataStore.tournaments.addOrUpdate(instance: tournament)
|
|
} catch {
|
|
Logger.error(error)
|
|
}
|
|
}
|
|
|
|
private func generateQRCode(from string: String) -> UIImage {
|
|
filter.message = Data(string.utf8)
|
|
|
|
if let outputImage = filter.outputImage {
|
|
if let cgimg = context.createCGImage(outputImage, from: outputImage.extent) {
|
|
return UIImage(cgImage: cgimg)
|
|
}
|
|
}
|
|
|
|
return UIImage(systemName: "xmark.circle") ?? UIImage()
|
|
}
|
|
|
|
@ViewBuilder
|
|
func actionForURL(_ url: URL, removeSource: Bool = false) -> some View {
|
|
Menu {
|
|
Button {
|
|
UIApplication.shared.open(url)
|
|
} label: {
|
|
Label("Voir", systemImage: "safari")
|
|
}
|
|
|
|
Button {
|
|
urlToShow = url.absoluteString
|
|
} label: {
|
|
Label("QRCode", systemImage: "qrcode")
|
|
}
|
|
|
|
ShareLink(item: url) {
|
|
Label("Partager le lien", systemImage: "link")
|
|
}
|
|
} label: {
|
|
HStack {
|
|
Spacer()
|
|
Image(systemName: "square.and.arrow.up")
|
|
}
|
|
}
|
|
.frame(maxWidth: .infinity)
|
|
.buttonStyle(.borderless)
|
|
}
|
|
|
|
|
|
}
|
|
|
|
#Preview {
|
|
BroadcastView()
|
|
}
|
|
|