Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weโ€™ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor/friend view calendar fetch #149

Merged
merged 6 commits into from
Dec 13, 2022
4 changes: 0 additions & 4 deletions DailyQuest/DailyQuest.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,6 @@
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 */; };
Expand Down Expand Up @@ -294,7 +293,6 @@
3472E8F029420D9600BB304F /* FriendViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FriendViewModel.swift; sourceTree = "<group>"; };
3472E8F42942135D00BB304F /* FriendQuestUseCase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FriendQuestUseCase.swift; sourceTree = "<group>"; };
3472E8F6294213BE00BB304F /* DefaultFriendQuestUseCase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DefaultFriendQuestUseCase.swift; sourceTree = "<group>"; };
3472E8F829421C7C00BB304F /* FriendCalendarUseCase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FriendCalendarUseCase.swift; sourceTree = "<group>"; };
3472E8FA29421CB500BB304F /* DefaultFriendCalendarUseCase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DefaultFriendCalendarUseCase.swift; sourceTree = "<group>"; };
347D258A292C60F40038FCA2 /* StatusView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatusView.swift; sourceTree = "<group>"; };
347D258C292C6E220038FCA2 /* MessageBubble.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageBubble.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -700,7 +698,6 @@
isa = PBXGroup;
children = (
3472E8F42942135D00BB304F /* FriendQuestUseCase.swift */,
3472E8F829421C7C00BB304F /* FriendCalendarUseCase.swift */,
);
path = Protocols;
sourceTree = "<group>";
Expand Down Expand Up @@ -1341,7 +1338,6 @@
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 */,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ final class BrowseSceneDIContainer {
return DefaultFriendUseCase(questsRepository: makeQuestsRepository())
}

func makeFriendCalendarUseCase(with user: User) -> FriendCalendarUseCase {
func makeFriendCalendarUseCase(with user: User) -> CalendarUseCase {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

์ด๋ถ€๋ถ„ ์ฐธ๊ณ ํ•ด์„œ, DI Container ๋ณ€๊ฒฝ๋˜๋Š” ๋ถ€๋ถ„์„ ์ฒ˜๋ฆฌํ•ด์•ผ๊ฒ ์Šต๋‹ˆ๋‹ค. ๊ณ ์ƒํ•˜์…จ์Šต๋‹ˆ๋‹ค!

return DefaultFriendCalendarUseCase(user: user, questsRepository: makeQuestsRepository())
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,15 +58,28 @@ extension DefaultQuestsRepository: QuestsRepository {
.toArray()
}

func fetch(by uuid: String, date: Date, filter: Date) -> Single<[Quest]> {
func fetch(by uuid: String, date: Date, filter: Date) -> Single<[Date: [Quest]]> {
return networkService.read(type: QuestDTO.self,
userCase: .anotherUser(uuid),
access: .quests,
filter: .month(filter))
.map({ $0.toDomain() })
.do(onNext: { print($0) })
.toArray()

.reduce([Date : [Quest]](), accumulator: ({ dict, questDTO in
let quest = questDTO.toDomain()
var dictionary = dict

dictionary[quest.date.startOfDay, default: [Quest]()].append(quest)
return dictionary
}))
.map { dict in
var dictionary = dict
date.rangeDaysOfMonth.forEach { date in
if dictionary[date] == nil {
dictionary[date] = []
}
}
return dictionary
}
.asSingle()
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,5 +58,5 @@ protocol QuestsRepository {

func fetch(by uuid: String, date: Date) -> Single<[Quest]>

func fetch(by uuid: String, date: Date, filter: Date) -> Single<[Quest]>
func fetch(by uuid: String, date: Date, filter: Date) -> Single<[Date: [Quest]]>
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import RxSwift

import RxSwift

final class DefaultFriendCalendarUseCase: FriendCalendarUseCase {
final class DefaultFriendCalendarUseCase: CalendarUseCase {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

๊ธฐ์กด๊ณผ ๋งฅ๋ฝ์ƒ ๋™์ผํ•œ ๋กœ์ง์ด๋ผ๋ฉด ๋Œ๋ ค์“ฐ๋Š”๊ฒŒ ์ข‹๊ธดํ•œ๊ฒƒ๊ฐ™์Šต๋‹ˆ๋‹ค !

private let user: User
private let questsRepository: QuestsRepository
private let disposeBag = DisposeBag()
Expand All @@ -27,20 +27,104 @@ final class DefaultFriendCalendarUseCase: FriendCalendarUseCase {

func setupMonths() {
let currentMonth = try? currentMonth.value()
let startDayOfLastMonth = currentMonth?.startDayOfLastMonth
let startDayOfCurrentMonth = currentMonth?.startDayOfCurrentMonth
let startDayOfNextMonth = currentMonth?.startDayOfNextMonth

let months = [startDayOfLastMonth, startDayOfCurrentMonth, startDayOfNextMonth]

let months = startDayOfCurrentMonth

Observable.just(months)
.flatMap(fetchAMontlyCompletion(_:))
.map { [[], $0, []] }
.bind(to: completionOfMonths)
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 selectDate(_ date: Date) {
selectedDate.onNext(date)
}

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 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)
}
}

extension DefaultFriendCalendarUseCase {
Expand All @@ -62,31 +146,27 @@ extension DefaultFriendCalendarUseCase {
private func fetchAMontlyCompletion(_ month: Date?) -> Observable<[DailyQuestCompletion]> {
guard let month = month else { return .empty() }

return Observable.just(month)
.concatMap { [weak self] date -> Observable<DailyQuestCompletion> in
guard let self else { return Observable.empty() }

return self.questsRepository
.fetch(by: self.user.uuid, date: date, filter: date)
.asObservable()
.map { quests -> DailyQuestCompletion in
let isSelected = (try? self.selectedDate.value().startOfDay == date) ?? false

return questsRepository.fetch(by: self.user.uuid, date: month, filter: month)
.map { dict -> [DailyQuestCompletion] in
let completionEndDaysOfLastMonth = month.rangeFromStartWeekdayOfLastMonthToEndDayOfCurrentMonth
.map { date -> DailyQuestCompletion in
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)
state: .hidden,
isSelected: false)
}

return firstWeekStates + states
let completionOfMonths = dict.keys.sorted().map { date -> DailyQuestCompletion in
let state = self.calculateDailyState(dict[date] ?? [])
let isSelected = (try? self.selectedDate.value().startOfDay == date) ?? false

return DailyQuestCompletion(
day: date,
state: state,
isSelected: isSelected)
}

return completionEndDaysOfLastMonth + completionOfMonths
}
.asObservable()
}
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,12 @@ final class FriendViewController: UIViewController {
}
}

let dragEventInCalendar = calendarView
.monthCollectionView
.rx
.didEndDecelerating
.withLatestFrom(willEndDragEvent)

let daySelected = calendarView
.monthCollectionView
.rx
Expand All @@ -127,7 +133,8 @@ final class FriendViewController: UIViewController {
let output = viewModel.transform(
input: FriendViewModel.Input(
viewDidLoad: viewDidLoad,
daySelected: daySelected
daySelected: daySelected,
dragEventInCalendar: dragEventInCalendar
),
disposableBag: disposableBag
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@ import RxCocoa
final class FriendViewModel {
private(set) var user: User
private let friendQuestUseCase: FriendQuestUseCase
private let friendCalendarUseCase: FriendCalendarUseCase
private let friendCalendarUseCase: CalendarUseCase

init(user: User,
friendQuestUseCase: FriendQuestUseCase,
friendCalendarUseCase: FriendCalendarUseCase)
friendCalendarUseCase: CalendarUseCase)
{
self.user = user
self.friendQuestUseCase = friendQuestUseCase
Expand All @@ -27,6 +27,7 @@ final class FriendViewModel {
struct Input {
let viewDidLoad: Observable<Date>
let daySelected: Observable<Date>
let dragEventInCalendar: Observable<CalendarView.ScrollDirection>
}

struct Output {
Expand Down Expand Up @@ -58,6 +59,20 @@ 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)
Expand Down