From da290b91003ead0c7600c762b68ef0b41dcee383 Mon Sep 17 00:00:00 2001 From: dlrjswns Date: Thu, 26 Sep 2024 05:52:30 +0900 Subject: [PATCH] =?UTF-8?q?#206=20=ED=99=88=ED=99=94=EB=A9=B4=20=EC=95=8C?= =?UTF-8?q?=EB=A6=BC=EB=B2=84=ED=8A=BC=EA=B4=80=EB=A0=A8=20=EB=B9=84?= =?UTF-8?q?=EC=A6=88=EB=8B=88=EC=8A=A4=20=EB=A1=9C=EC=A7=81=20=EB=B0=8F=20?= =?UTF-8?q?=ED=99=94=EB=A9=B4=EC=9D=B4=EB=8F=99=20=EC=BD=94=EB=93=9C=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ShowPot/ShowPot.xcodeproj/project.pbxproj | 12 ++++++++++ .../Featured/DefaultFeaturedUseCase.swift | 7 +++++- .../FetchNotificationUpdatesUseCase.swift | 13 +++++++++++ .../Tab/Featured/FeaturedCoordinator.swift | 7 +++++- .../Tab/Featured/FeaturedViewController.swift | 10 +++++++- .../Tab/Featured/FeaturedViewModel.swift | 23 +++++++++++++++++-- 6 files changed, 67 insertions(+), 5 deletions(-) create mode 100644 ShowPot/ShowPot/Domain/UseCase/Featured/Protocol/FetchNotificationUpdatesUseCase.swift diff --git a/ShowPot/ShowPot.xcodeproj/project.pbxproj b/ShowPot/ShowPot.xcodeproj/project.pbxproj index fb58add..4827625 100644 --- a/ShowPot/ShowPot.xcodeproj/project.pbxproj +++ b/ShowPot/ShowPot.xcodeproj/project.pbxproj @@ -139,6 +139,7 @@ 70DC8F6D2CA1B351006DDAF7 /* AlarmCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 70DC8F6C2CA1B351006DDAF7 /* AlarmCollectionViewCell.swift */; }; 70DC8F712CA27E37006DDAF7 /* MyAlarmListUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 70DC8F702CA27E37006DDAF7 /* MyAlarmListUseCase.swift */; }; 70DC8F732CA27E42006DDAF7 /* DefaultMyAlarmListUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 70DC8F722CA27E42006DDAF7 /* DefaultMyAlarmListUseCase.swift */; }; + 70DC8F762CA4A599006DDAF7 /* FetchNotificationUpdatesUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 70DC8F752CA4A599006DDAF7 /* FetchNotificationUpdatesUseCase.swift */; }; 70F3C0DB2C663A8900786738 /* MyShowAlarmViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 70F3C0DA2C663A8900786738 /* MyShowAlarmViewController.swift */; }; 70F3C0DD2C663A9C00786738 /* MyShowAlarmViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 70F3C0DC2C663A9C00786738 /* MyShowAlarmViewModel.swift */; }; 70F3C0DF2C663AA900786738 /* MyShowAlarmCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 70F3C0DE2C663AA900786738 /* MyShowAlarmCoordinator.swift */; }; @@ -436,6 +437,7 @@ 70DC8F6C2CA1B351006DDAF7 /* AlarmCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AlarmCollectionViewCell.swift; sourceTree = ""; }; 70DC8F702CA27E37006DDAF7 /* MyAlarmListUseCase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MyAlarmListUseCase.swift; sourceTree = ""; }; 70DC8F722CA27E42006DDAF7 /* DefaultMyAlarmListUseCase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DefaultMyAlarmListUseCase.swift; sourceTree = ""; }; + 70DC8F752CA4A599006DDAF7 /* FetchNotificationUpdatesUseCase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FetchNotificationUpdatesUseCase.swift; sourceTree = ""; }; 70F3C0DA2C663A8900786738 /* MyShowAlarmViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MyShowAlarmViewController.swift; sourceTree = ""; }; 70F3C0DC2C663A9C00786738 /* MyShowAlarmViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MyShowAlarmViewModel.swift; sourceTree = ""; }; 70F3C0DE2C663AA900786738 /* MyShowAlarmCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MyShowAlarmCoordinator.swift; sourceTree = ""; }; @@ -889,6 +891,7 @@ 70A95B812C7E29E80007836E /* Featured */ = { isa = PBXGroup; children = ( + 70DC8F742CA4A58E006DDAF7 /* Protocol */, 70A95B842C7E29FD0007836E /* DefaultFeaturedUseCase.swift */, ); path = Featured; @@ -1033,6 +1036,14 @@ path = MyAlarmList; sourceTree = ""; }; + 70DC8F742CA4A58E006DDAF7 /* Protocol */ = { + isa = PBXGroup; + children = ( + 70DC8F752CA4A599006DDAF7 /* FetchNotificationUpdatesUseCase.swift */, + ); + path = Protocol; + sourceTree = ""; + }; 70F3C0D92C663A7700786738 /* MyShowAlarm */ = { isa = PBXGroup; children = ( @@ -1973,6 +1984,7 @@ 7DD2CB872C2ED63E0052ECCD /* MyPageCoordinator.swift in Sources */, 7DEDA5492C70DFD000B07818 /* UIImageView+Extension.swift in Sources */, 7D6005052C7F595500B670A3 /* UserAccessRequest.swift in Sources */, + 70DC8F762CA4A599006DDAF7 /* FetchNotificationUpdatesUseCase.swift in Sources */, 7DD2CB812C2ED4430052ECCD /* FeaturedViewHolder.swift in Sources */, 700485112C7A382C00B9A964 /* TicketingAlarmBottomSheetViewController.swift in Sources */, 7D93096C2C569DFB000889DE /* SPSnackBar.swift in Sources */, diff --git a/ShowPot/ShowPot/Domain/UseCase/Featured/DefaultFeaturedUseCase.swift b/ShowPot/ShowPot/Domain/UseCase/Featured/DefaultFeaturedUseCase.swift index f6ea34d..9c1cf81 100644 --- a/ShowPot/ShowPot/Domain/UseCase/Featured/DefaultFeaturedUseCase.swift +++ b/ShowPot/ShowPot/Domain/UseCase/Featured/DefaultFeaturedUseCase.swift @@ -8,7 +8,7 @@ import Foundation import RxSwift import RxCocoa -final class DefaultFeaturedUseCase: SubscribeArtistUseCase, AllPerformanceUseCase { +final class DefaultFeaturedUseCase: SubscribeArtistUseCase, AllPerformanceUseCase, FetchNotificationUpdatesUseCase { private let disposeBag = DisposeBag() private let apiService: APIClient @@ -16,6 +16,7 @@ final class DefaultFeaturedUseCase: SubscribeArtistUseCase, AllPerformanceUseCas var artistList = BehaviorRelay<[FeaturedSubscribeArtistCellModel]>(value: []) var performanceList = BehaviorRelay<[FeaturedPerformanceWithTicketOnSaleSoonCellModel]>(value: []) var subscribeArtistResult = PublishSubject() + var hasNewNotifications = BehaviorRelay(value: false) init(apiService: APIClient = APIClient()) { self.apiService = apiService @@ -68,4 +69,8 @@ final class DefaultFeaturedUseCase: SubscribeArtistUseCase, AllPerformanceUseCas } .disposed(by: disposeBag) } + + func fetchNotificationUpdates() { + hasNewNotifications.accept([true, false].shuffled()[0]) + } } diff --git a/ShowPot/ShowPot/Domain/UseCase/Featured/Protocol/FetchNotificationUpdatesUseCase.swift b/ShowPot/ShowPot/Domain/UseCase/Featured/Protocol/FetchNotificationUpdatesUseCase.swift new file mode 100644 index 0000000..422329a --- /dev/null +++ b/ShowPot/ShowPot/Domain/UseCase/Featured/Protocol/FetchNotificationUpdatesUseCase.swift @@ -0,0 +1,13 @@ +// +// FetchNotificationUpdatesUseCase.swift +// ShowPot +// +// Created by 이건준 on 9/26/24. +// + +import RxCocoa + +protocol FetchNotificationUpdatesUseCase { + var hasNewNotifications: BehaviorRelay { get } + func fetchNotificationUpdates() +} diff --git a/ShowPot/ShowPot/Presentation/Scene/Tab/Featured/FeaturedCoordinator.swift b/ShowPot/ShowPot/Presentation/Scene/Tab/Featured/FeaturedCoordinator.swift index 3c35ae7..ba3fab1 100644 --- a/ShowPot/ShowPot/Presentation/Scene/Tab/Featured/FeaturedCoordinator.swift +++ b/ShowPot/ShowPot/Presentation/Scene/Tab/Featured/FeaturedCoordinator.swift @@ -25,7 +25,6 @@ final class FeaturedCoordinator: NavigationCoordinator { } -// TODO: 각 화면 개발 이후, 실제 로직 추가 필요 extension FeaturedCoordinator { func goToFeaturedSearchScreen() { @@ -57,4 +56,10 @@ extension FeaturedCoordinator { coordinator.start() self.childCoordinators.append(coordinator) } + + func goToMyAlarmListViewController() { + let coordinator = MyAlarmListCoordinator(navigationController: self.navigationController) + coordinator.start() + self.childCoordinators.append(coordinator) + } } diff --git a/ShowPot/ShowPot/Presentation/Scene/Tab/Featured/FeaturedViewController.swift b/ShowPot/ShowPot/Presentation/Scene/Tab/Featured/FeaturedViewController.swift index 1872a80..5c061f9 100644 --- a/ShowPot/ShowPot/Presentation/Scene/Tab/Featured/FeaturedViewController.swift +++ b/ShowPot/ShowPot/Presentation/Scene/Tab/Featured/FeaturedViewController.swift @@ -55,12 +55,14 @@ final class FeaturedViewController: ViewController { override func bind() { let input = FeaturedViewModel.Input( + viewWillAppear: self.rx.methodInvoked(#selector(UIViewController.viewWillAppear)).map { _ in Void() }, requestFeaturedSectionModel: .just(()), didTapSearchField: viewHolder.searchFieldTopView.rx.tapGesture().when(.recognized), didTappedSubscribeGenreButton: didTappedSubscribeGenreButtonSubject, didTappedSubscribeArtistButton: didTappedSubscribeArtistButtonSubject, didTappedFeaturedCell: viewHolder.featuredCollectionView.rx.itemSelected.asObservable(), - didTappedWatchTheFullPerformanceButton: didTappedWatchTheFullPerformanceButtonSubject.asObservable() + didTappedWatchTheFullPerformanceButton: didTappedWatchTheFullPerformanceButtonSubject.asObservable(), + didTappedRightBarButton: viewHolder.alarmRightBarButton.rx.tap.asObservable() ) let output = viewModel.transform(input: input) output.updateFeaturedLayout @@ -73,6 +75,12 @@ final class FeaturedViewController: ViewController { owner.showLoginBottomSheet() } .disposed(by: disposeBag) + + output.hasNewNotifications + .subscribe(with: self) { owner, hasNewNotifications in + owner.viewHolder.alarmRightBarButton.setImage(hasNewNotifications ? .icAlarmLargeOn : .icAlarmLarge, for: .normal) + } + .disposed(by: disposeBag) } } diff --git a/ShowPot/ShowPot/Presentation/Scene/Tab/Featured/FeaturedViewModel.swift b/ShowPot/ShowPot/Presentation/Scene/Tab/Featured/FeaturedViewModel.swift index a8a4ad3..88dec43 100644 --- a/ShowPot/ShowPot/Presentation/Scene/Tab/Featured/FeaturedViewModel.swift +++ b/ShowPot/ShowPot/Presentation/Scene/Tab/Featured/FeaturedViewModel.swift @@ -16,7 +16,7 @@ final class FeaturedViewModel: ViewModelType { var coordinator: FeaturedCoordinator private let disposeBag = DisposeBag() - private let usecase: SubscribeArtistUseCase & AllPerformanceUseCase + private let usecase: SubscribeArtistUseCase & AllPerformanceUseCase & FetchNotificationUpdatesUseCase private let subscribeGenreModelRelay = BehaviorRelay<[GenreType]>(value: []) private let recommendedPerformanceModelRelay = BehaviorRelay<[FeaturedRecommendedPerformanceCellModel]>(value: []) @@ -36,23 +36,26 @@ final class FeaturedViewModel: ViewModelType { featuredSectionModelRelay.value } - init(coordinator: FeaturedCoordinator, usecase: SubscribeArtistUseCase & AllPerformanceUseCase) { + init(coordinator: FeaturedCoordinator, usecase: SubscribeArtistUseCase & AllPerformanceUseCase & FetchNotificationUpdatesUseCase) { self.coordinator = coordinator self.usecase = usecase } struct Input { + let viewWillAppear: Observable let requestFeaturedSectionModel: Observable let didTapSearchField: Observable let didTappedSubscribeGenreButton: PublishSubject let didTappedSubscribeArtistButton: PublishSubject let didTappedFeaturedCell: Observable let didTappedWatchTheFullPerformanceButton: Observable + let didTappedRightBarButton: Observable } struct Output { let updateFeaturedLayout: Signal let showLoginBottomSheet: PublishSubject + let hasNewNotifications = PublishRelay() } func transform(input: Input) -> Output { @@ -82,6 +85,12 @@ final class FeaturedViewModel: ViewModelType { } .disposed(by: disposeBag) + input.didTappedRightBarButton + .subscribe(with: self) { owner, _ in + owner.coordinator.goToMyAlarmListViewController() + } + .disposed(by: disposeBag) + Observable.combineLatest( subscribeGenreModelRelay, usecase.artistList, @@ -97,6 +106,12 @@ final class FeaturedViewModel: ViewModelType { owner.updateFeaturedLayoutSubject.onNext(()) } .disposed(by: disposeBag) + + input.viewWillAppear + .subscribe(with: self) { owner, _ in + owner.usecase.fetchNotificationUpdates() + } + .disposed(by: disposeBag) } private func createOutput(from input: Input) -> Output { @@ -152,6 +167,10 @@ final class FeaturedViewModel: ViewModelType { } .disposed(by: disposeBag) + usecase.hasNewNotifications + .bind(to: output.hasNewNotifications) + .disposed(by: disposeBag) + return output } }