Skip to content

Commit

Permalink
Merge pull request #86 from Nexters/refactor/mypage-score-list(#84)
Browse files Browse the repository at this point in the history
마이페이지 스코어 리스트 & 홈 뷰
  • Loading branch information
enebin authored Sep 3, 2023
2 parents 933bfdb + 7949bfe commit 9a8c18a
Show file tree
Hide file tree
Showing 26 changed files with 510 additions and 381 deletions.
Binary file modified Encrypted/Secrets/GoogleService-Info.plist.encrypted
Binary file not shown.
4 changes: 2 additions & 2 deletions Projects/Domain/Sources/Client/KeymeTestsClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,12 @@ private func getClient(with network: KeymeAPIManager) -> KeymeTestsClient {
let api = KeymeAPI.test(.onboarding)
let response = try await network.request(api, object: KeymeTestsDTO.self)

return response.toIconModel()
return response.toKeymeTestsModel()
}, fetchDailyTests: {
let api = KeymeAPI.test(.daily)
let response = try await network.request(api, object: KeymeTestsDTO.self)

return response.toIconModel()
return response.toKeymeTestsModel()
}, fetchTestResult: { testResultId in
let api = KeymeAPI.test(.result(testResultId))
let response = try await network.request(api, object: TestResultDTO.self)
Expand Down
35 changes: 0 additions & 35 deletions Projects/Domain/Sources/Client/TestClient.swift

This file was deleted.

9 changes: 9 additions & 0 deletions Projects/Domain/Sources/Model/CirclePack/CharacterScore.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
// Copyright © 2023 team.humanwave. All rights reserved.
//

import Network
import Foundation

public struct CharacterScore: Identifiable, Equatable {
Expand All @@ -18,3 +19,11 @@ public struct CharacterScore: Identifiable, Equatable {
self.date = date
}
}

public extension QuestionResultScoresDTO {
func toCharacterScores() -> [CharacterScore] {
return self.data.results.map { resultItem in
CharacterScore(score: resultItem.score, date: resultItem.createdAt)
}
}
}
9 changes: 3 additions & 6 deletions Projects/Domain/Sources/Model/KeymeTestsModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import Network
import Kingfisher

public struct KeymeTestsModel: Equatable {
public let nickname: String
public let testId: Int
public let icons: [IconModel]
}
Expand All @@ -26,14 +25,12 @@ public struct IconModel: Equatable, Hashable {
}

public extension KeymeTestsDTO {
func toIconModel() -> KeymeTestsModel {
let nickname = data.owner.nickname
func toKeymeTestsModel() -> KeymeTestsModel {
let icons = data.questions.map {
IconModel(imageURL: $0.category.iconUrl,
color: Color.hex($0.category.color))
}
return KeymeTestsModel(nickname: nickname ?? "키미",
testId: data.testId,
icons: icons)

return KeymeTestsModel(testId: data.testId, icons: icons)
}
}
21 changes: 0 additions & 21 deletions Projects/Domain/Sources/Model/TestModel.swift

This file was deleted.

61 changes: 61 additions & 0 deletions Projects/Features/Sources/Home/KeymeTestHomeFeature.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
//
// KeymeTestHomeFeature.swift
// Features
//
// Created by 이영빈 on 2023/08/30.
// Copyright © 2023 team.humanwave. All rights reserved.
//

import ComposableArchitecture
import Domain
import Network

struct KeymeTestsHomeFeature: Reducer {
@Dependency(\.keymeAPIManager) private var network

// 테스트를 아직 풀지 않았거나, 풀었거나 2가지 케이스만 존재
struct State: Equatable {
@PresentationState var testStartViewState: KeymeTestsStartFeature.State?
var view: View

struct View: Equatable {
let nickname: String
var dailyTestId: Int?
}

init(nickname: String) {
self.view = View(nickname: nickname)
}
}

enum Action {
case fetchDailyTests
case showTestStartView(testData: KeymeTestsModel)
case startTest(PresentationAction<KeymeTestsStartFeature.Action>)

enum View {}
}

var body: some ReducerOf<Self> {
Reduce { state, action in
switch action {
case .fetchDailyTests:
return .run { send in
let fetchedTest = try await network.request(.test(.daily), object: KeymeTestsDTO.self)
let testData = fetchedTest.toKeymeTestsModel()

await send(.showTestStartView(testData: testData))
}

case .showTestStartView(let testData):
state.view.dailyTestId = testData.testId
state.testStartViewState = .init(nickname: state.view.nickname, testData: testData)

default:
break
}

return .none
}
}
}
71 changes: 71 additions & 0 deletions Projects/Features/Sources/Home/KeymeTestHomeView.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
//
// KeymeTestHomeView.swift
// Features
//
// Created by 이영빈 on 2023/08/30.
// Copyright © 2023 team.humanwave. All rights reserved.
//

import ComposableArchitecture
import DSKit
import SwiftUI

struct KeymeTestsHomeView: View {
var store: StoreOf<KeymeTestsHomeFeature>

init(store: StoreOf<KeymeTestsHomeFeature>) {
self.store = store
store.send(.fetchDailyTests)
}

var body: some View {
WithViewStore(store, observe: { $0.view }) { viewStore in
ZStack(alignment: .center) {
DSKitAsset.Color.keymeBlack.swiftUIColor.ignoresSafeArea()

VStack(alignment: .leading) {
// Filler
Spacer().frame(height: 75)

welcomeText(nickname: viewStore.nickname)
.foregroundColor(DSKitAsset.Color.keymeWhite.swiftUIColor)

Spacer()
}
.fullFrame()
.padding(.horizontal, 16)

// 테스트 뷰
testView

// 결과 화면 표시도 생각

}
}
}
}

extension KeymeTestsHomeView {
var testView: some View {
let startTestStore = store.scope(
state: \.$testStartViewState,
action: KeymeTestsHomeFeature.Action.startTest)

return IfLetStore(startTestStore) { store in
KeymeTestsStartView(store: store)
} else: {
Circle()
.strokeBorder(.white.opacity(0.3), lineWidth: 1)
.background(Circle().foregroundColor(.white.opacity(0.3)))
.frame(width: 280, height: 280)
}
}

func welcomeText(nickname: String) -> some View {
Text.keyme(
"환영해요 \(nickname)님!",
// "환영해요 \(viewStore.nickname)님!\n이제 문제를 풀어볼까요?",
font: .heading1)
}

}
33 changes: 10 additions & 23 deletions Projects/Features/Sources/Home/KeymeTestsStartFeature.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,21 @@ import Domain

public struct KeymeTestsStartFeature: Reducer {
public struct State: Equatable {
public let nickname: String
public let testData: KeymeTestsModel

public var icon: IconModel = .EMPTY
public var keymeTests: KeymeTestsFeature.State?
public var isAnimating: Bool = false
public var nickname: String?
public var testId: Int = 18 // TODO: change
public var icon: IconModel = .EMPTY

public init() { }
public init(nickname: String, testData: KeymeTestsModel) {
self.nickname = nickname
self.testData = testData
}
}

public enum Action {
case viewWillAppear
case fetchDailyTests(TaskResult<KeymeTestsModel>)
case startAnimation([IconModel])
case setIcon(IconModel)
case startButtonDidTap
Expand All @@ -40,24 +43,8 @@ public struct KeymeTestsStartFeature: Reducer {
Reduce { state, action in
switch action {
case .viewWillAppear:
return .run { send in
await send(.fetchDailyTests(
TaskResult {
try await self.keymeTestsClient.fetchDailyTests()
}
))
}

case let .fetchDailyTests(.success(tests)):
state.nickname = tests.nickname
state.testId = tests.testId
state.isAnimating = true

return .send(.startAnimation(tests.icons))

case .fetchDailyTests(.failure):
state.nickname = "키미" // TODO: 변경
return .send(.startAnimation([IconModel.EMPTY]))
return .send(.startAnimation(state.testData.icons))

case .startAnimation(let icons):
return .run { send in
Expand All @@ -74,7 +61,7 @@ public struct KeymeTestsStartFeature: Reducer {
state.isAnimating = true

case .startButtonDidTap:
let url = "https://keyme-frontend.vercel.app/test/\(state.testId)"
let url = "https://keyme-frontend.vercel.app/test/\(state.testData.testId)"
state.keymeTests = KeymeTestsFeature.State(url: url)

case .keymeTests:
Expand Down
56 changes: 17 additions & 39 deletions Projects/Features/Sources/Home/KeymeTestsStartView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,48 +24,26 @@ public struct KeymeTestsStartView: View {

public var body: some View {
WithViewStore(store, observe: { $0 }) { viewStore in
VStack {
IfLetStore(
self.store.scope(
state: \.keymeTests,
action: KeymeTestsStartFeature.Action.keymeTests
),
then: { store in
KeymeTestsView(store: store)
.ignoresSafeArea(.all)
.transition(.scale.animation(.easeIn))
},
else: {
Spacer()
.frame(height: 75)

welcomeText(viewStore)

Spacer()

startTestsButton(viewStore)
.onTapGesture {
viewStore.send(.startButtonDidTap)
}

Spacer()
}
)
}
.frame(maxWidth: .infinity)
.background(DSKitAsset.Color.keymeBlack.swiftUIColor)
IfLetStore(
self.store.scope(
state: \.keymeTests,
action: KeymeTestsStartFeature.Action.keymeTests
),
then: { store in
KeymeTestsView(store: store)
.ignoresSafeArea(.all)
.transition(.scale.animation(.easeIn))
},
else: {
startTestsButton(viewStore)
.onTapGesture {
viewStore.send(.startButtonDidTap)
}
}
)
}
}

func welcomeText(_ viewStore: ViewStore<KeymeTestsStartFeature.State, KeymeTestsStartFeature.Action>) -> some View {
Text.keyme(
"환영해요 \(viewStore.nickname ?? "키미")님!\n이제 문제를 풀어볼까요?",
font: .heading1) // TODO: 닉변
.foregroundColor(DSKitAsset.Color.keymeWhite.swiftUIColor)
.frame(maxWidth: .infinity, alignment: .leading)
.padding(Padding.insets(leading: 16))
}

func startTestsButton(_ viewStore: ViewStore<KeymeTestsStartFeature.State,
KeymeTestsStartFeature.Action>) -> some View {
ZStack {
Expand Down
Loading

0 comments on commit 9a8c18a

Please sign in to comment.