Skip to content

Commit

Permalink
✨ [feat] 대시보드에 랜덤하게 방문할 수 있는 NPC와 고정적으로 방문하는 NPC를 보여주도록 추가
Browse files Browse the repository at this point in the history
  • Loading branch information
leeari95 committed Dec 6, 2024
1 parent 6a2c670 commit 16f9031
Show file tree
Hide file tree
Showing 8 changed files with 330 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
"Today's Tasks" = "Today's Tasks";
"My Villagers" = "My Villagers";
"Collection Progress" = "Collection Progress";
"Residents who can visit randomly on weekdays" = "Residents who can visit randomly on weekdays";
"Residents who visit regularly" = "Residents who visit regularly";

// MARK: - UserInfoView
"Please set a name." = "Please set a name.";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
"Today's Tasks" = "오늘의 할일";
"My Villagers" = "마을 주민";
"Collection Progress" = "수집 현황";
"Residents who can visit randomly on weekdays" = "평일에 랜덤하게 방문할 수 있는 주민";
"Residents who visit regularly" = "고정으로 방문하는 주민";

// MARK: - UserInfoView
"Please set a name." = "이름을 설정해주세요.";
Expand Down
12 changes: 12 additions & 0 deletions Animal-Crossing-Wiki/Projects/App/Sources/Models/NPC.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,16 @@ struct NPC {
let birthday: String
let appearanceLocation: [AppearanceLocation]?
let translations: Translations

var isRandomVisit: Bool {
["C.J.", "Flick", "Redd", "Gulliver", "Gullivarrr", "Label", "Wisp", "Celeste"].contains(name)
}

var isFixedVisit: Bool {
["Saharah", "Kicks", "Leif", "Pascal", "Sable", "K.K.", "Daisy Mae"].contains(name)
}
}

extension NPC: Identifiable {
public var id: String { UUID().uuidString }
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ final class DashboardCoordinator: Coordinator {
case customTask(task: DailyTask)
case iconChooser
case villagerDetail(villager: Villager)
case npcDetail(npc: NPC)
case progress
case item(category: Category)
case itemDetail(item: Item)
Expand All @@ -43,7 +44,9 @@ final class DashboardCoordinator: Coordinator {
userInfoVM: UserInfoReactor(coordinator: self),
tasksVM: TodaysTasksSectionReactor(coordinator: self),
villagersVM: VillagersSectionReactor(coordinator: self),
progressVM: CollectionProgressSectionReactor(coordinator: self)
progressVM: CollectionProgressSectionReactor(coordinator: self),
fixeVisitdNPCListVM: NpcsSectionReactor(state: .init(), mode: .fixedVisit, coordinator: self),
randomVisitNPCListVM: NpcsSectionReactor(state: .init(), mode: .randomVisit, coordinator: self)
)
rootViewController.addChild(viewController)
}
Expand All @@ -58,16 +61,19 @@ final class DashboardCoordinator: Coordinator {
)
let navigationController = UINavigationController(rootViewController: viewController)
rootViewController.present(navigationController, animated: true)

case .about:
let viewController = AboutViewController()
viewController.bind(to: AboutReactor(coordinator: self))
let navigationController = UINavigationController(rootViewController: viewController)
rootViewController.present(navigationController, animated: true)

case .taskEdit:
let viewController = TaskEditViewController()
viewController.bind(to: TasksEditReactor(coordinator: self))
let navigationController = UINavigationController(rootViewController: viewController)
rootViewController.present(navigationController, animated: true)

case .customTask(let task):
let viewController = CustomTaskViewController()
delegate = viewController
Expand All @@ -80,11 +86,13 @@ final class DashboardCoordinator: Coordinator {
}
let navigationController = rootViewController.visibleViewController?.navigationController as? UINavigationController
navigationController?.pushViewController(viewController, animated: true)

case .iconChooser:
let viewController = IconChooserViewController()
viewController.coordinator = self
let navigationController = UINavigationController(rootViewController: viewController)
rootViewController.visibleViewController?.present(navigationController, animated: true)

case .villagerDetail(let villager):
let viewController = VillagerDetailViewController()
viewController.bind(
Expand All @@ -93,10 +101,21 @@ final class DashboardCoordinator: Coordinator {
let navigationController = UINavigationController(rootViewController: viewController)
rootViewController.present(navigationController, animated: true)
HapticManager.shared.notification(type: .success)

case let .npcDetail(npc):
let viewController = NPCDetailViewController()
viewController.bind(
to: NPCDetailReactor(npc: npc, state: .init(npc: npc))
)
let navigationController = UINavigationController(rootViewController: viewController)
rootViewController.present(navigationController, animated: true)
HapticManager.shared.notification(type: .success)

case .progress:
let viewController = CollectionProgressViewController()
viewController.bind(to: CollectionProgressReactor(coordinator: self))
rootViewController.pushViewController(viewController, animated: true)

case .item(let category):
let viewController = ItemsViewController()
let currentMonth = (Calendar.current.dateComponents([.month], from: Date()).month ?? 1).description
Expand All @@ -105,16 +124,20 @@ final class DashboardCoordinator: Coordinator {
keyword: [.month: currentMonth]
)
rootViewController.pushViewController(viewController, animated: true)

case .itemDetail(let item):
let viewController = ItemDetailViewController()
viewController.bind(to: ItemDetailReactor(item: item, coordinator: self))
rootViewController.pushViewController(viewController, animated: true)

case .keyword(let title, let keyword):
let viewController = ItemsViewController()
viewController.bind(to: ItemsReactor(coordinator: self, mode: .keyword(title: title, category: keyword)))
rootViewController.pushViewController(viewController, animated: true)

case .pop:
rootViewController.visibleViewController?.navigationController?.popViewController(animated: true)

case .dismiss:
rootViewController.visibleViewController?.navigationController?.dismiss(animated: true)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

import UIKit
import RxSwift
import SwiftUI

final class DashboardViewController: UIViewController {

Expand Down Expand Up @@ -60,7 +61,9 @@ final class DashboardViewController: UIViewController {
userInfoVM: UserInfoReactor,
tasksVM: TodaysTasksSectionReactor,
villagersVM: VillagersSectionReactor,
progressVM: CollectionProgressSectionReactor
progressVM: CollectionProgressSectionReactor,
fixeVisitdNPCListVM: NpcsSectionReactor,
randomVisitNPCListVM: NpcsSectionReactor
) {
let userInfoSection = SectionView(
title: "My Island".localized,
Expand All @@ -82,7 +85,22 @@ final class DashboardViewController: UIViewController {
iconName: "chart.pie.fill",
contentView: CollectionProgressView(viewModel: progressVM)
)
sectionsScrollView.addSection(userInfoSection, tasksSection, villagersSection, progressSection)
let randomVisitResidentsSectionView = SectionView(
title: "Residents who can visit randomly on weekdays".localized,
iconName: "bubbles.and.sparkles.fill",
contentView: NpcsView(randomVisitNPCListVM)
)
let fixedVisitResidentsSectionView = SectionView(
title: "Residents who visit regularly".localized,
iconName: "pin.fill",
contentView: NpcsView(fixeVisitdNPCListVM)
)
sectionsScrollView.addSection(userInfoSection,
tasksSection,
villagersSection,
progressSection,
randomVisitResidentsSectionView,
fixedVisitResidentsSectionView)
}

func bind(to reactor: DashboardReactor) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
//
// NpcsSectionReactor.swift
// ACNH-wiki
//
// Created by Ari on 12/6/24.
//

import Foundation
import ReactorKit
import RxSwift
import RxCocoa

final class NpcsSectionReactor: Reactor, ObservableObject {
enum Action {
case fetch
case npcLongPress(index: Int)
}

enum Mutation {
case transition(route: DashboardCoordinator.Route)
case setNpc(_ npcs: [NPC])
}

struct State {
var npcs: [NPC] = []
}

@Published var initialState: State
private var coordinator: DashboardCoordinator?
private let mode: Mode

init(state: State, mode: Mode, coordinator: DashboardCoordinator?) {
self.initialState = state
self.mode = mode
self.coordinator = coordinator
}

func mutate(action: Action) -> Observable<Mutation> {
switch action {
case .fetch:
return mode.npcs
.map { Mutation.setNpc($0) }
.asObservable()

case .npcLongPress(let index):
guard let npc = currentState.npcs[safe: index] else {
return Observable.empty()
}
return Observable.just(Mutation.transition(route: .npcDetail(npc: npc)))
}
}

func reduce(state: State, mutation: Mutation) -> State {
var newState = state
switch mutation {
case let .transition(route):
coordinator?.transition(for: route)

case let .setNpc(npcs):
newState.npcs = npcs
objectWillChange.send()
}
return newState
}
}

extension NpcsSectionReactor {
enum Mode {
case fixedVisit
case randomVisit

var npcs: Driver<[NPC]> {
switch self {
case .fixedVisit:
return Items.shared.fixedVisitNpcs
case .randomVisit:
return Items.shared.randomVisitNpcs
}
}
}
}
Loading

0 comments on commit 16f9031

Please sign in to comment.