Skip to content

Commit 19ec4cd

Browse files
committed
[feat] #173 미분류 링크 이동 로직 추가
1 parent f168d3a commit 19ec4cd

File tree

8 files changed

+118
-25
lines changed

8 files changed

+118
-25
lines changed
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
//
2+
// ContentMoveRequest.swift
3+
// CoreKit
4+
//
5+
// Created by 김민호 on 12/29/24.
6+
//
7+
import Foundation
8+
/// 미분류 링크를 카테고리로 이동
9+
public struct ContentMoveRequest: Encodable {
10+
let contentIds: [Int]
11+
let categoryId: Int
12+
13+
public init(contentIds: [Int], categoryId: Int) {
14+
self.contentIds = contentIds
15+
self.categoryId = categoryId
16+
}
17+
}
18+
19+
extension ContentMoveRequest {
20+
public static let mock: Self = Self(contentIds: [123,456], categoryId: 444)
21+
}

Projects/CoreKit/Sources/Data/Network/Content/ContentClient+LiveKey.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,9 @@ extension ContentClient: DependencyKey {
5555
try await provider.requestNoBody(
5656
.썸네일_수정(contentId: id, model: model)
5757
)
58+
},
59+
미분류_링크_포킷_이동: { model in
60+
try await provider.requestNoBody(.미분류_링크_포킷_이동(model: model))
5861
}
5962
)
6063
}()

Projects/CoreKit/Sources/Data/Network/Content/ContentClient+TestKey.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ extension ContentClient: TestDependencyKey {
1818
카테고리_내_컨텐츠_목록_조회: { _, _, _ in .mock },
1919
미분류_카테고리_컨텐츠_조회: { _ in .mock },
2020
컨텐츠_검색: { _, _ in .mock },
21-
썸네일_수정: { _, _ in }
21+
썸네일_수정: { _, _ in },
22+
미분류_링크_포킷_이동: { _ in }
2223
)
2324
}()
2425
}

Projects/CoreKit/Sources/Data/Network/Content/ContentClient.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,5 +44,8 @@ public struct ContentClient {
4444
_ contentId: String,
4545
_ model: ThumbnailRequest
4646
) async throws -> Void
47+
public var 미분류_링크_포킷_이동: @Sendable (
48+
_ model: ContentMoveRequest
49+
) async throws -> Void
4750
}
4851

Projects/CoreKit/Sources/Data/Network/Content/ContentEndpoint.swift

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ public enum ContentEndpoint {
2828
condition: BaseConditionRequest
2929
)
3030
case 썸네일_수정(contentId: String, model: ThumbnailRequest)
31+
case 미분류_링크_포킷_이동(model: ContentMoveRequest)
3132
}
3233

3334
extension ContentEndpoint: TargetType {
@@ -57,6 +58,8 @@ extension ContentEndpoint: TargetType {
5758
return ""
5859
case let .썸네일_수정(contentId, _):
5960
return "/thumbnail/\(contentId)"
61+
case .미분류_링크_포킷_이동:
62+
return ""
6063
}
6164
}
6265

@@ -72,7 +75,8 @@ extension ContentEndpoint: TargetType {
7275
return .post
7376

7477
case .컨텐츠_수정,
75-
.썸네일_수정:
78+
.썸네일_수정,
79+
.미분류_링크_포킷_이동:
7680
return .patch
7781

7882
case .카태고리_내_컨텐츠_목록_조회,
@@ -135,6 +139,9 @@ extension ContentEndpoint: TargetType {
135139
)
136140
case let .썸네일_수정(_, model):
137141
return .requestJSONEncodable(model)
142+
143+
case let .미분류_링크_포킷_이동(model):
144+
return .requestJSONEncodable(model)
138145
}
139146
}
140147

Projects/Feature/FeaturePokit/Sources/PokitLinkEditFeature.swift

Lines changed: 56 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,19 +5,28 @@
55
// Created by 김민호 on 12/24/24.
66

77
import ComposableArchitecture
8+
import CoreKit
89
import Domain
910
import Util
1011

1112
@Reducer
1213
public struct PokitLinkEditFeature {
1314
/// - Dependency
1415
@Dependency(\.dismiss) var dismiss
16+
@Dependency(CategoryClient.self) var categoryClient
17+
@Dependency(ContentClient.self) var contentClient
1518
/// - State
1619
@ObservableState
1720
public struct State: Equatable {
21+
/// 링크 아이템 Doamin
1822
var item: BaseContentListInquiry
23+
/// 카테고리 아이템 Domain
24+
var category: BaseCategoryListInquiry?
25+
/// 링크 목록
1926
var list = IdentifiedArrayOf<BaseContentItem>()
27+
/// 선택한 링크 목록
2028
var selectedItems = IdentifiedArrayOf<BaseContentItem>()
29+
/// 포킷 이동 눌렀을 때 sheet
2130
var isPresented: Bool = false
2231

2332
public init(linkList: BaseContentListInquiry) {
@@ -40,12 +49,17 @@ public struct PokitLinkEditFeature {
4049
public enum View: BindableAction, Equatable {
4150
case binding(BindingAction<State>)
4251
case dismiss
52+
case onAppear
4353

54+
case 카테고리_추가_버튼_눌렀을때
4455
case 체크박스_선택했을때(BaseContentItem)
4556
case 카테고리_선택했을때(BaseCategoryItem)
4657
}
4758

48-
public enum InnerAction: Equatable { case 없음 }
59+
public enum InnerAction: Equatable {
60+
case 카테고리_목록_조회_API_반영(BaseCategoryListInquiry)
61+
case 미분류_카테고리_이동_API_반영
62+
}
4963

5064
public enum AsyncAction: Equatable { case 없음 }
5165

@@ -101,6 +115,12 @@ private extension PokitLinkEditFeature {
101115
case .dismiss:
102116
return .run { _ in await dismiss() }
103117

118+
case .onAppear:
119+
return fetchCateogryList()
120+
121+
case .카테고리_추가_버튼_눌렀을때:
122+
return .none
123+
104124
case let .체크박스_선택했을때(item):
105125
/// 이미 체크되어 있다면 해제
106126
if state.selectedItems.contains(item) {
@@ -111,15 +131,27 @@ private extension PokitLinkEditFeature {
111131
return .none
112132

113133
case let .카테고리_선택했을때(pokit):
114-
//TODO: 포킷이동 네트워크 구현
115-
state.isPresented = false
116-
return .none
134+
return moveContentList(categoryId: pokit.id, state: &state)
117135
}
118136
}
119137

120138
/// - Inner Effect
121139
func handleInnerAction(_ action: Action.InnerAction, state: inout State) -> Effect<Action> {
122-
return .none
140+
switch action {
141+
case let .카테고리_목록_조회_API_반영(response):
142+
state.category = response
143+
return .none
144+
145+
case .미분류_카테고리_이동_API_반영:
146+
/// 1. 시트 내리기
147+
state.isPresented = false
148+
/// 2. 선택했던 체크리스트 삭제
149+
state.selectedItems
150+
.map { $0.id }
151+
.forEach { state.list.remove(id: $0) }
152+
state.selectedItems.removeAll()
153+
return .none
154+
}
123155
}
124156

125157
/// - Async Effect
@@ -154,4 +186,23 @@ private extension PokitLinkEditFeature {
154186
func handleDelegateAction(_ action: Action.DelegateAction, state: inout State) -> Effect<Action> {
155187
return .none
156188
}
189+
190+
/// 카테고리 목록 조회 API
191+
func fetchCateogryList() -> Effect<Action> {
192+
return .run { send in
193+
let request: BasePageableRequest = BasePageableRequest(page: 0, size: 100, sort: ["createdAt", "desc"])
194+
let response = try await categoryClient.카테고리_목록_조회(model: request, filterUncategorized: false).toDomain()
195+
await send(.inner(.카테고리_목록_조회_API_반영(response)))
196+
}
197+
}
198+
199+
/// 미분류 링크 카테고리 이동 API
200+
func moveContentList(categoryId: Int, state: inout State) -> Effect<Action> {
201+
return .run { [contentIds = state.selectedItems] send in
202+
let contentIds = contentIds.map { $0.id }
203+
let request = ContentMoveRequest(contentIds: contentIds, categoryId: categoryId)
204+
try await contentClient.미분류_링크_포킷_이동(request)
205+
await send(.inner(.미분류_카테고리_이동_API_반영))
206+
}
207+
}
157208
}

Projects/Feature/FeaturePokit/Sources/PokitLinkEditView.swift

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import ComposableArchitecture
1010
import DSKit
1111
import Domain
1212
import CoreKit
13+
import Util
1314

1415
@ViewAction(for: PokitLinkEditFeature.self)
1516
public struct PokitLinkEditView: View {
@@ -30,32 +31,35 @@ public extension PokitLinkEditView {
3031
ForEach(store.list, id: \.id) { item in
3132
let isFirst = item.id == self.store.list.first?.id
3233
let isLast = item.id == self.store.list.last?.id
33-
PokitLinkCard(
34-
link: item,
35-
state: isFirst
36-
? .top
37-
: isLast ? .bottom : .middle,
38-
type: .unCatgorized(isSelected: store.selectedItems.contains(item)),
39-
action: nil,
40-
kebabAction: nil,
41-
fetchMetaData: {},
42-
favoriteAction: nil,
43-
selectAction: { send(.체크박스_선택했을때(item)) }
44-
)
34+
WithPerceptionTracking {
35+
PokitLinkCard(
36+
link: item,
37+
state: isFirst
38+
? .top
39+
: isLast ? .bottom : .middle,
40+
type: .unCatgorized(isSelected: store.selectedItems.contains(item)),
41+
action: nil,
42+
kebabAction: nil,
43+
fetchMetaData: {},
44+
favoriteAction: nil,
45+
selectAction: { send(.체크박스_선택했을때(item)) }
46+
)
47+
}
4548
}
4649
}
50+
.padding(.bottom, 38)
4751
}
4852
.padding(.top, 16)
49-
.pokitNavigationBar(navigationBar)
5053
.overlay(alignment: .bottom) {
5154
actionFloatButtonView
5255
}
5356
.padding(.horizontal, 20)
54-
.ignoresSafeArea(edges: .bottom)
5557
.padding(.bottom, 24)
58+
.pokitNavigationBar(navigationBar)
59+
.ignoresSafeArea(edges: .bottom)
5660
.sheet(isPresented: $store.isPresented) {
5761
PokitSelectSheet(
58-
list: nil,
62+
list: store.category?.data ?? nil,
5963
itemSelected: { send(.카테고리_선택했을때($0)) },
6064
pokitAddAction: {}
6165
)
@@ -64,6 +68,7 @@ public extension PokitLinkEditView {
6468
.presentationDetents([.height(564)])
6569
.pokitPresentationBackground()
6670
}
71+
.task { await send(.onAppear).finish() }
6772
}
6873
}
6974
}
@@ -92,7 +97,7 @@ private extension PokitLinkEditView {
9297
store: Store(
9398
initialState: .init(
9499
linkList: BaseContentListInquiry(
95-
data: nil,
100+
data: [BaseContentItem(id: 3, categoryName: "23", categoryId: 255, title: "2323", memo: nil, thumbNail: Constants.mockImageUrl, data: "", domain: "", createdAt: "", isRead: false, isFavorite: false)],
96101
page: 0,
97102
size: 0,
98103
sort: [],

Projects/Feature/FeaturePokit/Sources/PokitRootView.swift

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,10 @@ public extension PokitRootView {
5959
state: \.linkEdit,
6060
action: \.scope.linkEdit
6161
)
62-
) {
63-
PokitLinkEditView(store: $0)
62+
) { store in
63+
WithPerceptionTracking {
64+
PokitLinkEditView(store: store)
65+
}
6466
}
6567
.task { await send(.뷰가_나타났을때).finish() }
6668
}

0 commit comments

Comments
 (0)