diff --git a/PingPong/Projects/App/Sources/Application/PingPongApp.swift b/PingPong/Projects/App/Sources/Application/PingPongApp.swift index 7f52687c..232d7f88 100644 --- a/PingPong/Projects/App/Sources/Application/PingPongApp.swift +++ b/PingPong/Projects/App/Sources/Application/PingPongApp.swift @@ -29,8 +29,9 @@ struct PingPongProjectApp: App { WindowGroup { ZStack { - if viewModel.isLoginCheck { + if authViewModel.isLoginCheck { CoreView(viewModel: commonViewViewModel, isFistUserPOPUP: $commonViewViewModel.isFirstUserPOPUP) + .environmentObject(authViewModel) .environmentObject(sheetManager) .navigationBarHidden(true) .onAppear { diff --git a/PingPong/Projects/Core/Authorization/Sources/ViewModel/AuthorizationViewModel.swift b/PingPong/Projects/Core/Authorization/Sources/ViewModel/AuthorizationViewModel.swift index 4a62e025..7c15c71d 100644 --- a/PingPong/Projects/Core/Authorization/Sources/ViewModel/AuthorizationViewModel.swift +++ b/PingPong/Projects/Core/Authorization/Sources/ViewModel/AuthorizationViewModel.swift @@ -29,7 +29,12 @@ public class AuthorizationViewModel: ObservableObject { @AppStorage("Uid") public var uid: String = "" @AppStorage("userUid") public var userUid: String = "" @AppStorage("userEmail") public var userEmail: String = "" - + @Published public var isLoginCheck: Bool = false + @AppStorage("isLogin") public var isLogin: Bool = false { + didSet { + self.isLoginCheck = isLogin + } + } @Published public var loginStatus: Bool = false @Published var deleteUser: Bool = false @@ -49,6 +54,7 @@ public class AuthorizationViewModel: ObservableObject { @Published public var userRmk: String = "" public init() { + isLogin = UserDefaults.standard.bool(forKey: "isLogin") self.userSession = Auth.auth().currentUser uid = UserDefaults.standard.string(forKey: "Uid") ?? "" userid = UserDefaults.standard.integer(forKey: "userId") diff --git a/PingPong/Projects/Feature/Core/Sources/UI/View/TabView/CoreView.swift b/PingPong/Projects/Feature/Core/Sources/UI/View/TabView/CoreView.swift index 2cb05c90..6062e7a6 100644 --- a/PingPong/Projects/Feature/Core/Sources/UI/View/TabView/CoreView.swift +++ b/PingPong/Projects/Feature/Core/Sources/UI/View/TabView/CoreView.swift @@ -10,7 +10,7 @@ import SwiftUI import DesignSystem import PopupView import Archive -//import Authorization +import Authorization import Model import Home import Profile @@ -20,7 +20,7 @@ public struct CoreView: View { @StateObject var appState: AppState = AppState() @Environment(\.presentationMode) var presentationMode @Binding var isFistUserPOPUP: Bool - + @EnvironmentObject var authViewModel: AuthorizationViewModel @StateObject var viewModel: CommonViewViewModel public init(viewModel: CommonViewViewModel, isFistUserPOPUP: Binding) { @@ -70,7 +70,6 @@ public struct CoreView: View { } } .navigationBarHidden(true) - .ignoresSafeArea() .onAppear { self.viewModel.setupCustomTabs() } diff --git a/PingPong/Projects/Feature/OnBoarding/Sources/UI/View/MainView/OnBoardingView.swift b/PingPong/Projects/Feature/OnBoarding/Sources/UI/View/MainView/OnBoardingView.swift index 1ca7773c..59cb6f5a 100644 --- a/PingPong/Projects/Feature/OnBoarding/Sources/UI/View/MainView/OnBoardingView.swift +++ b/PingPong/Projects/Feature/OnBoarding/Sources/UI/View/MainView/OnBoardingView.swift @@ -43,12 +43,19 @@ public struct OnBoardingView: View { .environmentObject(viewModel) } +// .fullScreenCover(isPresented: $appState.goToMainHomeView, content: { +// CoreView(viewModel: commonViewViewModel, isFistUserPOPUP: $commonViewViewModel.isFirstUserPOPUP) +// .environmentObject(sheetManager) +// .navigationBarHidden(true) +// }) + .navigationDestination(isPresented: $appState.goToMainHomeView) { CoreView(viewModel: commonViewViewModel, isFistUserPOPUP: $commonViewViewModel.isFirstUserPOPUP) .environmentObject(sheetManager) - .navigationBarHidden(true) + .environmentObject(authViewModel) } } + .popup(isPresented: $appState.signUPFaillPOPUP) { FloaterPOPUP(image: .errorCircle_rounded, floaterTitle: "알림", floaterSubTitle: "애플로그인에 오류가 생겼습니다. 다시 시도해주세요") @@ -160,6 +167,7 @@ public struct OnBoardingView: View { DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { if viewModel.completdSignUP { appState.goToMainHomeView.toggle() + authViewModel.isLogin = true } else { if !viewModel.isFirstUser { appState.serviceUseAgmentView.toggle() diff --git a/PingPong/Projects/Feature/OnBoarding/Sources/UI/View/OnBoardingPushViiew/CompletOnBoardingView.swift b/PingPong/Projects/Feature/OnBoarding/Sources/UI/View/OnBoardingPushViiew/CompletOnBoardingView.swift index cf25cf7e..9f97d2f2 100644 --- a/PingPong/Projects/Feature/OnBoarding/Sources/UI/View/OnBoardingPushViiew/CompletOnBoardingView.swift +++ b/PingPong/Projects/Feature/OnBoarding/Sources/UI/View/OnBoardingPushViiew/CompletOnBoardingView.swift @@ -115,7 +115,7 @@ public struct CompletOnBoardingView: View { } .onTapGesture { //MARK: - 취향 등록 api 성공 후 mainview 로직 - viewModel.isLogin = true + authViewModel.isLogin = true viewModel.isFirstUser = true } } diff --git a/PingPong/Projects/Feature/OnBoarding/Sources/ViewModel/OnBoardingViewModel.swift b/PingPong/Projects/Feature/OnBoarding/Sources/ViewModel/OnBoardingViewModel.swift index 765d15e6..57f10937 100644 --- a/PingPong/Projects/Feature/OnBoarding/Sources/ViewModel/OnBoardingViewModel.swift +++ b/PingPong/Projects/Feature/OnBoarding/Sources/ViewModel/OnBoardingViewModel.swift @@ -61,12 +61,6 @@ public class OnBoardingViewModel: ObservableObject { @Published var selectedFavoriteFlavor: String = "" @Published var selectedFavorite: [Favorite] = [] @Published var selectedCharacter: [String] = [] - @Published public var isLoginCheck: Bool = false - @AppStorage("isLogin") public var isLogin: Bool = false { - didSet { - self.isLoginCheck = isLogin - } - } @AppStorage("isFirstUser") public var isFirstUser: Bool = false @AppStorage("completdSignUP") public var completdSignUP: Bool = false @AppStorage("isFirstUserPOPUP") public var isFirstUserPOPUP: Bool = false @@ -104,7 +98,6 @@ public class OnBoardingViewModel: ObservableObject { public init() { isFirstUserPOPUP = UserDefaults.standard.bool(forKey: "isFirstUserPOPUP") - isLogin = UserDefaults.standard.bool(forKey: "isLogin") isFirstUser = UserDefaults.standard.bool(forKey: "isFirstUser") completdSignUP = UserDefaults.standard.bool(forKey: "completdSignUP") } diff --git a/PingPong/Projects/Feature/Profile/Project.swift b/PingPong/Projects/Feature/Profile/Project.swift index d02c512a..7826eb10 100644 --- a/PingPong/Projects/Feature/Profile/Project.swift +++ b/PingPong/Projects/Feature/Profile/Project.swift @@ -11,6 +11,7 @@ product: .staticFramework, setting: .appBaseSetting, dependencies: [ .core(implements: .Common), + .core(implements: .Authorization), .design(implements: .DesignSystem), .domain(implements: .Model), .domain(implements: .Service) diff --git a/PingPong/Projects/Feature/Profile/Sources/UI/View/ProfileView.swift b/PingPong/Projects/Feature/Profile/Sources/UI/View/ProfileView.swift index 4ee02af5..6ef8f42b 100644 --- a/PingPong/Projects/Feature/Profile/Sources/UI/View/ProfileView.swift +++ b/PingPong/Projects/Feature/Profile/Sources/UI/View/ProfileView.swift @@ -9,12 +9,14 @@ import Common import DesignSystem import Model +import Authorization import SwiftUI public struct ProfileView: View { @StateObject private var appState: AppState @StateObject private var viewModel: CommonViewViewModel @StateObject private var profileViewModel: ProfileViewViewModel = ProfileViewViewModel() + @EnvironmentObject var authViewModel: AuthorizationViewModel @Environment(\.presentationMode) var presentationMode @@ -86,6 +88,9 @@ public struct ProfileView: View { .pretendardFont(family: .Medium, size: 14) .foregroundColor(.logoutText) } + .onTapGesture { + authViewModel.isLogin = false + } } .navigationBarHidden(true) diff --git a/PingPong/Projects/Feature/Profile/Sources/UI/ViewModel/ProfileViewViewModel.swift b/PingPong/Projects/Feature/Profile/Sources/UI/ViewModel/ProfileViewViewModel.swift index e3bb4665..b18e1c21 100644 --- a/PingPong/Projects/Feature/Profile/Sources/UI/ViewModel/ProfileViewViewModel.swift +++ b/PingPong/Projects/Feature/Profile/Sources/UI/ViewModel/ProfileViewViewModel.swift @@ -18,265 +18,9 @@ import DesignSystem public class ProfileViewViewModel: ObservableObject { - @Published var appState: ProfileAppState = ProfileAppState() - - //MARK: - 사용자 취향 코드 모델 - var onBoardingSearchUserCancellable: AnyCancellable? - @Published var onBoardingSearchUserModel: CommonCodeModel? - - var onBoardingRegisterFlavorCancellable: AnyCancellable? - @Published var onBoardingRegisterFlavor: OnBoardingRegisterFlavorModel? - - @Published var allAgreeCheckButton: Bool = false - @Published var checkTermsService: Bool = false - @Published var checkPesonalInformation: Bool = false - @Published var checkReciveMarketingInformation: Bool = false - @Published var allConfirmAgreeView: Bool = false - - @Published var isLoginJobSettingView: Bool = false - @Published var isLoginSettingView: Bool = false - @Published var isCompleteSignupView: Bool = false - - @Published var isStartChoiceFavoritedView: Bool = false - @Published var isSelectedCategory: Bool = false - @Published var isSkipSelectedCategory: Bool = false - @Published var isSkipSelectedFlavor: Bool = false - @Published var isSelectedCharacter: Bool = false - @Published public var inviteMainView: Bool = false - - - - @Published var goToFavoriteViseView: Bool = false - - - @Published var nickname: String = "" - - @Published var nicknameValidation: NicknameValidationType = .notValidated - @Published var validationText: String = " " - @Published var validationColor: Color = .basicGray4 - @Published var validationImageName: String? - @Published var selectedJob: String? = nil - @Published var selectJobCode: Int = .zero - @Published var selectedFavoriteCategory: String = "" - @Published var selectedFavoriteFlavor: String = "" - @Published var selectedFavorite: [Favorite] = [] - @Published var selectedCharacter: [String] = [] - @Published public var isLoginCheck: Bool = false - @AppStorage("isLogin") public var isLogin: Bool = false { - didSet { - self.isLoginCheck = isLogin - } - } - @AppStorage("isFirstUser") public var isFirstUser: Bool = false - @AppStorage("completdSignUP") public var completdSignUP: Bool = false - @AppStorage("isFirstUserPOPUP") public var isFirstUserPOPUP: Bool = false - - let unicodeArray: [Character] = CheckRegister.generateUnicodeArray() - - @Published var flavorArray: SearchViewButtonInfo = SearchViewButtonInfo(title: .flavor, options: [ - SearchOption(korean: "달콤한 맛", english: "sweet", iconImageName: "🍰", detail: "지친 삶의 위로, 기쁨을 주는 명언"), - SearchOption(korean: "짭잘한 맛", english: "salty", iconImageName: "😭", detail: "울컥하게 만드는 감동적인 명언"), - SearchOption(korean: "매콤한 맛", english: "spicy", iconImageName: "🔥", detail: "따끔한 조언의 자극적인 명언"), - SearchOption(korean: "고소한 맛", english:"nutty", iconImageName: "🥜", detail: "재치있고 유희적인 명언"), - SearchOption(korean: "담백한 맛", english: "light", iconImageName: "🥖", detail: "언제봐도 좋은 명언") - ]) - - - public func searchFlavorIndex(commNm: String) -> Int { - for index in flavorArray.options.indices { - if flavorArray.options[index].korean == commNm { - return index - } - } - return .zero - } - - - - var checkAgreementStatus: Bool { - return checkTermsService && checkPesonalInformation - } - - var checkAllAgreeStatus: Bool { - return checkTermsService && checkPesonalInformation && checkReciveMarketingInformation - } - - public init() { - isFirstUserPOPUP = UserDefaults.standard.bool(forKey: "isFirstUserPOPUP") - isLogin = UserDefaults.standard.bool(forKey: "isLogin") - isFirstUser = UserDefaults.standard.bool(forKey: "isFirstUser") - completdSignUP = UserDefaults.standard.bool(forKey: "completdSignUP") - } - //MARK: - 동의 하는 관련 함수 - func updateAgreementStatus() { - if !allAgreeCheckButton || !checkTermsService || !checkPesonalInformation || !checkReciveMarketingInformation { - allAgreeCheckButton = true - checkTermsService = true - checkPesonalInformation = true - checkReciveMarketingInformation = true - } else { - allAgreeCheckButton = false - checkTermsService = false - checkPesonalInformation = false - checkReciveMarketingInformation = false - } - }; - //MARK: - 닉네임 유효성 검증 - public func allValidateNikname(nicknameValidate: Bool, duplicateValidate: Bool){ - if !nicknameValidate { - self.nicknameValidation = .invalid - } else if !duplicateValidate { - self.nicknameValidation = .duplicate - } else { - self.nicknameValidation = .valid - } - - self.validationText = CheckRegister.generateValidationText(validation: self.nicknameValidation) - self.validationColor = CheckRegister.generateValidationColor(validation: self.nicknameValidation) - self.validationImageName = CheckRegister.generateValidationImage(validation: self.nicknameValidation) - } - - public func validateNickname(nickname: String) -> Bool { - if nickname.count < 1 || nickname.count > 12 { return false } - for character in nickname { - if !self.unicodeArray.contains(character) { return false } - } - return true - } - - //MARK: - 사용자 취향 관련한 명언 공통코드 맛/출처 조회 - public func onBoardingSearchUserToViewModel(_ list: CommonCodeModel) { - self.onBoardingSearchUserModel = list - } - - - public func onBoardingSearchUserRequest() { - if let cancellable = onBoardingSearchUserCancellable { - cancellable.cancel() - } - - let provider = MoyaProvider(plugins: [MoyaLoggingPlugin()]) - onBoardingSearchUserCancellable = provider.requestWithProgressPublisher(.searchUserPreferenceRegister) - .compactMap{ $0.response?.data} - .handleEvents(receiveSubscription: { _ in - self.appState.netWorkErrorPOP = true - }, receiveCompletion: { [weak self] result in - switch result { - case .finished: - self?.appState.netWorkErrorPOP = false - case .failure(let error): - self?.appState.errorMessage = error.localizedDescription - self?.appState.netWorkErrorPOP = true - } - self?.appState.netWorkErrorPOP = true - - }, receiveCancel: { - // Handle cancellation if needed - self.appState.netWorkErrorPOP = false - - }) - .receive(on: DispatchQueue.main) - .decode(type: CommonCodeModel.self, decoder: JSONDecoder()) - .sink(receiveCompletion: { [weak self] result in - switch result { - case .finished: - break - case .failure(let error): - self?.appState.errorMessage = error.localizedDescription - self?.appState.netWorkErrorPOP = true - } - }, receiveValue: { [weak self] model in - if model.status == NetworkCode.success.status { - self?.onBoardingSearchUserToViewModel(model) - print("사용자 취향 관련한 명언 공통코드 맛/출처 조회", model) - } else { - self?.onBoardingSearchUserToViewModel(model) - print("사용자 취향 관련한 명언 공통코드 맛/출처 조회", model) - self?.appState.netWorkErrorPOP = true - } - }) - } - - - - //MARK: favorite 관련 - func appendAndPopFavorite(favorite: Favorite) { - guard self.selectedFavorite.count < 2 || self.selectedFavorite.contains(favorite) else { return } - - if self.selectedFavorite.contains(favorite) { - guard let index = self.selectedFavorite.firstIndex(of: favorite) else { return } - self.selectedFavorite.remove(at: index) - } else { - self.selectedFavorite.append(favorite) - } - } - - func searchCharacterColor(flavor: Flavor) -> FlavorColor { - switch flavor { - case .sweet: return FlavorColor(icon: .sweetIconText, - iconBackground: .sweetIconBG, - background: .sweetBG) - case .light: return FlavorColor(icon: .mildIconText, - iconBackground: .mildIconBG, - background: .mildBG) - case .nutty: return FlavorColor(icon: .nuttyIconText, - iconBackground: .nuttyIconBG, - background: .nuttyBG) - case .salty: return FlavorColor(icon: .saltyIconText, - iconBackground: .saltyIconBG, - background: .saltyBG) - case .spicy: return FlavorColor(icon: .hotIconText, - iconBackground: .hotIconBG, - background: .hotBG) - } - } - - //MARK: favorite character 관련 - func appendAndPopCharacter(character: String, index: Int) { - guard self.selectedCharacter.count < 2 || self.selectedCharacter.contains(character) else { return } - if self.selectedCharacter.contains(character) { - guard let arrayIndex = self.selectedCharacter.firstIndex(of: character) else { return } - self.selectedCharacter.remove(at: arrayIndex) - self.flavorArray.options[index].isCheck = false - } else { - self.selectedCharacter.append(character) - self.flavorArray.options[index].isCheck = true - } - } - - - //MARK: - 취향 등록 - public func onBoardingRegisterToViewModel(_ list: OnBoardingRegisterFlavorModel) { - self.onBoardingRegisterFlavor = list } - public func onBoardingRegisterPost(userId: Int, flavors: [String], sources: [String], failOnBoardingRegsiterAction: @escaping () -> Void) { - if let cancellable = onBoardingRegisterFlavorCancellable { - cancellable.cancel() - } - let provider = MoyaProvider(plugins: [MoyaLoggingPlugin()]) - onBoardingRegisterFlavorCancellable = provider.requestWithProgressPublisher(.userPreferenceRegister(userId: userId, flavors: flavors, sources: sources)) - .compactMap {$0.response?.data} - .decode(type: OnBoardingRegisterFlavorModel.self, decoder: JSONDecoder()) - .sink(receiveCompletion: { [weak self] result in - switch result { - case .finished: - break - case .failure(let error): - print("네트워크 에러 ",error.localizedDescription) - } - }, receiveValue: { [weak self] model in - if model.status == NetworkCode.success.status { - self?.onBoardingRegisterToViewModel(model) - print("사용자 취향 등록 성공", model) - } else { - self?.onBoardingRegisterToViewModel(model) - print("사용자 취향 등록 실패", model) - failOnBoardingRegsiterAction() - } - }) - } }