Skip to content

Commit

Permalink
Progress Charts (#29)
Browse files Browse the repository at this point in the history
  • Loading branch information
mazurio authored Dec 19, 2017
1 parent 5fee73b commit e301acd
Show file tree
Hide file tree
Showing 65 changed files with 3,696 additions and 1,267 deletions.
360 changes: 261 additions & 99 deletions BodyweightFitness.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

76 changes: 76 additions & 0 deletions BodyweightFitness/AbstractViewController.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import SnapKit

class AbstractViewController: UIViewController {
let scrollView = UIScrollView()
let contentView = UIView()
let contentStackView = UIStackView()

override func viewDidLoad() {
super.viewDidLoad()

self.initializeScrollView(attachToView: mainView())
}

func mainView() -> UIView {
return self.view
}

func initializeScrollView(attachToView: UIView) {
attachToView.backgroundColor = UIColor(red:0.96, green:0.96, blue:0.97, alpha:1.00)
attachToView.addSubview(self.scrollView)

self.scrollView.snp.makeConstraints { (make) -> Void in
make.edges.equalTo(attachToView)
}

self.scrollView.addSubview(self.contentView)
self.contentView.snp.makeConstraints { (make) -> Void in
make.top.bottom.equalTo(self.scrollView)
make.left.right.equalTo(attachToView)
}

self.createBackgroundView()

self.contentStackView.axis = .vertical
self.contentStackView.distribution = .fill
self.contentStackView.alignment = .fill
self.contentStackView.spacing = 16
self.contentStackView.translatesAutoresizingMaskIntoConstraints = false
self.contentView.addSubview(self.contentStackView)

self.contentStackView.snp.makeConstraints { (make) -> Void in
make.top.equalTo(contentView).offset(8)
make.left.equalTo(contentView).offset(8)
make.right.equalTo(contentView).offset(-8)
make.bottom.equalTo(contentView).offset(-8)
}
}

func initializeContent() {
self.removeAllViews()
}

func createBackgroundView(height: Int = 50) {
let view = UIView()
view.backgroundColor = UIColor.primary()

self.contentView.addSubview(view)

view.snp.makeConstraints { (make) -> Void in
make.top.equalTo(contentView)
make.left.equalTo(contentView)
make.right.equalTo(contentView)
make.height.equalTo(height)
}
}

func addView(_ view: UIView) {
self.contentStackView.addArrangedSubview(view)
}

func removeAllViews() {
for view in self.contentStackView.subviews {
view.removeFromSuperview()
}
}
}
File renamed without changes.
2 changes: 1 addition & 1 deletion BodyweightFitness/Controller/Cell/ProgressCardCell.swift
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class ProgressCardCell: UITableViewCell {
let logWorkoutController = LogWorkoutController()

logWorkoutController.parentController = self.parentController
logWorkoutController.setRepositoryRoutine(current!, repositoryRoutine: RepositoryStream.sharedInstance.getRepositoryRoutineForToday())
logWorkoutController.setRepositoryRoutine(repositoryExercise: current!, repositoryRoutine: RepositoryStream.sharedInstance.getRepositoryRoutineForToday())

logWorkoutController.modalTransitionStyle = .coverVertical
logWorkoutController.modalPresentationStyle = .custom
Expand Down
21 changes: 10 additions & 11 deletions BodyweightFitness/Controller/Modal/LogWorkoutController.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import UIKit
import RealmSwift

class LogWorkoutController: UIViewController {
var exercise: RepositoryExercise?
Expand Down Expand Up @@ -42,9 +43,9 @@ class LogWorkoutController: UIViewController {

var setView: SetView?
var set: RepositorySet?
let realm = RepositoryStream.sharedInstance.getRealm()

let realm = try! Realm()

var parentController: UIViewController?

func increaseRepsButtonDown(_ sender: AnyObject) {
Expand Down Expand Up @@ -190,17 +191,15 @@ class LogWorkoutController: UIViewController {
self.verticalStackView?.centerXAnchor.constraint(equalTo: self.contentView.centerXAnchor).isActive = true
self.verticalStackView?.centerYAnchor.constraint(equalTo: self.contentView.centerYAnchor).isActive = true
self.verticalStackView?.isHidden = false

for set in (self.exercise?.sets)! {
self.addSet(set)

if let e = exercise {
for set in e.sets {
self.addSet(set)
}
}

// Disable Navigation Drawer
// let appDelegate = UIApplication.sharedApplication().delegate as? AppDelegate
// appDelegate?.sideNavigationViewController?.enabled = false
}

func setRepositoryRoutine(_ repositoryExercise: RepositoryExercise, repositoryRoutine: RepositoryRoutine) {
func setRepositoryRoutine(repositoryExercise: RepositoryExercise, repositoryRoutine: RepositoryRoutine) {
self.exercise = repositoryExercise
self.routine = repositoryRoutine
}
Expand Down
17 changes: 15 additions & 2 deletions BodyweightFitness/Date+Extensions.swift
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
import Foundation

func secondsToHoursMinutesSeconds(_ seconds : Int) -> (Int, Int, Int) {
return (seconds / 3600, (seconds % 3600) / 60, (seconds % 3600) % 60)
}

extension Date {
public var globalDescription: String {
get {
let month = dateFormattedStringWithFormat("MMMM", fromDate: self)
let year = dateFormattedStringWithFormat("YYYY", fromDate: self)

return "\(month), \(year)"
return "\(month) \(year)"
}
}

Expand All @@ -16,7 +20,16 @@ extension Date {
let month = dateFormattedStringWithFormat("MMMM", fromDate: self)
let year = dateFormattedStringWithFormat("YYYY", fromDate: self)

return "\(day) \(month), \(year)"
return "\(day) \(month) \(year)"
}
}

public var description: String {
get {
let formatter = DateFormatter()
formatter.dateFormat = "EEEE, d MMMM YYYY"

return formatter.string(from: self)
}
}

Expand Down
9 changes: 9 additions & 0 deletions BodyweightFitness/Domain/CompletionRate.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
class CompletionRate {
let percentage: Int
let label: String

init(percentage: Int, label: String) {
self.percentage = percentage
self.label = label
}
}
76 changes: 76 additions & 0 deletions BodyweightFitness/Domain/DataEntriesCompanion.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import Foundation

class DataEntriesCompanion {

func getDataEntries(fromDate: Date,
numberOfDays: Int,
repositoryRoutines: [RepositoryRoutine],
workoutChartType: WorkoutChartType
) -> [WorkoutDataEntry] {
var dataEntries: [WorkoutDataEntry] = []

let baseLineDay: Date = (Calendar.current as NSCalendar).date(
byAdding: .day,
value: -numberOfDays,
to: fromDate,
options: []
)!

for index in 0...numberOfDays {
let date = (Calendar.current as NSCalendar).date(
byAdding: .day,
value: index,
to: baseLineDay,
options: []
)!

let routinesForDay = repositoryRoutines.filter({
return $0.startTime.commonDescription == date.commonDescription
})

if let repositoryRoutine = routinesForDay.first {
dataEntries.append(
WorkoutDataEntry(
x: Double(index),
y: self.getValue(repositoryRoutine: repositoryRoutine, workoutChartType: workoutChartType),
title: self.getTitle(repositoryRoutine: repositoryRoutine),
label: self.getLabel(repositoryRoutine: repositoryRoutine, workoutChartType: workoutChartType)
)
)
} else {
dataEntries.append(
WorkoutDataEntry(
x: Double(index),
y: 0,
title: date.description,
label: "No Data"
)
)
}
}

return dataEntries
}

private func getValue(repositoryRoutine: RepositoryRoutine, workoutChartType: WorkoutChartType) -> Double {
switch workoutChartType {
case .WorkoutLength:
return RepositoryRoutineCompanion(repositoryRoutine).workoutLengthInMinutes()
case .CompletionRate:
return Double(ListOfRepositoryExercisesCompanion(repositoryRoutine.exercises).completionRate().percentage)
}
}

private func getTitle(repositoryRoutine: RepositoryRoutine) -> String {
return RepositoryRoutineCompanion(repositoryRoutine).date()
}

private func getLabel(repositoryRoutine: RepositoryRoutine, workoutChartType: WorkoutChartType) -> String {
switch workoutChartType {
case .WorkoutLength:
return RepositoryRoutineCompanion(repositoryRoutine).workoutLength()
case .CompletionRate:
return ListOfRepositoryExercisesCompanion(repositoryRoutine.exercises).completionRate().label
}
}
}
67 changes: 67 additions & 0 deletions BodyweightFitness/Domain/ListOfRepositoryExercisesCompanion.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import Foundation
import RealmSwift

class ListOfRepositoryExercisesCompanion {
let repositoryExercises: List<RepositoryExercise>

init(_ repositoryExercises: List<RepositoryExercise>) {
self.repositoryExercises = repositoryExercises
}

func numberOfExercises() -> Int {
let filtered = self.repositoryExercises.filter({
$0.visible
})

return filtered.count
}

func numberOfCompletedExercises() -> Int {
let filtered = self.repositoryExercises.filter({
$0.visible && RepositoryExerciseCompanion($0).isCompleted()
})

return filtered.count
}

func allExercisesCompleted() -> Bool {
return numberOfCompletedExercises() == numberOfExercises()
}

func completionRate() -> CompletionRate {
let numberOfExercises = self.numberOfExercises()
let numberOfCompletedExercises = self.numberOfCompletedExercises()

if (numberOfExercises == 0 || numberOfCompletedExercises == 0) {
return CompletionRate(percentage: 0, label: "0%")
}

let value = numberOfCompletedExercises * 100 / numberOfExercises

return CompletionRate(percentage: value, label: "\(value)%")
}

func notCompletedExercises() -> [RepositoryExercise] {
let filtered = Array(self.repositoryExercises).filter({
$0.visible && !RepositoryExerciseCompanion($0).isCompleted()
})

return filtered
}

func visibleExercises() -> [RepositoryExercise] {
let filtered = Array(self.repositoryExercises).filter({
$0.visible
})

return filtered
}

func visibleOrCompletedExercises() -> [RepositoryExercise] {
let filtered = Array(self.repositoryExercises).filter({
$0.visible || RepositoryExerciseCompanion($0).isCompleted()
})

return filtered
}
}
50 changes: 0 additions & 50 deletions BodyweightFitness/Domain/RepositoryCategory.swift
Original file line number Diff line number Diff line change
@@ -1,56 +1,6 @@
import Foundation
import RealmSwift

class CompletionRate {
let percentage: Int
let label: String

init(percentage: Int, label: String) {
self.percentage = percentage
self.label = label
}
}

class RepositoryCategoryHelper {
class func getCompletionRate(_ repositoryCategory: RepositoryCategory) -> CompletionRate {
if (numberOfExercises(repositoryCategory) == 0) {
return CompletionRate(percentage: 0, label: "0%")
}

let percentage = numberOfCompletedExercises(repositoryCategory) * 100 / numberOfExercises(repositoryCategory)

return CompletionRate(percentage: percentage, label: String(percentage) + "%")
}

class func isCompleted(_ repositoryExercise: RepositoryExercise) -> Bool {
let size = repositoryExercise.sets.count

if (size == 0) {
return false
}

let firstSet = repositoryExercise.sets[0] as RepositorySet

if (size == 1 && firstSet.seconds == 0 && firstSet.reps == 0) {
return false
}

return true
}

class func numberOfCompletedExercises(_ repositoryCategory: RepositoryCategory) -> Int {
return repositoryCategory.exercises.filter({
$0.visible && isCompleted($0)
}).count
}

class func numberOfExercises(_ repositoryCategory: RepositoryCategory) -> Int {
return repositoryCategory.exercises.filter({
$0.visible
}).count
}
}

class RepositoryCategory: Object {
dynamic var id = "Category-" + UUID().uuidString
dynamic var categoryId = ""
Expand Down
Loading

0 comments on commit e301acd

Please sign in to comment.