diff --git a/Projects/Feature/FeatureCategorySharing/Sources/CategorySharing/CategorySharingFeature.swift b/Projects/Feature/FeatureCategorySharing/Sources/CategorySharing/CategorySharingFeature.swift index 67905525..9f97170e 100644 --- a/Projects/Feature/FeatureCategorySharing/Sources/CategorySharing/CategorySharingFeature.swift +++ b/Projects/Feature/FeatureCategorySharing/Sources/CategorySharing/CategorySharingFeature.swift @@ -7,6 +7,7 @@ import Foundation import ComposableArchitecture +import FeatureContentCard import Domain import CoreKit import Util @@ -26,16 +27,11 @@ public struct CategorySharingFeature { public struct State: Equatable { fileprivate var domain: CategorySharing var category: CategorySharing.Category { domain.sharedCategory.category } - var contents: IdentifiedArrayOf? { - var identifiedArray = IdentifiedArrayOf() - domain.sharedCategory.contentList.data.forEach { content in - identifiedArray.append(content) - } - return identifiedArray - } + var contents: IdentifiedArrayOf = [] var hasNext: Bool { domain.sharedCategory.contentList.hasNext } var error: BaseError? var isErrorSheetPresented: Bool = false + var isLoading: Bool = true public init(sharedCategory: CategorySharing.SharedCategory) { domain = .init( @@ -56,6 +52,7 @@ public struct CategorySharingFeature { case async(AsyncAction) case scope(ScopeAction) case delegate(DelegateAction) + case contents(IdentifiedActionOf) @CasePathable public enum View: Equatable, BindableAction { @@ -63,9 +60,9 @@ public struct CategorySharingFeature { case dismiss case 저장_버튼_눌렀을때 - case 컨텐츠_항목_눌렀을때(CategorySharing.Content) case 경고_확인버튼_눌렀을때 case 페이지_로딩중일때 + case 뷰가_나타났을때 } public enum InnerAction: Equatable { @@ -78,7 +75,9 @@ public struct CategorySharingFeature { case 공유받은_카테고리_조회_API } - public enum ScopeAction: Equatable { case 없음 } + public enum ScopeAction { + case contents(IdentifiedActionOf) + } public enum DelegateAction: Equatable { case 컨텐츠_아이템_클릭(categoryId: Int, content: CategorySharing.Content) @@ -111,6 +110,9 @@ public struct CategorySharingFeature { /// - Delegate case .delegate(let delegateAction): return handleDelegateAction(delegateAction, state: &state) + + case .contents(let contentsAction): + return .send(.scope(.contents(contentsAction))) } } @@ -118,6 +120,9 @@ public struct CategorySharingFeature { public var body: some ReducerOf { BindingReducer(action: \.view) Reduce(self.core) + .forEach(\.contents, action: \.contents) { + ContentCardFeature() + } } } //MARK: - FeatureAction Effect @@ -135,14 +140,27 @@ private extension CategorySharingFeature { let sharedCategory = state.domain.sharedCategory.category return .send(.delegate(.공유받은_카테고리_추가(sharedCategory: sharedCategory))) - case let .컨텐츠_항목_눌렀을때(content): - return .send(.delegate(.컨텐츠_아이템_클릭(categoryId: state.category.categoryId , content: content))) - case .경고_확인버튼_눌렀을때: return .none case .페이지_로딩중일때: return .send(.async(.공유받은_카테고리_조회_API)) + case .뷰가_나타났을때: + state.domain.sharedCategory.contentList.data.forEach { content in + state.contents.append(.init(content: .init( + id: content.id, + categoryName: content.categoryName, + categoryId: state.category.categoryId, + title: content.title, + thumbNail: content.thumbNail, + data: content.data, + domain: content.domain, + createdAt: content.createdAt, + isRead: content.isRead + ))) + } + state.isLoading = false + return .none } } @@ -151,6 +169,21 @@ private extension CategorySharingFeature { switch action { case let .공유받은_카테고리_API_반영(sharedCategory): state.domain.sharedCategory = sharedCategory + + sharedCategory.contentList.data.forEach { content in + state.contents.append(.init(content: .init( + id: content.id, + categoryName: content.categoryName, + categoryId: state.category.categoryId, + title: content.title, + thumbNail: content.thumbNail, + data: content.data, + domain: content.domain, + createdAt: content.createdAt, + isRead: content.isRead + ))) + } + state.isLoading = false return .none case let .경고_띄움(baseError): @@ -186,7 +219,20 @@ private extension CategorySharingFeature { /// - Scope Effect func handleScopeAction(_ action: Action.ScopeAction, state: inout State) -> Effect { - return .none + switch action { + case let .contents(.element(id: _, action: .delegate(.컨텐츠_항목_눌렀을때(content)))): + let sharedContent = state.domain.sharedCategory.contentList.data.first { item in + item.id == content.id + } + guard let sharedContent else { return .none } + + return .send(.delegate(.컨텐츠_아이템_클릭( + categoryId: state.category.categoryId, + content: sharedContent + ))) + case .contents: + return .none + } } /// - Delegate Effect diff --git a/Projects/Feature/FeatureCategorySharing/Sources/CategorySharing/CategorySharingView.swift b/Projects/Feature/FeatureCategorySharing/Sources/CategorySharing/CategorySharingView.swift index 04d7cfa0..3c9aec90 100644 --- a/Projects/Feature/FeatureCategorySharing/Sources/CategorySharing/CategorySharingView.swift +++ b/Projects/Feature/FeatureCategorySharing/Sources/CategorySharing/CategorySharingView.swift @@ -7,6 +7,7 @@ import SwiftUI import ComposableArchitecture +import FeatureContentCard import Domain import DSKit @@ -34,6 +35,7 @@ public extension CategorySharingView { .padding(.top, 12) .pokitNavigationBar { navigationBar } .ignoresSafeArea(edges: .bottom) + .onAppear { send(.뷰가_나타났을때, animation: .pokitDissolve) } .sheet(isPresented: $store.isErrorSheetPresented) { PokitAlert( store.error?.title ?? "에러", @@ -86,8 +88,8 @@ private extension CategorySharingView { var contentScrollView: some View { Group { - if let contents = store.contents { - if contents.isEmpty { + if !store.isLoading { + if store.contents.isEmpty { VStack { PokitCaution( image: .empty, @@ -101,16 +103,17 @@ private extension CategorySharingView { } else { ScrollView(showsIndicators: false) { LazyVStack(spacing: 0) { - ForEach(contents) { content in - let isFirst = content == contents.first - let isLast = content == contents.last + ForEachStore( + store.scope(state: \.contents, action: \.contents) + ) { store in + let isFirst = store.state.id == self.store.contents.first?.id + let isLast = store.state.id == self.store.contents.last?.id - PokitLinkCard( - link: content, - action: { send(.컨텐츠_항목_눌렀을때(content)) } + ContentCardView( + store: store, + isFirst: isFirst, + isLast: isLast ) - .divider(isFirst: isFirst, isLast: isLast) - .pokitScrollTransition(.opacity) } if store.hasNext {