44//
55// Created by 김도형 on 1/29/25.
66
7+ import SwiftUI
8+
79import ComposableArchitecture
810import Domain
911import CoreKit
@@ -14,6 +16,8 @@ public struct RecommendFeature {
1416 /// - Dependency
1517 @Dependency ( ContentClient . self)
1618 private var contentClient
19+ @Dependency ( UserClient . self)
20+ private var userClient
1721 @Dependency ( PasteboardClient . self)
1822 private var pasteBoard
1923 /// - State
@@ -33,7 +37,13 @@ public struct RecommendFeature {
3337 array. append ( contentsOf: list)
3438 return array
3539 }
40+ var interestList : IdentifiedArrayOf < BaseInterest > {
41+ var array = IdentifiedArrayOf < BaseInterest > ( )
42+ array. append ( contentsOf: domain. interests)
43+ return array
44+ }
3645 var isLoading : Bool = true
46+ var selectedInterest : BaseInterest ?
3747 }
3848
3949 /// - Action
@@ -45,10 +55,12 @@ public struct RecommendFeature {
4555 case delegate( DelegateAction )
4656
4757 @CasePathable
48- public enum View : Equatable {
58+ public enum View {
4959 case 추가하기_버튼_눌렀을때( BaseContentItem )
5060 case 공유하기_버튼_눌렀을때( BaseContentItem )
5161 case 신고하기_버튼_눌렀을때( BaseContentItem )
62+ case 전체보기_버튼_눌렀을때( ScrollViewProxy )
63+ case 관심사_버튼_눌렀을때( BaseInterest , ScrollViewProxy )
5264
5365 case onAppear
5466 case pagination
@@ -57,11 +69,13 @@ public struct RecommendFeature {
5769 public enum InnerAction : Equatable {
5870 case 추천_조회_API_반영( BaseContentListInquiry )
5971 case 추천_조회_페이징_API_반영( BaseContentListInquiry )
72+ case 유저_관심사_조회_API_반영( [ BaseInterest ] )
6073 }
6174
6275 public enum AsyncAction : Equatable {
6376 case 추천_조회_API
6477 case 추천_조회_페이징_API
78+ case 유저_관심사_조회_API
6579 }
6680
6781 public enum ScopeAction : Equatable { case doNothing }
@@ -108,7 +122,10 @@ private extension RecommendFeature {
108122 func handleViewAction( _ action: Action . View , state: inout State ) -> Effect < Action > {
109123 switch action {
110124 case . onAppear:
111- return shared ( . async( . 추천_조회_API) , state: & state)
125+ return . merge(
126+ shared ( . async( . 추천_조회_API) , state: & state) ,
127+ shared ( . async( . 유저_관심사_조회_API) , state: & state)
128+ )
112129 case . pagination:
113130 return shared ( . async( . 추천_조회_페이징_API) , state: & state)
114131 case let . 추가하기_버튼_눌렀을때( content) :
@@ -117,6 +134,18 @@ private extension RecommendFeature {
117134 return . none
118135 case let . 신고하기_버튼_눌렀을때( content) :
119136 return . none
137+ case let . 전체보기_버튼_눌렀을때( proxy) :
138+ guard state. selectedInterest != nil else { return . none }
139+
140+ state. selectedInterest = nil
141+ proxy. scrollTo ( " 전체보기 " , anchor: . leading)
142+ return shared ( . async( . 추천_조회_API) , state: & state)
143+ case let . 관심사_버튼_눌렀을때( interest, proxy) :
144+ guard state. selectedInterest != interest else { return . none }
145+
146+ state. selectedInterest = interest
147+ proxy. scrollTo ( interest. description, anchor: . leading)
148+ return shared ( . async( . 추천_조회_API) , state: & state)
120149 }
121150 }
122151
@@ -135,6 +164,9 @@ private extension RecommendFeature {
135164
136165 state. isLoading = false
137166 return . none
167+ case let . 유저_관심사_조회_API_반영( interests) :
168+ state. domain. interests = interests
169+ return . none
138170 }
139171 }
140172
@@ -148,16 +180,23 @@ private extension RecommendFeature {
148180 page: state. domain. pageable. page,
149181 size: state. domain. pageable. size,
150182 sort: state. domain. pageable. sort
151- )
183+ ) ,
184+ keyword = state. selectedInterest? . description
152185 ] send in
153186 let contentList = try await contentClient. 추천_컨텐츠_조회 (
154- model: pageableRequest
187+ pageable: pageableRequest,
188+ keyword: keyword
155189 ) . toDomain ( )
156190
157191 await send ( . inner( . 추천_조회_페이징_API_반영( contentList) ) )
158192 }
159193 case . 추천_조회_API:
160194 return contentListFetch ( state: & state)
195+ case . 유저_관심사_조회_API:
196+ return . run { send in
197+ let interests = try await userClient. 유저_관심사_목록_조회 ( ) . map { $0. toDomian ( ) }
198+ await send ( . inner( . 유저_관심사_조회_API_반영( interests) ) )
199+ }
161200 }
162201 }
163202
@@ -189,7 +228,8 @@ private extension RecommendFeature {
189228
190229 func contentListFetch( state: inout State ) -> Effect < Action > {
191230 return . run { [
192- pageable = state. domain. pageable
231+ pageable = state. domain. pageable,
232+ keyword = state. selectedInterest? . description
193233 ] send in
194234 let stream = AsyncThrowingStream < BaseContentListInquiry , Error > { continuation in
195235 Task {
@@ -200,7 +240,8 @@ private extension RecommendFeature {
200240 sort: pageable. sort
201241 )
202242 let contentList = try await contentClient. 추천_컨텐츠_조회 (
203- model: pageableRequest
243+ pageable: pageableRequest,
244+ keyword: keyword
204245 ) . toDomain ( )
205246 continuation. yield ( contentList)
206247 }
0 commit comments