diff --git a/Dear-World/Dear-World.xcodeproj/project.pbxproj b/Dear-World/Dear-World.xcodeproj/project.pbxproj index ef53569..cc8538f 100644 --- a/Dear-World/Dear-World.xcodeproj/project.pbxproj +++ b/Dear-World/Dear-World.xcodeproj/project.pbxproj @@ -30,6 +30,8 @@ 3914D9E6259F3FA1009765B0 /* Message.Model.Messages.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3914D9E5259F3FA1009765B0 /* Message.Model.Messages.swift */; }; 393E0D4025A23A12000DB3B9 /* World.Model.Map.swift in Sources */ = {isa = PBXBuildFile; fileRef = 393E0D3F25A23A12000DB3B9 /* World.Model.Map.swift */; }; 393E0D4525A23A7B000DB3B9 /* World.API.Map.swift in Sources */ = {isa = PBXBuildFile; fileRef = 393E0D4425A23A7B000DB3B9 /* World.API.Map.swift */; }; + 393E0D5725A2BE3C000DB3B9 /* AboutTeamViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 393E0D5625A2BE3C000DB3B9 /* AboutTeamViewController.swift */; }; + 393E0D5F25A2CEB6000DB3B9 /* AboutTeamReactor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 393E0D5E25A2CEB6000DB3B9 /* AboutTeamReactor.swift */; }; 3958257B25948E41007325AB /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3958257A25948E41007325AB /* AppDelegate.swift */; }; 3958258425948E43007325AB /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 3958258325948E43007325AB /* Assets.xcassets */; }; 3958258725948E43007325AB /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 3958258525948E43007325AB /* LaunchScreen.storyboard */; }; @@ -125,6 +127,8 @@ 3914D9E5259F3FA1009765B0 /* Message.Model.Messages.swift */ = {isa = PBXFileReference; indentWidth = 2; lastKnownFileType = sourcecode.swift; name = Message.Model.Messages.swift; path = "Dear-World/Source/Presentation/Scene/Main/Message.Model.Messages.swift"; sourceTree = SOURCE_ROOT; tabWidth = 2; }; 393E0D3F25A23A12000DB3B9 /* World.Model.Map.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = World.Model.Map.swift; sourceTree = ""; }; 393E0D4425A23A7B000DB3B9 /* World.API.Map.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = World.API.Map.swift; sourceTree = ""; }; + 393E0D5625A2BE3C000DB3B9 /* AboutTeamViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AboutTeamViewController.swift; sourceTree = ""; }; + 393E0D5E25A2CEB6000DB3B9 /* AboutTeamReactor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AboutTeamReactor.swift; sourceTree = ""; }; 3958257725948E41007325AB /* Dear-World.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Dear-World.app"; sourceTree = BUILT_PRODUCTS_DIR; }; 3958257A25948E41007325AB /* AppDelegate.swift */ = {isa = PBXFileReference; indentWidth = 2; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; tabWidth = 2; }; 3958258325948E43007325AB /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; @@ -280,6 +284,15 @@ path = Extension; sourceTree = ""; }; + 393E0D5525A2BE18000DB3B9 /* AboutTeam */ = { + isa = PBXGroup; + children = ( + 393E0D5625A2BE3C000DB3B9 /* AboutTeamViewController.swift */, + 393E0D5E25A2CEB6000DB3B9 /* AboutTeamReactor.swift */, + ); + path = AboutTeam; + sourceTree = ""; + }; 3958256E25948E41007325AB = { isa = PBXGroup; children = ( @@ -453,6 +466,7 @@ 3958260325962FAE007325AB /* About */ = { isa = PBXGroup; children = ( + 393E0D5525A2BE18000DB3B9 /* AboutTeam */, 3902F117259704AF00A3DF8C /* AboutViewController.swift */, 39E9F7CF25A1738F00BC2CC2 /* AboutReactor.swift */, ); @@ -766,6 +780,7 @@ 121BDB592597652A0062B15A /* MessageTableViewCell.swift in Sources */, 3902F12A259714D800A3DF8C /* RankerTableViewCell.swift in Sources */, 395826332596E693007325AB /* Logger.swift in Sources */, + 393E0D5F25A2CEB6000DB3B9 /* AboutTeamReactor.swift in Sources */, 1263E09725A1C87400E3F121 /* Message.API.Countries.swift in Sources */, 39F0C19025987A2B00A7001F /* ServiceAPI.swift in Sources */, 12A05EFF25A353700089EF1C /* Message.API.Like.swift in Sources */, @@ -796,6 +811,7 @@ 39F0C176259860D700A7001F /* UIControl+Rx.swift in Sources */, 121BDB2A2597259E0062B15A /* MessageCountBadgeView.swift in Sources */, 39F0C16B2597C7DF00A7001F /* UIImage+.swift in Sources */, + 393E0D5725A2BE3C000DB3B9 /* AboutTeamViewController.swift in Sources */, 39E9F7E025A1BC3C00BC2CC2 /* NoticeBadge.swift in Sources */, 12257E1825A622750007E65E /* SortTypeSelectController.swift in Sources */, 39E9F7ED25A1C84900BC2CC2 /* WorldMap.Model.Country.swift in Sources */, diff --git a/Dear-World/Dear-World/Resource/Assets.xcassets/Chipmunk.imageset/Chipmunk.png b/Dear-World/Dear-World/Resource/Assets.xcassets/Chipmunk.imageset/Chipmunk.png new file mode 100644 index 0000000..7f3374d Binary files /dev/null and b/Dear-World/Dear-World/Resource/Assets.xcassets/Chipmunk.imageset/Chipmunk.png differ diff --git a/Dear-World/Dear-World/Resource/Assets.xcassets/Chipmunk.imageset/Contents.json b/Dear-World/Dear-World/Resource/Assets.xcassets/Chipmunk.imageset/Contents.json new file mode 100644 index 0000000..00a5242 --- /dev/null +++ b/Dear-World/Dear-World/Resource/Assets.xcassets/Chipmunk.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "Chipmunk.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Dear-World/Dear-World/Resource/Assets.xcassets/Ifmoon.imageset/Contents.json b/Dear-World/Dear-World/Resource/Assets.xcassets/Ifmoon.imageset/Contents.json new file mode 100644 index 0000000..e589004 --- /dev/null +++ b/Dear-World/Dear-World/Resource/Assets.xcassets/Ifmoon.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "Ifmoon.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Dear-World/Dear-World/Resource/Assets.xcassets/Ifmoon.imageset/Ifmoon.png b/Dear-World/Dear-World/Resource/Assets.xcassets/Ifmoon.imageset/Ifmoon.png new file mode 100644 index 0000000..a79f140 Binary files /dev/null and b/Dear-World/Dear-World/Resource/Assets.xcassets/Ifmoon.imageset/Ifmoon.png differ diff --git a/Dear-World/Dear-World/Resource/Assets.xcassets/Judy.imageset/Contents.json b/Dear-World/Dear-World/Resource/Assets.xcassets/Judy.imageset/Contents.json new file mode 100644 index 0000000..945031f --- /dev/null +++ b/Dear-World/Dear-World/Resource/Assets.xcassets/Judy.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "Judy.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Dear-World/Dear-World/Resource/Assets.xcassets/Judy.imageset/Judy.png b/Dear-World/Dear-World/Resource/Assets.xcassets/Judy.imageset/Judy.png new file mode 100644 index 0000000..b170e3d Binary files /dev/null and b/Dear-World/Dear-World/Resource/Assets.xcassets/Judy.imageset/Judy.png differ diff --git a/Dear-World/Dear-World/Resource/Assets.xcassets/Minsour.imageset/Contents.json b/Dear-World/Dear-World/Resource/Assets.xcassets/Minsour.imageset/Contents.json new file mode 100644 index 0000000..c5613d7 --- /dev/null +++ b/Dear-World/Dear-World/Resource/Assets.xcassets/Minsour.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "Minsour.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Dear-World/Dear-World/Resource/Assets.xcassets/Minsour.imageset/Minsour.png b/Dear-World/Dear-World/Resource/Assets.xcassets/Minsour.imageset/Minsour.png new file mode 100644 index 0000000..8dcd58e Binary files /dev/null and b/Dear-World/Dear-World/Resource/Assets.xcassets/Minsour.imageset/Minsour.png differ diff --git a/Dear-World/Dear-World/Resource/Assets.xcassets/Owl.imageset/Contents.json b/Dear-World/Dear-World/Resource/Assets.xcassets/Owl.imageset/Contents.json new file mode 100644 index 0000000..a49d761 --- /dev/null +++ b/Dear-World/Dear-World/Resource/Assets.xcassets/Owl.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "Owl.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Dear-World/Dear-World/Resource/Assets.xcassets/Owl.imageset/Owl.png b/Dear-World/Dear-World/Resource/Assets.xcassets/Owl.imageset/Owl.png new file mode 100644 index 0000000..5648ce5 Binary files /dev/null and b/Dear-World/Dear-World/Resource/Assets.xcassets/Owl.imageset/Owl.png differ diff --git a/Dear-World/Dear-World/Resource/Assets.xcassets/Pengin.imageset/Contents.json b/Dear-World/Dear-World/Resource/Assets.xcassets/Pengin.imageset/Contents.json new file mode 100644 index 0000000..03fd3db --- /dev/null +++ b/Dear-World/Dear-World/Resource/Assets.xcassets/Pengin.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "Pengin.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Dear-World/Dear-World/Resource/Assets.xcassets/Pengin.imageset/Pengin.png b/Dear-World/Dear-World/Resource/Assets.xcassets/Pengin.imageset/Pengin.png new file mode 100644 index 0000000..8aca5ef Binary files /dev/null and b/Dear-World/Dear-World/Resource/Assets.xcassets/Pengin.imageset/Pengin.png differ diff --git a/Dear-World/Dear-World/Resource/Assets.xcassets/Peter.imageset/Contents.json b/Dear-World/Dear-World/Resource/Assets.xcassets/Peter.imageset/Contents.json new file mode 100644 index 0000000..3a4ee6a --- /dev/null +++ b/Dear-World/Dear-World/Resource/Assets.xcassets/Peter.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "Peter.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Dear-World/Dear-World/Resource/Assets.xcassets/Peter.imageset/Peter.png b/Dear-World/Dear-World/Resource/Assets.xcassets/Peter.imageset/Peter.png new file mode 100644 index 0000000..3667d8d Binary files /dev/null and b/Dear-World/Dear-World/Resource/Assets.xcassets/Peter.imageset/Peter.png differ diff --git a/Dear-World/Dear-World/Resource/Assets.xcassets/Rookie.imageset/Contents.json b/Dear-World/Dear-World/Resource/Assets.xcassets/Rookie.imageset/Contents.json new file mode 100644 index 0000000..fc9ded8 --- /dev/null +++ b/Dear-World/Dear-World/Resource/Assets.xcassets/Rookie.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "Rookie.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Dear-World/Dear-World/Resource/Assets.xcassets/Rookie.imageset/Rookie.png b/Dear-World/Dear-World/Resource/Assets.xcassets/Rookie.imageset/Rookie.png new file mode 100644 index 0000000..54ce65b Binary files /dev/null and b/Dear-World/Dear-World/Resource/Assets.xcassets/Rookie.imageset/Rookie.png differ diff --git a/Dear-World/Dear-World/Resource/Assets.xcassets/YuChoco.imageset/Contents.json b/Dear-World/Dear-World/Resource/Assets.xcassets/YuChoco.imageset/Contents.json new file mode 100644 index 0000000..90f2496 --- /dev/null +++ b/Dear-World/Dear-World/Resource/Assets.xcassets/YuChoco.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "YuChoco.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Dear-World/Dear-World/Resource/Assets.xcassets/YuChoco.imageset/YuChoco.png b/Dear-World/Dear-World/Resource/Assets.xcassets/YuChoco.imageset/YuChoco.png new file mode 100644 index 0000000..7d92fa0 Binary files /dev/null and b/Dear-World/Dear-World/Resource/Assets.xcassets/YuChoco.imageset/YuChoco.png differ diff --git a/Dear-World/Dear-World/Resource/Assets.xcassets/about_top_img.imageset/Contents.json b/Dear-World/Dear-World/Resource/Assets.xcassets/about_top_img.imageset/Contents.json new file mode 100644 index 0000000..093b8bd --- /dev/null +++ b/Dear-World/Dear-World/Resource/Assets.xcassets/about_top_img.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "about_top_img.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Dear-World/Dear-World/Resource/Assets.xcassets/about_top_img.imageset/about_top_img.png b/Dear-World/Dear-World/Resource/Assets.xcassets/about_top_img.imageset/about_top_img.png new file mode 100644 index 0000000..83e07d9 Binary files /dev/null and b/Dear-World/Dear-World/Resource/Assets.xcassets/about_top_img.imageset/about_top_img.png differ diff --git a/Dear-World/Dear-World/Resource/Assets.xcassets/backWhite.imageset/Contents.json b/Dear-World/Dear-World/Resource/Assets.xcassets/backWhite.imageset/Contents.json new file mode 100644 index 0000000..f756a80 --- /dev/null +++ b/Dear-World/Dear-World/Resource/Assets.xcassets/backWhite.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "backWhite.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Dear-World/Dear-World/Resource/Assets.xcassets/backWhite.imageset/backWhite.png b/Dear-World/Dear-World/Resource/Assets.xcassets/backWhite.imageset/backWhite.png new file mode 100644 index 0000000..3d3860d Binary files /dev/null and b/Dear-World/Dear-World/Resource/Assets.xcassets/backWhite.imageset/backWhite.png differ diff --git a/Dear-World/Dear-World/Source/Domain/Message/API/Message.Model.SendMessage.swift b/Dear-World/Dear-World/Source/Domain/Message/API/Message.Model.SendMessage.swift index aa5352d..ad6ec4e 100644 --- a/Dear-World/Dear-World/Source/Domain/Message/API/Message.Model.SendMessage.swift +++ b/Dear-World/Dear-World/Source/Domain/Message/API/Message.Model.SendMessage.swift @@ -9,12 +9,9 @@ import Foundation extension Message.Model { struct SendMessage: Decodable { - let uuid: String let likeCount: Int let id: Int let anonymousUserId: Int let content: String - let updatedAt: Date - let createdAt: Date } } diff --git a/Dear-World/Dear-World/Source/Presentation/Scene/About/AboutTeam/AboutTeamReactor.swift b/Dear-World/Dear-World/Source/Presentation/Scene/About/AboutTeam/AboutTeamReactor.swift new file mode 100644 index 0000000..e517cc7 --- /dev/null +++ b/Dear-World/Dear-World/Source/Presentation/Scene/About/AboutTeam/AboutTeamReactor.swift @@ -0,0 +1,34 @@ +// +// AboutTeamReactor.swift +// Dear-World +// +// Created by dongyoung.lee on 2021/01/04. +// + +import ReactorKit + +final class AboutTeamReactor: Reactor { + enum Action { + case initialize + case tapBack + } + + struct State { + var crews: [Crew] = [] + @Revision var isWillDismiss: Bool = false + } + + let initialState: State = State() + + func reduce(state: State, mutation: Action) -> State { + var newState: State = state + switch mutation { + case .initialize: + newState.crews = Crew.all + + case .tapBack: + newState.isWillDismiss = true + } + return newState + } +} diff --git a/Dear-World/Dear-World/Source/Presentation/Scene/About/AboutTeam/AboutTeamViewController.swift b/Dear-World/Dear-World/Source/Presentation/Scene/About/AboutTeam/AboutTeamViewController.swift new file mode 100644 index 0000000..6a52963 --- /dev/null +++ b/Dear-World/Dear-World/Source/Presentation/Scene/About/AboutTeam/AboutTeamViewController.swift @@ -0,0 +1,265 @@ +// +// AboutTeamViewController.swift +// Dear-World +// +// Created by dongyoung.lee on 2021/01/04. +// + +import Then +import ReactorKit +import UIKit + +final class AboutTeamViewController: UIViewController, View { + + typealias Reactor = AboutTeamReactor + + // MARK: 🖼 UI + private let scrollView: UIScrollView = UIScrollView() + private let crewsCollectionView: UICollectionView = UICollectionView( + frame: .zero, + collectionViewLayout: UICollectionViewFlowLayout() + ) + private let moreButton: UIButton = UIButton() + private let backButton: UIButton = UIButton() + + var disposeBag: DisposeBag = DisposeBag() + + // MARK: 🏁 Initialize + init() { + super.init(nibName: nil, bundle: nil) + + setupUI() + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + override func viewWillAppear(_ animated: Bool) { + super.viewWillAppear(animated) + + self.navigationController?.navigationBar.isHidden = true + } + // MARK: 🎛 Setup + private func setupUI() { + self.view.backgroundColor = .breathingWhite + + let headerView: UIImageView = UIImageView().then { + $0.image = UIImage(named: "about_top_img") + } + self.view.addSubview(headerView) + headerView.snp.makeConstraints { + $0.top.leading.trailing.equalToSuperview() + $0.height.equalTo(UIScreen.main.bounds.width * 240.0 / 375.0) + } + + self.view.addSubview(backButton) + backButton.do { + $0.setBackgroundImage(UIImage(named: "backWhite"), for: .normal) + } + backButton.snp.makeConstraints { + $0.leading.equalToSuperview().inset(20) + $0.top.equalTo(self.view.safeAreaLayoutGuide).inset(37) + } + + let teamGreetingTitleLabel: UILabel = UILabel().then { + $0.text = "Hello, we are team OFU!" + $0.font = .boldSystemFont(ofSize: 16) + $0.textColor = .warmBlue + } + let teamGreetingLabel: UILabel = UILabel().then { + $0.text = """ + Since Corona bothering the world, we start the project to + make people can encouraged themselves by writting their + stories on it. Our OFU crew always cheers you and hope we all overcome this corona blue. + """ + $0.font = .systemFont(ofSize: 12) + $0.textColor = .nightBlue + $0.numberOfLines = 0 + } + self.view.addSubview(teamGreetingTitleLabel) + self.view.addSubview(teamGreetingLabel) + teamGreetingTitleLabel.snp.makeConstraints { + $0.leading.trailing.equalToSuperview().inset(20) + $0.top.equalTo(headerView.snp.bottom).offset(30) + } + teamGreetingLabel.snp.makeConstraints { + $0.leading.trailing.equalToSuperview().inset(20) + $0.top.equalTo(teamGreetingTitleLabel.snp.bottom).offset(10) + } + + let crewsTitleLable: UILabel = UILabel().then { + $0.text = "OFU CREWS" + $0.textColor = .warmBlue + $0.font = .boldSystemFont(ofSize: 16) + } + self.view.addSubview(crewsTitleLable) + crewsTitleLable.snp.makeConstraints { + $0.top.equalTo(teamGreetingLabel.snp.bottom).offset(50) + $0.leading.trailing.equalToSuperview().inset(20) + } + + self.view.addSubview(crewsCollectionView) + crewsCollectionView.do { + $0.register(CrewCollectionViewCell.self, forCellWithReuseIdentifier: "CrewCollectionViewCell") + $0.backgroundColor = .breathingWhite + $0.delegate = self + $0.allowsSelection = false + } + crewsCollectionView.snp.makeConstraints { + $0.top.equalTo(crewsTitleLable.snp.bottom).offset(20) + $0.leading.trailing.equalToSuperview().inset(20) + $0.height.equalTo(440) + } + + let footerView: UIView = UIView().then { + $0.backgroundColor = .livelyBlue + } + self.view.addSubview(footerView) + footerView.snp.makeConstraints { + $0.leading.trailing.equalToSuperview() + $0.height.equalTo(144) + $0.top.equalTo(crewsCollectionView.snp.bottom).offset(100) + } + + footerView.addSubview(moreButton) + moreButton.do { + $0.backgroundColor = .illuminatingYellow + $0.setTitle("More about OFU CREW", for: .normal) + $0.titleLabel?.font = .systemFont(ofSize: 14) + $0.layer.cornerRadius = 10 + $0.setTitleColor(.warmBlue, for: .normal) + } + moreButton.snp.makeConstraints { + $0.top.equalToSuperview().inset(15) + $0.leading.trailing.equalToSuperview().inset(20) + $0.height.equalTo(48) + } + + let copyrightLabel: UILabel = UILabel().then { + $0.text = "ⓒ OFU 2021. Made in Korea" + $0.font = .systemFont(ofSize: 14) + $0.textColor = .breathingWhite + } + footerView.addSubview(copyrightLabel) + copyrightLabel.snp.makeConstraints { + $0.centerX.equalToSuperview() + $0.top.equalTo(moreButton.snp.bottom).offset(25) + } + } + + // MARK: 🔗 Bind + func bind(reactor: AboutTeamReactor) { + reactor.state.map { $0.crews } + .bind(to: crewsCollectionView.rx.items(cellIdentifier: "CrewCollectionViewCell", cellType: CrewCollectionViewCell.self)) { index, crew, cell in + cell.configure(crew) + } + .disposed(by: disposeBag) + + reactor.state.distinctUntilChanged(\.$isWillDismiss) + .filter { $0.isWillDismiss } + .subscribe(onNext: { [weak self] _ in + self?.dismiss(animated: true, completion: nil) + }) + .disposed(by: disposeBag) + + reactor.action.onNext(.initialize) + + backButton.rx.tap + .throttle(.milliseconds(300), scheduler: MainScheduler.instance) + .map { Reactor.Action.tapBack } + .bind(to: reactor.action) + .disposed(by: disposeBag) + } + +} +extension AboutTeamViewController: UICollectionViewDelegateFlowLayout { + private var inset: CGFloat { 20 } + private var itemSpacing: CGFloat { 48 } + var itemWidth: CGFloat { + (UIScreen.main.bounds.width - (inset * 2) - (itemSpacing * 2)) / 3 + } + var itemHeight: CGFloat { + itemWidth * 1.5 + } + + func collectionView( + _ collectionView: UICollectionView, + layout collectionViewLayout: UICollectionViewLayout, + sizeForItemAt indexPath: IndexPath + ) -> CGSize { + CGSize(width: itemWidth, height: itemHeight) + } +} + +struct Crew { + let name: String + let role: String + let profileImage: UIImage +} +extension Crew { + static let all: [Crew] = [ + Crew(name: "Judy", role: "PM, Design", profileImage: UIImage(named: "Judy")!), + Crew(name: "Pengin", role: "Backend Dev", profileImage: UIImage(named: "Pengin")!), + Crew(name: "Owl", role: "iOS Dev", profileImage: UIImage(named: "Owl")!), + Crew(name: "Rookie", role: "iOS Dev", profileImage: UIImage(named: "Rookie")!), + Crew(name: "Ifmoon", role: "Frontend Dev", profileImage: UIImage(named: "Ifmoon")!), + Crew(name: "Minsour", role: "Frontend Dev", profileImage: UIImage(named: "Minsour")!), + Crew(name: "Chipmunk", role: "Backend Dev", profileImage: UIImage(named: "Chipmunk")!), + Crew(name: "YuChoco", role: "Android Dev", profileImage: UIImage(named: "YuChoco")!), + Crew(name: "Peter", role: "Android Dev", profileImage: UIImage(named: "Peter")!) + ] +} + +final class CrewCollectionViewCell: UICollectionViewCell { + private let profileImageView: UIImageView = UIImageView() + private let nameLabel: UILabel = UILabel() + private let roleLabel: UILabel = UILabel() + + override init(frame: CGRect) { + super.init(frame: frame) + + setupUI() + } + + required init?(coder: NSCoder) { + super.init(coder: coder) + + setupUI() + } + + private func setupUI() { + self.addSubview(profileImageView) + profileImageView.snp.makeConstraints { + $0.width.height.equalTo(self.bounds.width) + } + + self.addSubview(nameLabel) + nameLabel.do { + $0.textAlignment = .center + $0.font = .systemFont(ofSize: 12) + $0.textColor = .warmBlue + } + nameLabel.snp.makeConstraints { + $0.top.equalTo(profileImageView.snp.bottom).offset(10) + $0.leading.trailing.equalToSuperview() + } + + self.addSubview(roleLabel) + roleLabel.do { + $0.textAlignment = .center + $0.font = .systemFont(ofSize: 10) + $0.textColor = .livelyBlue + } + roleLabel.snp.makeConstraints { + $0.top.equalTo(nameLabel.snp.bottom).offset(4) + $0.leading.trailing.equalToSuperview() + } + } + + func configure(_ crew: Crew) { + nameLabel.text = crew.name + roleLabel.text = crew.role + profileImageView.image = crew.profileImage + } +} diff --git a/Dear-World/Dear-World/Source/Presentation/Scene/About/AboutViewController.swift b/Dear-World/Dear-World/Source/Presentation/Scene/About/AboutViewController.swift index 3749c62..1080ad7 100644 --- a/Dear-World/Dear-World/Source/Presentation/Scene/About/AboutViewController.swift +++ b/Dear-World/Dear-World/Source/Presentation/Scene/About/AboutViewController.swift @@ -183,7 +183,10 @@ final class AboutViewController: UIViewController, View { .map { $0.isPresentCrewInfo } .filter { $0 } .subscribe(onNext: { _ in - print("isPresentCrewInfo") + let viewController: UIViewController = AboutTeamViewController().then { + $0.reactor = AboutTeamReactor() + } + self.navigationController?.pushViewController(viewController, animated: true) }) .disposed(by: disposeBag) diff --git a/Dear-World/Dear-World/Source/Presentation/Scene/Discover/DiscoverReactor.swift b/Dear-World/Dear-World/Source/Presentation/Scene/Discover/DiscoverReactor.swift index bc6a9da..8d05777 100644 --- a/Dear-World/Dear-World/Source/Presentation/Scene/Discover/DiscoverReactor.swift +++ b/Dear-World/Dear-World/Source/Presentation/Scene/Discover/DiscoverReactor.swift @@ -6,10 +6,12 @@ // import Foundation +import RxOptional import ReactorKit final class DiscoverReactor: Reactor { enum Action { + case viewWillAppear case tapAbout case countryDidChanged(country: Message.Model.Country?, sortType: Message.Model.ListType? = nil) case refresh @@ -48,6 +50,20 @@ final class DiscoverReactor: Reactor { // MARK: 🔫 Mutate func mutate(action: Action) -> Observable { switch action { + case .viewWillAppear: + return .merge( + Network.request(Message.API.MessageCount(countryCode: currentState.selectedCountry?.code)) + .filterNil() + .map { Mutation.setMessageCount($0.messageCount) }, + Network.request(Message.API.Messages( + countryCode: currentState.selectedCountry?.code, + lastMsgId: nil, + type: .recent + )) + .filterNil() + .map{ Mutation.setMessages(result: $0) } + ) + case let .countryDidChanged(country, sortType): return .merge( Network.request(Message.API.MessageCount(countryCode: country?.code)) @@ -99,13 +115,13 @@ final class DiscoverReactor: Reactor { case let .setRefreshing(flag): newState.isRefreshing = flag - + case let .addMessages(result: results): newState.messages = Message.Model.Messages(firstMsgId: state.messages.firstMsgId, lastMsgId: results.lastMsgId, messageCount: state.messageCount + results.messageCount, messages: currentState.messages.messages + results.messages) - + case let .setCountry(country: country): newState.selectedCountry = country - + case let .setLoading(flag): newState.isLoading = flag diff --git a/Dear-World/Dear-World/Source/Presentation/Scene/Discover/DiscoverViewController.swift b/Dear-World/Dear-World/Source/Presentation/Scene/Discover/DiscoverViewController.swift index 5628fea..9bd9f3d 100644 --- a/Dear-World/Dear-World/Source/Presentation/Scene/Discover/DiscoverViewController.swift +++ b/Dear-World/Dear-World/Source/Presentation/Scene/Discover/DiscoverViewController.swift @@ -33,6 +33,12 @@ final class DiscoverViewController: UIViewController, View { startInitAnimation() } + override func viewWillAppear(_ animated: Bool) { + super.viewWillAppear(animated) + + reactor?.action.onNext(.viewWillAppear) + } + private func startInitAnimation() { animate(view: messageCountBadgeView, alpha: 0.4, length: 20, duration: 0.4) animate(view: filterContainerView, alpha: 0.4, length: 20, duration: 0.4) diff --git a/Dear-World/Dear-World/Source/Presentation/Scene/Send Message/SendMessageReactor.swift b/Dear-World/Dear-World/Source/Presentation/Scene/Send Message/SendMessageReactor.swift index 9c1eef4..d11201e 100644 --- a/Dear-World/Dear-World/Source/Presentation/Scene/Send Message/SendMessageReactor.swift +++ b/Dear-World/Dear-World/Source/Presentation/Scene/Send Message/SendMessageReactor.swift @@ -21,6 +21,7 @@ final class SendMessageReactor: Reactor { } enum Mutation { + case setEmojiId(Int) case setEmoji(String) case setName(String) case setMessage(String) @@ -28,7 +29,7 @@ final class SendMessageReactor: Reactor { } struct State: Then { - var isPresented: Bool = true + @Revision var isPresented: Bool = true var emoji: String = "👽" var canSendMessage: Bool = false var name: String = "" @@ -67,8 +68,13 @@ final class SendMessageReactor: Reactor { case .tapRefresh: return Network.request(Emoji.API.Random()) - .filterNil() - .map { .setEmoji($0.unicode) } + .filterNil() + .flatMap { + Observable.from([ + .setEmojiId($0.id), + .setEmoji($0.unicode) + ]) + } case .typeName(let name): return .just(.setName(name)) @@ -83,9 +89,12 @@ final class SendMessageReactor: Reactor { name: currentState.name, message: currentState.message ) - return Network.request(api) - .filterNil() - .map { _ in .setMessage("완료") } + return .concat( + Network.request(api) + .filterNil() + .map { _ in .setMessage("완료") }, + .just(Mutation.setPresent(false)) + ) } } @@ -129,6 +138,8 @@ final class SendMessageReactor: Reactor { limitCount: $0.messageCountLimit ) } + case .setEmojiId(let id): + newState = state.with { $0.emojiId = id } } return newState }