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

✨ About 화면 구현 #22

Merged
merged 1 commit into from
Jan 3, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions Dear-World/Dear-World.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
39C832282597651F00236DDF /* RxRelay in Frameworks */ = {isa = PBXBuildFile; productRef = 39C832272597651F00236DDF /* RxRelay */; };
39C8322A2597651F00236DDF /* RxSwift in Frameworks */ = {isa = PBXBuildFile; productRef = 39C832292597651F00236DDF /* RxSwift */; };
39C8322C2597651F00236DDF /* RxCocoa in Frameworks */ = {isa = PBXBuildFile; productRef = 39C8322B2597651F00236DDF /* RxCocoa */; };
39E9F7D025A1738F00BC2CC2 /* AboutReactor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 39E9F7CF25A1738F00BC2CC2 /* AboutReactor.swift */; };
39EED22E259CFEB8007452E1 /* World.Model.Ranker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 39EED22D259CFEB8007452E1 /* World.Model.Ranker.swift */; };
39EED23C259D00F8007452E1 /* CheeringMapReactor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 39EED23B259D00F8007452E1 /* CheeringMapReactor.swift */; };
39EED241259D0227007452E1 /* Revision.swift in Sources */ = {isa = PBXBuildFile; fileRef = 39EED240259D0227007452E1 /* Revision.swift */; };
Expand Down Expand Up @@ -134,6 +135,7 @@
3971EB28259A7D720084E6DC /* SendMessageReactor.swift */ = {isa = PBXFileReference; indentWidth = 2; lastKnownFileType = sourcecode.swift; path = SendMessageReactor.swift; sourceTree = "<group>"; tabWidth = 2; };
3971EB36259A9C550084E6DC /* Message.API.SendMessage.swift */ = {isa = PBXFileReference; indentWidth = 2; lastKnownFileType = sourcecode.swift; path = Message.API.SendMessage.swift; sourceTree = "<group>"; tabWidth = 2; };
3971EB3B259A9C860084E6DC /* Message.Model.SendMessage.swift */ = {isa = PBXFileReference; indentWidth = 2; lastKnownFileType = sourcecode.swift; name = Message.Model.SendMessage.swift; path = "Dear-World/Source/Domain/Message/API/Message.Model.SendMessage.swift"; sourceTree = SOURCE_ROOT; tabWidth = 2; };
39E9F7CF25A1738F00BC2CC2 /* AboutReactor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AboutReactor.swift; sourceTree = "<group>"; };
39EED22D259CFEB8007452E1 /* World.Model.Ranker.swift */ = {isa = PBXFileReference; indentWidth = 2; lastKnownFileType = sourcecode.swift; path = World.Model.Ranker.swift; sourceTree = "<group>"; tabWidth = 2; };
39EED23B259D00F8007452E1 /* CheeringMapReactor.swift */ = {isa = PBXFileReference; indentWidth = 2; lastKnownFileType = sourcecode.swift; path = CheeringMapReactor.swift; sourceTree = "<group>"; tabWidth = 2; };
39EED240259D0227007452E1 /* Revision.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Revision.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -421,6 +423,7 @@
isa = PBXGroup;
children = (
3902F117259704AF00A3DF8C /* AboutViewController.swift */,
39E9F7CF25A1738F00BC2CC2 /* AboutReactor.swift */,
);
path = About;
sourceTree = "<group>";
Expand Down Expand Up @@ -710,6 +713,7 @@
39F465822597811900621327 /* CheerButton.swift in Sources */,
128313EE2598A14E00BDF8A3 /* Message.API.Messages.swift in Sources */,
128313E32598A08700BDF8A3 /* Message.swift in Sources */,
39E9F7D025A1738F00BC2CC2 /* AboutReactor.swift in Sources */,
121BDB44259735200062B15A /* UIColor+.swift in Sources */,
39658FBB259AE55C0050D180 /* World.Model.Rank.swift in Sources */,
39658FB6259AE5250050D180 /* World.API.Rank.swift in Sources */,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import Foundation

extension Int {
var formatted: String? {
if self >= 100_000 {
if self >= 10_000 {
return self.kFormat
} else {
return self.decimalFormat
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
//
// AboutReactor.swift
// Dear-World
//
// Created by dongyoung.lee on 2021/01/03.
//

import Foundation
import ReactorKit

final class AboutReactor: Reactor {

enum Action {
case initalize
case tapCrewInfo
case tapNotice
case tapVersion
}

enum Mutation {
case setPresentCrewInfo(Bool)
case setPresentNotice(Bool)
case setPresentAppStore(Bool)
case setNoticeCount(Int)
case setCurrentVersion(String)
}

struct State {
@Revision var isPresentCrewInfo: Bool = false
@Revision var isPresentNotice: Bool = false
@Revision var isPresentAppStore: Bool = false
var noticeCount: Int?
var currentVersion: String? = "10.1.1"
}

var initialState: State

// MARK: 🏁 Initialize
init() {
initialState = State()
}

// MARK: 🔫 Mutate
func mutate(action: Action) -> Observable<Mutation> {
switch action {
case .initalize:
return .empty()
case .tapCrewInfo:
return .just(.setPresentCrewInfo(true))

case .tapNotice:
return .just(.setPresentNotice(true))

case .tapVersion:
return .just(.setPresentAppStore(true))
}
}

// MARK: ⚡️ Reduce
func reduce(state: State, mutation: Mutation) -> State {
var newState: State = state
switch mutation {
case .setPresentCrewInfo(let isPresentCrewInfo):
newState.isPresentCrewInfo = isPresentCrewInfo

case .setPresentNotice(let isPresentNotice):
newState.isPresentNotice = isPresentNotice

case .setPresentAppStore(let isPresentAppStore):
newState.isPresentAppStore = isPresentAppStore

case .setNoticeCount(let count):
newState.noticeCount = count

case .setCurrentVersion(let version):
newState.currentVersion = version
}

return newState
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,25 +5,192 @@
// Created by dongyoung.lee on 2020/12/26.
//

import ReactorKit
import UIKit

class AboutViewController: UIViewController {

override func viewDidLoad() {
super.viewDidLoad()

// Do any additional setup after loading the view.
final class AboutViewController: UIViewController, View {

typealias Reactor = AboutReactor
typealias Action = Reactor.Action

// MARK: 🖼 UI
private let stackView: UIStackView = UIStackView()
private let crewInfoView: UIView = UIView()
private let noticeInfoView: UIView = UIView()
private let noticeCountLabel: UILabel = UILabel()
private let versionInfoView: UIView = UIView()

var disposeBag: DisposeBag = DisposeBag()

// MARK: 🏁 Initialize
init() {
super.init(nibName: nil, bundle: nil)

setupUI()
}

required init?(coder: NSCoder) {
super.init(coder: coder)

setupUI()
}

// MARK: 🎛 Setup
private func setupUI() {
view.backgroundColor = .breathingWhite

view.addSubview(stackView)
stackView.do {
$0.axis = .vertical
$0.spacing = 20
$0.addArrangedSubview(crewInfoView)
$0.addArrangedSubview(noticeInfoView)
$0.addArrangedSubview(versionInfoView)
}
stackView.snp.makeConstraints {
$0.top.leading.trailing.equalToSuperview().inset(20)
}


/*
// MARK: - Navigation

// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
// Get the new view controller using segue.destination.
// Pass the selected object to the new view controller.
let crewInfoTitleLabel: UILabel = UILabel().then {
$0.text = "Dear world, we are OFU Crew."
$0.font = .systemFont(ofSize: 14)
$0.textColor = .warmBlue
}
*/

let crewContentLabel: UILabel = UILabel().then {
$0.text = "🛸"
}
crewInfoView.do {
$0.backgroundColor = .grayWhite
$0.addSubview(crewInfoTitleLabel)
$0.addSubview(crewContentLabel)
$0.layer.cornerRadius = 10
}
crewInfoTitleLabel.snp.makeConstraints {
$0.leading.equalToSuperview().inset(20)
$0.centerY.equalToSuperview()
}
crewContentLabel.snp.makeConstraints {
$0.trailing.equalToSuperview().inset(20)
$0.centerY.equalToSuperview()
}
crewInfoView.snp.makeConstraints {
$0.height.equalTo(57)
}

let noticeInfoTitleLabel: UILabel = UILabel().then {
$0.text = "Notice"
$0.font = .systemFont(ofSize: 14)
$0.textColor = .warmBlue
}
noticeCountLabel.do {
$0.text = "1"
$0.backgroundColor = .warmBlue
$0.textColor = .illuminatingYellow
$0.layer.cornerRadius = 5
$0.layer.masksToBounds = true
}
noticeInfoView.do {
$0.backgroundColor = .grayWhite
$0.addSubview(noticeInfoTitleLabel)
$0.addSubview(noticeCountLabel)
$0.layer.cornerRadius = 10
}
noticeInfoTitleLabel.snp.makeConstraints {
$0.leading.equalToSuperview().inset(20)
$0.centerY.equalToSuperview()
}
noticeCountLabel.snp.makeConstraints {
$0.trailing.equalToSuperview().inset(20)
$0.centerY.equalToSuperview()
}
noticeInfoView.snp.makeConstraints {
$0.height.equalTo(57)
}

let versionInfoTitleLabel: UILabel = UILabel().then {
$0.text = "Version Info."
$0.font = .systemFont(ofSize: 14)
$0.textColor = .warmBlue
}
let versionLabel: UILabel = UILabel().then {
$0.text = "New Version"
$0.textColor = .livelyBlue
}
versionInfoView.do {
$0.backgroundColor = .grayWhite
$0.addSubview(versionInfoTitleLabel)
$0.addSubview(versionLabel)
$0.layer.cornerRadius = 10
}
versionInfoTitleLabel.snp.makeConstraints {
$0.leading.equalToSuperview().inset(20)
$0.centerY.equalToSuperview()
}
versionLabel.snp.makeConstraints {
$0.trailing.equalToSuperview().inset(20)
$0.centerY.equalToSuperview()
}
versionInfoView.snp.makeConstraints {
$0.height.equalTo(57)
}
}

// MARK: 🔗 Bind
func bind(reactor: AboutReactor) {
crewInfoView.rx.tapGesture()
.when(.recognized)
.throttle(.milliseconds(300), scheduler: MainScheduler.instance)
.map { _ in Action.tapCrewInfo }
.bind(to: reactor.action)
.disposed(by: disposeBag)

noticeInfoView.rx.tapGesture()
.when(.recognized)
.throttle(.milliseconds(300), scheduler: MainScheduler.instance)
.map { _ in Action.tapNotice }
.bind(to: reactor.action)
.disposed(by: disposeBag)

versionInfoView.rx.tapGesture()
.when(.recognized)
.throttle(.milliseconds(300), scheduler: MainScheduler.instance)
.map { _ in Action.tapVersion }
.bind(to: reactor.action)
.disposed(by: disposeBag)

reactor.state
.map { $0.noticeCount }
.distinctUntilChanged()
.filterNil()
.map { "\($0)" }
.bind(to: noticeCountLabel.rx.text)
.disposed(by: disposeBag)

reactor.state
.distinctUntilChanged(\.$isPresentCrewInfo)
.map { $0.isPresentCrewInfo }
.filter { $0 }
.subscribe(onNext: { _ in
print("isPresentCrewInfo")
})
.disposed(by: disposeBag)

reactor.state
.distinctUntilChanged(\.$isPresentNotice)
.map { $0.isPresentNotice }
.filter { $0 }
.subscribe(onNext: { _ in
print("isPresentNotice")
})
.disposed(by: disposeBag)

reactor.state
.distinctUntilChanged(\.$isPresentAppStore)
.map { $0.isPresentAppStore }
.filter { $0 }
.subscribe(onNext: { _ in
print("isPresentAppStore")
})
.disposed(by: disposeBag)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ final class CheeringMapReactor: Reactor {
switch mutation {
case .setRankers(let rankers):
newState.rankers = rankers

default:
()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import ReactorKit
final class DiscoverReactor: Reactor {

enum Action {
case tapAbout
case countryDidChanged(country: String)
case refresh
case loadMore
Expand All @@ -22,6 +23,7 @@ final class DiscoverReactor: Reactor {
case addMessages(result: [MessageMock], page: Int)
case setCountry(country: String)
case setLoading(Bool)
case setPresentAboutPage
}

struct State {
Expand All @@ -32,6 +34,7 @@ final class DiscoverReactor: Reactor {
var isLoading: Bool = false
var isAnimating: Bool = false
var currentPage: Int = 1
@Revision var isPresentAboutPage: Void?
}

var initialState: State
Expand Down Expand Up @@ -66,6 +69,9 @@ final class DiscoverReactor: Reactor {
APIMock().getMessages(page: 2, country: currentState.country)
.map { Mutation.addMessages(result: $0, page: 2) }
])

case .tapAbout:
return .just(.setPresentAboutPage)
}
}

Expand All @@ -89,6 +95,9 @@ final class DiscoverReactor: Reactor {

case let .setLoading(flag):
newState.isLoading = flag

case .setPresentAboutPage:
newState.isPresentAboutPage = Void()
}
return newState
}
Expand Down
Loading