|
|
|
|
@ -8,20 +8,20 @@ |
|
|
|
|
import SwiftUI |
|
|
|
|
|
|
|
|
|
protocol SpinDrawable { |
|
|
|
|
func segmentLabel(_ displayStyle: DisplayStyle) -> [String] |
|
|
|
|
func segmentLabel(_ displayStyle: DisplayStyle, hideNames: Bool) -> [String] |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
extension String: SpinDrawable { |
|
|
|
|
func segmentLabel(_ displayStyle: DisplayStyle) -> [String] { |
|
|
|
|
func segmentLabel(_ displayStyle: DisplayStyle, hideNames: Bool) -> [String] { |
|
|
|
|
[self] |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
extension Match: SpinDrawable { |
|
|
|
|
func segmentLabel(_ displayStyle: DisplayStyle) -> [String] { |
|
|
|
|
func segmentLabel(_ displayStyle: DisplayStyle, hideNames: Bool) -> [String] { |
|
|
|
|
let teams = teams() |
|
|
|
|
if teams.count == 1 { |
|
|
|
|
return teams.first!.segmentLabel(displayStyle) |
|
|
|
|
if teams.count == 1, hideNames == false { |
|
|
|
|
return teams.first!.segmentLabel(displayStyle, hideNames: hideNames) |
|
|
|
|
} else { |
|
|
|
|
return [roundTitle(), matchTitle(displayStyle)].compactMap { $0 } |
|
|
|
|
} |
|
|
|
|
@ -29,12 +29,16 @@ extension Match: SpinDrawable { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
extension TeamRegistration: SpinDrawable { |
|
|
|
|
func segmentLabel(_ displayStyle: DisplayStyle) -> [String] { |
|
|
|
|
func segmentLabel(_ displayStyle: DisplayStyle, hideNames: Bool) -> [String] { |
|
|
|
|
var strings: [String] = [] |
|
|
|
|
let indexLabel = tournamentObject()?.labelIndexOf(team: self) |
|
|
|
|
if let indexLabel { |
|
|
|
|
strings.append(indexLabel) |
|
|
|
|
if hideNames { |
|
|
|
|
return strings |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
strings.append(contentsOf: self.players().map { $0.playerLabel(displayStyle) }) |
|
|
|
|
return strings |
|
|
|
|
} |
|
|
|
|
@ -51,8 +55,8 @@ struct DrawOption: Identifiable, SpinDrawable { |
|
|
|
|
let initialIndex: Int |
|
|
|
|
let option: SpinDrawable |
|
|
|
|
|
|
|
|
|
func segmentLabel(_ displayStyle: DisplayStyle) -> [String] { |
|
|
|
|
option.segmentLabel(displayStyle) |
|
|
|
|
func segmentLabel(_ displayStyle: DisplayStyle, hideNames: Bool) -> [String] { |
|
|
|
|
option.segmentLabel(displayStyle, hideNames: hideNames) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@ -62,6 +66,7 @@ struct SpinDrawView: View { |
|
|
|
|
let drawees: [any SpinDrawable] |
|
|
|
|
@State var segments: [any SpinDrawable] |
|
|
|
|
var autoMode: Bool = false |
|
|
|
|
var hideNames: Bool = false |
|
|
|
|
let completion: ([DrawResult]) async -> Void // Completion closure |
|
|
|
|
|
|
|
|
|
@State private var drawCount: Int = 0 |
|
|
|
|
@ -89,12 +94,12 @@ struct SpinDrawView: View { |
|
|
|
|
} |
|
|
|
|
} else if drawCount < drawees.count { |
|
|
|
|
Section { |
|
|
|
|
_segmentLabelView(segment: drawees[drawCount].segmentLabel(.wide), horizontalAlignment: .center) |
|
|
|
|
_segmentLabelView(segment: drawees[drawCount].segmentLabel(.wide, hideNames: hideNames), horizontalAlignment: .center) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
Section { |
|
|
|
|
ZStack { |
|
|
|
|
FortuneWheelContainerView(segments: drawOptions, autoMode: autoMode) { index in |
|
|
|
|
FortuneWheelContainerView(segments: drawOptions, autoMode: autoMode, hideNames: hideNames) { index in |
|
|
|
|
self.selectedIndex = index |
|
|
|
|
self.draws.append(DrawResult(drawee: drawCount, drawIndex: drawOptions[index].initialIndex)) |
|
|
|
|
self.drawOptions.remove(at: index) |
|
|
|
|
@ -209,8 +214,8 @@ struct SpinDrawView: View { |
|
|
|
|
|
|
|
|
|
private func _segmentLabelView(segment: [String], horizontalAlignment: HorizontalAlignment = .leading) -> some View { |
|
|
|
|
VStack(alignment: horizontalAlignment, spacing: 0.0) { |
|
|
|
|
ForEach(segment, id: \.self) { string in |
|
|
|
|
Text(string).font(.title3) |
|
|
|
|
ForEach(segment.indices, id: \.self) { lineIndex in |
|
|
|
|
Text(segment[lineIndex]).font(.title3) |
|
|
|
|
.frame(maxWidth: .infinity) |
|
|
|
|
.lineLimit(1) |
|
|
|
|
} |
|
|
|
|
@ -221,13 +226,13 @@ struct SpinDrawView: View { |
|
|
|
|
private func _validationLabelView(drawee: Int, result: SpinDrawable) -> some View { |
|
|
|
|
VStack(spacing: 0.0) { |
|
|
|
|
let draw = drawees[drawee] |
|
|
|
|
_segmentLabelView(segment: draw.segmentLabel(.wide), horizontalAlignment: .center) |
|
|
|
|
_segmentLabelView(segment: draw.segmentLabel(.wide, hideNames: hideNames), horizontalAlignment: .center) |
|
|
|
|
if result as? TeamRegistration != nil { |
|
|
|
|
Image(systemName: "flag.2.crossed.fill").font(.largeTitle).foregroundColor(.logoRed) |
|
|
|
|
} else { |
|
|
|
|
Image(systemName: "arrowshape.down.fill").font(.largeTitle).foregroundColor(.logoRed) |
|
|
|
|
} |
|
|
|
|
_segmentLabelView(segment: result.segmentLabel(.wide), horizontalAlignment: .center) |
|
|
|
|
_segmentLabelView(segment: result.segmentLabel(.wide, hideNames: hideNames), horizontalAlignment: .center) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
@ -236,10 +241,11 @@ struct FortuneWheelContainerView: View { |
|
|
|
|
@State private var rotation: Double = 0 |
|
|
|
|
let segments: [any SpinDrawable] |
|
|
|
|
let autoMode: Bool |
|
|
|
|
let hideNames: Bool |
|
|
|
|
let completion: (Int) -> Void // Completion closure |
|
|
|
|
|
|
|
|
|
var body: some View { |
|
|
|
|
FortuneWheelView(segments: segments) |
|
|
|
|
FortuneWheelView(segments: segments, hideNames: hideNames) |
|
|
|
|
.rotationEffect(.degrees(rotation)) |
|
|
|
|
.aspectRatio(contentMode: .fill) |
|
|
|
|
.padding(.top, 5) |
|
|
|
|
@ -303,6 +309,7 @@ struct FortuneWheelContainerView: View { |
|
|
|
|
|
|
|
|
|
struct FortuneWheelView: View { |
|
|
|
|
let segments: [any SpinDrawable] |
|
|
|
|
let hideNames: Bool |
|
|
|
|
let colors: [Color] = [.yellow, .cyan, .green, .blue, .orange, .purple, .mint, .brown] |
|
|
|
|
|
|
|
|
|
func getColor(forIndex index: Int) -> Color { |
|
|
|
|
@ -333,9 +340,9 @@ struct FortuneWheelView: View { |
|
|
|
|
.fill(getColor(forIndex: index)) |
|
|
|
|
|
|
|
|
|
VStack(alignment: .trailing, spacing: 0.0) { |
|
|
|
|
let strings = segments[index].segmentLabel(.short) |
|
|
|
|
ForEach(strings, id: \.self) { string in |
|
|
|
|
Text(string).bold() |
|
|
|
|
let strings = labels(forIndex: index) |
|
|
|
|
ForEach(strings.indices, id: \.self) { lineIndex in |
|
|
|
|
Text(strings[lineIndex]).bold() |
|
|
|
|
.font(.subheadline) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
@ -349,6 +356,19 @@ struct FortuneWheelView: View { |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private func labels(forIndex index: Int) -> [String] { |
|
|
|
|
if segments.count < 5 { |
|
|
|
|
return segments[index].segmentLabel(.short, hideNames: hideNames) |
|
|
|
|
} else { |
|
|
|
|
let values = segments[index].segmentLabel(.short, hideNames: hideNames) |
|
|
|
|
if values.count < 3 { |
|
|
|
|
return values |
|
|
|
|
} else { |
|
|
|
|
return Array(segments[index].segmentLabel(.short, hideNames: hideNames).prefix(1)) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Calculate the position for the text in the middle of the arc segment |
|
|
|
|
private func arcPosition(index: Int, radius: Double) -> CGPoint { |
|
|
|
|
let segmentAngle = 360.0 / Double(segments.count) |
|
|
|
|
|