From dd90c80dd4ff524a6d62ae6c034cbd714fb77001 Mon Sep 17 00:00:00 2001 From: minhokim Date: Thu, 23 Jan 2025 21:41:45 +0900 Subject: [PATCH] =?UTF-8?q?[feat]=20#181=20=ED=82=A4=EC=9B=8C=EB=93=9C=20?= =?UTF-8?q?=EC=84=A4=EC=A0=95=20=EA=B8=B0=EB=8A=A5=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../PokitCategorySetting.swift | 2 +- .../Sources/PokitCategorySettingFeature.swift | 148 +++++++++++------- .../Sources/PokitCategorySettingView.swift | 14 +- 3 files changed, 105 insertions(+), 59 deletions(-) diff --git a/Projects/Domain/Sources/PokitCategorySetting/PokitCategorySetting.swift b/Projects/Domain/Sources/PokitCategorySetting/PokitCategorySetting.swift index 09b1fde1..5d24f29f 100644 --- a/Projects/Domain/Sources/PokitCategorySetting/PokitCategorySetting.swift +++ b/Projects/Domain/Sources/PokitCategorySetting/PokitCategorySetting.swift @@ -24,7 +24,7 @@ public struct PokitCategorySetting: Equatable { public var categoryImage: BaseCategoryImage? /// 카테고리 공개 여부(기본값: 공개) public var openType: BaseOpenType - /// 카테고리 키워드(기본값: default - 미선택) + /// 유저가 선택한 카테고리 키워드(기본값: default - 미선택) public var keywordType: BaseInterestType public init( diff --git a/Projects/Feature/FeatureCategorySetting/Sources/PokitCategorySettingFeature.swift b/Projects/Feature/FeatureCategorySetting/Sources/PokitCategorySettingFeature.swift index cc52653d..aa23fbfe 100644 --- a/Projects/Feature/FeatureCategorySetting/Sources/PokitCategorySettingFeature.swift +++ b/Projects/Feature/FeatureCategorySetting/Sources/PokitCategorySettingFeature.swift @@ -21,6 +21,8 @@ public struct PokitCategorySettingFeature { var pasteboard @Dependency(CategoryClient.self) var categoryClient + @Dependency(UserClient.self) + var userClient /// - State @ObservableState public struct State: Equatable { @@ -38,6 +40,11 @@ public struct PokitCategorySettingFeature { get { domain.imageList } } + var selectedKeywordType: BaseInterestType { + get { domain.keywordType } + set { domain.keywordType = newValue } + } + var isPublicType: Bool { get { domain.openType == .공개 ? true : false } set { domain.openType = newValue ? .공개 : .비공개 } @@ -45,7 +52,9 @@ public struct PokitCategorySettingFeature { let type: SettingType let shareType: ShareType + var keywordSelectType: KeywordSelectType = .normal var isProfileSheetPresented: Bool = false + var isKeywordSheetPresented: Bool = false var pokitNameTextInpuState: PokitInputStyle.State = .default @Shared(.inMemory("SelectCategory")) var categoryId: Int? /// - 포킷 수정 API / 추가 API @@ -89,6 +98,8 @@ public struct PokitCategorySettingFeature { case 저장_버튼_눌렀을때 case 뷰가_나타났을때 case 포킷명지우기_버튼_눌렀을때 + case 키워드_바텀시트_활성화(Bool) + case 키워드_선택_버튼_눌렀을때(BaseInterestType) } public enum InnerAction: Equatable { @@ -152,6 +163,12 @@ private extension PokitCategorySettingFeature { /// - View Effect func handleViewAction(_ action: Action.View, state: inout State) -> Effect { switch action { + case .binding(\.isPublicType): + if !state.isPublicType { + state.selectedKeywordType = .default + state.keywordSelectType = .normal + } + return .none case .binding: return .none @@ -163,66 +180,77 @@ private extension PokitCategorySettingFeature { return .none case .저장_버튼_눌렀을때: - return .run { [domain = state.domain, - type = state.type] send in - switch type { - case .추가: - guard let image = domain.categoryImage else { return } - let request = CategoryEditRequest( - categoryName: domain.categoryName, - categoryImageId: image.id, - openType: domain.openType.title, - keywordType: domain.keywordType.title - ) - let response = try await categoryClient.카테고리_생성(request) - let responseToCategoryDomain = BaseCategoryItem( - id: response.categoryId, - userId: 0, - categoryName: response.categoryName, - categoryImage: BaseCategoryImage( - imageId: response.categoryImage.imageId, - imageURL: response.categoryImage.imageUrl - ), - contentCount: 0, - createdAt: "", - //TODO: v2 property 수정 - openType: domain.openType, - keywordType: domain.keywordType, - userCount: 0 - ) - await send(.inner(.카테고리_인메모리_저장(responseToCategoryDomain))) - await send(.delegate(.settingSuccess)) - - case .수정: - guard let categoryId = domain.categoryId else { return } - guard let image = domain.categoryImage else { return } - let request = CategoryEditRequest( - categoryName: domain.categoryName, - categoryImageId: image.id, - openType: domain.openType.title, - keywordType: domain.keywordType.title - ) - let _ = try await categoryClient.카테고리_수정(categoryId, request) - await send(.delegate(.settingSuccess)) - - case .공유추가: - guard let categoryId = domain.categoryId else { return } - guard let image = domain.categoryImage else { return } - try await categoryClient.공유받은_카테고리_저장( - CopiedCategoryRequest( - originCategoryId: categoryId, + /// 전체공개 설정을 했는데 키워드 설정을 안했을 때 + if state.domain.openType == .공개 + && state.domain.keywordType == .default { + state.keywordSelectType = .warnning + return .none + } else { + return .run { [domain = state.domain, + type = state.type] send in + switch type { + case .추가: + guard let image = domain.categoryImage else { return } + let request = CategoryEditRequest( + categoryName: domain.categoryName, + categoryImageId: image.id, + openType: domain.openType.title, + keywordType: domain.keywordType.title + ) + let response = try await categoryClient.카테고리_생성(request) + let responseToCategoryDomain = BaseCategoryItem( + id: response.categoryId, + userId: 0, + categoryName: response.categoryName, + categoryImage: BaseCategoryImage( + imageId: response.categoryImage.imageId, + imageURL: response.categoryImage.imageUrl + ), + contentCount: 0, + createdAt: "", + //TODO: v2 property 수정 + openType: domain.openType, + keywordType: domain.keywordType, + userCount: 0 + ) + await send(.inner(.카테고리_인메모리_저장(responseToCategoryDomain))) + await send(.delegate(.settingSuccess)) + + case .수정: + guard let categoryId = domain.categoryId else { return } + guard let image = domain.categoryImage else { return } + let request = CategoryEditRequest( categoryName: domain.categoryName, - categoryImageId: image.id + categoryImageId: image.id, + openType: domain.openType.title, + keywordType: domain.keywordType.title ) - ) - await send(.delegate(.settingSuccess)) + let _ = try await categoryClient.카테고리_수정(categoryId, request) + await send(.delegate(.settingSuccess)) + + case .공유추가: + guard let categoryId = domain.categoryId else { return } + guard let image = domain.categoryImage else { return } + try await categoryClient.공유받은_카테고리_저장( + CopiedCategoryRequest( + originCategoryId: categoryId, + categoryName: domain.categoryName, + categoryImageId: image.id + ) + ) + await send(.delegate(.settingSuccess)) + } + } catch: { error, send in + guard let errorResponse = error as? ErrorResponse else { return } + await send(.inner(.포킷_오류_핸들링(BaseError(response: errorResponse)))) } - } catch: { error, send in - guard let errorResponse = error as? ErrorResponse else { return } - await send(.inner(.포킷_오류_핸들링(BaseError(response: errorResponse)))) } case .뷰가_나타났을때: + let selectType = state.selectedKeywordType + if selectType != .default { + state.keywordSelectType = .select(keywordName: selectType.title) + } /// 단순 조회API들의 나열이라 merge사용 return .merge( .send(.async(.프로필_목록_조회_API)), @@ -231,6 +259,18 @@ private extension PokitCategorySettingFeature { case .포킷명지우기_버튼_눌렀을때: state.domain.categoryName = "" return .none + + case let .키워드_바텀시트_활성화(isActive): + state.isKeywordSheetPresented = isActive + return .none + + //TODO: 액션 마이그레이션 시 반영 + case let .키워드_선택_버튼_눌렀을때(type): + state.domain.keywordType = type + state.keywordSelectType = .select(keywordName: type.title) + return .run { send in + await send(.view(.키워드_바텀시트_활성화(false))) + } } } diff --git a/Projects/Feature/FeatureCategorySetting/Sources/PokitCategorySettingView.swift b/Projects/Feature/FeatureCategorySetting/Sources/PokitCategorySettingView.swift index 0fcf97ba..025a3397 100644 --- a/Projects/Feature/FeatureCategorySetting/Sources/PokitCategorySettingView.swift +++ b/Projects/Feature/FeatureCategorySetting/Sources/PokitCategorySettingView.swift @@ -9,6 +9,7 @@ import SwiftUI import ComposableArchitecture import Domain import DSKit +import Util import NukeUI @ViewAction(for: PokitCategorySettingFeature.self) @@ -17,7 +18,6 @@ public struct PokitCategorySettingView: View { @Perception.Bindable public var store: StoreOf @FocusState private var isFocused: Bool - @State private var isOn = false /// - Initializer public init(store: StoreOf) { @@ -51,6 +51,12 @@ public extension PokitCategorySettingView { delegateSend: { store.send(.scope(.profile($0))) } ) } + .sheet(isPresented: $store.isKeywordSheetPresented) { + PokitKeywordBottomSheet( + selectedKeywordType: store.selectedKeywordType, + action: { send(.키워드_선택_버튼_눌렀을때($0)) } + ) + } .task { await send(.뷰가_나타났을때).finish() } } } @@ -170,7 +176,7 @@ private extension PokitCategorySettingView { Group { if store.isPublicType { VStack(alignment: .leading, spacing: 4) { - Button(action: {}) { + Button(action: { send(.키워드_바텀시트_활성화(true)) }) { Text("포킷 키워드") .pokitFont(.b1(.b)) .foregroundStyle(.pokit(.text(.primary))) @@ -178,9 +184,9 @@ private extension PokitCategorySettingView { Image(.icon(.arrowRight)) } .buttonStyle(.plain) - Text("추천을 위해 포킷 키워드를 선택해 주세요.") + Text(store.keywordSelectType.label) .pokitFont(.detail1) - .foregroundStyle(.pokit(.text(.tertiary))) + .foregroundStyle(store.keywordSelectType.fontColor) } .padding(.vertical, 12) .padding(.leading, 8)