From c7246d7db5f51086ad63a04322961fab6acb300a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=8F=84=ED=98=95?= <108233361+ShapeKim98@users.noreply.github.com> Date: Sat, 28 Sep 2024 19:47:55 +0900 Subject: [PATCH 1/8] =?UTF-8?q?[refactor]=20#129=20ContentSettingFeature?= =?UTF-8?q?=20=EC=95=A1=EC=85=98=20=ED=95=9C=EA=B8=80=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ContentSettingFeature.swift | 130 +++++++++--------- .../ContentSetting/ContentSettingView.swift | 12 +- 2 files changed, 71 insertions(+), 71 deletions(-) diff --git a/Projects/Feature/FeatureContentSetting/Sources/ContentSetting/ContentSettingFeature.swift b/Projects/Feature/FeatureContentSetting/Sources/ContentSetting/ContentSettingFeature.swift index d18d28ee..2a80f5c0 100644 --- a/Projects/Feature/FeatureContentSetting/Sources/ContentSetting/ContentSettingFeature.swift +++ b/Projects/Feature/FeatureContentSetting/Sources/ContentSetting/ContentSettingFeature.swift @@ -87,36 +87,36 @@ public struct ContentSettingFeature { /// - Binding case binding(BindingAction) /// - Button Tapped - case pokitSelectButtonTapped - case pokitSelectItemButtonTapped(pokit: BaseCategoryItem) - case contentSettingViewOnAppeared - case saveBottomButtonTapped - case addPokitButtonTapped - case linkCopyButtonTapped + case 포킷선택_버튼_눌렀을때 + case 포킷선택_항목_눌렀을때(pokit: BaseCategoryItem) + case 뷰가_나타났을때 + case 저장_버튼_눌렀을때 + case 포킷추가_버튼_눌렀을때 + case 링크복사_버튼_눌렀을때 - case dismiss + case 뒤로가기_버튼_눌렀을때 } public enum InnerAction: Equatable { - case fetchMetadata(url: URL) - case parsingInfo(title: String?, imageURL: String?) - case parsingURL - case showPopup - case showLinkPopup(URL?) - case updateURLText(String?) - case 컨텐츠_갱신(content: BaseContentDetail) - case 카테고리_갱신(category: BaseCategory) - case 카테고리_목록_갱신(categoryList: BaseCategoryListInquiry) - case 링크미리보기_presented + case maxCategoryPopup + case linkPopup(URL?) + case 메타데이터_조회_수행(url: URL) + case 메타데이텨_조회_반영(title: String?, imageURL: String?) + case URL_유효성_확인 + case 링크복사_반영(String?) + case 컨텐츠_상세_조회_API_반영(content: BaseContentDetail) + case 카테고리_상세_조회_API_반영(category: BaseCategory) + case 카테고리_목록_조회_API_반영(categoryList: BaseCategoryListInquiry) + case linkPreview case 선택한_포킷_인메모리_삭제 } public enum AsyncAction: Equatable { - case 컨텐츠_상세_조회(id: Int) - case 카테고리_상세_조회(id: Int?, sharedId: Int?) - case 카테고리_목록_조회 - case 컨텐츠_수정 - case 컨텐츠_추가 + case 컨텐츠_상세_조회_API(id: Int) + case 카테고리_상세_조회_API(id: Int?, sharedId: Int?) + case 카테고리_목록_조회_API + case 컨텐츠_수정_API + case 컨텐츠_추가_API } public enum ScopeAction: Equatable { case doNothing } @@ -169,7 +169,7 @@ private extension ContentSettingFeature { case .binding(\.urlText): enum CancelID { case urlTextChanged } return .run { send in - await send(.inner(.parsingURL)) + await send(.inner(.URL_유효성_확인)) } /// - 1초마다 `urlText`변화의 마지막을 감지하여 이벤트 방출 .throttle( @@ -180,59 +180,59 @@ private extension ContentSettingFeature { ) case .binding: return .none - case .pokitSelectButtonTapped: - return .send(.async(.카테고리_목록_조회)) - case .pokitSelectItemButtonTapped(pokit: let pokit): + case .포킷선택_버튼_눌렀을때: + return .send(.async(.카테고리_목록_조회_API)) + case .포킷선택_항목_눌렀을때(pokit: let pokit): state.selectedPokit = pokit return .none - case .contentSettingViewOnAppeared: + case .뷰가_나타났을때: return .run { [id = state.domain.contentId] send in if let id { - await send(.async(.컨텐츠_상세_조회(id: id))) + await send(.async(.컨텐츠_상세_조회_API(id: id))) } - await send(.async(.카테고리_목록_조회)) - await send(.inner(.parsingURL)) + await send(.async(.카테고리_목록_조회_API)) + await send(.inner(.URL_유효성_확인)) for await _ in self.pasteboard.changes() { let url = try await pasteboard.probableWebURL() - await send(.inner(.showLinkPopup(url)), animation: .pokitSpring) + await send(.inner(.linkPopup(url)), animation: .pokitSpring) } } - case .saveBottomButtonTapped: + case .저장_버튼_눌렀을때: return .run { [isEdit = state.domain.categoryId != nil] send in if isEdit { - await send(.async(.컨텐츠_수정)) + await send(.async(.컨텐츠_수정_API)) } else { - await send(.async(.컨텐츠_추가)) + await send(.async(.컨텐츠_추가_API)) } } - case .addPokitButtonTapped: + case .포킷추가_버튼_눌렀을때: guard state.domain.categoryTotalCount < 30 else { /// 🚨 Error Case [1]: 포킷 갯수가 30개 이상일 경우 - return .send(.inner(.showPopup), animation: .pokitSpring) + return .send(.inner(.maxCategoryPopup), animation: .pokitSpring) } return .send(.delegate(.포킷추가하기)) - case .dismiss: + case .뒤로가기_버튼_눌렀을때: return .run { _ in await dismiss() } - case .linkCopyButtonTapped: - return .send(.inner(.updateURLText(state.link))) + case .링크복사_버튼_눌렀을때: + return .send(.inner(.링크복사_반영(state.link))) } } /// - Inner Effect func handleInnerAction(_ action: Action.InnerAction, state: inout State) -> Effect { switch action { - case .fetchMetadata(url: let url): + case .메타데이터_조회_수행(url: let url): return .run { send in let (title, imageURL) = await swiftSoup.parseOGTitleAndImage(url) { - await send(.inner(.링크미리보기_presented), animation: .pokitDissolve) + await send(.inner(.linkPreview), animation: .pokitDissolve) } await send( - .inner(.parsingInfo(title: title, imageURL: imageURL)), + .inner(.메타데이텨_조회_반영(title: title, imageURL: imageURL)), animation: .pokitDissolve ) } - case let .parsingInfo(title: title, imageURL: imageURL): + case let .메타데이텨_조회_반영(title: title, imageURL: imageURL): state.linkTitle = title state.linkImageURL = imageURL if let title, state.domain.title.isEmpty { @@ -240,7 +240,7 @@ private extension ContentSettingFeature { } state.domain.thumbNail = imageURL return .none - case .parsingURL: + case .URL_유효성_확인: guard let url = URL(string: state.domain.data), !state.domain.data.isEmpty else { /// 🚨 Error Case [1]: 올바른 링크가 아닐 때 @@ -251,17 +251,17 @@ private extension ContentSettingFeature { state.domain.thumbNail = nil return .none } - return .send(.inner(.fetchMetadata(url: url)), animation: .pokitDissolve) - case .showPopup: + return .send(.inner(.메타데이터_조회_수행(url: url)), animation: .pokitDissolve) + case .maxCategoryPopup: state.showMaxCategoryPopup = true return .none - case .updateURLText(let urlText): + case .링크복사_반영(let urlText): state.showDetectedURLPopup = false state.link = nil guard let urlText else { return .none } state.domain.data = urlText - return .send(.inner(.parsingURL)) - case .컨텐츠_갱신(content: let content): + return .send(.inner(.URL_유효성_확인)) + case .컨텐츠_상세_조회_API_반영(content: let content): state.domain.content = content state.domain.data = content.data state.domain.contentId = content.id @@ -274,10 +274,10 @@ private extension ContentSettingFeature { id = content.category.categoryId, sharedCategoryId = state.categoryId ] send in - await send(.inner(.parsingURL)) - await send(.async(.카테고리_상세_조회(id: id, sharedId: sharedCategoryId))) + await send(.inner(.URL_유효성_확인)) + await send(.async(.카테고리_상세_조회_API(id: id, sharedId: sharedCategoryId))) } - case .카테고리_갱신(category: let category): + case .카테고리_상세_조회_API_반영(category: let category): state.selectedPokit = BaseCategoryItem( id: category.categoryId, userId: 0, @@ -287,7 +287,7 @@ private extension ContentSettingFeature { createdAt: "" ) return .none - case .카테고리_목록_갱신(categoryList: let categoryList): + case .카테고리_목록_조회_API_반영(categoryList: let categoryList): /// - `카테고리_목록_조회`의 filter 옵션을 `false`로 해두었기 때문에 `미분류` 카테고리 또한 항목에서 조회가 가능함 /// [1]. `미분류`에 해당하는 인덱스 번호와 항목을 체크, 없다면 목록갱신이 불가함 @@ -307,12 +307,12 @@ private extension ContentSettingFeature { state.selectedPokit = unclassifiedItem } return .none - case let .showLinkPopup(url): + case let .linkPopup(url): guard let url else { return .none } state.link = url.absoluteString state.showDetectedURLPopup = true return .none - case .링크미리보기_presented: + case .linkPreview: state.showLinkPreview = true return .none @@ -325,24 +325,24 @@ private extension ContentSettingFeature { /// - Async Effect func handleAsyncAction(_ action: Action.AsyncAction, state: inout State) -> Effect { switch action { - case .컨텐츠_상세_조회(id: let id): + case .컨텐츠_상세_조회_API(id: let id): state.contentLoading = true return .run { [id] send in let content = try await contentClient.컨텐츠_상세_조회("\(id)").toDomain() - await send(.inner(.컨텐츠_갱신(content: content))) + await send(.inner(.컨텐츠_상세_조회_API_반영(content: content))) } - case let .카테고리_상세_조회(id, sharedId): + case let .카테고리_상세_조회_API(id, sharedId): return .run { send in if let sharedId { let category = try await categoryClient.카테고리_상세_조회("\(sharedId)").toDomain() - await send(.inner(.카테고리_갱신(category: category))) + await send(.inner(.카테고리_상세_조회_API_반영(category: category))) } else if let id { let category = try await categoryClient.카테고리_상세_조회("\(id)").toDomain() - await send(.inner(.카테고리_갱신(category: category))) + await send(.inner(.카테고리_상세_조회_API_반영(category: category))) } } - case .카테고리_목록_조회: + case .카테고리_목록_조회_API: return .run { [ pageable = state.domain.pageable, id = state.domain.categoryId, @@ -357,10 +357,10 @@ private extension ContentSettingFeature { false ).toDomain() - await send(.async(.카테고리_상세_조회(id: id, sharedId: sharedId))) - await send(.inner(.카테고리_목록_갱신(categoryList: categoryList)), animation: .pokitDissolve) + await send(.async(.카테고리_상세_조회_API(id: id, sharedId: sharedId))) + await send(.inner(.카테고리_목록_조회_API_반영(categoryList: categoryList)), animation: .pokitDissolve) } - case .컨텐츠_수정: + case .컨텐츠_수정_API: guard let contentId = state.domain.contentId else { return .none } @@ -390,7 +390,7 @@ private extension ContentSettingFeature { await send(.inner(.선택한_포킷_인메모리_삭제)) await send(.delegate(.저장하기_완료)) } - case .컨텐츠_추가: + case .컨텐츠_추가_API: guard let categoryId = state.selectedPokit?.id else { return .none } diff --git a/Projects/Feature/FeatureContentSetting/Sources/ContentSetting/ContentSettingView.swift b/Projects/Feature/FeatureContentSetting/Sources/ContentSetting/ContentSettingView.swift index 705d33b0..37e2cb54 100644 --- a/Projects/Feature/FeatureContentSetting/Sources/ContentSetting/ContentSettingView.swift +++ b/Projects/Feature/FeatureContentSetting/Sources/ContentSetting/ContentSettingView.swift @@ -61,7 +61,7 @@ public extension ContentSettingView { "복사한 링크 저장하기", isPresented: $store.showDetectedURLPopup, type: .link(url: store.link ?? ""), - action: { send(.linkCopyButtonTapped, animation: .pokitSpring) } + action: { send(.링크복사_버튼_눌렀을때, animation: .pokitSpring) } ) } } @@ -74,14 +74,14 @@ public extension ContentSettingView { "저장하기", state: isDisable ? .disable : .filled(.primary), isLoading: $store.saveIsLoading, - action: { send(.saveBottomButtonTapped) } + action: { send(.저장_버튼_눌렀을때) } ) .padding(.horizontal, 20) .pokitMaxWidth() } .pokitNavigationBar { navigationBar } .ignoresSafeArea(edges: focusedType == nil ? .bottom : []) - .onAppear { send(.contentSettingViewOnAppeared) } + .onAppear { send(.뷰가_나타났을때) } } } } @@ -91,7 +91,7 @@ private extension ContentSettingView { PokitHeader(title: store.content == nil ? "링크 추가" : "링크 수정") { PokitHeaderItems(placement: .leading) { PokitToolbarButton(.icon(.arrowLeft)) { - send(.dismiss) + send(.뒤로가기_버튼_눌렀을때) } } } @@ -134,7 +134,7 @@ private extension ContentSettingView { selectedItem: $store.selectedPokit, label: "포킷", list: store.pokitList, - action: { send(.pokitSelectItemButtonTapped(pokit: $0), animation: .pokitDissolve) } + action: { send(.포킷선택_항목_눌렀을때(pokit: $0), animation: .pokitDissolve) } ) } @@ -144,7 +144,7 @@ private extension ContentSettingView { state: .filled(.primary), size: .large, shape: .rectangle - ) { send(.addPokitButtonTapped, animation: .pokitSpring) } + ) { send(.포킷추가_버튼_눌렀을때, animation: .pokitSpring) } } var memoTextArea: some View { From be57baf0e2821a3a4ec0e3d6fc2a92c787d17c53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=8F=84=ED=98=95?= <108233361+ShapeKim98@users.noreply.github.com> Date: Sat, 28 Sep 2024 19:55:04 +0900 Subject: [PATCH 2/8] =?UTF-8?q?[refactor]=20=EB=B6=88=ED=95=84=EC=9A=94?= =?UTF-8?q?=ED=95=9C=20=EC=95=A1=EC=85=98=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ContentSettingFeature.swift | 27 ++++++++----------- .../ContentSetting/ContentSettingView.swift | 1 + 2 files changed, 12 insertions(+), 16 deletions(-) diff --git a/Projects/Feature/FeatureContentSetting/Sources/ContentSetting/ContentSettingFeature.swift b/Projects/Feature/FeatureContentSetting/Sources/ContentSetting/ContentSettingFeature.swift index 2a80f5c0..a497bf18 100644 --- a/Projects/Feature/FeatureContentSetting/Sources/ContentSetting/ContentSettingFeature.swift +++ b/Projects/Feature/FeatureContentSetting/Sources/ContentSetting/ContentSettingFeature.swift @@ -98,7 +98,6 @@ public struct ContentSettingFeature { } public enum InnerAction: Equatable { - case maxCategoryPopup case linkPopup(URL?) case 메타데이터_조회_수행(url: URL) case 메타데이텨_조회_반영(title: String?, imageURL: String?) @@ -208,10 +207,11 @@ private extension ContentSettingFeature { case .포킷추가_버튼_눌렀을때: guard state.domain.categoryTotalCount < 30 else { /// 🚨 Error Case [1]: 포킷 갯수가 30개 이상일 경우 - return .send(.inner(.maxCategoryPopup), animation: .pokitSpring) + state.showMaxCategoryPopup = true + return .none } + return .send(.delegate(.포킷추가하기)) - case .뒤로가기_버튼_눌렀을때: return .run { _ in await dismiss() } case .링크복사_버튼_눌렀을때: @@ -222,6 +222,14 @@ private extension ContentSettingFeature { /// - Inner Effect func handleInnerAction(_ action: Action.InnerAction, state: inout State) -> Effect { switch action { + case let .linkPopup(url): + guard let url else { return .none } + state.link = url.absoluteString + state.showDetectedURLPopup = true + return .none + case .linkPreview: + state.showLinkPreview = true + return .none case .메타데이터_조회_수행(url: let url): return .run { send in let (title, imageURL) = await swiftSoup.parseOGTitleAndImage(url) { @@ -252,9 +260,6 @@ private extension ContentSettingFeature { return .none } return .send(.inner(.메타데이터_조회_수행(url: url)), animation: .pokitDissolve) - case .maxCategoryPopup: - state.showMaxCategoryPopup = true - return .none case .링크복사_반영(let urlText): state.showDetectedURLPopup = false state.link = nil @@ -307,15 +312,6 @@ private extension ContentSettingFeature { state.selectedPokit = unclassifiedItem } return .none - case let .linkPopup(url): - guard let url else { return .none } - state.link = url.absoluteString - state.showDetectedURLPopup = true - return .none - case .linkPreview: - state.showLinkPreview = true - return .none - case .선택한_포킷_인메모리_삭제: state.selectedPokit = nil return .none @@ -340,7 +336,6 @@ private extension ContentSettingFeature { let category = try await categoryClient.카테고리_상세_조회("\(id)").toDomain() await send(.inner(.카테고리_상세_조회_API_반영(category: category))) } - } case .카테고리_목록_조회_API: return .run { [ diff --git a/Projects/Feature/FeatureContentSetting/Sources/ContentSetting/ContentSettingView.swift b/Projects/Feature/FeatureContentSetting/Sources/ContentSetting/ContentSettingView.swift index 37e2cb54..c182f394 100644 --- a/Projects/Feature/FeatureContentSetting/Sources/ContentSetting/ContentSettingView.swift +++ b/Projects/Feature/FeatureContentSetting/Sources/ContentSetting/ContentSettingView.swift @@ -56,6 +56,7 @@ public extension ContentSettingView { isPresented: $store.showMaxCategoryPopup, type: .text ) + .animation(.pokitSpring, value: store.showMaxCategoryPopup) } else if store.state.showDetectedURLPopup { PokitLinkPopup( "복사한 링크 저장하기", From e48d5a907857a67dd6648b93ce9ffb7a18e9d3df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=8F=84=ED=98=95?= <108233361+ShapeKim98@users.noreply.github.com> Date: Sat, 28 Sep 2024 19:58:08 +0900 Subject: [PATCH 3/8] =?UTF-8?q?[refactor]=20#129=20=EB=B6=88=ED=95=84?= =?UTF-8?q?=EC=9A=94=ED=95=9C=20=ED=81=B4=EB=A1=9C=EC=A0=80=20=EC=BA=A1?= =?UTF-8?q?=EC=B2=98=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Sources/ContentSetting/ContentSettingFeature.swift | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/Projects/Feature/FeatureContentSetting/Sources/ContentSetting/ContentSettingFeature.swift b/Projects/Feature/FeatureContentSetting/Sources/ContentSetting/ContentSettingFeature.swift index a497bf18..7a171c7d 100644 --- a/Projects/Feature/FeatureContentSetting/Sources/ContentSetting/ContentSettingFeature.swift +++ b/Projects/Feature/FeatureContentSetting/Sources/ContentSetting/ContentSettingFeature.swift @@ -99,6 +99,7 @@ public struct ContentSettingFeature { public enum InnerAction: Equatable { case linkPopup(URL?) + case linkPreview case 메타데이터_조회_수행(url: URL) case 메타데이텨_조회_반영(title: String?, imageURL: String?) case URL_유효성_확인 @@ -106,7 +107,6 @@ public struct ContentSettingFeature { case 컨텐츠_상세_조회_API_반영(content: BaseContentDetail) case 카테고리_상세_조회_API_반영(category: BaseCategory) case 카테고리_목록_조회_API_반영(categoryList: BaseCategoryListInquiry) - case linkPreview case 선택한_포킷_인메모리_삭제 } @@ -323,7 +323,7 @@ private extension ContentSettingFeature { switch action { case .컨텐츠_상세_조회_API(id: let id): state.contentLoading = true - return .run { [id] send in + return .run { send in let content = try await contentClient.컨텐츠_상세_조회("\(id)").toDomain() await send(.inner(.컨텐츠_상세_조회_API_반영(content: content))) } @@ -363,16 +363,14 @@ private extension ContentSettingFeature { return .none } return .run { [ - id = contentId, data = state.domain.data, title = state.domain.title, - categoryId = categoryId, memo = state.domain.memo, alertYn = state.domain.alertYn, thumbNail = state.domain.thumbNail ] send in let _ = try await contentClient.컨텐츠_수정( - "\(id)", + "\(contentId)", ContentBaseRequest( data: data, title: title, @@ -393,7 +391,6 @@ private extension ContentSettingFeature { return .run { [ data = state.domain.data, title = state.domain.title, - categoryId = categoryId, memo = state.domain.memo, alertYn = state.domain.alertYn, thumbNail = state.domain.thumbNail From 7123f5cc67972d2191c725fa66b459e1bc10f779 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=8F=84=ED=98=95?= <108233361+ShapeKim98@users.noreply.github.com> Date: Sat, 28 Sep 2024 20:10:57 +0900 Subject: [PATCH 4/8] =?UTF-8?q?[refactor]=20#129=20=EC=BD=94=EB=93=9C=20?= =?UTF-8?q?=EC=A0=95=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ContentSettingFeature.swift | 72 ++++++++----------- 1 file changed, 28 insertions(+), 44 deletions(-) diff --git a/Projects/Feature/FeatureContentSetting/Sources/ContentSetting/ContentSettingFeature.swift b/Projects/Feature/FeatureContentSetting/Sources/ContentSetting/ContentSettingFeature.swift index 7a171c7d..1fa38b84 100644 --- a/Projects/Feature/FeatureContentSetting/Sources/ContentSetting/ContentSettingFeature.swift +++ b/Projects/Feature/FeatureContentSetting/Sources/ContentSetting/ContentSettingFeature.swift @@ -171,11 +171,10 @@ private extension ContentSettingFeature { await send(.inner(.URL_유효성_확인)) } /// - 1초마다 `urlText`변화의 마지막을 감지하여 이벤트 방출 - .throttle( + .debounce( id: CancelID.urlTextChanged, for: 1, - scheduler: DispatchQueue.main, - latest: true + scheduler: DispatchQueue.main ) case .binding: return .none @@ -339,46 +338,37 @@ private extension ContentSettingFeature { } case .카테고리_목록_조회_API: return .run { [ - pageable = state.domain.pageable, + request = BasePageableRequest( + page: state.domain.pageable.page, + size: 30, + sort: state.domain.pageable.sort + ), id = state.domain.categoryId, sharedId = state.categoryId ] send in - let categoryList = try await categoryClient.카테고리_목록_조회( - BasePageableRequest( - page: pageable.page, - size: 100, - sort: pageable.sort - ), - false - ).toDomain() + let categoryList = try await categoryClient.카테고리_목록_조회(request, false).toDomain() await send(.async(.카테고리_상세_조회_API(id: id, sharedId: sharedId))) await send(.inner(.카테고리_목록_조회_API_반영(categoryList: categoryList)), animation: .pokitDissolve) } case .컨텐츠_수정_API: - guard let contentId = state.domain.contentId else { - return .none - } - guard let categoryId = state.selectedPokit?.id else { + guard let contentId = state.domain.contentId, + let categoryId = state.selectedPokit?.id else { return .none } return .run { [ - data = state.domain.data, - title = state.domain.title, - memo = state.domain.memo, - alertYn = state.domain.alertYn, - thumbNail = state.domain.thumbNail + request = ContentBaseRequest( + data: state.domain.data, + title: state.domain.title, + categoryId: categoryId, + memo: state.domain.memo, + alertYn: state.domain.alertYn.rawValue, + thumbNail: state.domain.thumbNail + ) ] send in let _ = try await contentClient.컨텐츠_수정( "\(contentId)", - ContentBaseRequest( - data: data, - title: title, - categoryId: categoryId, - memo: memo, - alertYn: alertYn.rawValue, - thumbNail: thumbNail - ) + request ) await send(.inner(.선택한_포킷_인메모리_삭제)) await send(.delegate(.저장하기_완료)) @@ -389,22 +379,16 @@ private extension ContentSettingFeature { } return .run { [ - data = state.domain.data, - title = state.domain.title, - memo = state.domain.memo, - alertYn = state.domain.alertYn, - thumbNail = state.domain.thumbNail - ] send in - let _ = try await contentClient.컨텐츠_추가( - ContentBaseRequest( - data: data, - title: title, - categoryId: categoryId, - memo: memo, - alertYn: alertYn.rawValue, - thumbNail: thumbNail - ) + request = ContentBaseRequest( + data: state.domain.data, + title: state.domain.title, + categoryId: categoryId, + memo: state.domain.memo, + alertYn: state.domain.alertYn.rawValue, + thumbNail: state.domain.thumbNail ) + ] send in + let _ = try await contentClient.컨텐츠_추가(request) await send(.inner(.선택한_포킷_인메모리_삭제)) await send(.delegate(.저장하기_완료)) } From dbd1bfbfbdff6c20b04553182d40be7d094699a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=8F=84=ED=98=95?= <108233361+ShapeKim98@users.noreply.github.com> Date: Sat, 28 Sep 2024 20:14:35 +0900 Subject: [PATCH 5/8] =?UTF-8?q?[refactor]=20#129=20=EB=B6=88=ED=95=84?= =?UTF-8?q?=EC=9A=94=ED=95=9C=20=ED=81=B4=EB=A1=9C=EC=A0=80=20=EC=BA=A1?= =?UTF-8?q?=EC=B3=90=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ContentSettingFeature.swift | 51 +++++++++---------- 1 file changed, 24 insertions(+), 27 deletions(-) diff --git a/Projects/Feature/FeatureContentSetting/Sources/ContentSetting/ContentSettingFeature.swift b/Projects/Feature/FeatureContentSetting/Sources/ContentSetting/ContentSettingFeature.swift index 1fa38b84..0e41ccce 100644 --- a/Projects/Feature/FeatureContentSetting/Sources/ContentSetting/ContentSettingFeature.swift +++ b/Projects/Feature/FeatureContentSetting/Sources/ContentSetting/ContentSettingFeature.swift @@ -274,8 +274,8 @@ private extension ContentSettingFeature { state.domain.memo = content.memo state.domain.alertYn = content.alertYn state.contentLoading = false + let id = content.category.categoryId return .run { [ - id = content.category.categoryId, sharedCategoryId = state.categoryId ] send in await send(.inner(.URL_유효성_확인)) @@ -337,12 +337,12 @@ private extension ContentSettingFeature { } } case .카테고리_목록_조회_API: + let request = BasePageableRequest( + page: state.domain.pageable.page, + size: 30, + sort: state.domain.pageable.sort + ) return .run { [ - request = BasePageableRequest( - page: state.domain.pageable.page, - size: 30, - sort: state.domain.pageable.sort - ), id = state.domain.categoryId, sharedId = state.categoryId ] send in @@ -356,16 +356,15 @@ private extension ContentSettingFeature { let categoryId = state.selectedPokit?.id else { return .none } - return .run { [ - request = ContentBaseRequest( - data: state.domain.data, - title: state.domain.title, - categoryId: categoryId, - memo: state.domain.memo, - alertYn: state.domain.alertYn.rawValue, - thumbNail: state.domain.thumbNail - ) - ] send in + let request = ContentBaseRequest( + data: state.domain.data, + title: state.domain.title, + categoryId: categoryId, + memo: state.domain.memo, + alertYn: state.domain.alertYn.rawValue, + thumbNail: state.domain.thumbNail + ) + return .run { send in let _ = try await contentClient.컨텐츠_수정( "\(contentId)", request @@ -377,17 +376,15 @@ private extension ContentSettingFeature { guard let categoryId = state.selectedPokit?.id else { return .none } - - return .run { [ - request = ContentBaseRequest( - data: state.domain.data, - title: state.domain.title, - categoryId: categoryId, - memo: state.domain.memo, - alertYn: state.domain.alertYn.rawValue, - thumbNail: state.domain.thumbNail - ) - ] send in + let request = ContentBaseRequest( + data: state.domain.data, + title: state.domain.title, + categoryId: categoryId, + memo: state.domain.memo, + alertYn: state.domain.alertYn.rawValue, + thumbNail: state.domain.thumbNail + ) + return .run { send in let _ = try await contentClient.컨텐츠_추가(request) await send(.inner(.선택한_포킷_인메모리_삭제)) await send(.delegate(.저장하기_완료)) From ca62f46f72759e365bf4e15da3e48cfcd5e6fa7f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=8F=84=ED=98=95?= <108233361+ShapeKim98@users.noreply.github.com> Date: Sun, 6 Oct 2024 16:17:18 +0900 Subject: [PATCH 6/8] =?UTF-8?q?[refactor]=20#129=20ContentSettingFeature?= =?UTF-8?q?=20doNothing=20=ED=95=9C=EA=B8=80=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Sources/ContentSetting/ContentSettingFeature.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Projects/Feature/FeatureContentSetting/Sources/ContentSetting/ContentSettingFeature.swift b/Projects/Feature/FeatureContentSetting/Sources/ContentSetting/ContentSettingFeature.swift index 0e41ccce..0c0abfba 100644 --- a/Projects/Feature/FeatureContentSetting/Sources/ContentSetting/ContentSettingFeature.swift +++ b/Projects/Feature/FeatureContentSetting/Sources/ContentSetting/ContentSettingFeature.swift @@ -118,7 +118,7 @@ public struct ContentSettingFeature { case 컨텐츠_추가_API } - public enum ScopeAction: Equatable { case doNothing } + public enum ScopeAction: Equatable { case 없음 } public enum DelegateAction: Equatable { case 저장하기_완료 From 1ad543c27814ef8e826451d9f937f7aa977aa450 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=8F=84=ED=98=95?= <108233361+ShapeKim98@users.noreply.github.com> Date: Sun, 6 Oct 2024 20:11:24 +0900 Subject: [PATCH 7/8] =?UTF-8?q?[refactor]=20#129=20ContentSettingFeature?= =?UTF-8?q?=20=EC=95=A1=EC=85=98=20=EB=B0=98=ED=99=98=20=ED=95=B8=EB=93=A4?= =?UTF-8?q?=EB=A7=81=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ContentSettingFeature.swift | 99 ++++++++++--------- 1 file changed, 53 insertions(+), 46 deletions(-) diff --git a/Projects/Feature/FeatureContentSetting/Sources/ContentSetting/ContentSettingFeature.swift b/Projects/Feature/FeatureContentSetting/Sources/ContentSetting/ContentSettingFeature.swift index 0c0abfba..d42dcb21 100644 --- a/Projects/Feature/FeatureContentSetting/Sources/ContentSetting/ContentSettingFeature.swift +++ b/Projects/Feature/FeatureContentSetting/Sources/ContentSetting/ContentSettingFeature.swift @@ -167,9 +167,9 @@ private extension ContentSettingFeature { switch action { case .binding(\.urlText): enum CancelID { case urlTextChanged } - return .run { send in - await send(.inner(.URL_유효성_확인)) - } + return .send( + .inner(.URL_유효성_확인) + ) /// - 1초마다 `urlText`변화의 마지막을 감지하여 이벤트 방출 .debounce( id: CancelID.urlTextChanged, @@ -184,24 +184,27 @@ private extension ContentSettingFeature { state.selectedPokit = pokit return .none case .뷰가_나타났을때: - return .run { [id = state.domain.contentId] send in - if let id { - await send(.async(.컨텐츠_상세_조회_API(id: id))) - } - await send(.async(.카테고리_목록_조회_API)) - await send(.inner(.URL_유효성_확인)) - for await _ in self.pasteboard.changes() { - let url = try await pasteboard.probableWebURL() - await send(.inner(.linkPopup(url)), animation: .pokitSpring) + var mergeEffect: [Effect] = [ + .send(.async(.카테고리_목록_조회_API)), + .send(.inner(.URL_유효성_확인)), + .run { send in + for await _ in self.pasteboard.changes() { + let url = try await pasteboard.probableWebURL() + await send(.inner(.linkPopup(url)), animation: .pokitSpring) + } } + ] + if let id = state.domain.contentId { + mergeEffect.append(.send(.async(.컨텐츠_상세_조회_API(id: id)))) } + return .merge(mergeEffect) case .저장_버튼_눌렀을때: - return .run { [isEdit = state.domain.categoryId != nil] send in - if isEdit { - await send(.async(.컨텐츠_수정_API)) - } else { - await send(.async(.컨텐츠_추가_API)) - } + let isEdit = state.domain.categoryId != nil + + if isEdit { + return .send(.async(.컨텐츠_수정_API)) + } else { + return .send(.async(.컨텐츠_추가_API)) } case .포킷추가_버튼_눌렀을때: guard state.domain.categoryTotalCount < 30 else { @@ -275,12 +278,14 @@ private extension ContentSettingFeature { state.domain.alertYn = content.alertYn state.contentLoading = false let id = content.category.categoryId - return .run { [ - sharedCategoryId = state.categoryId - ] send in - await send(.inner(.URL_유효성_확인)) - await send(.async(.카테고리_상세_조회_API(id: id, sharedId: sharedCategoryId))) - } + + return .merge( + .send(.inner(.URL_유효성_확인)), + .send(.async(.카테고리_상세_조회_API( + id: id, + sharedId: state.categoryId + ))) + ) case .카테고리_상세_조회_API_반영(category: let category): state.selectedPokit = BaseCategoryItem( id: category.categoryId, @@ -342,15 +347,15 @@ private extension ContentSettingFeature { size: 30, sort: state.domain.pageable.sort ) - return .run { [ - id = state.domain.categoryId, - sharedId = state.categoryId - ] send in - let categoryList = try await categoryClient.카테고리_목록_조회(request, false).toDomain() - - await send(.async(.카테고리_상세_조회_API(id: id, sharedId: sharedId))) - await send(.inner(.카테고리_목록_조회_API_반영(categoryList: categoryList)), animation: .pokitDissolve) - } + let id = state.domain.categoryId + let sharedId = state.categoryId + return .merge( + .send(.async(.카테고리_상세_조회_API(id: id, sharedId: sharedId))), + .run { send in + let categoryList = try await categoryClient.카테고리_목록_조회(request, false).toDomain() + await send(.inner(.카테고리_목록_조회_API_반영(categoryList: categoryList)), animation: .pokitDissolve) + } + ) case .컨텐츠_수정_API: guard let contentId = state.domain.contentId, let categoryId = state.selectedPokit?.id else { @@ -364,14 +369,16 @@ private extension ContentSettingFeature { alertYn: state.domain.alertYn.rawValue, thumbNail: state.domain.thumbNail ) - return .run { send in - let _ = try await contentClient.컨텐츠_수정( - "\(contentId)", - request - ) - await send(.inner(.선택한_포킷_인메모리_삭제)) - await send(.delegate(.저장하기_완료)) - } + return .concatenate( + .run { _ in + let _ = try await contentClient.컨텐츠_수정( + "\(contentId)", + request + ) + }, + .send(.inner(.선택한_포킷_인메모리_삭제)), + .send(.delegate(.저장하기_완료)) + ) case .컨텐츠_추가_API: guard let categoryId = state.selectedPokit?.id else { return .none @@ -384,11 +391,11 @@ private extension ContentSettingFeature { alertYn: state.domain.alertYn.rawValue, thumbNail: state.domain.thumbNail ) - return .run { send in - let _ = try await contentClient.컨텐츠_추가(request) - await send(.inner(.선택한_포킷_인메모리_삭제)) - await send(.delegate(.저장하기_완료)) - } + return .concatenate( + .run { _ in let _ = try await contentClient.컨텐츠_추가(request) }, + .send(.inner(.선택한_포킷_인메모리_삭제)), + .send(.delegate(.저장하기_완료)) + ) } } From e9cac18ea1d2c8bfd943d744e14b22301540bf33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=8F=84=ED=98=95?= <108233361+ShapeKim98@users.noreply.github.com> Date: Tue, 15 Oct 2024 16:17:49 +0900 Subject: [PATCH 8/8] =?UTF-8?q?[refactor]=20#129=20=ED=94=BC=EB=93=9C?= =?UTF-8?q?=EB=B0=B1=20=EB=B0=98=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ContentSettingFeature.swift | 63 ++++++++++--------- 1 file changed, 33 insertions(+), 30 deletions(-) diff --git a/Projects/Feature/FeatureContentSetting/Sources/ContentSetting/ContentSettingFeature.swift b/Projects/Feature/FeatureContentSetting/Sources/ContentSetting/ContentSettingFeature.swift index d42dcb21..de1d4c5b 100644 --- a/Projects/Feature/FeatureContentSetting/Sources/ContentSetting/ContentSettingFeature.swift +++ b/Projects/Feature/FeatureContentSetting/Sources/ContentSetting/ContentSettingFeature.swift @@ -116,6 +116,7 @@ public struct ContentSettingFeature { case 카테고리_목록_조회_API case 컨텐츠_수정_API case 컨텐츠_추가_API + case 클립보드_감지 } public enum ScopeAction: Equatable { case 없음 } @@ -167,11 +168,8 @@ private extension ContentSettingFeature { switch action { case .binding(\.urlText): enum CancelID { case urlTextChanged } - return .send( - .inner(.URL_유효성_확인) - ) - /// - 1초마다 `urlText`변화의 마지막을 감지하여 이벤트 방출 - .debounce( + return .send(.inner(.URL_유효성_확인)).debounce( + /// - 1초마다 `urlText`변화의 마지막을 감지하여 이벤트 방출 id: CancelID.urlTextChanged, for: 1, scheduler: DispatchQueue.main @@ -187,12 +185,7 @@ private extension ContentSettingFeature { var mergeEffect: [Effect] = [ .send(.async(.카테고리_목록_조회_API)), .send(.inner(.URL_유효성_확인)), - .run { send in - for await _ in self.pasteboard.changes() { - let url = try await pasteboard.probableWebURL() - await send(.inner(.linkPopup(url)), animation: .pokitSpring) - } - } + .send(.async(.클립보드_감지)) ] if let id = state.domain.contentId { mergeEffect.append(.send(.async(.컨텐츠_상세_조회_API(id: id)))) @@ -201,11 +194,9 @@ private extension ContentSettingFeature { case .저장_버튼_눌렀을때: let isEdit = state.domain.categoryId != nil - if isEdit { - return .send(.async(.컨텐츠_수정_API)) - } else { - return .send(.async(.컨텐츠_추가_API)) - } + return isEdit + ? .send(.async(.컨텐츠_수정_API)) + : .send(.async(.컨텐츠_추가_API)) case .포킷추가_버튼_눌렀을때: guard state.domain.categoryTotalCount < 30 else { /// 🚨 Error Case [1]: 포킷 갯수가 30개 이상일 경우 @@ -281,10 +272,7 @@ private extension ContentSettingFeature { return .merge( .send(.inner(.URL_유효성_확인)), - .send(.async(.카테고리_상세_조회_API( - id: id, - sharedId: state.categoryId - ))) + .send(.async(.카테고리_상세_조회_API(id: id, sharedId: state.categoryId))) ) case .카테고리_상세_조회_API_반영(category: let category): state.selectedPokit = BaseCategoryItem( @@ -351,10 +339,7 @@ private extension ContentSettingFeature { let sharedId = state.categoryId return .merge( .send(.async(.카테고리_상세_조회_API(id: id, sharedId: sharedId))), - .run { send in - let categoryList = try await categoryClient.카테고리_목록_조회(request, false).toDomain() - await send(.inner(.카테고리_목록_조회_API_반영(categoryList: categoryList)), animation: .pokitDissolve) - } + categoryListFetch(request: request) ) case .컨텐츠_수정_API: guard let contentId = state.domain.contentId, @@ -370,12 +355,7 @@ private extension ContentSettingFeature { thumbNail: state.domain.thumbNail ) return .concatenate( - .run { _ in - let _ = try await contentClient.컨텐츠_수정( - "\(contentId)", - request - ) - }, + contentEdit(request: request, contentId: contentId), .send(.inner(.선택한_포킷_인메모리_삭제)), .send(.delegate(.저장하기_완료)) ) @@ -396,6 +376,13 @@ private extension ContentSettingFeature { .send(.inner(.선택한_포킷_인메모리_삭제)), .send(.delegate(.저장하기_완료)) ) + case .클립보드_감지: + return .run { send in + for await _ in self.pasteboard.changes() { + let url = try await pasteboard.probableWebURL() + await send(.inner(.linkPopup(url)), animation: .pokitSpring) + } + } } } @@ -408,4 +395,20 @@ private extension ContentSettingFeature { func handleDelegateAction(_ action: Action.DelegateAction, state: inout State) -> Effect { return .none } + + func contentEdit(request: ContentBaseRequest, contentId: Int) -> Effect { + return .run { _ in + let _ = try await contentClient.컨텐츠_수정( + "\(contentId)", + request + ) + } + } + + func categoryListFetch(request: BasePageableRequest) -> Effect { + return .run { send in + let categoryList = try await categoryClient.카테고리_목록_조회(request, false).toDomain() + await send(.inner(.카테고리_목록_조회_API_반영(categoryList: categoryList)), animation: .pokitDissolve) + } + } }