diff --git a/PingPong/Projects/Core/Common/Sources/ViewModel/CommonViewViewModel.swift b/PingPong/Projects/Core/Common/Sources/ViewModel/CommonViewViewModel.swift index 78a20e38..60cd7dde 100644 --- a/PingPong/Projects/Core/Common/Sources/ViewModel/CommonViewViewModel.swift +++ b/PingPong/Projects/Core/Common/Sources/ViewModel/CommonViewViewModel.swift @@ -38,9 +38,9 @@ public class CommonViewViewModel: ObservableObject { print(selectedSource) } } - @Published public var selectedCharacter: [Flavor] = [] { + @Published public var selectedFlavor: [Flavor] = [] { didSet { - print(selectedCharacter) + print(selectedFlavor) } } @@ -107,11 +107,31 @@ public class CommonViewViewModel: ObservableObject { SearchOption(korean: "위인", english: "greatman", iconImageName: "", detail: "시간이 흘러도 바래지 않는 묵직한 명언"), SearchOption(korean: "유명인", english: "celeb", iconImageName: "", detail: "영향력있는 인물들의 인상적인 명언"), SearchOption(korean: "드라마/영화", english: "film", iconImageName: "", detail: "감성을 자극하는 감수성 풍부한 명언"), - SearchOption(korean: "애니메이션", english: "animation", iconImageName: "", detail: "순수함과 동심을 살려주는 따스한 명언"), + SearchOption(korean: "애니메이션", english: "anime", iconImageName: "", detail: "순수함과 동심을 살려주는 따스한 명언"), SearchOption(korean: "책", english: "book", iconImageName: "", detail: "정신적 성장을 도와주는 현명한 명언") ]), ] + @Published public var profileButtonInfoArray: [SearchViewButtonInfo] = [ + SearchViewButtonInfo(title: .source, options: [ + SearchOption(korean: "위인", english: "greatman", iconImageName: "", detail: "시간이 흘러도 바래지 않는 묵직한 명언"), + SearchOption(korean: "유명인", english: "celeb", iconImageName: "", detail: "영향력있는 인물들의 인상적인 명언"), + SearchOption(korean: "드라마/영화", english: "film", iconImageName: "", detail: "감성을 자극하는 감수성 풍부한 명언"), + SearchOption(korean: "애니메이션", english: "anime", iconImageName: "", detail: "순수함과 동심을 살려주는 따스한 명언"), + SearchOption(korean: "책", english: "book", iconImageName: "", detail: "정신적 성장을 도와주는 현명한 명언") + ]), + + 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: "지친 삶의 위로, 기쁨을 주는 명언") + ]), + + + ] + @Published public var homeBaseModel: BaseModel? var homeLikeCancellable: AnyCancellable? @@ -365,27 +385,30 @@ public class CommonViewViewModel: ObservableObject { } } - public func appendAndPopFavorite(favorite: Source) { + public func appendAndPopSource(source: Source) -> Bool { if selectedSource.count > 2 { selectedSource = [] } - guard self.selectedSource.count < 2 || self.selectedSource.contains(favorite) else { return } + guard self.selectedSource.count < 2 || self.selectedSource.contains(source) else { return false } - if self.selectedSource.contains(favorite) { - guard let index = self.selectedSource.firstIndex(of: favorite) else { return } + if self.selectedSource.contains(source) { + guard let index = self.selectedSource.firstIndex(of: source) else { return false } self.selectedSource.remove(at: index) } else { - self.selectedSource.append(favorite) + self.selectedSource.append(source) } + return true } - public func appendAndPopCharacter(character: Flavor, index: Int) { - guard self.selectedCharacter.count < 2 || self.selectedCharacter.contains(character) else { return } + public func appendAndPopFlavor(flavor: Flavor) -> Bool { + if selectedFlavor.count > 2 { selectedFlavor = [] } + guard self.selectedFlavor.count < 2 || self.selectedFlavor.contains(flavor) else { return false } - if self.selectedCharacter.contains(character) { - guard let arrayIndex = self.selectedCharacter.firstIndex(of: character) else { return } - self.selectedCharacter.remove(at: arrayIndex) + if self.selectedFlavor.contains(flavor) { + guard let index = self.selectedFlavor.firstIndex(of: flavor) else { return false } + self.selectedFlavor.remove(at: index) } else { - self.selectedCharacter.append(character) + self.selectedFlavor.append(flavor) } + return true } } 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 7859eb5f..35e1b688 100644 --- a/PingPong/Projects/Feature/Core/Sources/UI/View/TabView/CoreView.swift +++ b/PingPong/Projects/Feature/Core/Sources/UI/View/TabView/CoreView.swift @@ -32,6 +32,7 @@ public struct CoreView: View { NavigationStack { ZStack{ Color.basicGray1BG + .ignoresSafeArea() ZStack { VStack { if self.viewModel.selectedTab == .home { diff --git a/PingPong/Projects/Feature/Profile/Sources/UI/View/MainView/ProfileView.swift b/PingPong/Projects/Feature/Profile/Sources/UI/View/MainView/ProfileView.swift index 5dc33187..20dcca63 100644 --- a/PingPong/Projects/Feature/Profile/Sources/UI/View/MainView/ProfileView.swift +++ b/PingPong/Projects/Feature/Profile/Sources/UI/View/MainView/ProfileView.swift @@ -77,10 +77,10 @@ public struct ProfileView: View { await profileViewModel.randomNameRequest(commCdTpCd: .userDesc) } - await profileViewModel.profileUserPrefRequset(userid: "\(authViewModel.userid)", completion: { + await profileViewModel.profileUserPrefRequset(userid: "\(authViewModel.userid)", completion: {_ in for userFlavor in profileViewModel.profileUserPrefModel?.data?.flavors ?? [] { guard let flavor = Flavor(rawValue: userFlavor) else { continue } - viewModel.selectedCharacter.append(flavor) + viewModel.selectedFlavor.append(flavor) } for userSource in profileViewModel.profileUserPrefModel?.data?.sources ?? [] { print(userSource) @@ -239,9 +239,6 @@ public struct ProfileView: View { .foregroundColor(.basicGray8) .padding(EdgeInsets(top: 16, leading: 16, bottom: 12, trailing: 0)) Spacer() - Image(assetName: "editImage") - .frame(width: 24.62, height: 24) - .padding(.trailing, 16) } .frame(width: UIScreen.screenWidth - 40, height: 52) @@ -272,7 +269,7 @@ public struct ProfileView: View { ) .onTapGesture { withAnimation { - sheetManager.present(with: .init(idx: 1)) + sheetManager.present(with: .init(idx: 0)) sheetManager.isPopup = true } } @@ -302,7 +299,7 @@ public struct ProfileView: View { ) .onTapGesture { withAnimation { - sheetManager.present(with: .init(idx: 1)) + sheetManager.present(with: .init(idx: 0)) sheetManager.isPopup = true } } @@ -321,7 +318,7 @@ public struct ProfileView: View { Spacer() - if viewModel.selectedCharacter.count > 2 || viewModel.selectedCharacter.count == 0 { + if viewModel.selectedFlavor.count > 2 || viewModel.selectedFlavor.count == 0 { HStack{ HStack { Text("성향 전체") @@ -349,7 +346,7 @@ public struct ProfileView: View { } } else { - ForEach(viewModel.selectedCharacter, id: \.self) { character in + ForEach(viewModel.selectedFlavor, id: \.self) { character in HStack{ HStack { diff --git a/PingPong/Projects/Feature/Profile/Sources/UI/View/ModalModifier/ProfileModalView.swift b/PingPong/Projects/Feature/Profile/Sources/UI/View/ModalModifier/ProfileModalView.swift index f0a57e50..9dbc1e08 100644 --- a/PingPong/Projects/Feature/Profile/Sources/UI/View/ModalModifier/ProfileModalView.swift +++ b/PingPong/Projects/Feature/Profile/Sources/UI/View/ModalModifier/ProfileModalView.swift @@ -6,6 +6,7 @@ // Copyright © 2023 Wonji Suh. All rights reserved. // +import Authorization import Common import DesignSystem import Foundation @@ -17,7 +18,10 @@ public struct ProfileModalView: View { let config: SheetManager.Config let isPopup: Bool let defaultYoffset: CGFloat + let hashtagsTitleArray: [String] = ["유형", "성향"] + @StateObject var authViewModel: AuthorizationViewModel = AuthorizationViewModel() + let profileViewModel = ProfileViewViewModel() @StateObject private var viewModel: CommonViewViewModel @StateObject var exploreViewViewModel: ExploreViewModel = ExploreViewModel() @@ -44,7 +48,7 @@ public struct ProfileModalView: View { contents - filterBox(isButtonAble: viewModel.generateIsButtonAble(situationFlavorSourceTitle: viewModel.searchViewButtonInfoArray[config.idx].title)) + filterBox(isButtonAble: viewModel.generateIsButtonAble(situationFlavorSourceTitle: viewModel.profileButtonInfoArray[config.idx].title)) } .frame(maxWidth: .infinity, maxHeight: height) .padding(.horizontal, 24) @@ -72,6 +76,38 @@ public struct ProfileModalView: View { } } ) + .task { + await profileViewModel.profileUserPrefRequset(userid: String(authViewModel.userid)) { userInfo in + + + guard let flavors = userInfo.data?.flavors else { return } + if flavors.count > 2 + for stringFlavor in flavors { + guard let flavor = Flavor(rawValue: stringFlavor) else { continue } + let isToggle: Bool = viewModel.appendAndPopFlavor(flavor: flavor) + + guard let buttonInfo = viewModel.profileButtonInfoArray[config.idx].options.filter({ $0.english == stringFlavor }).first, + let idx = viewModel.profileButtonInfoArray[config.idx].options.firstIndex(of: buttonInfo) + else { continue } + if isToggle { + viewModel.profileButtonInfoArray[config.idx].options[idx].isCheck.toggle() + } + } + + guard let sources = userInfo.data?.sources else { return } + for stringSource in sources { + guard let source = Source(rawValue: stringSource) else { continue } + let isToggle: Bool = viewModel.appendAndPopSource(source: source) + + guard let buttonInfo = viewModel.profileButtonInfoArray[config.idx].options.filter({ $0.english == stringSource }).first, + let idx = viewModel.profileButtonInfoArray[config.idx].options.firstIndex(of: buttonInfo) + else { continue } + if isToggle { + viewModel.profileButtonInfoArray[config.idx].options[idx].isCheck.toggle() + } + } + } + } } } @@ -89,7 +125,7 @@ private extension ProfileModalView { private extension ProfileModalView { var headLine: some View { HStack { - Text("\(viewModel.searchViewButtonInfoArray[config.idx].title.rawValue)") + Text("\(viewModel.profileButtonInfoArray[config.idx].title.rawValue)") .pretendardFont(family: .SemiBold, size: 18) .foregroundColor(.cardTextMain) @@ -99,8 +135,8 @@ private extension ProfileModalView { .padding(.leading, 16) Spacer() Button(action: { - for idx in viewModel.searchViewButtonInfoArray[config.idx].options.indices { - viewModel.searchViewButtonInfoArray[config.idx].options[idx].isCheck = false + for idx in viewModel.profileButtonInfoArray[config.idx].options.indices { + viewModel.profileButtonInfoArray[config.idx].options[idx].isCheck = false } }) { @@ -113,14 +149,14 @@ private extension ProfileModalView { var contents: some View { VStack { - ForEach(viewModel.searchViewButtonInfoArray[config.idx].options.indices, id: \.self) { idx in - let option = viewModel.searchViewButtonInfoArray[config.idx].options[idx] + ForEach(viewModel.profileButtonInfoArray[config.idx].options.indices, id: \.self) { idx in + let option = viewModel.profileButtonInfoArray[config.idx].options[idx] let situationFlavorSource = SituationFlavorSource(rawValue: option.korean)! let colorSet = generateSituationFlavorSourceColor(situationFlavorSource: situationFlavorSource) RoundedRectangle(cornerRadius: 10) - .stroke(viewModel.searchViewButtonInfoArray[config.idx].options[idx].isCheck ? colorSet.iconBackground : .basicGray3, style: .init(lineWidth: 1)) + .stroke(viewModel.profileButtonInfoArray[config.idx].options[idx].isCheck ? colorSet.iconBackground : .basicGray3, style: .init(lineWidth: 1)) .frame(width: 336, height: 68) - .background(viewModel.searchViewButtonInfoArray[config.idx].options[idx].isCheck ? colorSet.background : .basicGray2) + .background(viewModel.profileButtonInfoArray[config.idx].options[idx].isCheck ? colorSet.background : .basicGray2) .overlay( HStack { Circle() @@ -132,13 +168,13 @@ private extension ProfileModalView { ) VStack { HStack { - Text(viewModel.searchViewButtonInfoArray[config.idx].options[idx].korean) + Text(viewModel.profileButtonInfoArray[config.idx].options[idx].korean) .pretendardFont(family: .Medium, size: 16) .foregroundColor(.basicGray8) Spacer() } HStack { - Text(viewModel.searchViewButtonInfoArray[config.idx].options[idx].detail) + Text(viewModel.profileButtonInfoArray[config.idx].options[idx].detail) .pretendardFont(family: .Medium, size: 12) .foregroundColor(.basicGray6) Spacer() @@ -146,11 +182,23 @@ private extension ProfileModalView { } Spacer() Button(action: { - viewModel.appendAndPopFavorite(favorite: .anime) - viewModel.searchViewButtonInfoArray[config.idx].options[idx].isCheck.toggle() + if config.idx == 0 { + guard let source = Source(rawValue: viewModel.profileButtonInfoArray[config.idx].options[idx].english) else { return } + let isToggle: Bool = viewModel.appendAndPopSource(source: source) + if isToggle { + viewModel.profileButtonInfoArray[config.idx].options[idx].isCheck.toggle() + } + } else if config.idx == 1 { + guard let flavor = Flavor(rawValue: viewModel.profileButtonInfoArray[config.idx].options[idx].english) else { return } + let isToggle: Bool = viewModel.appendAndPopFlavor(flavor: flavor) + if isToggle { + viewModel.profileButtonInfoArray[config.idx].options[idx].isCheck.toggle() + } + } + }) { - Image(systemName: viewModel.searchViewButtonInfoArray[config.idx].options[idx].isCheck ? "checkmark.circle.fill" : "checkmark.circle") - .foregroundColor(viewModel.searchViewButtonInfoArray[config.idx].options[idx].isCheck ? colorSet.iconBackground : .basicGray4) + Image(systemName: viewModel.profileButtonInfoArray[config.idx].options[idx].isCheck ? "checkmark.circle.fill" : "checkmark.circle") + .foregroundColor(viewModel.profileButtonInfoArray[config.idx].options[idx].isCheck ? colorSet.iconBackground : .basicGray4) .padding() } } @@ -178,33 +226,12 @@ private extension ProfileModalView { .frame(width: 336, height: 68) .foregroundColor(.primaryOrange) .overlay( - Text("필터 적용") + Text("\(hashtagsTitleArray[config.idx]) 설정 완료") .foregroundColor(.basicWhite) ) .onTapGesture { -// let moodParameter: [String] = viewModel.generateParameter(searchType: .situation) -// let flavorParameter: [String] = viewModel.generateParameter(searchType: .flavor) -// let sourceParameter: [String] = viewModel.generateParameter(searchType: .source) - -// Task { -// await exploreViewViewModel.searchRequest(keyword: viewModel.exploreViewSearchBarText, flavors: flavorParameter, sources: sourceParameter, mood: moodParameter, orderBy: "") { -// viewModel.searchedCards = [] -// -// for quoteContent in exploreViewViewModel.searchModel?.data?.content ?? [] { -// let hashTags = viewModel.getHashtags(post: quoteContent) -// let card = CardInfomation(qouteId: quoteContent.quoteID ?? .zero, -// hashtags: hashTags, image: "", -// title: quoteContent.content ?? "", -// sources: quoteContent.author ?? "", -// isBookrmark: quoteContent.likeID != nil, -// likeId: quoteContent.likeID -// ) -// viewModel.searchedCards.append(card) -// } -// } -// } -// -// didClose() +// 이부분이 설정완료 후 눌리는 탭입니다. + didClose() } } } diff --git a/PingPong/Projects/Feature/Profile/Sources/UI/View/ViewModel/ProfileViewViewModel.swift b/PingPong/Projects/Feature/Profile/Sources/UI/View/ViewModel/ProfileViewViewModel.swift index c25f38a0..5de82345 100644 --- a/PingPong/Projects/Feature/Profile/Sources/UI/View/ViewModel/ProfileViewViewModel.swift +++ b/PingPong/Projects/Feature/Profile/Sources/UI/View/ViewModel/ProfileViewViewModel.swift @@ -90,7 +90,7 @@ public class ProfileViewViewModel: ObservableObject { } - public func profileUserPrefRequset(userid: String, completion: @escaping () -> Void) async { + public func profileUserPrefRequset(userid: String, completion: @escaping (ProfileUserPrefModel) -> Void) async { if let cancellable = profileUserPrefCancellable { cancellable.cancel() } @@ -113,7 +113,7 @@ public class ProfileViewViewModel: ObservableObject { self?.profileUserPrefToViewModel(model) Log.network("회원정보 조회", model) self?.userPrefId = model.data?.userPrefID ?? .zero - completion() + completion(model) } else { self?.profileUserPrefToViewModel(model) Log.network("회원정보 조회", model)