Skip to content

Commit

Permalink
Feature/workout mode/main (#53)
Browse files Browse the repository at this point in the history
* feat: add shortcut

* feat: add training mode

* feat: GetRecordGoalStrengthUsecase

* feat: SubscribeTrainingModeUsecase

* feat: subscribe training mode

* feat: add test case

* feat: add business logic

* feat: CheckGoalAchievedUsecase

* refactor: using usecase

* feat: assign strength goal

* feat: change goal view

* feat: adjust ui

* feat: change test case

* feat: add navigation

* feat: PostTraingModeUsecase

* feat: manage training mode view

* feat: footer
  • Loading branch information
donggyushin authored Jul 13, 2024
1 parent 02db66e commit 8da18fb
Show file tree
Hide file tree
Showing 33 changed files with 681 additions and 32 deletions.
65 changes: 65 additions & 0 deletions dg-muscle-ios/Tests/History/CheckGoalAchievedUsecaseTest.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
//
// CheckGoalAchievedUsecaseTest.swift
// AppTests
//
// Created by 신동규 on 7/13/24.
//

import XCTest
import Domain

final class CheckGoalAchievedUsecaseTest: XCTestCase {

func testAchieved() {
// given
let usecase = CheckGoalAchievedUsecase()

let goal: ExerciseSet = .init(
id: UUID().uuidString,
unit: .kg,
reps: 13,
weight: 60
)

let record: ExerciseRecord = .init(
id: UUID().uuidString,
exerciseId: "squat",
sets: [
.init(id: UUID().uuidString, unit: .kg, reps: 13, weight: 60)
]
)

// when
let result = usecase.implement(goal: goal, record: record)

// then
XCTAssertTrue(result)
}

func testNotAchieved() {
// given
let usecase = CheckGoalAchievedUsecase()

let goal: ExerciseSet = .init(
id: UUID().uuidString,
unit: .kg,
reps: 13,
weight: 60
)

let record: ExerciseRecord = .init(
id: UUID().uuidString,
exerciseId: "squat",
sets: [
.init(id: UUID().uuidString, unit: .kg, reps: 12, weight: 60)
]
)

// when
let result = usecase.implement(goal: goal, record: record)

// then
XCTAssertFalse(result)
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
//
// CheckStrengthGoalAchievedUsecaseTest.swift
// AppTests
//
// Created by 신동규 on 7/13/24.
//

import XCTest
import Domain

final class CheckStrengthGoalAchievedUsecaseTest: XCTestCase {

func testFalseCase() {
// given
let usecase = CheckStrengthGoalAchievedUsecase()
let goal: ExerciseSet = .init(
id: UUID().uuidString,
unit: .kg,
reps: 5,
weight: 65
)

let record: ExerciseRecord = .init(
id: UUID().uuidString,
exerciseId: "squat",
sets: [
.init(id: UUID().uuidString, unit: .kg, reps: 5, weight: 60),
.init(id: UUID().uuidString, unit: .kg, reps: 5, weight: 60),
.init(id: UUID().uuidString, unit: .kg, reps: 5, weight: 60),
.init(id: UUID().uuidString, unit: .kg, reps: 5, weight: 60),
.init(id: UUID().uuidString, unit: .kg, reps: 5, weight: 60),
]
)

// when
let result = usecase.implement(goal: goal, record: record)

// then
XCTAssertFalse(result)
}

func testTrueCase() {
// given
let usecase = CheckStrengthGoalAchievedUsecase()
let goal: ExerciseSet = .init(
id: UUID().uuidString,
unit: .kg,
reps: 5,
weight: 60
)

let record: ExerciseRecord = .init(
id: UUID().uuidString,
exerciseId: "squat",
sets: [
.init(id: UUID().uuidString, unit: .kg, reps: 5, weight: 60),
.init(id: UUID().uuidString, unit: .kg, reps: 5, weight: 60),
.init(id: UUID().uuidString, unit: .kg, reps: 5, weight: 60),
.init(id: UUID().uuidString, unit: .kg, reps: 5, weight: 60),
.init(id: UUID().uuidString, unit: .kg, reps: 5, weight: 60),
]
)

// when
let result = usecase.implement(goal: goal, record: record)

// then
XCTAssertTrue(result)
}
}
59 changes: 59 additions & 0 deletions dg-muscle-ios/Tests/History/GetRecordGoalStrengthUsecaseTest.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
//
// GetRecordGoalStrengthUsecaseTest.swift
// AppTests
//
// Created by 신동규 on 7/13/24.
//

import XCTest
import Domain

final class GetRecordGoalStrengthUsecaseTest: XCTestCase {

func testMoreWeight() {
// given
let useCase = GetRecordGoalStrengthUsecase()

let record: ExerciseRecord = .init(
id: UUID().uuidString,
exerciseId: "squat",
sets: [
.init(id: UUID().uuidString, unit: .kg, reps: 15, weight: 60),
.init(id: UUID().uuidString, unit: .kg, reps: 15, weight: 60),
.init(id: UUID().uuidString, unit: .kg, reps: 5, weight: 60),
.init(id: UUID().uuidString, unit: .kg, reps: 5, weight: 60),
.init(id: UUID().uuidString, unit: .kg, reps: 5, weight: 60)
]
)

// when
let goal = useCase.implement(previousRecord: record)

// then
XCTAssertEqual(goal?.weight, 65)
XCTAssertEqual(goal?.reps, 5)
}

func testSameWeigth() {
// given
let useCase = GetRecordGoalStrengthUsecase()

let record: ExerciseRecord = .init(
id: UUID().uuidString,
exerciseId: "squat",
sets: [
.init(id: UUID().uuidString, unit: .kg, reps: 15, weight: 60),
.init(id: UUID().uuidString, unit: .kg, reps: 15, weight: 60),
.init(id: UUID().uuidString, unit: .kg, reps: 15, weight: 60)
]
)

// when
let goal = useCase.implement(previousRecord: record)

// then
XCTAssertEqual(goal?.weight, 60)
XCTAssertEqual(goal?.reps, 5)
}

}
7 changes: 7 additions & 0 deletions dg-muscle-ios/sources/App/DI/HistoryAssembly.swift
Original file line number Diff line number Diff line change
Expand Up @@ -108,5 +108,12 @@ public struct HistoryAssembly: Assembly {

return DateToSelectHistoryView(historyRepository: historyRepository)
}

container.register(ManageTrainingModeView.self) { resolver in

let userRepository = resolver.resolve(UserRepository.self)!

return ManageTrainingModeView(userRepository: userRepository)
}
}
}
3 changes: 2 additions & 1 deletion dg-muscle-ios/sources/App/DI/MainAssembly.swift
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@ public struct MainAssembly: Assembly {
logsFactory: { resolver.resolve(LogsView.self)! },
friendMainFactory: { anchor in resolver.resolve(FriendMainView.self, argument: anchor)! },
friendHistoryFactory: { friendId, today in resolver.resolve(FriendHistoryView.self, arguments: friendId, today)! },
historyDetailFactory: { friendId, historyId in resolver.resolve(HistoryDetailView.self, arguments: friendId, historyId)! }
historyDetailFactory: { friendId, historyId in resolver.resolve(HistoryDetailView.self, arguments: friendId, historyId)! },
manageTrainingModeFactory: { resolver.resolve(ManageTrainingModeView.self)! }
)
}

Expand Down
10 changes: 10 additions & 0 deletions dg-muscle-ios/sources/App/Delegate/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,16 @@ class AppDelegate: NSObject, UIApplicationDelegate {
UNUserNotificationCenter.current().requestAuthorization(options: authOptions) { _, _ in }
application.registerForRemoteNotifications()
Messaging.messaging().delegate = self

application.shortcutItems = [
UIApplicationShortcutItem(
type: "dgmuscle://history",
localizedTitle: "Quick Record",
localizedSubtitle: "move to today record page directly",
icon: .init(systemImageName: "figure.snowboarding")
)
]

return true
}

Expand Down
13 changes: 10 additions & 3 deletions dg-muscle-ios/sources/App/Delegate/SceneDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ class SceneDelegate: NSObject, UIWindowSceneDelegate {

func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
if let shortcutItem = connectionOptions.shortcutItem {
print("dg: shortcutItem is \(shortcutItem)")
handleShortCutItem(item: shortcutItem)
}

if let urlContext = connectionOptions.urlContexts.first {
Expand All @@ -26,7 +26,7 @@ class SceneDelegate: NSObject, UIWindowSceneDelegate {
}

func windowScene(_ windowScene: UIWindowScene, performActionFor shortcutItem: UIApplicationShortcutItem, completionHandler: @escaping (Bool) -> Void) {
print("dg: shortcutItem is \(shortcutItem)")
handleShortCutItem(item: shortcutItem)
completionHandler(true)
}

Expand All @@ -35,6 +35,12 @@ class SceneDelegate: NSObject, UIWindowSceneDelegate {
handleURL(url: url)
}

private func handleShortCutItem(item: UIApplicationShortcutItem) {
if let url = URL(string: item.type) {
handleURL(url: url)
}
}

private func handleURL(url: URL) {
if UserRepositoryImpl.shared.isReady == false {
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
Expand Down Expand Up @@ -91,7 +97,8 @@ class SceneDelegate: NSObject, UIWindowSceneDelegate {
coordinator?.history.setDuration(duration: Int(duration) ?? 0)
case "datetoselecthistory":
coordinator?.history.dateToSelectHistory()

case "managetraingmode":
coordinator?.history.manageTrainigMode()
default: break
}
}
Expand Down
32 changes: 32 additions & 0 deletions dg-muscle-ios/sources/DataLayer/User/Model/TrainingMode.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
//
// TrainingMode.swift
// DataLayer
//
// Created by 신동규 on 7/13/24.
//

import Foundation
import Domain

public enum TrainingMode: Codable {
case mass
case strength

init(domain: Domain.TrainingMode) {
switch domain {
case .mass:
self = .mass
case .strength:
self = .strength
}
}

var domain: Domain.TrainingMode {
switch self {
case .mass:
return .mass
case .strength:
return .strength
}
}
}
5 changes: 4 additions & 1 deletion dg-muscle-ios/sources/DataLayer/User/Model/UserData.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ struct UserData: Codable {
var link: String?
var developer: Bool?
var onlyShowsFavoriteExercises: Bool?
var trainingMode: TrainingMode?

init(domain: Domain.User) {
self.id = domain.uid
Expand All @@ -31,6 +32,7 @@ struct UserData: Codable {
self.deleted = false
self.developer = domain.developer
self.onlyShowsFavoriteExercises = domain.onlyShowsFavoriteExercises
self.trainingMode = .init(domain: domain.trainingMode)
}

var domain: Domain.User {
Expand All @@ -43,7 +45,8 @@ struct UserData: Codable {
fcmToken: fcmToken,
link: .init(string: link ?? ""),
developer: developer ?? false,
onlyShowsFavoriteExercises: onlyShowsFavoriteExercises ?? false
onlyShowsFavoriteExercises: onlyShowsFavoriteExercises ?? false,
trainingMode: trainingMode?.domain ?? .mass
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,10 @@ public final class UserRepositoryImpl: UserRepository {
_user?.onlyShowsFavoriteExercises = onlyShowsFavoriteExercises
}

public func updateUser(trainingMode: Domain.TrainingMode) {
_user?.trainingMode = trainingMode
}

public func withDrawal() async -> (any Error)? {

if _user?.uid == "taEJh30OpGVsR3FEFN2s67A8FvF3" {
Expand Down Expand Up @@ -169,7 +173,8 @@ public final class UserRepositoryImpl: UserRepository {
fcmToken: nil,
link: nil,
developer: false,
onlyShowsFavoriteExercises: false
onlyShowsFavoriteExercises: false,
trainingMode: .mass
)
return user
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//
// CheckGoalAchievedUsecase.swift
// Domain
//
// Created by 신동규 on 7/13/24.
//

import Foundation

public final class CheckGoalAchievedUsecase {
public init() { }

public func implement(goal: ExerciseSet, record: ExerciseRecord) -> Bool {
return !record.sets.filter({ set in
goal.weight <= set.weight && goal.reps <= set.reps
}).isEmpty
}
}
Loading

0 comments on commit 8da18fb

Please sign in to comment.