From d9ba113391327ffc7fe8596f5ed54def53cac31b Mon Sep 17 00:00:00 2001 From: wongbingg Date: Tue, 18 Feb 2025 09:56:52 +0900 Subject: [PATCH] =?UTF-8?q?[ITDS-75]=20feat:=20#61=20-=20UpdateBannerUseCa?= =?UTF-8?q?se=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../PostRecommendCoordinator.swift | 6 ++- .../Reactor/PostRecommendReactor.swift | 45 ++++++++++++++++++- .../View/PostRecommendViewController.swift | 31 +++++++++---- 3 files changed, 72 insertions(+), 10 deletions(-) diff --git a/Targets/PresentationLayer/Sources/PostRecommend/Coordinator/PostRecommendCoordinator.swift b/Targets/PresentationLayer/Sources/PostRecommend/Coordinator/PostRecommendCoordinator.swift index ad2b39b..f472095 100644 --- a/Targets/PresentationLayer/Sources/PostRecommend/Coordinator/PostRecommendCoordinator.swift +++ b/Targets/PresentationLayer/Sources/PostRecommend/Coordinator/PostRecommendCoordinator.swift @@ -63,9 +63,13 @@ private extension PostRecommendCoordinator { guard let fetchBannerUseCase = DIContainer.shared.resolve(type: FetchBannerUseCaseType.self) else { fatalError() } + guard let updateBannerUseCase = DIContainer.shared.resolve(type: UpdateBannerUseCaseType.self) else { + fatalError() + } let reactor = PostRecommendReactor( recommendedPostStream: mutableRecommendedPostStream, - fetchBannerUseCase: fetchBannerUseCase + fetchBannerUseCase: fetchBannerUseCase, + updateBannerUseCase: updateBannerUseCase ) let viewController = PostRecommendViewController(reactor: reactor) viewController.coordinator = self diff --git a/Targets/PresentationLayer/Sources/PostRecommend/Reactor/PostRecommendReactor.swift b/Targets/PresentationLayer/Sources/PostRecommend/Reactor/PostRecommendReactor.swift index fffc5b2..c99f308 100644 --- a/Targets/PresentationLayer/Sources/PostRecommend/Reactor/PostRecommendReactor.swift +++ b/Targets/PresentationLayer/Sources/PostRecommend/Reactor/PostRecommendReactor.swift @@ -24,15 +24,18 @@ final class PostRecommendReactor: Reactor { var initialState: State = .init() private let recommendedPostStream: MutableRecommendedPostStream private let fetchBannerUseCase: FetchBannerUseCaseType + private let updateBannerUseCase: UpdateBannerUseCaseType private let disposeBag = DisposeBag() // MARK: - Initializer init( recommendedPostStream: MutableRecommendedPostStream, - fetchBannerUseCase: FetchBannerUseCaseType + fetchBannerUseCase: FetchBannerUseCaseType, + updateBannerUseCase: UpdateBannerUseCaseType ) { self.recommendedPostStream = recommendedPostStream self.fetchBannerUseCase = fetchBannerUseCase + self.updateBannerUseCase = updateBannerUseCase bindStream() } @@ -44,16 +47,21 @@ final class PostRecommendReactor: Reactor { case imageViewDidTap(Int) case inputImage(Data) case setUploadableTrue + case completeButtonDidTap } enum Mutation { + case setLoading(Bool) case setPosts([RecommendCellData]) case setUploadableTrue case setAlertHistoryDataTrue + case setIsUploadComplete } struct State { var isUploadable = false + var isLoading = false + var isUploadComplete = false var alertHistoryData = false var posts: [RecommendCellData] = [] } @@ -92,6 +100,7 @@ final class PostRecommendReactor: Reactor { case let .refreshData(data): refreshDataMutation(with: data) case let .inputImage(imageData): inputImageMutation(with: imageData) case let .imageViewDidTap(index): imageViewDidTapMutation(at: index) + case .completeButtonDidTap: completeButtonDidTapMutation() } } @@ -137,13 +146,47 @@ final class PostRecommendReactor: Reactor { recommendedPostStream.setTargetIndex(index) return .empty() } + + func completeButtonDidTapMutation() -> Observable { + + let bannerForUpdate = recommendedPostStream.data.value.filter { $0.isUploadAvailable } + var streams: [Observable] = [] + for banner in bannerForUpdate { + guard let imageData = banner.imageData else { continue } + + let requestDTO = BannerUpdateRequestDTO.init( + featuredPostId: banner.featuredPostID, + infoPostId: banner.infoID, + imgFile: imageData + ) + let requestStream = updateBannerUseCase.execute(requestDTO: requestDTO) + .do(onError: { + print($0.localizedDescription) + }) + .flatMap { _ in + return Observable.empty() + } + streams.append(requestStream) + } + + let mergedStream: Observable = .merge(streams) + + return .concat([ + .just(.setLoading(true)), + mergedStream, + .just(.setLoading(false)), + .just(.setIsUploadComplete) + ]) + } func reduce(state: State, mutation: Mutation) -> State { var newState = state switch mutation { case let .setPosts(data): newState.posts = data + case let .setLoading(bool): newState.isLoading = bool case .setUploadableTrue: newState.isUploadable = true case .setAlertHistoryDataTrue: newState.alertHistoryData = true + case .setIsUploadComplete: newState.isUploadComplete = true ; PostRecommendCache.cachedRecommendPost = [] } return newState } diff --git a/Targets/PresentationLayer/Sources/PostRecommend/View/PostRecommendViewController.swift b/Targets/PresentationLayer/Sources/PostRecommend/View/PostRecommendViewController.swift index b26baf3..9344957 100644 --- a/Targets/PresentationLayer/Sources/PostRecommend/View/PostRecommendViewController.swift +++ b/Targets/PresentationLayer/Sources/PostRecommend/View/PostRecommendViewController.swift @@ -106,10 +106,33 @@ private extension PostRecommendViewController { .bind(to: reactor.action) .disposed(by: disposeBag) + completeButton.rx.tap + .map { Action.completeButtonDidTap } + .bind(to: reactor.action) + .disposed(by: disposeBag) } func bindState(reactor: PostRecommendReactor) { + reactor.state + .map(\.isLoading) + .distinctUntilChanged() + .asDriver(onErrorJustReturn: false) + .drive { + $0 ? LoadingIndicator.start(withDimming: true) : LoadingIndicator.stop() + } + .disposed(by: disposeBag) + + reactor.state + .map(\.isUploadComplete) + .distinctUntilChanged() + .filter { $0 } + .asSignal(onErrorJustReturn: true) + .emit(with: self) { owner, _ in + owner.coordinator?.didFinish() + } + .disposed(by: disposeBag) + reactor.state .map(\.posts) .distinctUntilChanged() @@ -159,14 +182,6 @@ private extension PostRecommendViewController { owner.checkPhotoLibraryPermission() } .disposed(by: disposeBag) - - completeButton.rx.tap - .asSignal() - .emit(with: self) { owner, _ in - print("업로드 고고") - - } - .disposed(by: disposeBag) } func showHistoryAlert() {