This commit is contained in:
2025-07-19 16:42:47 -04:00
parent 6e46775f58
commit e3c3f2c6f0
38 changed files with 556 additions and 367 deletions

View File

@ -2,8 +2,8 @@ import Foundation
import SwiftData
@Model
final class SplitExerciseAssignment {
var exerciseName: String = ""
final class Exercise {
var name: String = ""
var order: Int = 0
var sets: Int = 0
var reps: Int = 0
@ -14,7 +14,7 @@ final class SplitExerciseAssignment {
init(split: Split, exerciseName: String, order: Int, sets: Int, reps: Int, weight: Int) {
self.split = split
self.exerciseName = exerciseName
self.name = exerciseName
self.order = order
self.sets = sets
self.reps = reps

View File

@ -1,66 +0,0 @@
import Foundation
import Yams
struct ExerciseList: Codable {
let name: String
let source: String
let exercises: [ExerciseItem]
struct ExerciseItem: Codable, Identifiable {
let name: String
let descr: String
let type: String
var id: String { name }
}
}
class ExerciseListLoader {
static func loadExerciseLists() -> [String: ExerciseList] {
var exerciseLists: [String: ExerciseList] = [:]
guard let resourcePath = Bundle.main.resourcePath else {
print("Could not find resource path")
return exerciseLists
}
do {
let fileManager = FileManager.default
let resourceURL = URL(fileURLWithPath: resourcePath)
let yamlFiles = try fileManager.contentsOfDirectory(at: resourceURL, includingPropertiesForKeys: nil)
.filter { $0.pathExtension == "yaml" && $0.lastPathComponent.hasSuffix(".exercises.yaml") }
for yamlFile in yamlFiles {
let fileName = yamlFile.lastPathComponent
do {
let yamlString = try String(contentsOf: yamlFile, encoding: .utf8)
if let exerciseList = try Yams.load(yaml: yamlString) as? [String: Any],
let name = exerciseList["name"] as? String,
let source = exerciseList["source"] as? String,
let exercisesData = exerciseList["exercises"] as? [[String: Any]] {
var exercises: [ExerciseList.ExerciseItem] = []
for exerciseData in exercisesData {
if let name = exerciseData["name"] as? String,
let descr = exerciseData["descr"] as? String,
let type = exerciseData["type"] as? String {
let exercise = ExerciseList.ExerciseItem(name: name, descr: descr, type: type)
exercises.append(exercise)
}
}
let exerciseList = ExerciseList(name: name, source: source, exercises: exercises)
exerciseLists[fileName] = exerciseList
}
} catch {
print("Error loading YAML file \(fileName): \(error)")
}
}
} catch {
print("Error listing directory contents: \(error)")
}
return exerciseLists
}
}

View File

@ -1,30 +0,0 @@
//
// OrderableItem.swift
// Workouts
//
// Created by rzen on 7/18/25 at 5:19 PM.
//
// Copyright 2025 Rouslan Zenetl. All Rights Reserved.
//
import Foundation
/// Protocol for items that can be ordered in a sequence
protocol OrderableItem {
/// Updates the order of the item to the specified index
func updateOrder(to index: Int)
}
/// Extension to make Split conform to OrderableItem
extension Split: OrderableItem {
func updateOrder(to index: Int) {
self.order = index
}
}
/// Extension to make SplitExerciseAssignment conform to OrderableItem
extension SplitExerciseAssignment: OrderableItem {
func updateOrder(to index: Int) {
self.order = index
}
}

View File

@ -15,8 +15,8 @@ final class Split {
return Color.color(from: self.color)
}
@Relationship(deleteRule: .cascade, inverse: \SplitExerciseAssignment.split)
var exercises: [SplitExerciseAssignment]? = []
@Relationship(deleteRule: .cascade, inverse: \Exercise.split)
var exercises: [Exercise]? = []
@Relationship(deleteRule: .nullify, inverse: \Workout.split)
var workouts: [Workout]? = []
@ -109,7 +109,7 @@ fileprivate struct SplitFormView: View {
Section(header: Text("Exercises")) {
NavigationLink {
SplitExercisesListView(model: model)
ExerciseListView(split: model)
} label: {
ListItem(
text: "Exercises",

View File

@ -5,20 +5,25 @@ import SwiftData
final class Workout {
var start: Date = Date()
var end: Date?
var status: WorkoutStatus? = WorkoutStatus.notStarted
@Relationship(deleteRule: .nullify)
var split: Split?
@Relationship(deleteRule: .cascade, inverse: \WorkoutLog.workout)
var logs: [WorkoutLog]? = []
init(start: Date, end: Date? = nil, split: Split?) {
init(start: Date, end: Date, split: Split?) {
self.start = start
self.end = end
self.split = split
}
var label: String {
start.formattedDate()
if status == .completed, let endDate = end {
return "\(start.formattedDate())\(endDate.formattedDate())"
} else {
return start.formattedDate()
}
}
}

View File

@ -1,24 +0,0 @@
//
// WorkoutStatus.swift
// Workouts
//
// Created by rzen on 7/16/25 at 7:03PM.
//
// Copyright 2025 Rouslan Zenetl. All Rights Reserved.
//
enum WorkoutStatus: Int, Codable {
case notStarted = 1
case inProgress = 2
case completed = 3
case skipped = 4
var checkboxStatus: CheckboxStatus {
switch (self) {
case .notStarted: .unchecked
case .inProgress: .intermediate
case .completed: .checked
case .skipped: .cancelled
}
}
}