git.iko.soy/dashared/GDproject
on master help sign in
working on coordination between anonymous channels. in close future: design and implement channels' card
e5bb705Darya Rednikina
GDproject/Base.lproj/Main.storyboard+2
@@ -526,6 +526,7 @@
526 <constraint firstItem="4pw-5n-XsC" firstAttribute="leading" secondItem="Qwh-6O-iyN" secondAttribute="leading" id="nau-1I-Bh7"/>
526 <constraint firstItem="4pw-5n-XsC" firstAttribute="leading" secondItem="Qwh-6O-iyN" secondAttribute="leading" id="nau-1I-Bh7"/>
527 <constraint firstAttribute="trailing" secondItem="4pw-5n-XsC" secondAttribute="trailing" id="vnT-kX-h1h"/>
527 <constraint firstAttribute="trailing" secondItem="4pw-5n-XsC" secondAttribute="trailing" id="vnT-kX-h1h"/>
528 </constraints>
528 </constraints>
529+ <viewLayoutGuide key="safeArea" id="uUX-ik-SiW"/>
529 </view>
530 </view>
530 <connections>
531 <connections>
531 <outlet property="tableView" destination="4pw-5n-XsC" id="usq-Vi-rXA"/>
532 <outlet property="tableView" destination="4pw-5n-XsC" id="usq-Vi-rXA"/>
@@ -543,6 +544,7 @@
543 <rect key="frame" x="0.0" y="0.0" width="375" height="323.5"/>
544 <rect key="frame" x="0.0" y="0.0" width="375" height="323.5"/>
544 <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
545 <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
545 <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
546 <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
547+ <viewLayoutGuide key="safeArea" id="Vki-Ji-EOU"/>
546 </view>
548 </view>
547 </viewController>
549 </viewController>
548 <placeholder placeholderIdentifier="IBFirstResponder" id="KTe-P9-g8t" userLabel="First Responder" sceneMemberID="firstResponder"/>
550 <placeholder placeholderIdentifier="IBFirstResponder" id="KTe-P9-g8t" userLabel="First Responder" sceneMemberID="firstResponder"/>
GDproject/Controller/ News and channels/ChannelListController.swift+1−1
@@ -100,7 +100,7 @@ class ChannelListController: UITableViewController {
100 navigationController?.pushViewController(vc, animated: true)
100 navigationController?.pushViewController(vc, animated: true)
101 }
101 }
102
102
103− static let generalChannel = Model.Channels(people: [], name: "General", id: -1, tags: [])
103+ static let generalChannel = Model.Channels(people: [], name: "General", tags: [])
104
104
105 var dataSource : [Model.Channels] = [ ChannelListController.generalChannel ]
105 var dataSource : [Model.Channels] = [ ChannelListController.generalChannel ]
106
106
GDproject/Controller/ News and channels/NewsController.swift+30−32
@@ -21,19 +21,10 @@ protocol UpdateableWithUser: class {
21}
21}
22// MARK:- Controller with posts and channels availiable.
22// MARK:- Controller with posts and channels availiable.
23// Search is availiable within every table (posts and channels). Has button-functionality for boths post and chnnels
23// Search is availiable within every table (posts and channels). Has button-functionality for boths post and chnnels
24−class NewsController: UIViewController, UISearchControllerDelegate, NewPostDelegate, UpdateableWithChannel, DataDelegate
24+class NewsController: UIViewController, UISearchControllerDelegate, NewPostDelegate, UpdateableWithChannel
25{
25{
26−
27 var changedChannelName: ((String)->())?
26 var changedChannelName: ((String)->())?
28
27
29− func passData(for row: Int, channel: Model.Channels) {
30− if channel.id == -1{
31− self.channel = nil
32− } else {
33− self.channel = channel
34− }
35− }
36−
37 @IBOutlet weak var tableView: UITableView!
28 @IBOutlet weak var tableView: UITableView!
38
29
39 var dictionary: [Int: Model.Users]? {
30 var dictionary: [Int: Model.Users]? {
@@ -49,19 +40,15 @@ class NewsController: UIViewController, UISearchControllerDelegate, NewPostDeleg
49
40
50 })
41 })
51
42
52−
53 news.dataSourse = newPosts
43 news.dataSourse = newPosts
54 tableView.reloadData()
44 tableView.reloadData()
55 }
45 }
56 }
46 }
57
47
58− var posts: [Model.Posts]? {
48+ var posts: [Model.Posts]?
59− didSet{
60−
61− }
62− }
63
49
64 var channel: Model.Channels?
50 var channel: Model.Channels?
51+ var anonymousChannel: (users: [Int: Model.Users],posts: [Model.Posts])?
65
52
66 // MARK: - Output -
53 // MARK: - Output -
67 var onSelectChannel: (() -> Void)?
54 var onSelectChannel: (() -> Void)?
@@ -73,6 +60,7 @@ class NewsController: UIViewController, UISearchControllerDelegate, NewPostDeleg
73 var searchController = UISearchController(searchResultsController: nil)
60 var searchController = UISearchController(searchResultsController: nil)
74
61
75 var news = NewsVC()
62 var news = NewsVC()
63+ var type: HeaderType? = .NEWS
76
64
77 var refreshContr = UIRefreshControl()
65 var refreshContr = UIRefreshControl()
78
66
@@ -90,7 +78,7 @@ class NewsController: UIViewController, UISearchControllerDelegate, NewPostDeleg
90 // setUpSearchContr()
78 // setUpSearchContr()
91
79
92 news.viewController = self
80 news.viewController = self
93− news.type = .NEWS
81+ news.type = type == .NEWS ? .NEWS : type!
94
82
95 setUpNavigationItemsforPosts()
83 setUpNavigationItemsforPosts()
96
84
@@ -134,22 +122,32 @@ class NewsController: UIViewController, UISearchControllerDelegate, NewPostDeleg
134 }
122 }
135
123
136 func decideWhatChannelDisplay(){
124 func decideWhatChannelDisplay(){
125+ switch type! {
126+ case .NEWS, .NONE:
137− if let channel = channel, let id = channel.id {
127+ if let channel = channel, let id = channel.id {
138−
128+
139− Model.getChannel(with: id) { [weak self] in
129+ Model.getChannel(with: id) { [weak self] in
140− self?.posts = $0.posts
130+ self?.posts = $0.posts
141− self?.dictionary = $0.users
131+ self?.dictionary = $0.users
142− self?.refreshContr.endRefreshing()
132+ self?.refreshContr.endRefreshing()
143− self?.changedChannelName?(channel.name)
133+ self?.changedChannelName?(channel.name)
134+ }
135+
136+ } else if let _ = posts {
137+ print("here!")
138+ } else {
139+ Model.getLast { [weak self] in
140+ self?.posts = $0.posts
141+ self?.dictionary = $0.users
142+ self?.refreshContr.endRefreshing()
143+ self?.changedChannelName?("General")
144+ }
144 }
145 }
145−
146+ default:
146− } else {
147+ if let anonChannel = anonymousChannel {
147−
148− Model.getLast { [weak self] in
149− self?.posts = $0.posts
148+ posts = anonChannel.posts
150− self?.dictionary = $0.users
149+ dictionary = anonChannel.users
151− self?.refreshContr.endRefreshing()
152− self?.changedChannelName?("General")
150+ changedChannelName?("Anonymous")
153 }
151 }
154 }
152 }
155 }
153 }
GDproject/Controller/ News and channels/NewsVC.swift+14−6
@@ -27,6 +27,10 @@ struct PostCellData{
27
27
28class NewsVC: UIViewController, UITableViewDelegate, UITableViewDataSource{
28class NewsVC: UIViewController, UITableViewDelegate, UITableViewDataSource{
29
29
30+ var onChannelDidChange: ((([Int: Model.Users],[Model.Posts]))->())?
31+
32+ var onFullPost: ((HeaderType, Model.Posts)->())?
33+
30 var dataSourse: [Model.Posts] = [] {
34 var dataSourse: [Model.Posts] = [] {
31 didSet {
35 didSet {
32 cellDataSourse = []
36 cellDataSourse = []
@@ -48,11 +52,7 @@ class NewsVC: UIViewController, UITableViewDelegate, UITableViewDataSource{
48
52
49 func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
53 func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
50 {
54 {
51− tableView.deselectRow(at: indexPath, animated: true)
52− let vc = viewController!.storyboard!.instantiateViewController(withIdentifier: fullPostControllerId) as! FullPostController
53− vc.type = type
54− vc.post = dataSourse[indexPath.row]
55+ onFullPost?(type, dataSourse[indexPath.row])
55− viewController!.navigationController!.pushViewController(vc, animated: true)
56 }
56 }
57
57
58 func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
58 func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
@@ -72,12 +72,19 @@ class NewsVC: UIViewController, UITableViewDelegate, UITableViewDataSource{
72 vc.idProfile = id
72 vc.idProfile = id
73 self?.viewController!.navigationController!.pushViewController(vc, animated: true)
73 self?.viewController!.navigationController!.pushViewController(vc, animated: true)
74 }
74 }
75− case .NONE:
75+ default:
76 cell.onUserDisplay = { (id) in
76 cell.onUserDisplay = { (id) in
77 print("tapped when profile is open already \(id)")
77 print("tapped when profile is open already \(id)")
78 }
78 }
79 }
79 }
80
80
81+ cell.onAnonymousChannelDisplay = {
82+ [weak self] (tag) in
83+ Model.getAnonymousChannel(by: Model.AnonymousChannel(people: [], tags: [tag]),
84+ completion: { (tuple) in self?.onChannelDidChange?(tuple) }
85+ )
86+ }
87+
81 cell.selectionStyle = .none
88 cell.selectionStyle = .none
82 return cell
89 return cell
83 }
90 }
@@ -95,4 +102,5 @@ class NewsVC: UIViewController, UITableViewDelegate, UITableViewDataSource{
95enum HeaderType {
102enum HeaderType {
96 case NONE
103 case NONE
97 case NEWS
104 case NEWS
105+ case ANONYMOUS
98}
106}
GDproject/Controller/ News and channels/PostViewCell.swift+8−3
@@ -15,6 +15,8 @@ class PostViewCell: UITableViewCell
15{
15{
16 var onUserDisplay: ((Int)->())?
16 var onUserDisplay: ((Int)->())?
17
17
18+ var onAnonymousChannelDisplay: ((String)->())?
19+
18 let nameLabel: UIButton = {
20 let nameLabel: UIButton = {
19 let button = UIButton()
21 let button = UIButton()
20 button.setTitleColor(.black, for: .normal)
22 button.setTitleColor(.black, for: .normal)
@@ -120,8 +122,7 @@ class PostViewCell: UITableViewCell
120 for hash in hashtags {
122 for hash in hashtags {
121 let button = UIButton()
123 let button = UIButton()
122 button.setTitle("#" + hash, for: .normal)
124 button.setTitle("#" + hash, for: .normal)
123− //button.backgroundColor = #colorLiteral(red: 0.8039215803, green: 0.8039215803, blue: 0.8039215803, alpha: 1)
125+ button.addTarget(self, action: #selector(setAnonymousChannel(on:)), for: .touchUpInside)
124− //button.layer.cornerRadius = 10
125 button.titleLabel?.font = UIFont.monospacedDigitSystemFont(ofSize: 15, weight: .semibold)
126 button.titleLabel?.font = UIFont.monospacedDigitSystemFont(ofSize: 15, weight: .semibold)
126 button.setTitleColor(#colorLiteral(red: 0, green: 0.4784313725, blue: 1, alpha: 1), for: .normal)
127 button.setTitleColor(#colorLiteral(red: 0, green: 0.4784313725, blue: 1, alpha: 1), for: .normal)
127 buttons.append(button)
128 buttons.append(button)
@@ -179,7 +180,11 @@ class PostViewCell: UITableViewCell
179 }
180 }
180
181
181 @objc func displayProfile(){
182 @objc func displayProfile(){
182− print("buttonTapped")
183 onUserDisplay?(post!.authorId)
183 onUserDisplay?(post!.authorId)
184 }
184 }
185+
186+ @objc func setAnonymousChannel(on button: UIButton){
187+ print("\(button.titleLabel?.text ?? "nothing")")
188+ onAnonymousChannelDisplay?(String(button.titleLabel!.text!.dropFirst()))
189+ }
185}
190}
GDproject/Controller/Coordinators/ChannelsCoordinator.swift+24−4
@@ -34,18 +34,38 @@ class ChannelsCoordinator: BaseCoordinator{
34 navigationController?.setViewControllers([channels,presentNewsController()], animated: false)
34 navigationController?.setViewControllers([channels,presentNewsController()], animated: false)
35 }
35 }
36
36
37− private func presentNewsController(with channel: Model.Channels? = nil) -> PulleyViewController {
37+ func presentNewsController(with channel: Model.Channels? = nil) -> PulleyViewController {
38
38
39 let mainContentVC = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: newsController) as! NewsController
39 let mainContentVC = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: newsController) as! NewsController
40+ let drawerContentVC = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "DrawerContentViewController")
41+
40 mainContentVC.channel = channel
42 mainContentVC.channel = channel
43+ mainContentVC.news.onFullPost = {
44+ [weak self] (type,post) in
45+
46+ let vc = self?.storyboard.instantiateViewController(withIdentifier: fullPostControllerId) as! FullPostController
47+ vc.type = type
48+ vc.post = post
49+ self?.navigationController!.pushViewController(vc, animated: true)
50+ }
41
51
42− let drawerContentVC = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "DrawerContentViewController")
52+ mainContentVC.news.onChannelDidChange = {
53+ [weak self, weak mainContentVC] (tuple) in print("hep")
54+ switch mainContentVC!.news.type {
55+ case .ANONYMOUS:
56+ mainContentVC!.posts = tuple.1
57+ mainContentVC!.dictionary = tuple.0
58+ default:
59+ let vc = self!.presentNewsController()
60+ (vc.primaryContentViewController as! NewsController).anonymousChannel = tuple
61+ (vc.primaryContentViewController as! NewsController).type = .ANONYMOUS
62+ self?.navigationController?.pushViewController(vc, animated: true)
63+ }
64+ }
43
65
44 let pulleyDrawerVC = PulleyViewController(contentViewController: mainContentVC, drawerViewController: drawerContentVC)
66 let pulleyDrawerVC = PulleyViewController(contentViewController: mainContentVC, drawerViewController: drawerContentVC)
45
67
46 pulleyDrawerVC.initialDrawerPosition = .collapsed
68 pulleyDrawerVC.initialDrawerPosition = .collapsed
47−
48−
49 mainContentVC.changedChannelName = {
69 mainContentVC.changedChannelName = {
50 [weak pulleyDrawerVC] (title) in pulleyDrawerVC?.navigationItem.title = title
70 [weak pulleyDrawerVC] (title) in pulleyDrawerVC?.navigationItem.title = title
51 }
71 }
GDproject/Simple model/Model.swift+82
@@ -14,6 +14,7 @@ class Model{
14 static let invalidTocken = 498
14 static let invalidTocken = 498
15
15
16 private static var isValidTocken: ((Int)->())? = { responce in
16 private static var isValidTocken: ((Int)->())? = { responce in
17+ print(responce)
17 if responce == invalidTocken {
18 if responce == invalidTocken {
18 DataStorage.standard.setIsLoggedIn(value: false, with: 0)
19 DataStorage.standard.setIsLoggedIn(value: false, with: 0)
19 }
20 }
@@ -33,6 +34,7 @@ class Model{
33 static let channelsListURL = URL(string: "\(baseUrl)/channels")!
34 static let channelsListURL = URL(string: "\(baseUrl)/channels")!
34 static let channelsCreateURL = URL(string: "\(baseUrl)/channels/create")!
35 static let channelsCreateURL = URL(string: "\(baseUrl)/channels/create")!
35 static let channelsDeleteURL = URL(string: "\(baseUrl)/channels/delete")!
36 static let channelsDeleteURL = URL(string: "\(baseUrl)/channels/delete")!
37+ static let channelsGetAnonURL = URL(string: "\(baseUrl)/channels/getAnonymous")!
36
38
37
39
38 struct QueryPosts: Codable{
40 struct QueryPosts: Codable{
@@ -417,4 +419,84 @@ class Model{
417 isValidTocken?(response.response?.statusCode ?? 498)
419 isValidTocken?(response.response?.statusCode ?? 498)
418 }
420 }
419 }
421 }
422+
423+ struct AnonymousChannel: Codable {
424+
425+ var limit = 10
426+ var request: RequestPeopleTags
427+
428+ enum CodingKeys: String, CodingKey {
429+ case limit
430+ case request
431+ }
432+
433+ init(people: [Int], tags: [String]) {
434+ self.request = RequestPeopleTags(people: people, tags: tags)
435+ }
436+
437+ func encode(to encoder: Encoder) throws {
438+ var container = encoder.container(keyedBy: CodingKeys.self)
439+ try container.encode(limit, forKey: .limit)
440+ try container.encode(request, forKey: .request)
441+ }
442+
443+ struct RequestPeopleTags: Codable {
444+
445+ var people: [Int]
446+ var tags: [String]
447+
448+ init(people: [Int], tags: [String]) {
449+ self.people = people
450+ self.tags = tags
451+ }
452+
453+ func encode(to encoder: Encoder) throws {
454+ var container = encoder.container(keyedBy: CodingKeys.self)
455+ try container.encode(people, forKey: .people)
456+ try container.encode(tags, forKey: .tags)
457+ }
458+
459+ enum CodingKeys: String, CodingKey {
460+ case people
461+ case tags
462+ }
463+
464+ }
465+ }
466+ /*
467+ {
468+ "limit": 11,
469+ "request": {
470+ "people": [
471+ 2,
472+ 7,
473+ 8
474+ ],
475+ "tags": [
476+ "thisIsHashTag",
477+ "thisIsAlsoHashTag"
478+ ]
479+ }
480+ }
481+ */
482+ static func getAnonymousChannel(by anonymousChannel: Model.AnonymousChannel, completion: @escaping (((users:[Int: Users], posts:[Posts]))->())){
483+
484+ var request = URLRequest(url: channelsGetAnonURL)
485+ request.httpMethod = "POST"
486+ request.httpBody = try? JSONEncoder().encode(anonymousChannel)
487+
488+ request.setValue("application/json; charset=utf-8", forHTTPHeaderField: "Content-Type")
489+ AF.request(request).response {
490+ (response) in
491+
492+ isValidTocken?(response.response?.statusCode ?? 498)
493+
494+ guard let json = response.data else { return }
495+
496+ guard let newQueery = try? decoder.decode(QueryPosts.self, from: json) else { return }
497+
498+ // idUser = newQueery.users
499+ completion((newQueery.users, newQueery.posts))
500+ }
501+ }
420}
502}