Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feat/#128] 프로필 화면 재구성 #131

Merged
merged 16 commits into from
Jul 11, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
//
// FetchWorkoutRequestDTO.swift
// DomainWorkoutInterface
//
// Created by 송영모 on 2023/07/10.
//

import Foundation

// MARK: - FetchWorkoutResponseDTO
public struct FetchWorkoutResponseDTO: Codable {
let workouts: [FetchWorkoutDTO]

public func toDomain() -> ProfileWorkoutInfo {
return .init(workouts: workouts.map {
return .init(
workoutDate: $0.workoutDate,
totalTime: $0.totalTime,
averageHeartbeat: $0.averageHeartbeat,
totalCalories: $0.totalCalories,
maxWorkoutPart: $0.maxWorkoutPart,
maxWorkoutPartTime: $0.maxWorkoutPartTime)
})
}
}

// MARK: - FetchWorkoutDTO
public struct FetchWorkoutDTO: Codable {
let workoutDate: String
let totalTime, averageHeartbeat, totalCalories: Int
let maxWorkoutPart: WorkoutCategory
let maxWorkoutPartTime: Int
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
//
// ProfileInfo.swift
// DomainWorkoutInterface
//
// Created by 송영모 on 2023/07/10.
//

import Foundation

// MARK: - ProfileWorkoutInfo
public struct ProfileWorkoutInfo {
public let workouts: [ProfileWorkout]
}

// MARK: - ProfileWorkout
public struct ProfileWorkout: Codable {
let workoutDate: String
let totalTime, averageHeartbeat, totalCalories: Int
let maxWorkoutPart: WorkoutCategory
let maxWorkoutPartTime: Int
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import Foundation

public struct PumpingTimer: Codable, Equatable {
public let id: UUID
public let workoutCategoryIdentifier: WorkoutCategoryIdentifier
public let workoutCategoryIdentifier: WorkoutPart
public var time: Int

public var heartRateSum: Double
Expand All @@ -21,7 +21,7 @@ public struct PumpingTimer: Codable, Equatable {

public init(
id: UUID,
workoutCategoryIdentifier: WorkoutCategoryIdentifier,
workoutCategoryIdentifier: WorkoutPart,
time: Int = 0,
heartRateSum: Double = 0.0,
heartRateCount: Int = 0,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,30 +7,30 @@

import Foundation

//MARK: WorkoutCategoryIdentifierType
//MARK: WorkoutCategory

public enum WorkoutCategoryIdentifierType: String, CaseIterable {
case whole = "전신"
case upper = "상체"
case lower = "하체"
public enum WorkoutCategory: String, CaseIterable, Codable {
case whole = "WHOLE"
case up = "UP"
case down = "DOWN"
}

public extension WorkoutCategoryIdentifierType {
var identifiers: [WorkoutCategoryIdentifier] {
public extension WorkoutCategory {
var parts: [WorkoutPart] {
switch self {
case .whole:
return [.aerobic]
case .upper:
case .up:
return [.shoulder, .chest, .arm, .back]
case .lower:
case .down:
return [.hip]
}
}
}

//MARK: WorkoutCategoryIdentifier
//MARK: WorkoutPart

public enum WorkoutCategoryIdentifier: String, CaseIterable, Equatable, Codable {
public enum WorkoutPart: String, CaseIterable, Equatable, Codable {
case aerobic = "AEROBIC"
case shoulder = "SHOULDER"
case chest = "CHEST"
Expand All @@ -40,7 +40,7 @@ public enum WorkoutCategoryIdentifier: String, CaseIterable, Equatable, Codable
case leg = "LEG"
}

public extension WorkoutCategoryIdentifier {
public extension WorkoutPart {
var title: String {
switch self {
case .aerobic: return "유산소"
Expand All @@ -53,11 +53,11 @@ public extension WorkoutCategoryIdentifier {
}
}

var type: WorkoutCategoryIdentifierType {
var category: WorkoutCategory {
switch self {
case .aerobic: return .whole
case .shoulder, .chest, .arm, .back: return .upper
case .hip, .leg: return .lower
case .shoulder, .chest, .arm, .back: return .up
case .hip, .leg: return .down
}
}
}
14 changes: 10 additions & 4 deletions Projects/Domain/Workout/Interface/Sources/WorkoutClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,25 @@ import Foundation
import ComposableArchitecture

public struct WorkoutClient {
public var fetchWorkout: @Sendable (String?) async throws -> ProfileWorkoutInfo
public var makeWorkout: @Sendable ([PumpingTimer]) async throws -> String

public init(makeWorkout: @escaping @Sendable ([PumpingTimer]) async throws -> String) {
self.makeWorkout = makeWorkout
}

public init(
fetchWorkout: @escaping @Sendable (String?) async throws -> ProfileWorkoutInfo,
makeWorkout: @escaping @Sendable ([PumpingTimer]) async throws -> String) {
self.fetchWorkout = fetchWorkout
self.makeWorkout = makeWorkout
}
}

extension WorkoutClient: TestDependencyKey {
public static var previewValue = Self(
fetchWorkout: unimplemented("\(Self.self).fetchWorkout"),
makeWorkout: unimplemented("\(Self.self).makeWorkout")
)

public static let testValue = Self(
fetchWorkout: unimplemented("\(Self.self).fetchWorkout"),
makeWorkout: unimplemented("\(Self.self).makeWorkout")
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,14 @@ import CoreNetworkInterface
import CoreKeyChainStore

public struct WorkoutEndpoint {
public static func fetchWorkout(userId: String? = nil) -> Endpoint<FetchWorkoutResponseDTO> {
let accessToken = KeyChainStore.shared.load(property: .accessToken)

return Endpoint(path: "workout/" + String(describing: userId),
httpMethod: .get,
headers: ["Authorization" : "Bearer \(accessToken)"])
}

public static func makeWorkout(_ requestDTO: MakeWorkoutRequestDTO) -> Endpoint<MakeWorkoutResponseDTO> {
let accessToken = KeyChainStore.shared.load(property: .accessToken)

Expand Down
22 changes: 15 additions & 7 deletions Projects/Domain/Workout/Sources/WorkoutClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,21 @@ import DomainWorkoutInterface
import Core

extension WorkoutClient: DependencyKey {
public static let liveValue = WorkoutClient { timers in
let makeWorkoutRequestDTO = MakeWorkoutRequestDTO(timers: timers.map { $0.toDTO() })
let apiEndpoint = WorkoutEndpoint.makeWorkout(makeWorkoutRequestDTO)
let response = try await NetworkProvider.shared.sendRequest(apiEndpoint).toDomain()

return response
}
public static let liveValue = WorkoutClient(
fetchWorkout: { userId in
let apiEndpoint = WorkoutEndpoint.fetchWorkout(userId: userId)
let response = try await NetworkProvider.shared.sendRequest(apiEndpoint).toDomain()

return response
},
makeWorkout: { timers in
let makeWorkoutRequestDTO = MakeWorkoutRequestDTO(timers: timers.map { $0.toDTO() })
let apiEndpoint = WorkoutEndpoint.makeWorkout(makeWorkoutRequestDTO)
let response = try await NetworkProvider.shared.sendRequest(apiEndpoint).toDomain()

return response
}
)
}

extension DependencyValues {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,33 +18,36 @@ public enum CrewScene: Hashable {
public struct CrewRootStore: ReducerProtocol {
private let reducer: Reduce<State, Action>

public let profileHomeStore: ProfileHomeStore
public let profileWidthOfChangeStore: ProfileWidthOfChangeStore

private let crewHomeStore: CrewHomeStore
private let crewRankingStore: CrewRankingStore
private let profileStore: ProfileStore
private let widthOfChangeStore: WidthOfChangeStore

public init(
reducer: Reduce<State, Action>,
profileHomeStore: ProfileHomeStore,
profileWidthOfChangeStore: ProfileWidthOfChangeStore,
crewHomeStore: CrewHomeStore,
crewRankingStore: CrewRankingStore,
profileStore: ProfileStore,
widthOfChangeStore: WidthOfChangeStore
crewRankingStore: CrewRankingStore
) {
self.reducer = reducer

self.profileHomeStore = profileHomeStore
self.profileWidthOfChangeStore = profileWidthOfChangeStore
self.crewHomeStore = crewHomeStore
self.crewRankingStore = crewRankingStore
self.profileStore = profileStore
self.widthOfChangeStore = widthOfChangeStore
}

public struct State: Equatable {
@BindingState public var path: [CrewScene] = []
public var crewHome: CrewHomeStore.State = .init()
@BindingState public var showingCrew: Bool = false

public var profile: ProfileStore.State?
public var widthOfChange: WidthOfChangeStore.State?
// child
public var crewHome: CrewHomeStore.State = .init()
public var crewRanking: CrewRankingStore.State?
public var profileHome: ProfileHomeStore.State?
public var profileWidthOfChange: ProfileWidthOfChangeStore.State?

public init() { }
}
Expand All @@ -54,8 +57,8 @@ public struct CrewRootStore: ReducerProtocol {

case crewHome(CrewHomeStore.Action)
case crewRanking(CrewRankingStore.Action)
case profile(ProfileStore.Action)
case widthOfChange(WidthOfChangeStore.Action)
case profileHome(ProfileHomeStore.Action)
case profileWidthOfChange(ProfileWidthOfChangeStore.Action)
}

public var body: some ReducerProtocol<State, Action> {
Expand All @@ -69,8 +72,8 @@ public struct CrewRootStore: ReducerProtocol {
.ifLet(\.crewRanking, action: /Action.crewRanking) {
crewRankingStore
}
.ifLet(\.profile, action: /Action.profile) {
profileStore
.ifLet(\.profileHome, action: /Action.profileHome) {
profileHomeStore
}
}
}
11 changes: 6 additions & 5 deletions Projects/Feature/Crew/Interface/Sources/Root/CrewRootView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -34,19 +34,20 @@ public struct CrewRootView: View {
}

case .profile:
IfLetStore(self.store.scope(state: \.profile, action: { .profile($0) })) {
ProfileView(store: $0, profileSubject: .my)
IfLetStore(self.store.scope(state: \.profileHome, action: { .profileHome($0) })) {
ProfileHomeView(store: $0)
.toolbarRole(.editor)
}

case .widthOfChange:
IfLetStore(self.store.scope(state: \.widthOfChange, action: { .widthOfChange($0) })) {
WidthOfChangeView(store: $0)
IfLetStore(self.store.scope(state: \.profileWidthOfChange, action: { .profileWidthOfChange($0) })) {
ProfileWidthOfChangeView(store: $0)
.toolbarRole(.editor)
}
}
}
}
.accentColor(PumpingColors.colorGrey800.swiftUIColor)
}
}
}
16 changes: 8 additions & 8 deletions Projects/Feature/Crew/Sources/Root/CrewRootStore.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ import FeatureProfileInterface

extension CrewRootStore {
public init(
profileStore: ProfileStore,
widthOfChangeStore: WidthOfChangeStore
profileHomeStore: ProfileHomeStore,
profileWidthOfChangeStore: ProfileWidthOfChangeStore
) {
let reducer: Reduce<State, Action> = .init { state, action in
switch action {
Expand All @@ -24,7 +24,7 @@ extension CrewRootStore {
switch action {
case .goToProfileView:
state.path.append(.profile)
state.profile = .init()
state.profileHome = .init(type: .other)//TODO: other이 아닌경우 체크 해야함
return .none

//TODO: 머지 컨플릭트 해결후 버그
Expand All @@ -37,9 +37,9 @@ extension CrewRootStore {
return .none
}

case .profile(.tapWidthOfChangeButton):
case .profileHome(.tapWidthOfChangeButton):
state.path.append(.widthOfChange)
state.widthOfChange = .init()
state.profileWidthOfChange = .init()
return .none

default:
Expand All @@ -49,10 +49,10 @@ extension CrewRootStore {

self.init(
reducer: reducer,
profileHomeStore: profileHomeStore,
profileWidthOfChangeStore: profileWidthOfChangeStore,
crewHomeStore: .init(),
crewRankingStore: .init(),
profileStore: profileStore,
widthOfChangeStore: widthOfChangeStore
crewRankingStore: .init()
)
}
}
Loading