From 02e40d888710e8e0d8ea71dfc497ce85e88999e7 Mon Sep 17 00:00:00 2001 From: jjinwoong Date: Thu, 8 Dec 2022 23:22:22 +0900 Subject: [PATCH 01/11] =?UTF-8?q?[chore]=20=ED=95=84=EC=9A=94=ED=95=9C=20?= =?UTF-8?q?=ED=8C=8C=EC=9D=BC=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../UseCases/Common/DefaultFriendQuestUseCase.swift | 8 ++++++++ .../Common/Protocols/DefaultFriendCalendarUseCase.swift | 8 ++++++++ .../UseCases/Common/Protocols/FriendCalendarUseCase.swift | 8 ++++++++ .../UseCases/Common/Protocols/FriendQuestUseCase.swift | 8 ++++++++ .../Presentation/Common/ViewModel/FriendViewModel.swift | 8 ++++++++ 5 files changed, 40 insertions(+) create mode 100644 DailyQuest/DailyQuest/Domain/UseCases/Common/DefaultFriendQuestUseCase.swift create mode 100644 DailyQuest/DailyQuest/Domain/UseCases/Common/Protocols/DefaultFriendCalendarUseCase.swift create mode 100644 DailyQuest/DailyQuest/Domain/UseCases/Common/Protocols/FriendCalendarUseCase.swift create mode 100644 DailyQuest/DailyQuest/Domain/UseCases/Common/Protocols/FriendQuestUseCase.swift create mode 100644 DailyQuest/DailyQuest/Presentation/Common/ViewModel/FriendViewModel.swift diff --git a/DailyQuest/DailyQuest/Domain/UseCases/Common/DefaultFriendQuestUseCase.swift b/DailyQuest/DailyQuest/Domain/UseCases/Common/DefaultFriendQuestUseCase.swift new file mode 100644 index 0000000..f191197 --- /dev/null +++ b/DailyQuest/DailyQuest/Domain/UseCases/Common/DefaultFriendQuestUseCase.swift @@ -0,0 +1,8 @@ +// +// DefaultFriendQuestUseCase.swift +// DailyQuest +// +// Created by jinwoong Kim on 2022/12/08. +// + +import Foundation diff --git a/DailyQuest/DailyQuest/Domain/UseCases/Common/Protocols/DefaultFriendCalendarUseCase.swift b/DailyQuest/DailyQuest/Domain/UseCases/Common/Protocols/DefaultFriendCalendarUseCase.swift new file mode 100644 index 0000000..e6c6e40 --- /dev/null +++ b/DailyQuest/DailyQuest/Domain/UseCases/Common/Protocols/DefaultFriendCalendarUseCase.swift @@ -0,0 +1,8 @@ +// +// DefaultFriendCalendarUseCase.swift +// DailyQuest +// +// Created by jinwoong Kim on 2022/12/08. +// + +import Foundation diff --git a/DailyQuest/DailyQuest/Domain/UseCases/Common/Protocols/FriendCalendarUseCase.swift b/DailyQuest/DailyQuest/Domain/UseCases/Common/Protocols/FriendCalendarUseCase.swift new file mode 100644 index 0000000..2c787b0 --- /dev/null +++ b/DailyQuest/DailyQuest/Domain/UseCases/Common/Protocols/FriendCalendarUseCase.swift @@ -0,0 +1,8 @@ +// +// FriendCalendarUseCase.swift +// DailyQuest +// +// Created by jinwoong Kim on 2022/12/08. +// + +import Foundation diff --git a/DailyQuest/DailyQuest/Domain/UseCases/Common/Protocols/FriendQuestUseCase.swift b/DailyQuest/DailyQuest/Domain/UseCases/Common/Protocols/FriendQuestUseCase.swift new file mode 100644 index 0000000..f85dd3e --- /dev/null +++ b/DailyQuest/DailyQuest/Domain/UseCases/Common/Protocols/FriendQuestUseCase.swift @@ -0,0 +1,8 @@ +// +// FriendQuestUseCase.swift +// DailyQuest +// +// Created by jinwoong Kim on 2022/12/08. +// + +import Foundation diff --git a/DailyQuest/DailyQuest/Presentation/Common/ViewModel/FriendViewModel.swift b/DailyQuest/DailyQuest/Presentation/Common/ViewModel/FriendViewModel.swift new file mode 100644 index 0000000..ef658e7 --- /dev/null +++ b/DailyQuest/DailyQuest/Presentation/Common/ViewModel/FriendViewModel.swift @@ -0,0 +1,8 @@ +// +// FriendViewModel.swift +// DailyQuest +// +// Created by jinwoong Kim on 2022/12/08. +// + +import Foundation From c5bcc27bed0e829737447d1e981608b0ae84e7a0 Mon Sep 17 00:00:00 2001 From: jjinwoong Date: Thu, 8 Dec 2022 23:22:49 +0900 Subject: [PATCH 02/11] =?UTF-8?q?[feat]=20FriendQuest=20Usecase=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Common/DefaultFriendQuestUseCase.swift | 16 ++++++++++++++++ .../Common/Protocols/FriendQuestUseCase.swift | 6 ++++++ 2 files changed, 22 insertions(+) diff --git a/DailyQuest/DailyQuest/Domain/UseCases/Common/DefaultFriendQuestUseCase.swift b/DailyQuest/DailyQuest/Domain/UseCases/Common/DefaultFriendQuestUseCase.swift index f191197..dd38790 100644 --- a/DailyQuest/DailyQuest/Domain/UseCases/Common/DefaultFriendQuestUseCase.swift +++ b/DailyQuest/DailyQuest/Domain/UseCases/Common/DefaultFriendQuestUseCase.swift @@ -6,3 +6,19 @@ // import Foundation + +import RxSwift + +final class DefaultFriendUseCase { + private let questsRepository: QuestsRepository + + init(questsRepository: QuestsRepository) { + self.questsRepository = questsRepository + } +} + +extension DefaultFriendUseCase: FriendQuestUseCase { + func fetch(with uuid: String, by date: Date) -> Observable<[Quest]> { + return questsRepository.fetch(by: uuid, date: date) + } +} diff --git a/DailyQuest/DailyQuest/Domain/UseCases/Common/Protocols/FriendQuestUseCase.swift b/DailyQuest/DailyQuest/Domain/UseCases/Common/Protocols/FriendQuestUseCase.swift index f85dd3e..a8d8ce8 100644 --- a/DailyQuest/DailyQuest/Domain/UseCases/Common/Protocols/FriendQuestUseCase.swift +++ b/DailyQuest/DailyQuest/Domain/UseCases/Common/Protocols/FriendQuestUseCase.swift @@ -6,3 +6,9 @@ // import Foundation + +import RxSwift + +protocol FriendQuestUseCase { + func fetch(with uuid: String, by date: Date) -> Observable<[Quest]> +} From 9c26019a207d72a1603cdae8c1f028d0ebf41930 Mon Sep 17 00:00:00 2001 From: jjinwoong Date: Thu, 8 Dec 2022 23:23:18 +0900 Subject: [PATCH 03/11] =?UTF-8?q?[feat]=20FriendCalendarUseCase=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Common/DefaultFriendCalendarUseCase.swift | 176 ++++++++++++++++++ .../DefaultFriendCalendarUseCase.swift | 8 - .../Protocols/FriendCalendarUseCase.swift | 14 ++ 3 files changed, 190 insertions(+), 8 deletions(-) create mode 100644 DailyQuest/DailyQuest/Domain/UseCases/Common/DefaultFriendCalendarUseCase.swift delete mode 100644 DailyQuest/DailyQuest/Domain/UseCases/Common/Protocols/DefaultFriendCalendarUseCase.swift diff --git a/DailyQuest/DailyQuest/Domain/UseCases/Common/DefaultFriendCalendarUseCase.swift b/DailyQuest/DailyQuest/Domain/UseCases/Common/DefaultFriendCalendarUseCase.swift new file mode 100644 index 0000000..b1da2c1 --- /dev/null +++ b/DailyQuest/DailyQuest/Domain/UseCases/Common/DefaultFriendCalendarUseCase.swift @@ -0,0 +1,176 @@ +// +// DefaultFriendCalendarUseCase.swift +// DailyQuest +// +// Created by jinwoong Kim on 2022/12/08. +// + +import Foundation + +import RxSwift + +import RxSwift + +final class DefaultFriendCalendarUseCase: FriendCalendarUseCase { + private let user: User + private let questsRepository: QuestsRepository + private let disposeBag = DisposeBag() + + let currentMonth = BehaviorSubject(value: Date()) + let completionOfMonths = BehaviorSubject<[[DailyQuestCompletion]]>(value: [[], [], []]) + let selectedDate = BehaviorSubject(value: Date()) + + init(user: User, questsRepository: QuestsRepository) { + self.user = user + self.questsRepository = questsRepository + } + + func fetchNextMontlyCompletion() { + guard let nextMonth = try? currentMonth.value()?.startDayOfNextMonth else { return } + currentMonth.onNext(nextMonth) + + let monthAfterNext = nextMonth.startDayOfNextMonth + + fetchAMontlyCompletion(monthAfterNext) + .subscribe(onNext: { [weak self] monthlyCompletion in + guard + let self, + var values = try? self.completionOfMonths.value() + else { + return + } + + values.removeFirst() + values.append(monthlyCompletion) + + self.completionOfMonths.onNext(values) + }) + .disposed(by: disposeBag) + } + + func fetchLastMontlyCompletion() { + guard let lastMonth = try? currentMonth.value()?.startDayOfLastMonth else { return } + currentMonth.onNext(lastMonth) + + let monthBeforeLast = lastMonth.startDayOfLastMonth + + fetchAMontlyCompletion(monthBeforeLast) + .subscribe(onNext: { [weak self] monthlyCompletion in + guard + let self, + var values = try? self.completionOfMonths.value() + else { + return + } + + values.removeLast() + values.insert(monthlyCompletion, at: 0) + + self.completionOfMonths.onNext(values) + }) + .disposed(by: disposeBag) + } + + func setupMonths() { + let currentMonth = try? currentMonth.value() + let startDayOfLastMonth = currentMonth?.startDayOfLastMonth + let startDayOfCurrentMonth = currentMonth?.startDayOfCurrentMonth + let startDayOfNextMonth = currentMonth?.startDayOfNextMonth + + let months = [startDayOfLastMonth, startDayOfCurrentMonth, startDayOfNextMonth] + + Observable.from(months) + .concatMap { [weak self] monthDate in + guard let self else { return Observable<[DailyQuestCompletion]>.empty() } + + return self.fetchAMontlyCompletion(monthDate) + } + .toArray() + .subscribe(onSuccess: { [weak self] completionOfMonths in + self?.completionOfMonths.onNext(completionOfMonths) + }) + .disposed(by: disposeBag) + } + + func refreshMontlyCompletion(for date: Date) { + guard + let months = try? self.completionOfMonths.value(), + let index = months.firstIndex(where: { month in + month.contains { dailyQuestCompletion in + (dailyQuestCompletion.state != .hidden) + && (dailyQuestCompletion.day.startOfDay == date.startOfDay) + } + }), + let reloadMonth = months[index].last?.day.startDayOfCurrentMonth + else { + return + } + + fetchAMontlyCompletion(reloadMonth) + .subscribe(onNext: { [weak self] monthlyCompletion in + guard + let self, + var values = try? self.completionOfMonths.value() + else { + return + } + + values[index] = monthlyCompletion + + self.completionOfMonths.onNext(values) + }) + .disposed(by: disposeBag) + } + + func selectDate(_ date: Date) { + selectedDate.onNext(date) + } +} + +extension DefaultFriendCalendarUseCase { + + private func calculateDailyState(_ quests: [Quest]) -> DailyQuestCompletion.State { + guard !quests.isEmpty else { + return .normal + } + + let filteredQuests = quests.filter { !$0.state } + + if filteredQuests.isEmpty { + return .done + } else { + return .notDone(filteredQuests.count) + } + } + + private func fetchAMontlyCompletion(_ month: Date?) -> Observable<[DailyQuestCompletion]> { + guard let month = month else { return .empty() } + + return Observable.from(month.rangeDaysOfMonth) + .concatMap { [weak self] date -> Observable in + guard let self else { return Observable.empty() } + + return self.questsRepository + .fetch(by: self.user.uuid, date: date) + .map { quests -> DailyQuestCompletion in + let isSelected = (try? self.selectedDate.value().startOfDay == date) ?? false + + return DailyQuestCompletion( + day: date, + state: self.calculateDailyState(quests), + isSelected: isSelected + ) + } + } + .toArray() + .map { states in + let firstWeekStates = month.rangeFromStartWeekdayOfLastMonthToEndDayOfCurrentMonth + .map { date -> DailyQuestCompletion in + return DailyQuestCompletion(day: date, state: .hidden, isSelected: false) + } + + return firstWeekStates + states + } + .asObservable() + } +} diff --git a/DailyQuest/DailyQuest/Domain/UseCases/Common/Protocols/DefaultFriendCalendarUseCase.swift b/DailyQuest/DailyQuest/Domain/UseCases/Common/Protocols/DefaultFriendCalendarUseCase.swift deleted file mode 100644 index e6c6e40..0000000 --- a/DailyQuest/DailyQuest/Domain/UseCases/Common/Protocols/DefaultFriendCalendarUseCase.swift +++ /dev/null @@ -1,8 +0,0 @@ -// -// DefaultFriendCalendarUseCase.swift -// DailyQuest -// -// Created by jinwoong Kim on 2022/12/08. -// - -import Foundation diff --git a/DailyQuest/DailyQuest/Domain/UseCases/Common/Protocols/FriendCalendarUseCase.swift b/DailyQuest/DailyQuest/Domain/UseCases/Common/Protocols/FriendCalendarUseCase.swift index 2c787b0..0561238 100644 --- a/DailyQuest/DailyQuest/Domain/UseCases/Common/Protocols/FriendCalendarUseCase.swift +++ b/DailyQuest/DailyQuest/Domain/UseCases/Common/Protocols/FriendCalendarUseCase.swift @@ -6,3 +6,17 @@ // import Foundation + +import RxSwift + +protocol FriendCalendarUseCase { + var currentMonth: BehaviorSubject { get } + var completionOfMonths: BehaviorSubject<[[DailyQuestCompletion]]> { get } + var selectedDate: BehaviorSubject { get } + + func fetchNextMontlyCompletion() + func fetchLastMontlyCompletion() + func setupMonths() + func refreshMontlyCompletion(for date: Date) + func selectDate(_ date: Date) +} From ff3bd14fc33bc63f5f0c782132edecb4a49c027f Mon Sep 17 00:00:00 2001 From: jjinwoong Date: Thu, 8 Dec 2022 23:23:49 +0900 Subject: [PATCH 04/11] =?UTF-8?q?[feat]=20BrowseView=EC=97=90=EC=84=9C=20?= =?UTF-8?q?=EC=85=80=20=EC=84=A0=ED=83=9D=EC=8B=9C,=20=ED=95=B4=EB=8B=B9?= =?UTF-8?q?=20user=EB=A5=BC=20emit=ED=95=98=EB=8A=94=20publisher=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Browse/ViewController/BrowseViewController.swift | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/DailyQuest/DailyQuest/Presentation/Browse/ViewController/BrowseViewController.swift b/DailyQuest/DailyQuest/Presentation/Browse/ViewController/BrowseViewController.swift index e32d544..6146964 100644 --- a/DailyQuest/DailyQuest/Presentation/Browse/ViewController/BrowseViewController.swift +++ b/DailyQuest/DailyQuest/Presentation/Browse/ViewController/BrowseViewController.swift @@ -11,6 +11,9 @@ import RxSwift import RxCocoa final class BrowseViewController: UITableViewController { + + var coordinatorPublisher = PublishSubject() + private var viewModel: BrowseViewModel! private var disposableBag = DisposeBag() @@ -51,7 +54,13 @@ final class BrowseViewController: UITableViewController { cell.setup(with: item) } .disposed(by: disposableBag) - + + tableView + .rx + .modelSelected(BrowseItemViewModel.self) + .map { $0.user } + .bind(to: coordinatorPublisher) + .disposed(by: disposableBag) } } From da2ed1dacb495a95a741d66edeff15a97ac512f8 Mon Sep 17 00:00:00 2001 From: jjinwoong Date: Thu, 8 Dec 2022 23:24:09 +0900 Subject: [PATCH 05/11] =?UTF-8?q?[refactor]=20FriendStatusView=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Presentation/Common/FriendStatusView.swift | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/DailyQuest/DailyQuest/Presentation/Common/FriendStatusView.swift b/DailyQuest/DailyQuest/Presentation/Common/FriendStatusView.swift index baa8898..ca13cb4 100644 --- a/DailyQuest/DailyQuest/Presentation/Common/FriendStatusView.swift +++ b/DailyQuest/DailyQuest/Presentation/Common/FriendStatusView.swift @@ -15,6 +15,8 @@ final class FriendStatusView: UIView { private(set) lazy var profileImageView: UIImageView = { let profileImageView = UIImageView() profileImageView.image = UIImage(named: "StatusMax") + profileImageView.layer.cornerRadius = 35 + profileImageView.clipsToBounds = true return profileImageView }() @@ -58,15 +60,14 @@ final class FriendStatusView: UIView { addSubview(profileImageView) profileImageView.snp.makeConstraints { make in - make.height.equalToSuperview() - make.width.equalTo(profileImageView.snp.height) - make.leading.equalToSuperview() + make.height.width.equalTo(70) make.centerY.equalToSuperview() + make.leading.equalToSuperview().inset(15) } addSubview(labelContainer) labelContainer.snp.makeConstraints { make in - make.leading.equalTo(profileImageView.snp.trailing) + make.leading.equalTo(profileImageView.snp.trailing).offset(15) make.centerY.equalToSuperview() } } From 555ec5091f8d1d6b88bc63edd92551bbf7ef64b9 Mon Sep 17 00:00:00 2001 From: jjinwoong Date: Thu, 8 Dec 2022 23:24:27 +0900 Subject: [PATCH 06/11] =?UTF-8?q?[refactor]=20QuestViewHeader=EC=9D=98=20?= =?UTF-8?q?=EB=B2=84=ED=8A=BC=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../DailyQuest/Presentation/Home/View/QuestViewHeader.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DailyQuest/DailyQuest/Presentation/Home/View/QuestViewHeader.swift b/DailyQuest/DailyQuest/Presentation/Home/View/QuestViewHeader.swift index f46c408..732d810 100644 --- a/DailyQuest/DailyQuest/Presentation/Home/View/QuestViewHeader.swift +++ b/DailyQuest/DailyQuest/Presentation/Home/View/QuestViewHeader.swift @@ -25,7 +25,7 @@ final class QuestViewHeader: UIStackView { return titleLabel }() - private lazy var plusButton: UIButton = { + private(set) lazy var plusButton: UIButton = { var config = UIButton.Configuration.maxStyle() let plusButton = UIButton(configuration: config) From 8e03823567aa053a43471f7a0f64f9aeaf0dffa6 Mon Sep 17 00:00:00 2001 From: jjinwoong Date: Thu, 8 Dec 2022 23:24:38 +0900 Subject: [PATCH 07/11] =?UTF-8?q?[feat]=20FriendViewController=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ViewController/FriendViewController.swift | 167 +++++++++++++++++- 1 file changed, 158 insertions(+), 9 deletions(-) diff --git a/DailyQuest/DailyQuest/Presentation/Common/ViewController/FriendViewController.swift b/DailyQuest/DailyQuest/Presentation/Common/ViewController/FriendViewController.swift index 3b474ac..ed77437 100644 --- a/DailyQuest/DailyQuest/Presentation/Common/ViewController/FriendViewController.swift +++ b/DailyQuest/DailyQuest/Presentation/Common/ViewController/FriendViewController.swift @@ -8,9 +8,15 @@ import UIKit import SnapKit +import RxSwift +import RxCocoa final class FriendViewController: UIViewController { + private var viewModel: FriendViewModel! + private var disposableBag = DisposeBag() + private var questViewDelegate: QuestViewDelegate? + // MARK: - Components private lazy var scrollView: UIScrollView = { return UIScrollView() @@ -27,28 +33,47 @@ final class FriendViewController: UIViewController { return FriendStatusView() }() - /** - Calendar view goes here. - */ + private lazy var calendarView: CalendarView = { + return CalendarView() + }() + + private lazy var questView: QuestView = { + let questView = QuestView() + + return questView + }() - /** - Quest view goes here. - */ + private lazy var questViewHeader: QuestViewHeader = { + let questViewHeader = QuestViewHeader() + questViewHeader.plusButton.isHidden = true + + return questViewHeader + }() // MARK: - Life Cycle - /** - property method, `create` goes here. - */ + static func create(with viewModel: FriendViewModel) -> FriendViewController { + let vc = FriendViewController() + vc.viewModel = viewModel + + return vc + } override func viewDidLoad() { super.viewDidLoad() + questViewDelegate = QuestViewDelegate(header: questViewHeader) + questView.delegate = questViewDelegate + configureUI() + + bind() } private func configureUI() { view.backgroundColor = .white stackView.addArrangedSubview(friendStatusView) + stackView.addArrangedSubview(calendarView) + stackView.addArrangedSubview(questView) scrollView.addSubview(stackView) @@ -66,5 +91,129 @@ final class FriendViewController: UIViewController { friendStatusView.snp.makeConstraints { make in make.height.equalTo(100) } + + calendarView.snp.makeConstraints { make in + make.height.equalTo(calendarView.snp.width).multipliedBy(1.4) + } + } + + private func bind() { + let viewDidLoad = Observable.just(Date()).share().asObservable() + + let willEndDragEvent = calendarView + .monthCollectionView + .rx + .willEndDragging + .map { (velocity, _) -> CalendarView.ScrollDirection in + if velocity.x > 0 { + return .next + } else if velocity.x < 0 { + return .prev + } else { + return .none + } + } + + let dragEventInCalendar = calendarView + .monthCollectionView + .rx + .didEndDecelerating + .withLatestFrom(willEndDragEvent) + + let daySelected = calendarView + .monthCollectionView + .rx + .itemSelected + .compactMap(calendarView.dataSource.itemIdentifier(for:)) + .map { dailyQuestCompletion in + dailyQuestCompletion.day + } + .asObservable() + + let output = viewModel.transform( + input: FriendViewModel.Input( + viewDidLoad: viewDidLoad, + dragEventInCalendar: dragEventInCalendar, + daySelected: daySelected + ), + disposableBag: disposableBag + ) + + bindToStatusView(with: output) + bindToCalendarView(with: output) + bindToQuestView(with: output) + } + + private func bindToStatusView(with output: FriendViewModel.Output) { + output + .userData + .map({ $0.nickName }) + .drive(friendStatusView.userNameLabel.rx.text) + .disposed(by: disposableBag) + + output + .userData + .map({ $0.introduce }) + .drive(friendStatusView.introduceLabel.rx.text) + .disposed(by: disposableBag) + + output + .userData + .drive(onNext: { [weak self] user in + guard let self = self else { return } + if user.profileURL != "" { + self.friendStatusView.profileImageView.setImage(with: user.profileURL) + } else { + self.friendStatusView.profileImageView.image = UIImage(named: "StatusMax") + } + }) + .disposed(by: disposableBag) + } + + private func bindToCalendarView(with output: FriendViewModel.Output) { + output + .displayDays + .drive(onNext: { [weak self] dailyQuestCompletions in + var snapshot = NSDiffableDataSourceSnapshot() + let allSectionIndex = dailyQuestCompletions.indices.map { Int($0) } + snapshot.appendSections(allSectionIndex) + + allSectionIndex.forEach { index in + snapshot.appendItems(dailyQuestCompletions[index], toSection: index) + } + + self?.calendarView.dataSource.apply(snapshot, animatingDifferences: false) + self?.calendarView.monthCollectionView.layoutIfNeeded() + + let selectedItem = dailyQuestCompletions + .flatMap({ $0 }) + .first(where: { dailyQuestCompletion in + dailyQuestCompletion.isSelected + }) + + if let selectedItem, let indexPath = self?.calendarView.dataSource.indexPath(for: selectedItem) { + self?.calendarView.monthCollectionView.selectItem(at: indexPath, animated: false, scrollPosition: .centeredHorizontally) + } + + self?.calendarView.monthCollectionView.scrollToItem(at: IndexPath(item: 0, section: 1), + at: .centeredHorizontally, + animated: false) + }) + .disposed(by: disposableBag) + + output + .currentMonth + .compactMap({ $0?.toFormat }) + .bind(to: calendarView.yearMonthLabel.rx.text) + .disposed(by: disposableBag) + } + + private func bindToQuestView(with output: FriendViewModel.Output) { + output + .data + .drive(questView.rx.items(cellIdentifier: QuestCell.reuseIdentifier, cellType: QuestCell.self)) { _, item, cell in + cell.setup(with: item) + } + .disposed(by: disposableBag) } } From 4be280a1051b6030bd863810ee7f75726510b06d Mon Sep 17 00:00:00 2001 From: jjinwoong Date: Thu, 8 Dec 2022 23:24:48 +0900 Subject: [PATCH 08/11] =?UTF-8?q?[feat]=20FriendViewModel=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Common/ViewModel/FriendViewModel.swift | 89 +++++++++++++++++++ 1 file changed, 89 insertions(+) diff --git a/DailyQuest/DailyQuest/Presentation/Common/ViewModel/FriendViewModel.swift b/DailyQuest/DailyQuest/Presentation/Common/ViewModel/FriendViewModel.swift index ef658e7..5439d18 100644 --- a/DailyQuest/DailyQuest/Presentation/Common/ViewModel/FriendViewModel.swift +++ b/DailyQuest/DailyQuest/Presentation/Common/ViewModel/FriendViewModel.swift @@ -6,3 +6,92 @@ // import Foundation + +import RxSwift +import RxCocoa + +final class FriendViewModel { + private(set) var user: User + private let friendQuestUseCase: FriendQuestUseCase + private let friendCalendarUseCase: FriendCalendarUseCase + + init(user: User, + friendQuestUseCase: FriendQuestUseCase, + friendCalendarUseCase: FriendCalendarUseCase) + { + self.user = user + self.friendQuestUseCase = friendQuestUseCase + self.friendCalendarUseCase = friendCalendarUseCase + } + + struct Input { + let viewDidLoad: Observable + let dragEventInCalendar: Observable + let daySelected: Observable + } + + struct Output { + let userData: Driver + let data: Driver<[Quest]> + let currentMonth: Observable + let displayDays: Driver<[[DailyQuestCompletion]]> + } + + func transform(input: Input, disposableBag: DisposeBag) -> Output { + + let data = Observable + .merge( + input.viewDidLoad, + input.daySelected + ) + .flatMap(fetch(by:)) + .asDriver(onErrorJustReturn: []) + + let userData = input.viewDidLoad + .compactMap({ [weak self] _ in self?.user }) + .asDriver(onErrorJustReturn: User()) + + input + .viewDidLoad + .subscribe(onNext: { [weak self] _ in + self?.friendCalendarUseCase.setupMonths() + }) + .disposed(by: disposableBag) + + input + .dragEventInCalendar + .subscribe(onNext: { [weak self] direction in + switch direction { + case .prev: + self?.friendCalendarUseCase.fetchLastMontlyCompletion() + case .none: + break + case .next: + self?.friendCalendarUseCase.fetchNextMontlyCompletion() + } + }) + .disposed(by: disposableBag) + + input.daySelected + .bind { [weak self] date in + self?.friendCalendarUseCase.selectDate(date) + } + .disposed(by: disposableBag) + + let currentMonth = friendCalendarUseCase + .currentMonth + .asObserver() + + let displayDays = friendCalendarUseCase + .completionOfMonths + .asDriver(onErrorJustReturn: [[], [], []]) + + return Output(userData: userData, data: data, currentMonth: currentMonth, displayDays: displayDays) + } +} + +private extension FriendViewModel { + func fetch(by date: Date) -> Observable<[Quest]> { + return friendQuestUseCase.fetch(with: user.uuid, by: date) + } +} From 7793ae0a31a7f7d3fb12f21166011e79e173352b Mon Sep 17 00:00:00 2001 From: jjinwoong Date: Thu, 8 Dec 2022 23:24:59 +0900 Subject: [PATCH 09/11] =?UTF-8?q?[feat]=20=EA=B4=80=EB=A0=A8=20DI=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../DIContainer/BrowseSceneDIContainer.swift | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/DailyQuest/DailyQuest/Application/DIContainer/BrowseSceneDIContainer.swift b/DailyQuest/DailyQuest/Application/DIContainer/BrowseSceneDIContainer.swift index 625eae9..e8e80c2 100644 --- a/DailyQuest/DailyQuest/Application/DIContainer/BrowseSceneDIContainer.swift +++ b/DailyQuest/DailyQuest/Application/DIContainer/BrowseSceneDIContainer.swift @@ -10,27 +10,50 @@ import UIKit final class BrowseSceneDIContainer { lazy var browseQuestsStorage: BrowseQuestsStorage = RealmBrowseQuestsStorage() + lazy var questsStorage: QuestsStorage = RealmQuestsStorage() // MARK: - Repositories func makeBrowseRepository() -> BrowseRepository { return DefaultBrowseRepository(persistentStorage: browseQuestsStorage) } + func makeQuestsRepository() -> QuestsRepository { + return DefaultQuestsRepository(persistentStorage: questsStorage) + } + // MARK: - Use Cases func makeBrowseUseCase() -> BrowseUseCase { return DefaultBrowseUseCase(browseRepository: makeBrowseRepository()) } + func makeFriendQuestUseCase() -> FriendQuestUseCase { + return DefaultFriendUseCase(questsRepository: makeQuestsRepository()) + } + + func makeFriendCalendarUseCase(with user: User) -> FriendCalendarUseCase { + return DefaultFriendCalendarUseCase(user: user, questsRepository: makeQuestsRepository()) + } + // MARK: - View Models func makeBrowseViewModel() -> BrowseViewModel { return BrowseViewModel(browseUseCase: makeBrowseUseCase()) } + func makeFriendViewModel(with user: User) -> FriendViewModel { + return FriendViewModel(user: user, + friendQuestUseCase: makeFriendQuestUseCase(), + friendCalendarUseCase: makeFriendCalendarUseCase(with: user)) + } + // MARK: - View Controller func makeBrowseViewController() -> BrowseViewController { return BrowseViewController.create(with: makeBrowseViewModel()) } + func makeFriendViewController(with user: User) -> FriendViewController { + return FriendViewController.create(with: makeFriendViewModel(with: user)) + } + // MARK: - Flow func makeBrowseCoordinator(navigationController: UINavigationController, browseSceneDIContainer: BrowseSceneDIContainer) -> BrowseCoordinator { From ed76053edd4a5fd88fdd4775f88052264ed2711c Mon Sep 17 00:00:00 2001 From: jjinwoong Date: Thu, 8 Dec 2022 23:25:22 +0900 Subject: [PATCH 10/11] =?UTF-8?q?[feat]=20BrowseCoordinator=EC=97=90?= =?UTF-8?q?=EC=84=9C=20FriendView=EB=A1=9C=20=EC=9D=B4=EB=8F=99=ED=95=A0?= =?UTF-8?q?=20=EC=88=98=20=EC=9E=88=EB=8A=94=20=EA=B8=B0=EB=8A=A5=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../DailyQuest.xcodeproj/project.pbxproj | 44 +++++++++++++++++++ .../Browse/Flow/BrowseCoordinator.swift | 16 +++++-- 2 files changed, 57 insertions(+), 3 deletions(-) diff --git a/DailyQuest/DailyQuest.xcodeproj/project.pbxproj b/DailyQuest/DailyQuest.xcodeproj/project.pbxproj index 2edd43d..2fc6926 100644 --- a/DailyQuest/DailyQuest.xcodeproj/project.pbxproj +++ b/DailyQuest/DailyQuest.xcodeproj/project.pbxproj @@ -62,6 +62,11 @@ 345687FA2937815900CA51E3 /* QuantityView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 345687F92937815900CA51E3 /* QuantityView.swift */; }; 345687FE29378AB900CA51E3 /* EnrollViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 345687FD29378AB900CA51E3 /* EnrollViewModel.swift */; }; 34642AB62925D9E40052FA0E /* UserInfoView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34642AB52925D9E40052FA0E /* UserInfoView.swift */; }; + 3472E8F129420D9600BB304F /* FriendViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3472E8F029420D9600BB304F /* FriendViewModel.swift */; }; + 3472E8F52942135D00BB304F /* FriendQuestUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3472E8F42942135D00BB304F /* FriendQuestUseCase.swift */; }; + 3472E8F7294213BE00BB304F /* DefaultFriendQuestUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3472E8F6294213BE00BB304F /* DefaultFriendQuestUseCase.swift */; }; + 3472E8F929421C7C00BB304F /* FriendCalendarUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3472E8F829421C7C00BB304F /* FriendCalendarUseCase.swift */; }; + 3472E8FB29421CB500BB304F /* DefaultFriendCalendarUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3472E8FA29421CB500BB304F /* DefaultFriendCalendarUseCase.swift */; }; 347D258B292C60F40038FCA2 /* StatusView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 347D258A292C60F40038FCA2 /* StatusView.swift */; }; 347D258D292C6E220038FCA2 /* MessageBubble.swift in Sources */ = {isa = PBXBuildFile; fileRef = 347D258C292C6E220038FCA2 /* MessageBubble.swift */; }; 34874AA0292509A4000570DF /* QuestViewHeader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34874A9F292509A4000570DF /* QuestViewHeader.swift */; }; @@ -285,6 +290,11 @@ 345687F92937815900CA51E3 /* QuantityView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QuantityView.swift; sourceTree = ""; }; 345687FD29378AB900CA51E3 /* EnrollViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EnrollViewModel.swift; sourceTree = ""; }; 34642AB52925D9E40052FA0E /* UserInfoView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UserInfoView.swift; sourceTree = ""; }; + 3472E8F029420D9600BB304F /* FriendViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FriendViewModel.swift; sourceTree = ""; }; + 3472E8F42942135D00BB304F /* FriendQuestUseCase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FriendQuestUseCase.swift; sourceTree = ""; }; + 3472E8F6294213BE00BB304F /* DefaultFriendQuestUseCase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DefaultFriendQuestUseCase.swift; sourceTree = ""; }; + 3472E8F829421C7C00BB304F /* FriendCalendarUseCase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FriendCalendarUseCase.swift; sourceTree = ""; }; + 3472E8FA29421CB500BB304F /* DefaultFriendCalendarUseCase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DefaultFriendCalendarUseCase.swift; sourceTree = ""; }; 347D258A292C60F40038FCA2 /* StatusView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatusView.swift; sourceTree = ""; }; 347D258C292C6E220038FCA2 /* MessageBubble.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageBubble.swift; sourceTree = ""; }; 34874A9F292509A4000570DF /* QuestViewHeader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QuestViewHeader.swift; sourceTree = ""; }; @@ -634,6 +644,7 @@ 3449AD5E292219D600B87619 /* Common */ = { isa = PBXGroup; children = ( + 3472E8EF29420D8D00BB304F /* ViewModel */, 34FCD367293DEEBC00E0DC8A /* ViewController */, 3499551C292332DE007AB99E /* Cells */, B50078D529222F3F0070AFC4 /* CircleCheckView.swift */, @@ -654,6 +665,33 @@ path = View; sourceTree = ""; }; + 3472E8EF29420D8D00BB304F /* ViewModel */ = { + isa = PBXGroup; + children = ( + 3472E8F029420D9600BB304F /* FriendViewModel.swift */, + ); + path = ViewModel; + sourceTree = ""; + }; + 3472E8F22942133B00BB304F /* Common */ = { + isa = PBXGroup; + children = ( + 3472E8F32942134000BB304F /* Protocols */, + 3472E8FA29421CB500BB304F /* DefaultFriendCalendarUseCase.swift */, + 3472E8F6294213BE00BB304F /* DefaultFriendQuestUseCase.swift */, + ); + path = Common; + sourceTree = ""; + }; + 3472E8F32942134000BB304F /* Protocols */ = { + isa = PBXGroup; + children = ( + 3472E8F42942135D00BB304F /* FriendQuestUseCase.swift */, + 3472E8F829421C7C00BB304F /* FriendCalendarUseCase.swift */, + ); + path = Protocols; + sourceTree = ""; + }; 34995510292321FD007AB99E /* Utils */ = { isa = PBXGroup; children = ( @@ -684,6 +722,7 @@ 34995516292329F4007AB99E /* UseCases */ = { isa = PBXGroup; children = ( + 3472E8F22942133B00BB304F /* Common */, 3417B1402935DA1B00900454 /* Settings */, 3417B13F2935DA1500900454 /* Browse */, 3416FC85292B549900B504C5 /* Home */, @@ -1291,6 +1330,7 @@ buildActionMask = 2147483647; files = ( 34404D94293EF9850007E661 /* SettingsUseCase.swift in Sources */, + 3472E8F929421C7C00BB304F /* FriendCalendarUseCase.swift in Sources */, A5A8C8362936EC7E00988C88 /* SubQuestEntity.swift in Sources */, 34EC71D1292DF27E004813CB /* Date+.swift in Sources */, 34D8360129359C8A001DE9DF /* BrowseRepository.swift in Sources */, @@ -1332,6 +1372,7 @@ A50F9A3429266F45005C00FE /* NetworkService.swift in Sources */, A51F01DA292345990031ECA2 /* BrowseQuest.swift in Sources */, A5AC96E629223F06003B7637 /* QuestsStorage.swift in Sources */, + 3472E8F129420D9600BB304F /* FriendViewModel.swift in Sources */, A51F01D52923407E0031ECA2 /* BrowseQuestEntity.swift in Sources */, 3416FC8A292B560800B504C5 /* DefaultQuestUseCase.swift in Sources */, 9BD8CCF32935BC0D00E6EA2F /* DefaultBrowseRepository.swift in Sources */, @@ -1377,6 +1418,7 @@ A51189C329226E66008A9D33 /* QuestEntity+Mapping.swift in Sources */, A51F01D3292340360031ECA2 /* BrowseQuestsStorage.swift in Sources */, A50F9A3729266F6F005C00FE /* FirebaseService.swift in Sources */, + 3472E8F52942135D00BB304F /* FriendQuestUseCase.swift in Sources */, 9B1CFB3F292B585700CCE97A /* QuestDTO+Mapping.swift in Sources */, 34874AA0292509A4000570DF /* QuestViewHeader.swift in Sources */, 342830F4292E19B700AE811B /* PlainCell.swift in Sources */, @@ -1401,6 +1443,7 @@ 34283101292E2D7A00AE811B /* ToggleItemViewModel.swift in Sources */, 34FCD366293DE62700E0DC8A /* DefaultEnrollUseCase.swift in Sources */, A5AC96E829223F27003B7637 /* RealmQuestsStorage.swift in Sources */, + 3472E8FB29421CB500BB304F /* DefaultFriendCalendarUseCase.swift in Sources */, A5003AB4293F5FEC00082A9C /* SignUpViewModel.swift in Sources */, 345687F829374D2500CA51E3 /* DayNamePickerView.swift in Sources */, 349955122923220E007AB99E /* SwiftUIPreview.swift in Sources */, @@ -1409,6 +1452,7 @@ 9BED4DEE2941932200C60631 /* CameraIconView.swift in Sources */, 34ACC32F291DE9C000741371 /* SceneDelegate.swift in Sources */, 34A529D829247A87001BAD34 /* HomeCoordinator.swift in Sources */, + 3472E8F7294213BE00BB304F /* DefaultFriendQuestUseCase.swift in Sources */, 34283103292E2D9B00AE811B /* ToggleCell.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; diff --git a/DailyQuest/DailyQuest/Presentation/Browse/Flow/BrowseCoordinator.swift b/DailyQuest/DailyQuest/Presentation/Browse/Flow/BrowseCoordinator.swift index 8df4d9b..d62587f 100644 --- a/DailyQuest/DailyQuest/Presentation/Browse/Flow/BrowseCoordinator.swift +++ b/DailyQuest/DailyQuest/Presentation/Browse/Flow/BrowseCoordinator.swift @@ -7,11 +7,15 @@ import UIKit +import RxSwift + protocol BrowseCoordinator: Coordinator { - func showDetailFlow() + func showFriendFlow(with user: User) } final class DefaultBrowseCoordinator: BrowseCoordinator { + private var disposableBag = DisposeBag() + var finishDelegate: CoordinatorFinishDelegate? var childCoordinators: [Coordinator] = [] var navigationController: UINavigationController @@ -26,10 +30,16 @@ final class DefaultBrowseCoordinator: BrowseCoordinator { func start() { let browseViewController = browseSceneDIContainer.makeBrowseViewController() navigationController.pushViewController(browseViewController, animated: false) + + browseViewController + .coordinatorPublisher + .subscribe(onNext: showFriendFlow(with:)) + .disposed(by: disposableBag) } - func showDetailFlow() { - + func showFriendFlow(with user: User) { + let friendViewController = browseSceneDIContainer.makeFriendViewController(with: user) + navigationController.present(friendViewController, animated: true) } } From 0fab7cde48bd0ec3a59f1ee0914d5ed05ff708cc Mon Sep 17 00:00:00 2001 From: jjinwoong Date: Thu, 8 Dec 2022 23:37:24 +0900 Subject: [PATCH 11/11] =?UTF-8?q?[refactor]=20=EC=BA=98=EB=A6=B0=EB=8D=94?= =?UTF-8?q?=20=EC=A0=95=EB=B3=B4=EB=A5=BC=20=ED=95=9C=EB=8B=AC=EC=B9=98?= =?UTF-8?q?=EB=A7=8C=20=EA=B0=80=EC=A0=B8=EC=98=A4=EA=B2=8C=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Common/DefaultFriendCalendarUseCase.swift | 94 +------------------ .../Protocols/FriendCalendarUseCase.swift | 3 - .../ViewController/FriendViewController.swift | 7 -- .../Common/ViewModel/FriendViewModel.swift | 15 --- 4 files changed, 5 insertions(+), 114 deletions(-) diff --git a/DailyQuest/DailyQuest/Domain/UseCases/Common/DefaultFriendCalendarUseCase.swift b/DailyQuest/DailyQuest/Domain/UseCases/Common/DefaultFriendCalendarUseCase.swift index b1da2c1..200d439 100644 --- a/DailyQuest/DailyQuest/Domain/UseCases/Common/DefaultFriendCalendarUseCase.swift +++ b/DailyQuest/DailyQuest/Domain/UseCases/Common/DefaultFriendCalendarUseCase.swift @@ -25,100 +25,16 @@ final class DefaultFriendCalendarUseCase: FriendCalendarUseCase { self.questsRepository = questsRepository } - func fetchNextMontlyCompletion() { - guard let nextMonth = try? currentMonth.value()?.startDayOfNextMonth else { return } - currentMonth.onNext(nextMonth) - - let monthAfterNext = nextMonth.startDayOfNextMonth - - fetchAMontlyCompletion(monthAfterNext) - .subscribe(onNext: { [weak self] monthlyCompletion in - guard - let self, - var values = try? self.completionOfMonths.value() - else { - return - } - - values.removeFirst() - values.append(monthlyCompletion) - - self.completionOfMonths.onNext(values) - }) - .disposed(by: disposeBag) - } - - func fetchLastMontlyCompletion() { - guard let lastMonth = try? currentMonth.value()?.startDayOfLastMonth else { return } - currentMonth.onNext(lastMonth) - - let monthBeforeLast = lastMonth.startDayOfLastMonth - - fetchAMontlyCompletion(monthBeforeLast) - .subscribe(onNext: { [weak self] monthlyCompletion in - guard - let self, - var values = try? self.completionOfMonths.value() - else { - return - } - - values.removeLast() - values.insert(monthlyCompletion, at: 0) - - self.completionOfMonths.onNext(values) - }) - .disposed(by: disposeBag) - } - func setupMonths() { let currentMonth = try? currentMonth.value() - let startDayOfLastMonth = currentMonth?.startDayOfLastMonth let startDayOfCurrentMonth = currentMonth?.startDayOfCurrentMonth - let startDayOfNextMonth = currentMonth?.startDayOfNextMonth - - let months = [startDayOfLastMonth, startDayOfCurrentMonth, startDayOfNextMonth] - Observable.from(months) - .concatMap { [weak self] monthDate in - guard let self else { return Observable<[DailyQuestCompletion]>.empty() } - - return self.fetchAMontlyCompletion(monthDate) - } - .toArray() - .subscribe(onSuccess: { [weak self] completionOfMonths in - self?.completionOfMonths.onNext(completionOfMonths) - }) - .disposed(by: disposeBag) - } - - func refreshMontlyCompletion(for date: Date) { - guard - let months = try? self.completionOfMonths.value(), - let index = months.firstIndex(where: { month in - month.contains { dailyQuestCompletion in - (dailyQuestCompletion.state != .hidden) - && (dailyQuestCompletion.day.startOfDay == date.startOfDay) - } - }), - let reloadMonth = months[index].last?.day.startDayOfCurrentMonth - else { - return - } + let months = startDayOfCurrentMonth - fetchAMontlyCompletion(reloadMonth) - .subscribe(onNext: { [weak self] monthlyCompletion in - guard - let self, - var values = try? self.completionOfMonths.value() - else { - return - } - - values[index] = monthlyCompletion - - self.completionOfMonths.onNext(values) - }) + Observable.just(months) + .flatMap(fetchAMontlyCompletion(_:)) + .map { [[], $0, []] } + .bind(to: completionOfMonths) .disposed(by: disposeBag) } diff --git a/DailyQuest/DailyQuest/Domain/UseCases/Common/Protocols/FriendCalendarUseCase.swift b/DailyQuest/DailyQuest/Domain/UseCases/Common/Protocols/FriendCalendarUseCase.swift index 0561238..28eaca2 100644 --- a/DailyQuest/DailyQuest/Domain/UseCases/Common/Protocols/FriendCalendarUseCase.swift +++ b/DailyQuest/DailyQuest/Domain/UseCases/Common/Protocols/FriendCalendarUseCase.swift @@ -14,9 +14,6 @@ protocol FriendCalendarUseCase { var completionOfMonths: BehaviorSubject<[[DailyQuestCompletion]]> { get } var selectedDate: BehaviorSubject { get } - func fetchNextMontlyCompletion() - func fetchLastMontlyCompletion() func setupMonths() - func refreshMontlyCompletion(for date: Date) func selectDate(_ date: Date) } diff --git a/DailyQuest/DailyQuest/Presentation/Common/ViewController/FriendViewController.swift b/DailyQuest/DailyQuest/Presentation/Common/ViewController/FriendViewController.swift index ed77437..92a72ae 100644 --- a/DailyQuest/DailyQuest/Presentation/Common/ViewController/FriendViewController.swift +++ b/DailyQuest/DailyQuest/Presentation/Common/ViewController/FriendViewController.swift @@ -114,12 +114,6 @@ final class FriendViewController: UIViewController { } } - let dragEventInCalendar = calendarView - .monthCollectionView - .rx - .didEndDecelerating - .withLatestFrom(willEndDragEvent) - let daySelected = calendarView .monthCollectionView .rx @@ -133,7 +127,6 @@ final class FriendViewController: UIViewController { let output = viewModel.transform( input: FriendViewModel.Input( viewDidLoad: viewDidLoad, - dragEventInCalendar: dragEventInCalendar, daySelected: daySelected ), disposableBag: disposableBag diff --git a/DailyQuest/DailyQuest/Presentation/Common/ViewModel/FriendViewModel.swift b/DailyQuest/DailyQuest/Presentation/Common/ViewModel/FriendViewModel.swift index 5439d18..b934e0b 100644 --- a/DailyQuest/DailyQuest/Presentation/Common/ViewModel/FriendViewModel.swift +++ b/DailyQuest/DailyQuest/Presentation/Common/ViewModel/FriendViewModel.swift @@ -26,7 +26,6 @@ final class FriendViewModel { struct Input { let viewDidLoad: Observable - let dragEventInCalendar: Observable let daySelected: Observable } @@ -58,20 +57,6 @@ final class FriendViewModel { }) .disposed(by: disposableBag) - input - .dragEventInCalendar - .subscribe(onNext: { [weak self] direction in - switch direction { - case .prev: - self?.friendCalendarUseCase.fetchLastMontlyCompletion() - case .none: - break - case .next: - self?.friendCalendarUseCase.fetchNextMontlyCompletion() - } - }) - .disposed(by: disposableBag) - input.daySelected .bind { [weak self] date in self?.friendCalendarUseCase.selectDate(date)