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

[WEAV-135] 프로필, 이상형 정보 입력 Intro 뷰 생성 #45

Merged
merged 4 commits into from
Nov 21, 2024
Merged
Show file tree
Hide file tree
Changes from 3 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
8 changes: 8 additions & 0 deletions Projects/App/Sources/Debug/AuthInfoView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,14 @@ struct AuthDebugInfoView: View {
dismissButton: .default(Text("확인"))
)
}
.toolbarRole(.navigationStack)
.toolbar {
ToolbarItem(placement: .topBarTrailing) {
Button("로그아웃", role: .destructive) {
AppCoordinator.shared.logout()
}
}
}
}

// 클립보드에 복사하는 함수
Expand Down
5 changes: 5 additions & 0 deletions Projects/App/Sources/Navigation/NavigationStack.swift
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ extension PathType {
case .authAgreement(let input):
AuthAgreementView(input)

case .profileIntro(let input):
ProfileIntroView(input)

case .authGreeting(let input):
AuthGreetingView(input)
case .authProfileGender(let input):
Expand All @@ -55,6 +58,8 @@ extension PathType {
case .authName(let input):
AuthNameInputView(input)

case .dreamPartnerIntro(let input):
DreamPartnerIntroView(input)
case .dreamPartnerAgeRange(let input):
DreamPartnerAgeView(input)
case .dreamPartnerJobOccupation(let input):
Expand Down
7 changes: 7 additions & 0 deletions Projects/Core/CommonKit/Sources/AppCoordinator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -122,4 +122,11 @@ public final class AppCoordinator: ObservableObject {
}
}
}

public func logout() {
TokenManager.accessToken = nil
TokenManager.refreshToken = nil
TokenManager.registerToken = nil
AuthState.change(.loggedOut)
}
}
10 changes: 10 additions & 0 deletions Projects/Core/CommonKit/Sources/Path/PathTypes.swift
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ public enum PathType: Hashable {
.signUp(.authRegion(input: .mock)),
.signUp(.authPhoneInput),

.signUp(.dreamPartnerIntro(input: .mock)),
.signUp(.dreamPartnerAgeRange(input: .mock))
]
#endif
Expand All @@ -69,6 +70,8 @@ public enum PathType: Hashable {
case .authPhoneVerify: return "전화번호 인증"
case .authAgreement: return "이용 약관"

case .profileIntro: return "프로필 입력 인트로"

case .authGreeting: return "가입 후 환영"
case .authProfileGender: return "성별 입력"
case .authProfileAge: return "나이 입력"
Expand All @@ -77,6 +80,7 @@ public enum PathType: Hashable {
case .authRegion: return "내 지역, 선호 지역 입력"
case .authName: return "이름 입력"

case .dreamPartnerIntro: return "이상형 입력 인트로"
case .dreamPartnerAgeRange: return "이상형 나이대"
case .dreamPartnerJobOccupation: return "이상형 직업"
case .dreamPartnerDistance: return "이상형과의 거리"
Expand All @@ -90,6 +94,7 @@ public enum SignUpSubViewType: Hashable {
case authPhoneVerify(SMSSendResponse)
case authAgreement(input: SignUpFormDomain)

case profileIntro(input: SignUpFormDomain)
case authGreeting(input: SignUpFormDomain)
case authProfileGender(input: SignUpFormDomain)
case authProfileAge(input: SignUpFormDomain)
Expand All @@ -98,6 +103,7 @@ public enum SignUpSubViewType: Hashable {
case authRegion(input: SignUpFormDomain)
case authName(input: SignUpFormDomain)

case dreamPartnerIntro(input: SignUpFormDomain)
case dreamPartnerAgeRange(input: SignUpFormDomain)
case dreamPartnerJobOccupation(input: SignUpFormDomain)
case dreamPartnerDistance(input: SignUpFormDomain)
Expand All @@ -108,6 +114,8 @@ public enum SignUpSubViewType: Hashable {

public func hash(into hasher: inout Hasher) {
switch self {
case .profileIntro:
hasher.combine(-1)
Comment on lines +117 to +118
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

해시 값 할당 방식의 개선이 필요합니다.

현재 인트로 화면들에 대해 음수 값(-1, -2)을 사용하고 있는데, 이는 기존의 양수 시퀀스 패턴과 일치하지 않습니다. 유지보수성을 높이기 위해 일관된 번호 체계를 사용하는 것이 좋습니다.

다음과 같이 수정하는 것을 제안드립니다:

case .profileIntro:
-    hasher.combine(-1)
+    hasher.combine(13)
case .dreamPartnerIntro:
-    hasher.combine(-2)
+    hasher.combine(14)

Also applies to: 140-141

case .authPhoneInput:
hasher.combine(0)
case .authPhoneVerify:
Expand All @@ -129,6 +137,8 @@ public enum SignUpSubViewType: Hashable {
case .authName:
hasher.combine(9)

case .dreamPartnerIntro:
hasher.combine(-2)
case .dreamPartnerAgeRange:
hasher.combine(10)
case .dreamPartnerJobOccupation:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"images" : [
{
"filename" : "heart-with-arrow.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "heart-with-arrow@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "heart-with-arrow@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"images" : [
{
"filename" : "magnifying-glass.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "magnifying-glass@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "magnifying-glass@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ extension AuthAgreementIntent: AuthAgreementIntent.Intentable {
func onTapNextButton() {
Task {
await AppCoordinator.shared.changeRootView(
.signUp(.authGreeting(input: input.input))
.signUp(.profileIntro(input: input.input))
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ public struct DreamPartnerAgeView: View {
}
.ignoresSafeArea(.keyboard)
.textureBackground()
.setPopNavigation {
.setNavigation(showLeftBackButton: false) {
AppCoordinator.shared.pop()
}
.setLoading(state.isLoading)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
//
// DreamPartnerIntroIntent.swift
// SignUp
//
// Created by 김지수 on 11/21/24.
// Copyright © 2024 com.weave. All rights reserved.
//

import Foundation
import CommonKit
import CoreKit
import Model

//MARK: - Intent
class DreamPartnerIntroIntent {
private weak var model: DreamPartnerIntroModelActionable?
private let input: DataModel

// MARK: Life cycle
init(
model: DreamPartnerIntroModelActionable,
input: DataModel
) {
self.input = input
self.model = model

Task {
try? await Task.sleep(for: .milliseconds(2500))
await pushNextView()
}
}
}
Comment on lines +14 to +32
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

초기화 시 자동 전환 로직 검토 필요

Task 내에서 sleep을 사용하여 지연된 화면 전환을 구현하고 있습니다. 다음 사항들을 고려해주세요:

  1. 사용자가 화면을 벗어나거나 앱이 백그라운드로 전환될 때 Task가 적절히 취소되어야 합니다.
  2. 화면 전환 시간(2.5초)을 상수로 분리하는 것이 좋습니다.
  3. Task.sleep 대신 더 안전한 방법을 고려해볼 수 있습니다.

다음과 같이 수정하는 것을 제안드립니다:

+ private let transitionDelay: Double = 2.5
+ private var transitionTask: Task<Void, Error>?

  init(
      model: DreamPartnerIntroModelActionable,
      input: DataModel
  ) {
      self.input = input
      self.model = model
      
-     Task {
+     transitionTask = Task {
          try? await Task.sleep(for: .milliseconds(2500))
          await pushNextView()
      }
  }

+ deinit {
+     transitionTask?.cancel()
+ }

Committable suggestion skipped: line range outside the PR's diff.

🧰 Tools
🪛 SwiftLint

[Warning] 14-14: Prefer at least one space after slashes for comments

(comment_spacing)


[Warning] 14-14: MARK comment should be in valid format. e.g. '// MARK: ...' or '// MARK: - ...'

(mark)


//MARK: - Intentable
extension DreamPartnerIntroIntent {
protocol Intentable {
// content
func pushNextView() async
func onTapNextButton()

// default
func onAppear()
func task() async
}

struct DataModel {
let input: SignUpFormDomain
}
}

//MARK: - Intentable
extension DreamPartnerIntroIntent: DreamPartnerIntroIntent.Intentable {
// default
func onAppear() {}

func task() async {}

// content
@MainActor
func pushNextView() async {
AppCoordinator.shared.changeRootView(
.signUp(.dreamPartnerAgeRange(input: input.input))
)
}
func onTapNextButton() {}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
//
// DreamPartnerIntroModel.swift
// SignUp
//
// Created by 김지수 on 11/21/24.
// Copyright © 2024 com.weave. All rights reserved.
//

import Foundation
import CommonKit
import CoreKit

final class DreamPartnerIntroModel: ObservableObject {

//MARK: Stateful
protocol Stateful {
// content
var isValidated: Bool { get }

// default
var isLoading: Bool { get }

// error
var showErrorView: ErrorModel? { get }
var showErrorAlert: ErrorModel? { get }
}

//MARK: State Properties
// content
@Published var isValidated: Bool = false

// default
@Published var isLoading: Bool = false

// error
@Published var showErrorView: ErrorModel?
@Published var showErrorAlert: ErrorModel?
}

extension DreamPartnerIntroModel: DreamPartnerIntroModel.Stateful {}

//MARK: - Actionable
protocol DreamPartnerIntroModelActionable: AnyObject {
// content
func setValidation(value: Bool)

// default
func setLoading(status: Bool)

// error
func showErrorView(error: ErrorModel)
func showErrorAlert(error: ErrorModel)
func resetError()
}

extension DreamPartnerIntroModel: DreamPartnerIntroModelActionable {
// content
func setValidation(value: Bool) {
isValidated = value
}

// default
func setLoading(status: Bool) {
isLoading = status
}

// error
func showErrorView(error: ErrorModel) {
showErrorView = error
}
func showErrorAlert(error: ErrorModel) {
showErrorAlert = error
}
func resetError() {
showErrorView = nil
showErrorAlert = nil
}
}
Loading
Loading