Files
SwimBuddy/targets/watch/Views/ActiveWorkoutView.swift
T

160 lines
5.4 KiB
Swift

import SwiftUI
struct ActiveWorkoutView: View {
@ObservedObject var workoutManager: WorkoutManager
var body: some View {
VStack(spacing: 8) {
if workoutManager.isResting {
RestView(workoutManager: workoutManager)
} else {
SwimView(workoutManager: workoutManager)
}
}
.padding()
}
}
struct SwimView: View {
@ObservedObject var workoutManager: WorkoutManager
var body: some View {
VStack(spacing: 6) {
if let workout = workoutManager.selectedWorkout,
workoutManager.currentSetIndex < workout.sets.count {
let currentSet = workout.sets[workoutManager.currentSetIndex]
HStack {
Text("Set \(workoutManager.currentSetIndex + 1)/\(workout.sets.count)")
.font(.caption2)
.foregroundColor(.secondary)
Text("·")
.foregroundColor(.secondary)
Text("Rep \(workoutManager.currentRep + 1)/\(currentSet.repCount)")
.font(.caption2)
.foregroundColor(.secondary)
}
Text(currentSet.stroke)
.font(.headline)
.foregroundColor(.cyan)
Text("\(Int(workoutManager.currentSetDistanceSwum))/\(Int(workoutManager.currentSetTotalDistance))m")
.font(.system(size: 36, weight: .bold, design: .rounded))
.foregroundColor(.cyan)
}
HStack(spacing: 4) {
Image(systemName: "figure.pool.swim")
.font(.caption)
.foregroundColor(.cyan)
Text("\(Int(workoutManager.totalDistanceSwum))m total")
.font(.caption)
.foregroundColor(.secondary)
}
Text(formatTime(workoutManager.elapsedSeconds))
.font(.system(.title3, design: .monospaced))
HStack(spacing: 12) {
HStack(spacing: 4) {
Image(systemName: "flame.fill")
.foregroundColor(.orange)
.font(.caption)
Text("\(Int(workoutManager.estimatedCalories))")
.font(.caption)
}
if workoutManager.heartRate > 0 {
HStack(spacing: 4) {
Image(systemName: "heart.fill")
.foregroundColor(.red)
.font(.caption)
Text("\(Int(workoutManager.heartRate))")
.font(.caption)
}
}
}
if workoutManager.lapDetected {
Text("Lap detected!")
.font(.caption)
.foregroundColor(.green)
.transition(.opacity)
}
HStack(spacing: 12) {
Button {
workoutManager.completeLap()
} label: {
Text("Complete Lap")
.font(.headline)
.frame(maxWidth: .infinity)
}
.buttonStyle(.borderedProminent)
.tint(.cyan)
}
Button("End") {
workoutManager.endWorkout()
}
.font(.caption)
.foregroundColor(.red)
}
}
private func formatTime(_ seconds: TimeInterval) -> String {
let mins = Int(seconds) / 60
let secs = Int(seconds) % 60
return String(format: "%d:%02d", mins, secs)
}
}
struct RestView: View {
@ObservedObject var workoutManager: WorkoutManager
var body: some View {
VStack(spacing: 12) {
Text("Rest")
.font(.headline)
.foregroundColor(.secondary)
Text(formatTime(workoutManager.restTimeRemaining))
.font(.system(size: 44, weight: .bold, design: .monospaced))
.foregroundColor(.cyan)
if let workout = workoutManager.selectedWorkout,
workoutManager.currentSetIndex + 1 < workout.sets.count {
let nextSet = workout.sets[workoutManager.currentSetIndex + 1]
Text("Next: \(nextSet.stroke) \(nextSet.distancePerRep)m")
.font(.caption)
.foregroundColor(.secondary)
}
HStack(spacing: 12) {
HStack(spacing: 4) {
Image(systemName: "figure.pool.swim")
.font(.caption)
.foregroundColor(.cyan)
Text("\(Int(workoutManager.totalDistanceSwum))m")
.font(.caption)
}
HStack(spacing: 4) {
Image(systemName: "flame.fill")
.font(.caption)
.foregroundColor(.orange)
Text("\(Int(workoutManager.estimatedCalories))kcal")
.font(.caption)
}
}
.foregroundColor(.secondary)
}
}
private func formatTime(_ seconds: TimeInterval) -> String {
let mins = Int(seconds) / 60
let secs = Int(seconds) % 60
return String(format: "%d:%02d", mins, secs)
}
}