git.iko.soy/dashared/GDproject
on master help sign in
Added alerts for log in and registration
a733f64Darya Rednikina
GDproject/Base.lproj/Main.storyboard+6−6
@@ -248,37 +248,37 @@
248 <stackView opaque="NO" contentMode="scaleToFill" spacing="12" translatesAutoresizingMaskIntoConstraints="NO" id="2Gj-pC-RZ2">
248 <stackView opaque="NO" contentMode="scaleToFill" spacing="12" translatesAutoresizingMaskIntoConstraints="NO" id="2Gj-pC-RZ2">
249 <rect key="frame" x="37.5" y="99" width="300" height="58"/>
249 <rect key="frame" x="37.5" y="99" width="300" height="58"/>
250 <subviews>
250 <subviews>
251− <textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" placeholder="_" textAlignment="center" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="744-t1-YNn">
251+ <textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" placeholder="_" textAlignment="center" adjustsFontSizeToFit="NO" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="744-t1-YNn">
252 <rect key="frame" x="0.0" y="0.0" width="40" height="58"/>
252 <rect key="frame" x="0.0" y="0.0" width="40" height="58"/>
253 <nil key="textColor"/>
253 <nil key="textColor"/>
254 <fontDescription key="fontDescription" type="system" pointSize="45"/>
254 <fontDescription key="fontDescription" type="system" pointSize="45"/>
255 <textInputTraits key="textInputTraits" keyboardType="numberPad"/>
255 <textInputTraits key="textInputTraits" keyboardType="numberPad"/>
256 </textField>
256 </textField>
257− <textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" placeholder="_" textAlignment="center" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="jcR-jp-s7a">
257+ <textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" placeholder="_" textAlignment="center" adjustsFontSizeToFit="NO" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="jcR-jp-s7a">
258 <rect key="frame" x="52" y="0.0" width="40" height="58"/>
258 <rect key="frame" x="52" y="0.0" width="40" height="58"/>
259 <nil key="textColor"/>
259 <nil key="textColor"/>
260 <fontDescription key="fontDescription" type="system" pointSize="45"/>
260 <fontDescription key="fontDescription" type="system" pointSize="45"/>
261 <textInputTraits key="textInputTraits" keyboardType="numberPad"/>
261 <textInputTraits key="textInputTraits" keyboardType="numberPad"/>
262 </textField>
262 </textField>
263− <textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" placeholder="_" textAlignment="center" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="YKO-0M-KD8">
263+ <textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" placeholder="_" textAlignment="center" adjustsFontSizeToFit="NO" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="YKO-0M-KD8">
264 <rect key="frame" x="104" y="0.0" width="40" height="58"/>
264 <rect key="frame" x="104" y="0.0" width="40" height="58"/>
265 <nil key="textColor"/>
265 <nil key="textColor"/>
266 <fontDescription key="fontDescription" type="system" pointSize="45"/>
266 <fontDescription key="fontDescription" type="system" pointSize="45"/>
267 <textInputTraits key="textInputTraits" keyboardType="numberPad"/>
267 <textInputTraits key="textInputTraits" keyboardType="numberPad"/>
268 </textField>
268 </textField>
269− <textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" placeholder="_" textAlignment="center" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="SmG-Ae-oOs">
269+ <textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" placeholder="_" textAlignment="center" adjustsFontSizeToFit="NO" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="SmG-Ae-oOs">
270 <rect key="frame" x="156" y="0.0" width="40" height="58"/>
270 <rect key="frame" x="156" y="0.0" width="40" height="58"/>
271 <nil key="textColor"/>
271 <nil key="textColor"/>
272 <fontDescription key="fontDescription" type="system" pointSize="45"/>
272 <fontDescription key="fontDescription" type="system" pointSize="45"/>
273 <textInputTraits key="textInputTraits" keyboardType="numberPad"/>
273 <textInputTraits key="textInputTraits" keyboardType="numberPad"/>
274 </textField>
274 </textField>
275− <textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" placeholder="_" textAlignment="center" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="vaP-rO-NZW">
275+ <textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" placeholder="_" textAlignment="center" adjustsFontSizeToFit="NO" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="vaP-rO-NZW">
276 <rect key="frame" x="208" y="0.0" width="40" height="58"/>
276 <rect key="frame" x="208" y="0.0" width="40" height="58"/>
277 <nil key="textColor"/>
277 <nil key="textColor"/>
278 <fontDescription key="fontDescription" type="system" pointSize="45"/>
278 <fontDescription key="fontDescription" type="system" pointSize="45"/>
279 <textInputTraits key="textInputTraits" keyboardType="numberPad"/>
279 <textInputTraits key="textInputTraits" keyboardType="numberPad"/>
280 </textField>
280 </textField>
281− <textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" placeholder="_" textAlignment="center" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="qDh-32-HSn">
281+ <textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" placeholder="_" textAlignment="center" adjustsFontSizeToFit="NO" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="qDh-32-HSn">
282 <rect key="frame" x="260" y="0.0" width="40" height="58"/>
282 <rect key="frame" x="260" y="0.0" width="40" height="58"/>
283 <nil key="textColor"/>
283 <nil key="textColor"/>
284 <fontDescription key="fontDescription" type="system" pointSize="45"/>
284 <fontDescription key="fontDescription" type="system" pointSize="45"/>
GDproject/Controller/ News and channels/PostViewCell.swift+1
@@ -42,6 +42,7 @@ class PostViewCell: UITableViewCell
42
42
43 let shareButton: UIButton = {
43 let shareButton: UIButton = {
44 let button = UIButton(type: UIButton.ButtonType.detailDisclosure)
44 let button = UIButton(type: UIButton.ButtonType.detailDisclosure)
45+ button.isHidden = true
45 return button
46 return button
46 }()
47 }()
47
48
GDproject/Controller/Coordinators/LogInCoordinator.swift+2−1
@@ -26,13 +26,14 @@ class LogInCoordinator: BaseCoordinator {
26 let logInVC = LogInViewController()
26 let logInVC = LogInViewController()
27 logInVC.authenticate = { [weak self, weak logInVC] (email) in
27 logInVC.authenticate = { [weak self, weak logInVC] (email) in
28
28
29+ DataStorage.standard.setEmail(email: email)
29 Model.authenticate(with: email) { [weak self]
30 Model.authenticate(with: email) { [weak self]
30 (authStatus) in
31 (authStatus) in
31
32
32 print(authStatus.userStatus)
33 print(authStatus.userStatus)
33
34
34 if (authStatus.userStatus == "invalid") {
35 if (authStatus.userStatus == "invalid") {
35− logInVC?.mailTextField.text = "invalid"
36+ logInVC?.presentAlertInvalidCode()
36 }
37 }
37 else if (authStatus.userStatus == "canRegister") { // register form
38 else if (authStatus.userStatus == "canRegister") { // register form
38 self?.presentRegisterVC()
39 self?.presentRegisterVC()
GDproject/Controller/Log In/CodeViewController.swift+47−8
@@ -7,6 +7,7 @@
7//
7//
8
8
9import UIKit
9import UIKit
10+import TinyConstraints
10
11
11class CodeViewController: UIViewController {
12class CodeViewController: UIViewController {
12
13
@@ -17,12 +18,16 @@ class CodeViewController: UIViewController {
17 @IBOutlet weak var f5: UITextField!
18 @IBOutlet weak var f5: UITextField!
18 @IBOutlet weak var f6: UITextField!
19 @IBOutlet weak var f6: UITextField!
19
20
21+ var loading = UIActivityIndicatorView(style: .gray)
22+
20 var onSuccessLogIn: (()->())?
23 var onSuccessLogIn: (()->())?
21
24
22 override func viewDidLoad() {
25 override func viewDidLoad() {
23 super.viewDidLoad()
26 super.viewDidLoad()
24 setUpConstraint()
27 setUpConstraint()
25
28
29+ navigationItem.title = DataStorage.standard.getEmail()
30+
26 f1.addTarget(self, action: #selector(textFiledDidChange(textField:)), for: .editingChanged)
31 f1.addTarget(self, action: #selector(textFiledDidChange(textField:)), for: .editingChanged)
27 f2.addTarget(self, action: #selector(textFiledDidChange(textField:)), for: .editingChanged)
32 f2.addTarget(self, action: #selector(textFiledDidChange(textField:)), for: .editingChanged)
28 f3.addTarget(self, action: #selector(textFiledDidChange(textField:)), for: .editingChanged)
33 f3.addTarget(self, action: #selector(textFiledDidChange(textField:)), for: .editingChanged)
@@ -31,6 +36,12 @@ class CodeViewController: UIViewController {
31 f6.addTarget(self, action: #selector(textFiledDidChange(textField:)), for: .editingChanged)
36 f6.addTarget(self, action: #selector(textFiledDidChange(textField:)), for: .editingChanged)
32 }
37 }
33
38
39+ override func viewWillDisappear(_ animated: Bool) {
40+ super.viewWillDisappear(animated)
41+
42+ loading.stopAnimating()
43+ }
44+
34 override func viewWillAppear(_ animated: Bool) {
45 override func viewWillAppear(_ animated: Bool) {
35 super.viewWillAppear(animated)
46 super.viewWillAppear(animated)
36
47
@@ -62,28 +73,56 @@ class CodeViewController: UIViewController {
62 }
73 }
63
74
64
75
76+ func presentAlertInvalidData(with text: String)
77+ {
78+ let alert = UIAlertController(title: "Invalid code", message: text, preferredStyle: .alert)
79+ alert.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
80+ self.present(alert, animated: true, completion: nil)
81+
82+ loading.stopAnimating()
83+ }
84+
65 @IBOutlet weak var bottomConstraint: NSLayoutConstraint!
85 @IBOutlet weak var bottomConstraint: NSLayoutConstraint!
66
86
67 @IBAction func whereToGoNext(_ sender: UIButton)
87 @IBAction func whereToGoNext(_ sender: UIButton)
68 {
88 {
89+ guard let f1t = f1.text, let f2t = f2.text, let f3t = f3.text, let f4t = f4.text, let f5t = f5.text, let f6t = f6.text else {
90+ presentAlertInvalidData(with: "Some fields are missing");
91+ return
92+ }
93+
94+ if f1t.isEmpty || f2t.isEmpty || f3t.isEmpty || f4t.isEmpty || f5t.isEmpty || f6t.isEmpty {
95+ presentAlertInvalidData(with: "Some fields are missing");
96+ return
97+ }
98+
69 let code = "\(f1.text!)\(f2.text!)\(f3.text!)\(f4.text!)\(f5.text!)\(f6.text!)"
99 let code = "\(f1.text!)\(f2.text!)\(f3.text!)\(f4.text!)\(f5.text!)\(f6.text!)"
70 if let codeToInt = Int(code)
100 if let codeToInt = Int(code)
71 {
101 {
102+ loading.startAnimating()
72− Model.verify(with: codeToInt) { _ in
103+ Model.verify(with: codeToInt) { [weak self] in
73 // if everything is okay we can authemticicate
104 // if everything is okay we can authemticicate
105+ if !$0 {
106+ self?.presentAlertInvalidData(with: "Wrong code. Try again!")
107+ self?.loading.stopAnimating()
108+ return
109+ } else {
74− // Model.authemticiateMe
110+ // Model.authemticiateMe
75− Model.authenticateMe { [weak self] (res) in
111+ Model.authenticateMe { [weak self] (res) in
76− if res {
112+ if res {
77− self?.onSuccessLogIn?()
113+ self?.onSuccessLogIn?()
78− } else {
114+ }
79− print("sosi")
80 }
115 }
116+ return
81 }
117 }
82 }
118 }
83 }
119 }
84 }
120 }
85
121
86− func setUpConstraint(){
122+ func setUpConstraint()
123+ {
124+ self.view.addSubview(loading)
125+ loading.centerInSuperview()
87 // for keyboard notifications
126 // for keyboard notifications
88 NotificationCenter.default.addObserver(self, selector: #selector(handleKeyboardNotifications), name: UIResponder.keyboardWillShowNotification, object: nil)
127 NotificationCenter.default.addObserver(self, selector: #selector(handleKeyboardNotifications), name: UIResponder.keyboardWillShowNotification, object: nil)
89
128
GDproject/Controller/Log In/LogInViewController.swift+24−1
@@ -14,8 +14,25 @@ import Result
14
14
15class LogInViewController: UIViewController {
15class LogInViewController: UIViewController {
16
16
17+ var loading = UIActivityIndicatorView(style: .gray)
18+
17 var authenticate: ((String)->())?
19 var authenticate: ((String)->())?
18
20
21+ func presentAlertInvalidCode()
22+ {
23+ let alert = UIAlertController(title: "Invalid email", message: "Try again. Use @hse.ru mail.", preferredStyle: .alert)
24+ alert.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
25+ self.present(alert, animated: true, completion: nil)
26+ mailTextField.text = ""
27+ loading.stopAnimating()
28+ }
29+
30+ override func viewWillDisappear(_ animated: Bool) {
31+ super.viewWillDisappear(animated)
32+
33+ loading.stopAnimating()
34+ }
35+
19 let logInLabel: UILabel = {
36 let logInLabel: UILabel = {
20 let label = UILabel()
37 let label = UILabel()
21 label.text = "Log In"
38 label.text = "Log In"
@@ -45,6 +62,7 @@ class LogInViewController: UIViewController {
45 }()
62 }()
46
63
47 @objc func handleTap(){
64 @objc func handleTap(){
65+ loading.startAnimating()
48 authenticate?(mailTextField.text!)
66 authenticate?(mailTextField.text!)
49 }
67 }
50
68
@@ -55,6 +73,10 @@ class LogInViewController: UIViewController {
55 func setUpView(){
73 func setUpView(){
56 // logIn stack with textField and label
74 // logIn stack with textField and label
57 view.addSubview(contentView)
75 view.addSubview(contentView)
76+ view.addSubview(loading)
77+
78+ loading.centerInSuperview()
79+
58 contentView.edgesToSuperview(excluding: .bottom, insets: .left(16) + .right(16) + .top(80), usingSafeArea: true)
80 contentView.edgesToSuperview(excluding: .bottom, insets: .left(16) + .right(16) + .top(80), usingSafeArea: true)
59 let views = [logInLabel, mailTextField]
81 let views = [logInLabel, mailTextField]
60 contentView.stack(views, axis: .vertical, spacing: 10)
82 contentView.stack(views, axis: .vertical, spacing: 10)
@@ -62,6 +84,7 @@ class LogInViewController: UIViewController {
62
84
63 func configureKeyboard(){
85 func configureKeyboard(){
64
86
87+ mailTextField.keyboardType = .emailAddress
65 // configure keyboardBar setUp
88 // configure keyboardBar setUp
66 view.addSubview(keyboardBar)
89 view.addSubview(keyboardBar)
67 keyboardBar.height(50)
90 keyboardBar.height(50)
@@ -79,7 +102,7 @@ class LogInViewController: UIViewController {
79 func logicOfLogInInputValidation() -> ((String?)->()) {
102 func logicOfLogInInputValidation() -> ((String?)->()) {
80
103
81 let logic: ((String?)->()) = { [weak self] (someText) in
104 let logic: ((String?)->()) = { [weak self] (someText) in
82− if let text = someText, !text.isEmpty {
105+ if let text = someText, !text.isEmpty, text.contains("@") {
83 self?.logInButton.isEnabled = true
106 self?.logInButton.isEnabled = true
84 } else {
107 } else {
85 self?.logInButton.isEnabled = false
108 self?.logInButton.isEnabled = false
GDproject/Controller/Log In/RegisterTableViewController.swift+13−2
@@ -11,6 +11,13 @@ import UIKit
11class RegisterTableViewController: UITableViewController, ChosenFactulty
11class RegisterTableViewController: UITableViewController, ChosenFactulty
12{
12{
13
13
14+ func presentAlertInvalidData()
15+ {
16+ let alert = UIAlertController(title: "Invalid data", message: "Some fields are missing. Add more information", preferredStyle: .alert)
17+ alert.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
18+ self.present(alert, animated: true, completion: nil)
19+ }
20+
14 func onChooseFaculty(faculty: Model.Faculty) {
21 func onChooseFaculty(faculty: Model.Faculty) {
15 self.faculty = faculty
22 self.faculty = faculty
16 tableView.reloadData()
23 tableView.reloadData()
@@ -20,7 +27,7 @@ class RegisterTableViewController: UITableViewController, ChosenFactulty
20 var onRegistration: (()->())?
27 var onRegistration: (()->())?
21
28
22 var faculty: Model.Faculty?
29 var faculty: Model.Faculty?
23− var user: Model.NewRegistration = Model.NewRegistration(email: "dyurednikina@edu.hse.ru", firstName: nil, middleName: nil, lastName: nil, faculty: nil)
30+ var user: Model.NewRegistration = Model.NewRegistration(email: DataStorage.standard.getEmail()!, firstName: nil, middleName: nil, lastName: nil, faculty: nil)
24
31
25 override func viewDidLoad()
32 override func viewDidLoad()
26 {
33 {
@@ -34,10 +41,14 @@ class RegisterTableViewController: UITableViewController, ChosenFactulty
34 @objc func endRegistration()
41 @objc func endRegistration()
35 {
42 {
36 updateUser()
43 updateUser()
37− guard let faculty = faculty else { return }
44+ guard let faculty = faculty else { presentAlertInvalidData(); return }
38
45
39 user.faculty = faculty.url
46 user.faculty = faculty.url
40
47
48+ guard let _ = user.firstName else { presentAlertInvalidData(); return }
49+ guard let _ = user.middleName else { presentAlertInvalidData(); return }
50+ guard let _ = user.lastName else { presentAlertInvalidData(); return }
51+
41 Model.register(object: user)
52 Model.register(object: user)
42 { [weak self] in
53 { [weak self] in
43 self?.onRegistration?()
54 self?.onRegistration?()
GDproject/Controller/Profile/ProfileViewController.swift+1−1
@@ -56,7 +56,7 @@ class ProfileViewController: UIViewController
56 self.nameLabel.text = "\(user.firstName) \(user.middleName)"
56 self.nameLabel.text = "\(user.firstName) \(user.middleName)"
57 self.surnameLabel.text = "\(user.lastName)"
57 self.surnameLabel.text = "\(user.lastName)"
58 self.profileImageView.image = protoDictionary[user.faculty.campusCode]?.roundedImage
58 self.profileImageView.image = protoDictionary[user.faculty.campusCode]?.roundedImage
59− self.placeLabel.text = "📍\(user.faculty.campusName)"
59+ self.placeLabel.text = "📍\(user.faculty.address)"
60 if user.id == DataStorage.standard.getUserId() {
60 if user.id == DataStorage.standard.getUserId() {
61 newMessageButton.isHidden = true
61 newMessageButton.isHidden = true
62 } else {
62 } else {
GDproject/DataStorage.swift+8
@@ -37,6 +37,13 @@ class DataStorage{
37 return UserDefaults.standard.integer(forKey: UserDefaultsKeys.id.rawValue)
37 return UserDefaults.standard.integer(forKey: UserDefaultsKeys.id.rawValue)
38 }
38 }
39
39
40+ func setEmail(email: String) {
41+ UserDefaults.standard.set(email, forKey: UserDefaultsKeys.email.rawValue)
42+ }
43+
44+ func getEmail() -> String? {
45+ return UserDefaults.standard.string(forKey: UserDefaultsKeys.email.rawValue)
46+ }
40 /**
47 /**
41 Function to determine is user logged in already or not
48 Function to determine is user logged in already or not
42 */
49 */
@@ -49,4 +56,5 @@ class DataStorage{
49enum UserDefaultsKeys: String{
56enum UserDefaultsKeys: String{
50 case loggedIn
57 case loggedIn
51 case id
58 case id
59+ case email
52}
60}
GDproject/Simple model/Model.swift+3−2
@@ -267,9 +267,9 @@ class Model{
267 if statusCode == 204 {
267 if statusCode == 204 {
268 // at this point cookies are set
268 // at this point cookies are set
269 completion(true)
269 completion(true)
270+ } else {
271+ completion(false)
270 }
272 }
271−
272− completion(false)
273 }
273 }
274 }
274 }
275
275
@@ -976,6 +976,7 @@ class Model{
976 var campusCode: String
976 var campusCode: String
977 var name: String
977 var name: String
978 var tags: [String]
978 var tags: [String]
979+ var address: String
979
980
980 }
981 }
981
982