diff --git a/Projects/.swiftlint.yml b/Projects/.swiftlint.yml deleted file mode 100644 index e69de29b..00000000 diff --git a/Projects/Core/Sources/Steps/EasterEggStep.swift b/Projects/Core/Sources/Steps/EasterEggStep.swift new file mode 100644 index 00000000..27c2e1a5 --- /dev/null +++ b/Projects/Core/Sources/Steps/EasterEggStep.swift @@ -0,0 +1,5 @@ +import RxFlow + +public enum EasterEggStep: Step { + case easterEggIsRequired +} diff --git a/Projects/Core/Sources/Steps/HomeStep.swift b/Projects/Core/Sources/Steps/HomeStep.swift index 5c378af0..ac1ae26f 100644 --- a/Projects/Core/Sources/Steps/HomeStep.swift +++ b/Projects/Core/Sources/Steps/HomeStep.swift @@ -4,6 +4,7 @@ public enum HomeStep: Step { case homeIsRequired case alarmIsRequired case companyIsRequired + case easterEggIsRequired case rejectReasonIsRequired( recruitmentID: Int, applicationID: Int, diff --git a/Projects/Flow/Sources/Home/EasterEggFlow.swift b/Projects/Flow/Sources/Home/EasterEggFlow.swift new file mode 100644 index 00000000..25465b74 --- /dev/null +++ b/Projects/Flow/Sources/Home/EasterEggFlow.swift @@ -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)) + } +} diff --git a/Projects/Flow/Sources/Home/HomeFlow.swift b/Projects/Flow/Sources/Home/HomeFlow.swift index 7fc47097..d7327980 100644 --- a/Projects/Flow/Sources/Home/HomeFlow.swift +++ b/Projects/Flow/Sources/Home/HomeFlow.swift @@ -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) @@ -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 diff --git a/Projects/Presentation/Resources/Images/OnboardingImages.xcassets/Jobis logo.imageset/Contents.json b/Projects/Modules/DesignSystem/Resources/Images/Images.xcassets/Easter Egg/Close.imageset/Contents.json similarity index 87% rename from Projects/Presentation/Resources/Images/OnboardingImages.xcassets/Jobis logo.imageset/Contents.json rename to Projects/Modules/DesignSystem/Resources/Images/Images.xcassets/Easter Egg/Close.imageset/Contents.json index e9e3d1a0..acb0efb2 100644 --- a/Projects/Presentation/Resources/Images/OnboardingImages.xcassets/Jobis logo.imageset/Contents.json +++ b/Projects/Modules/DesignSystem/Resources/Images/Images.xcassets/Easter Egg/Close.imageset/Contents.json @@ -1,7 +1,7 @@ { "images" : [ { - "filename" : "Jobis logo.png", + "filename" : "close.png", "idiom" : "universal", "scale" : "1x" }, diff --git a/Projects/Modules/DesignSystem/Resources/Images/Images.xcassets/Easter Egg/Close.imageset/close.png b/Projects/Modules/DesignSystem/Resources/Images/Images.xcassets/Easter Egg/Close.imageset/close.png new file mode 100644 index 00000000..35f4bb58 Binary files /dev/null and b/Projects/Modules/DesignSystem/Resources/Images/Images.xcassets/Easter Egg/Close.imageset/close.png differ diff --git a/Projects/Presentation/Resources/Images/OnboardingImages.xcassets/Contents.json b/Projects/Modules/DesignSystem/Resources/Images/Images.xcassets/Easter Egg/Contents.json similarity index 52% rename from Projects/Presentation/Resources/Images/OnboardingImages.xcassets/Contents.json rename to Projects/Modules/DesignSystem/Resources/Images/Images.xcassets/Easter Egg/Contents.json index 73c00596..6e965652 100644 --- a/Projects/Presentation/Resources/Images/OnboardingImages.xcassets/Contents.json +++ b/Projects/Modules/DesignSystem/Resources/Images/Images.xcassets/Easter Egg/Contents.json @@ -2,5 +2,8 @@ "info" : { "author" : "xcode", "version" : 1 + }, + "properties" : { + "provides-namespace" : true } } diff --git a/Projects/Presentation/Resources/Images/OnboardingImages.xcassets/Team return logo.imageset/Contents.json b/Projects/Modules/DesignSystem/Resources/Images/Images.xcassets/Easter Egg/Open.imageset/Contents.json similarity index 86% rename from Projects/Presentation/Resources/Images/OnboardingImages.xcassets/Team return logo.imageset/Contents.json rename to Projects/Modules/DesignSystem/Resources/Images/Images.xcassets/Easter Egg/Open.imageset/Contents.json index deb1b019..d392df76 100644 --- a/Projects/Presentation/Resources/Images/OnboardingImages.xcassets/Team return logo.imageset/Contents.json +++ b/Projects/Modules/DesignSystem/Resources/Images/Images.xcassets/Easter Egg/Open.imageset/Contents.json @@ -1,7 +1,7 @@ { "images" : [ { - "filename" : "Team return logo.png", + "filename" : "open.png", "idiom" : "universal", "scale" : "1x" }, diff --git a/Projects/Modules/DesignSystem/Resources/Images/Images.xcassets/Easter Egg/Open.imageset/open.png b/Projects/Modules/DesignSystem/Resources/Images/Images.xcassets/Easter Egg/Open.imageset/open.png new file mode 100644 index 00000000..0993df17 Binary files /dev/null and b/Projects/Modules/DesignSystem/Resources/Images/Images.xcassets/Easter Egg/Open.imageset/open.png differ diff --git a/Projects/Modules/DesignSystem/Sources/View/StudentInfoView.swift b/Projects/Modules/DesignSystem/Sources/View/StudentInfoView.swift index efc73ec7..ef390534 100644 --- a/Projects/Modules/DesignSystem/Sources/View/StudentInfoView.swift +++ b/Projects/Modules/DesignSystem/Sources/View/StudentInfoView.swift @@ -14,10 +14,10 @@ public final class StudentInfoView: UIView { $0.alignment = .leading } private let userInfoLabel = UILabel().then { - $0.setJobisText("0000 가가가", font: .subHeadLine, color: .GrayScale.gray90) + $0.setJobisText("불러오는 중...", font: .subHeadLine, color: .GrayScale.gray90) } private let departmentLabel = UILabel().then { - $0.setJobisText("가가가가가가가가", font: .description, color: .GrayScale.gray70) + $0.setJobisText("", font: .description, color: .GrayScale.gray70) } public init() { diff --git a/Projects/Presentation/Resources/Images/OnboardingImages.xcassets/Jobis logo.imageset/Jobis logo.png b/Projects/Presentation/Resources/Images/OnboardingImages.xcassets/Jobis logo.imageset/Jobis logo.png deleted file mode 100644 index 5916851a..00000000 Binary files a/Projects/Presentation/Resources/Images/OnboardingImages.xcassets/Jobis logo.imageset/Jobis logo.png and /dev/null differ diff --git a/Projects/Presentation/Resources/Images/OnboardingImages.xcassets/Team return logo.imageset/Team return logo.png b/Projects/Presentation/Resources/Images/OnboardingImages.xcassets/Team return logo.imageset/Team return logo.png deleted file mode 100644 index 69c0f2a0..00000000 Binary files a/Projects/Presentation/Resources/Images/OnboardingImages.xcassets/Team return logo.imageset/Team return logo.png and /dev/null differ diff --git a/Projects/Presentation/Sources/DI/PresentationAssembly.swift b/Projects/Presentation/Sources/DI/PresentationAssembly.swift index 13457393..3d48d35b 100644 --- a/Projects/Presentation/Sources/DI/PresentationAssembly.swift +++ b/Projects/Presentation/Sources/DI/PresentationAssembly.swift @@ -251,5 +251,9 @@ public final class PresentationAssembly: Assembly { fetchRejectionReasonUseCase: resolver.resolve(FetchRejectionReasonUseCase.self)! ) } + + container.register(EasterEggViewController.self) { resolver in + EasterEggViewController() + } } } diff --git a/Projects/Presentation/Sources/EasterEgg/EasterEggView.swift b/Projects/Presentation/Sources/EasterEgg/EasterEggView.swift new file mode 100644 index 00000000..c2fde643 --- /dev/null +++ b/Projects/Presentation/Sources/EasterEgg/EasterEggView.swift @@ -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.. 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() + } +} diff --git a/Projects/Presentation/Sources/EasterEgg/EasterEggViewController.swift b/Projects/Presentation/Sources/EasterEgg/EasterEggViewController.swift new file mode 100644 index 00000000..d7f5d0f2 --- /dev/null +++ b/Projects/Presentation/Sources/EasterEgg/EasterEggViewController.swift @@ -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() + } +} diff --git a/Projects/Presentation/Sources/EasterEgg/RxFlowViewController.swift b/Projects/Presentation/Sources/EasterEgg/RxFlowViewController.swift new file mode 100644 index 00000000..a63d3777 --- /dev/null +++ b/Projects/Presentation/Sources/EasterEgg/RxFlowViewController.swift @@ -0,0 +1,27 @@ +import UIKit +import RxFlow +import RxCocoa + +public class RxFlowViewController: UIViewController, RxFlow.Stepper { + public let steps = PublishRelay() + 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 + } +} diff --git a/Projects/Presentation/Sources/Home/Alarm/AlarmViewController.swift b/Projects/Presentation/Sources/Home/Alarm/AlarmViewController.swift index 890f2f79..32776dd2 100644 --- a/Projects/Presentation/Sources/Home/Alarm/AlarmViewController.swift +++ b/Projects/Presentation/Sources/Home/Alarm/AlarmViewController.swift @@ -48,9 +48,9 @@ public final class AlarmViewController: BaseViewController { } public override func configureViewController() { - self.viewWillDisappearPublisher.asObservable() - .subscribe(onNext: { [weak self] in - self?.showTabbar() + self.viewWillAppearPublisher.asObservable() + .subscribe(onNext: { + self.hideTabbar() }) .disposed(by: disposeBag) } diff --git a/Projects/Presentation/Sources/Home/HomeViewController.swift b/Projects/Presentation/Sources/Home/HomeViewController.swift index 3b96ddb3..45aad217 100644 --- a/Projects/Presentation/Sources/Home/HomeViewController.swift +++ b/Projects/Presentation/Sources/Home/HomeViewController.swift @@ -45,7 +45,7 @@ public final class HomeViewController: BaseViewController { } private var findCompanysCard = CareerNavigationCard() private var findWinterRecruitmentsCard = CareerNavigationCard() - + private var navigateToEasterEggDidTap = PublishRelay() public override func addView() { self.view.addSubview(scrollView) self.scrollView.addSubview(contentView) @@ -108,12 +108,20 @@ public final class HomeViewController: BaseViewController { 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 @@ -172,12 +180,6 @@ public final class HomeViewController: BaseViewController { 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) diff --git a/Projects/Presentation/Sources/Home/HomeViewModel.swift b/Projects/Presentation/Sources/Home/HomeViewModel.swift index 7fec4f6d..19f7dfc1 100644 --- a/Projects/Presentation/Sources/Home/HomeViewModel.swift +++ b/Projects/Presentation/Sources/Home/HomeViewModel.swift @@ -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, @@ -24,7 +26,9 @@ public final class HomeViewModel: BaseViewModel, Stepper { public struct Input { let viewAppear: PublishRelay + let viewDisappear: PublishRelay let navigateToAlarmButtonDidTap: Signal + let navigateToEasterEggDidTap: PublishRelay let navigateToCompanyButtonDidTap: Signal let rejectButtonDidTap: PublishRelay let reApplyButtonDidTap: PublishRelay @@ -51,6 +55,12 @@ 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 @@ -58,6 +68,20 @@ public final class HomeViewModel: BaseViewModel, Stepper { .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) diff --git a/Scripts/.swiftlint.yml b/Scripts/.swiftlint.yml index 06776fda..e51d1056 100644 --- a/Scripts/.swiftlint.yml +++ b/Scripts/.swiftlint.yml @@ -1,3 +1,4 @@ disabled_rules: - function_body_length - function_parameter_count + - cyclomatic_complexity