Skip to content

Commit

Permalink
✨ About 화면 구현 (#22)
Browse files Browse the repository at this point in the history
  • Loading branch information
O-O-wl authored Jan 3, 2021
1 parent 518cb3a commit 8cd8f15
Show file tree
Hide file tree
Showing 7 changed files with 293 additions and 17 deletions.
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

0 comments on commit 8cd8f15

Please sign in to comment.