Skip to content

Commit

Permalink
🧩 :: PopCat 이스터에그
Browse files Browse the repository at this point in the history
  • Loading branch information
HongSJae committed Apr 3, 2024
1 parent c20401f commit 0e5a866
Show file tree
Hide file tree
Showing 19 changed files with 216 additions and 12 deletions.
Empty file removed Projects/.swiftlint.yml
Empty file.
5 changes: 5 additions & 0 deletions Projects/Core/Sources/Steps/EasterEggStep.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import RxFlow

public enum EasterEggStep: Step {
case easterEggIsRequired
}
1 change: 1 addition & 0 deletions Projects/Core/Sources/Steps/HomeStep.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ public enum HomeStep: Step {
case homeIsRequired
case alarmIsRequired
case companyIsRequired
case easterEggIsRequired
case rejectReasonIsRequired(
recruitmentID: Int,
applicationID: Int,
Expand Down
35 changes: 35 additions & 0 deletions Projects/Flow/Sources/Home/EasterEggFlow.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import UIKit
import SwiftUI
import Presentation
import Swinject
import RxFlow
import Core


public final class EasterEggFlow: Flow {
public let container: Container
private let rootViewController: RxFlowViewController
public var root: Presentable {
return rootViewController
}

public init(container: Container) {
self.container = container
self.rootViewController = container.resolve(EasterEggViewController.self)!
}

public func navigate(to step: Step) -> FlowContributors {
guard let step = step as? EasterEggStep else { return .none }

switch step {
case .easterEggIsRequired:
return navigateToEasterEgg()
}
}
}

private extension EasterEggFlow {
func navigateToEasterEgg() -> FlowContributors {
return .one(flowContributor: .contribute(withNext: rootViewController))
}
}
18 changes: 18 additions & 0 deletions Projects/Flow/Sources/Home/HomeFlow.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ public final class HomeFlow: Flow {
case .companyIsRequired:
return navigateToCompany()

case .easterEggIsRequired:
return navigateToEasterEgg()

case let .rejectReasonIsRequired(recruitmentID, applicationID, companyName, companyImageUrl):
return navigateToRejectReason(recruitmentID, applicationID, companyName, companyImageUrl)

Expand Down Expand Up @@ -67,6 +70,21 @@ private extension HomeFlow {
))
}

func navigateToEasterEgg() -> FlowContributors {
let easterEggFlow = EasterEggFlow(container: container)

Flows.use(easterEggFlow, when: .created) { root in
self.rootViewController.present(
root, animated: true
)
}

return .one(flowContributor: .contribute(
withNextPresentable: easterEggFlow,
withNextStepper: OneStepper(withSingleStep: EasterEggStep.easterEggIsRequired)
))
}

func navigateToCompany() -> FlowContributors {
let companyFlow = CompanyFlow(container: container)
Flows.use(companyFlow, when: .created) { root in
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"images" : [
{
"filename" : "Jobis logo.png",
"filename" : "close.png",
"idiom" : "universal",
"scale" : "1x"
},
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,8 @@
"info" : {
"author" : "xcode",
"version" : 1
},
"properties" : {
"provides-namespace" : true
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"images" : [
{
"filename" : "Team return logo.png",
"filename" : "open.png",
"idiom" : "universal",
"scale" : "1x"
},
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Binary file not shown.
4 changes: 4 additions & 0 deletions Projects/Presentation/Sources/DI/PresentationAssembly.swift
Original file line number Diff line number Diff line change
Expand Up @@ -242,5 +242,9 @@ public final class PresentationAssembly: Assembly {
fetchRejectionReasonUseCase: resolver.resolve(FetchRejectionReasonUseCase.self)!
)
}

container.register(EasterEggViewController.self) { resolver in
EasterEggViewController()
}
}
}
60 changes: 60 additions & 0 deletions Projects/Presentation/Sources/EasterEgg/EasterEggView.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import SwiftUI
import DesignSystem

struct EasterEggView: View {
@State private var count = 0
@State private var angle = 0
@State private var index = 0
private var colors: [Color] = [
.yellow,
.red,
.blue,
.green,
.purple,
.orange,
.mint,
.white
]
var body: some View {
VStack {
Button("", action: addAction)
.buttonStyle(CatButtonStyle())
.rotationEffect(.degrees(Double(angle)))

Text("\(count)")
.padding(.top, 50)
}
.frame(maxWidth: .infinity, maxHeight: .infinity)
.padding()
.background(colors[index])
}

private func addAction() {
count += 1
angle = (angle + 45) % 360
index = Int.random(in: 0..<colors.count)
HapticManager.instance.impact(style: .heavy)
}
}

private struct CatButtonStyle: ButtonStyle {
func makeBody(configuration: Configuration) -> some View {
configuration.isPressed ? DesignSystemAsset.Images.EasterEgg.open.swiftUIImage:
DesignSystemAsset.Images.EasterEgg.close.swiftUIImage
}
}

final private class HapticManager {
static let instance = HapticManager()

func notification(type: UINotificationFeedbackGenerator.FeedbackType) {

let generator = UINotificationFeedbackGenerator()
generator.notificationOccurred(type)
}

func impact(style: UIImpactFeedbackGenerator.FeedbackStyle) {
let generator = UIImpactFeedbackGenerator(style: style)
generator.impactOccurred()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import UIKit
import SwiftUI
import RxFlow
import RxCocoa
import RxSwift
import DesignSystem

public final class EasterEggViewController: RxFlowViewController {
public init() {
super.init(nibName: nil, bundle: nil)
contentViewController = UIHostingController(rootView: EasterEggView())
}

required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}

public override func viewDidLoad() {
super.viewDidLoad()
}

public override func viewWillAppear(_ animated: Bool) {
self.hideTabbar()
}
}
27 changes: 27 additions & 0 deletions Projects/Presentation/Sources/EasterEgg/RxFlowViewController.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import UIKit
import RxFlow
import RxCocoa

public class RxFlowViewController: UIViewController, RxFlow.Stepper {
public let steps = PublishRelay<Step>()
var contentViewController = UIViewController()

private var didSetupConstraints = false

open override func viewDidLoad() {
super.viewDidLoad()

addChild(contentViewController)
view.addSubview(contentViewController.view)
setupConstraints()

}

fileprivate func setupConstraints() {
contentViewController.view.translatesAutoresizingMaskIntoConstraints = false
contentViewController.view.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
contentViewController.view.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
contentViewController.view.leftAnchor.constraint(equalTo: view.leftAnchor).isActive = true
contentViewController.view.rightAnchor.constraint(equalTo: view.rightAnchor).isActive = true
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,9 @@ public final class AlarmViewController: BaseViewController<AlarmViewModel> {
}

public override func configureViewController() {
self.viewWillDisappearPublisher.asObservable()
.subscribe(onNext: { [weak self] in
self?.showTabbar()
self.viewWillAppearPublisher.asObservable()
.subscribe(onNext: {
self.hideTabbar()
})
.disposed(by: disposeBag)
}
Expand Down
16 changes: 9 additions & 7 deletions Projects/Presentation/Sources/Home/HomeViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ public final class HomeViewController: BaseViewController<HomeViewModel> {
}
private var findCompanysCard = CareerNavigationCard()
private var findWinterRecruitmentsCard = CareerNavigationCard()

private var navigateToEasterEggDidTap = PublishRelay<Void>()
public override func addView() {
self.view.addSubview(scrollView)
self.scrollView.addSubview(contentView)
Expand Down Expand Up @@ -108,12 +108,20 @@ public final class HomeViewController: BaseViewController<HomeViewModel> {
public override func bind() {
let input = HomeViewModel.Input(
viewAppear: viewWillAppearPublisher,
viewDisappear: viewWillDisappearPublisher,
navigateToAlarmButtonDidTap: navigateToAlarmButton.rx.tap.asSignal(),
navigateToEasterEggDidTap: navigateToEasterEggDidTap,
navigateToCompanyButtonDidTap: findCompanysCard.rx.tap.asSignal(),
rejectButtonDidTap: rejectButtonDidTap,
reApplyButtonDidTap: reApplyButtonDidTap
)

titleImageView.rx.tapGesture().when(.recognized).asObservable()
.bind { [weak self] _ in
self?.navigateToEasterEggDidTap.accept(())
}
.disposed(by: disposeBag)

let output = viewModel.transform(input)

output.studentInfo
Expand Down Expand Up @@ -172,12 +180,6 @@ public final class HomeViewController: BaseViewController<HomeViewModel> {
public override func configureViewController() {
checkWinterSeason()

navigateToAlarmButton.rx.tap.asObservable()
.subscribe(onNext: { [weak self] _ in
self?.hideTabbar()
})
.disposed(by: disposeBag)

isWinterSeason.asObservable()
.bind { [weak self] in
self?.findCompanysCard.setCard(style: $0 ? .small(type: .findCompanys) : .large)
Expand Down
24 changes: 24 additions & 0 deletions Projects/Presentation/Sources/Home/HomeViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ public final class HomeViewModel: BaseViewModel, Stepper {
private let fetchApplicationUseCase: FetchApplicationUseCase
private let fetchBannerListUseCase: FetchBannerListUseCase

private var touchedPopcatCount = 0

init(
fetchStudentInfoUseCase: FetchStudentInfoUseCase,
fetchApplicationUseCase: FetchApplicationUseCase,
Expand All @@ -24,7 +26,9 @@ public final class HomeViewModel: BaseViewModel, Stepper {

public struct Input {
let viewAppear: PublishRelay<Void>
let viewDisappear: PublishRelay<Void>
let navigateToAlarmButtonDidTap: Signal<Void>
let navigateToEasterEggDidTap: PublishRelay<Void>
let navigateToCompanyButtonDidTap: Signal<Void>
let rejectButtonDidTap: PublishRelay<ApplicationEntity>
let reApplyButtonDidTap: PublishRelay<ApplicationEntity>
Expand All @@ -51,13 +55,33 @@ public final class HomeViewModel: BaseViewModel, Stepper {
.bind(to: studentInfo)
.disposed(by: disposeBag)

input.viewAppear.asObservable()
.bind { _ in
self.touchedPopcatCount = 0
}
.disposed(by: disposeBag)

input.navigateToAlarmButtonDidTap.asObservable()
.map { _ in
HomeStep.alarmIsRequired
}
.bind(to: steps)
.disposed(by: disposeBag)

input.navigateToEasterEggDidTap.asObservable()
.do { _ in
self.touchedPopcatCount += 1
}
.filter { _ in
self.touchedPopcatCount >= 5
}
.map { _ in
self.touchedPopcatCount = 0
return HomeStep.easterEggIsRequired
}
.bind(to: steps)
.disposed(by: disposeBag)

input.navigateToCompanyButtonDidTap.asObservable()
.map { _ in HomeStep.companyIsRequired }
.bind(to: steps)
Expand Down

0 comments on commit 0e5a866

Please sign in to comment.