diff --git a/Targets/PresentationLayer/Sources/PostSearch/Coordinator/PostSearchCoordinator.swift b/Targets/PresentationLayer/Sources/PostSearch/Coordinator/PostSearchCoordinator.swift index 31b450a..dffc689 100644 --- a/Targets/PresentationLayer/Sources/PostSearch/Coordinator/PostSearchCoordinator.swift +++ b/Targets/PresentationLayer/Sources/PostSearch/Coordinator/PostSearchCoordinator.swift @@ -12,6 +12,7 @@ import UIKit public protocol PostSearchCoordinatorType: CoordinatorType { func start() + func startSelectMode(stream: MutableRecommendedPostStream) func pushPostDetail(id: Int) } @@ -32,6 +33,11 @@ final class PostSearchCoordinator: PostSearchCoordinatorType { let vc = postSearchViewController() navigationController.pushViewController(vc, animated: true) } + + func startSelectMode(stream: MutableRecommendedPostStream) { /// 추천공고 선택모드 + let vc = postSearchViewController(stream: stream) + navigationController.pushViewController(vc, animated: true) + } func disappear() { if childCoordinators.isEmpty && navigationController.presentedViewController == nil { @@ -66,4 +72,15 @@ private extension PostSearchCoordinator { viewController.coordinator = self return viewController } + + func postSearchViewController(stream: MutableRecommendedPostStream) -> PostSearchViewController { + guard let searchPostListUseCase = DIContainer.shared.resolve(type: SearchPostListUseCaseType.self) else { + fatalError() + } + let reactor = PostSearchReactor(searchPostListUseCase: searchPostListUseCase, + mutableRecommendedPostStream: stream) + let viewController = PostSearchViewController(reactor: reactor) + viewController.coordinator = self + return viewController + } } diff --git a/Targets/PresentationLayer/Sources/PostSearch/Reactor/PostSearchReactor.swift b/Targets/PresentationLayer/Sources/PostSearch/Reactor/PostSearchReactor.swift index f406fcd..add530a 100644 --- a/Targets/PresentationLayer/Sources/PostSearch/Reactor/PostSearchReactor.swift +++ b/Targets/PresentationLayer/Sources/PostSearch/Reactor/PostSearchReactor.swift @@ -16,13 +16,17 @@ final class PostSearchReactor: Reactor { // MARK: - Properties private let searchPostListUseCase: SearchPostListUseCaseType + private let mutableRecommendedPostStream: MutableRecommendedPostStream? + var initialState: State = .init() // MARK: - Initializer init( - searchPostListUseCase: SearchPostListUseCaseType + searchPostListUseCase: SearchPostListUseCaseType, + mutableRecommendedPostStream: MutableRecommendedPostStream? = nil ) { - self.searchPostListUseCase = searchPostListUseCase + self.searchPostListUseCase = searchPostListUseCase + self.mutableRecommendedPostStream = mutableRecommendedPostStream } enum Action { @@ -32,12 +36,14 @@ final class PostSearchReactor: Reactor { enum Mutation { case setLoading(Bool) + case setSelectComplete(Bool) case setPosts(data: [PostCellData]) case setSelectedCell(data: PostCellData?) } struct State { var isLoading: Bool = false + var isSelectComplete: Bool = false var selectedCell: PostCellData? var posts: [PostCellData] = [] @@ -54,9 +60,10 @@ final class PostSearchReactor: Reactor { func reduce(state: State, mutation: Mutation) -> State { var newState = state switch mutation { - case let .setLoading(bool): newState.isLoading = bool - case let .setPosts(data): newState.posts = data - case let .setSelectedCell(data): newState.selectedCell = data + case let .setLoading(bool): newState.isLoading = bool + case let .setSelectComplete(bool): newState.isSelectComplete = bool + case let .setPosts(data): newState.posts = data + case let .setSelectedCell(data): newState.selectedCell = data } return newState } @@ -77,11 +84,17 @@ final class PostSearchReactor: Reactor { private func tapCell(at indexPath: IndexPath) -> Observable { return fetchCellData(at: indexPath) - .flatMap { cellData -> Observable in - Observable.concat([ - .just(.setSelectedCell(data: cellData)), - .just(.setSelectedCell(data: nil)) - ]) + .withUnretained(self) + .flatMap { owner, cellData -> Observable in + if let mutableRecommendedPostStream = owner.mutableRecommendedPostStream { + mutableRecommendedPostStream.updatePostInfo(id: cellData.id, subTitle: cellData.title) + return .just(.setSelectComplete(true)) + } else { + return Observable.concat([ + .just(.setSelectedCell(data: cellData)), + .just(.setSelectedCell(data: nil)) + ]) + } } } diff --git a/Targets/PresentationLayer/Sources/PostSearch/View/PostSearchViewController.swift b/Targets/PresentationLayer/Sources/PostSearch/View/PostSearchViewController.swift index 65409d2..9deea19 100644 --- a/Targets/PresentationLayer/Sources/PostSearch/View/PostSearchViewController.swift +++ b/Targets/PresentationLayer/Sources/PostSearch/View/PostSearchViewController.swift @@ -15,7 +15,7 @@ import PinLayout import ReactorKit import RxCocoa -final class PostSearchViewController: BaseViewController, Coordinatable { +final class PostSearchViewController: BaseViewController, Alertable, Coordinatable { // MARK: Properties weak var coordinator: PostSearchCoordinator? @@ -115,7 +115,7 @@ private extension PostSearchViewController { .disposed(by: disposeBag) searchBar.searchTextObservable - .skip(1) + .filter { $0?.isEmpty == false } .distinctUntilChanged() .compactMap { $0 } .debounce(.milliseconds(500), scheduler: ConcurrentDispatchQueueScheduler(qos: .background)) @@ -134,6 +134,17 @@ private extension PostSearchViewController { } .disposed(by: disposeBag) + reactor.state + .map(\.isSelectComplete) + .distinctUntilChanged() + .asSignal(onErrorJustReturn: true) + .emit(with: self) { owner, isComplete in + if isComplete { + owner.coordinator?.didFinish() + } + } + .disposed(by: disposeBag) + reactor.state .map { $0.posts } .distinctUntilChanged()