git.iko.soy/dashared/GDproject
on master help sign in
Working on pagination. Still something left. Removed a lot of unnecessary information!
commitbce7fa115e57387d77e08cb1d2fd3b8330b4ff29 authorDarya Rednikina <rednikina.com@yandex.ru> dateMon 29 Apr 2019, 23:41 (7 years ago) parentb9768d6
7 files changed+65−212
GDproject.xcodeproj/project.pbxproj−4 GDproject/Controller/ News and channels/NewsController.swift+9−120 GDproject/Controller/ News and channels/NewsVC.swift+29−15 GDproject/Controller/Coordinators/ChannelsCoordinator.swift+3−2 GDproject/Simple model/Model.swift+24−4 GDproject/Simple model/Post.swift−26 GDproject/Simple model/User.swift−41
GDproject.xcodeproj/project.pbxproj−4
@@ -36,7 +36,6 @@
3636 12E36DA3221424ED006FCDD7 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 12E36DA2221424ED006FCDD7 /* Assets.xcassets */; };
3737 12E36DA6221424ED006FCDD7 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 12E36DA4221424ED006FCDD7 /* LaunchScreen.storyboard */; };
3838 12E36DB72214400A006FCDD7 /* Post.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12E36DB62214400A006FCDD7 /* Post.swift */; };
39− 12E36DB922144016006FCDD7 /* User.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12E36DB822144016006FCDD7 /* User.swift */; };
4039 12E36DCA22144635006FCDD7 /* NewPostViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12E36DC922144635006FCDD7 /* NewPostViewController.swift */; };
4140 12E36DCC22144725006FCDD7 /* PostViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12E36DCB22144725006FCDD7 /* PostViewCell.swift */; };
4241 12E36DCE22144756006FCDD7 /* Constants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12E36DCD22144756006FCDD7 /* Constants.swift */; };
@@ -121,7 +120,6 @@
121120 12E36DA5221424ED006FCDD7 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
122121 12E36DA7221424ED006FCDD7 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
123122 12E36DB62214400A006FCDD7 /* Post.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Post.swift; sourceTree = "<group>"; };
124− 12E36DB822144016006FCDD7 /* User.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = User.swift; sourceTree = "<group>"; };
125123 12E36DC922144635006FCDD7 /* NewPostViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewPostViewController.swift; sourceTree = "<group>"; };
126124 12E36DCB22144725006FCDD7 /* PostViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PostViewCell.swift; sourceTree = "<group>"; };
127125 12E36DCD22144756006FCDD7 /* Constants.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Constants.swift; sourceTree = "<group>"; };
@@ -248,7 +246,6 @@
248246 124CC7022221C00C009DF531 /* Model.swift */,
249247 12E36DB62214400A006FCDD7 /* Post.swift */,
250248 12D7D136221D78E800B35452 /* Channel.swift */,
251− 12E36DB822144016006FCDD7 /* User.swift */,
252249 );
253250 path = "Simple model";
254251 sourceTree = "<group>";
@@ -379,7 +376,6 @@
379376 12E36DD522156559006FCDD7 /* MyStackView.swift in Sources */,
380377 12D7D137221D78E800B35452 /* Channel.swift in Sources */,
381378 1291BE3622218DBF009D3F23 /* LogInCoordinator1.swift in Sources */,
382− 12E36DB922144016006FCDD7 /* User.swift in Sources */,
383379 1210A0BB223940310080686D /* SimplifiedChannelsList.swift in Sources */,
384380 125BD5812217314A008A3575 /* NewsVC.swift in Sources */,
385381 12E36DB72214400A006FCDD7 /* Post.swift in Sources */,
GDproject/Controller/ News and channels/NewsController.swift+9−120
@@ -13,49 +13,23 @@ import Cartography
1313protocol UpdateableWithChannel: class {
1414 var channel: Model.Channels? { get set }
1515}
16−protocol NewPostDelegate {
17− func addPost(post: Post)
18−}
16+
1917protocol UpdateableWithUser: class {
2018 var user: Model.Users? { get set }
2119}
2220// MARK:- Controller with posts and channels availiable.
2321// Search is availiable within every table (posts and channels). Has button-functionality for boths post and chnnels
24−class NewsController: UIViewController, UISearchControllerDelegate, NewPostDelegate, UpdateableWithChannel
22+class NewsController: UIViewController, UISearchControllerDelegate, UpdateableWithChannel
2523{
2624 var changedChannelName: ((String)->())?
2725
2826 @IBOutlet weak var tableView: UITableView!
2927
30− var dictionary: [Int: Model.Users]? {
31− didSet {
32−
33− var newPosts: [Model.Posts] = []
34−
35− posts!.forEach({ (post) in
36−
37− newPosts.append(Model.Posts(body: post.body, authorId: post.authorId, id: post.id, user: dictionary![post.authorId]!, date: post.updated, tags: post.tags))
38−
39− post.tags.forEach { Model.Channels.fullTags.insert($0) }
40−
41− })
42−
43− news.dataSourse = newPosts
44− tableView.reloadData()
45− }
46− }
47−
48− var posts: [Model.Posts]?
49−
5028 var channel: Model.Channels?
51− var anonymousChannel: (users: [Int: Model.Users],posts: [Model.Posts])?
29+ var anonymousChannel: (users: [Int: Model.Users], posts: [Model.Posts])?
5230
5331 // MARK: - Output -
5432 var onSelectChannel: (() -> Void)?
55−
56− func addPost(post: Post) {
57− //news.dataSourse.insert(post, at: 0)
58− }
5933
6034 var searchController = UISearchController(searchResultsController: nil)
6135
@@ -101,16 +75,6 @@ class NewsController: UIViewController, UISearchControllerDelegate, NewPostDeleg
10175 print("news clear")
10276 }
10377
104− let label : UILabel = {
105− let label = UILabel()
106− label.text = "No posts to display yet!"
107− label.font = UIFont.systemFont(ofSize: 18)
108− label.textColor = .black
109− label.isHidden = true
110− label.numberOfLines = 0
111− return label
112− }()
113−
11478 override func viewWillAppear(_ animated: Bool) {
11579 super.viewWillAppear(animated)
11680 searchController.isActive = false
@@ -127,26 +91,23 @@ class NewsController: UIViewController, UISearchControllerDelegate, NewPostDeleg
12791 if let channel = channel, let id = channel.id {
12892
12993 Model.getChannel(with: id) { [weak self] in
130− self?.posts = $0.posts
131− self?.dictionary = $0.users
94+ self?.news.dataSourse = $0.posts
95+ self?.news.dictionary = $0.users
13296 self?.refreshContr.endRefreshing()
13397 self?.changedChannelName?(channel.name)
13498 }
135−
136− } else if let _ = posts {
137− print("here!")
13899 } else {
139100 Model.getLast { [weak self] in
140− self?.posts = $0.posts
141− self?.dictionary = $0.users
101+ self?.news.dataSourse = $0.posts
102+ self?.news.dictionary = $0.users
142103 self?.refreshContr.endRefreshing()
143104 self?.changedChannelName?("General")
144105 }
145106 }
146107 default:
147108 if let anonChannel = anonymousChannel {
148− posts = anonChannel.posts
149− dictionary = anonChannel.users
109+ news.dataSourse = anonChannel.posts
110+ news.dictionary = anonChannel.users
150111 changedChannelName?("Anonymous")
151112 }
152113 }
@@ -157,76 +118,4 @@ class NewsController: UIViewController, UISearchControllerDelegate, NewPostDeleg
157118 tableView.dataSource = news
158119 tableView.reloadData()
159120 }
160−
161−
162− // for animating the banner
163− var topConstraint: NSLayoutConstraint?
164−
165− let bannerView: UIView = {
166− let view = UIView()
167− view.backgroundColor = .blue
168− view.layer.cornerRadius = 25.0
169− view.clipsToBounds = true
170− return view
171− }()
172−
173− let statusLabel: UILabel = {
174− let label = UILabel()
175− label.text = "-"
176− label.textColor = .white
177− label.textAlignment = .center
178− return label
179− }()
180−
181− // MARK:- banner
182− private func setUpBanner()
183− {
184− view.addSubview(bannerView)
185− bannerView.addSubview(statusLabel)
186− statusLabel.edgesToSuperview()
187−
188− let tap = UITapGestureRecognizer(target: self, action: #selector(handleTap(sender:)))
189−
190− bannerView.addGestureRecognizer(tap)
191− topConstraint = NSLayoutConstraint(item: bannerView, attribute: .top, relatedBy: .equal, toItem: view.safeAreaLayoutGuide, attribute: .top, multiplier: 1, constant: -300)
192− view.addConstraint(topConstraint!)
193−
194− bannerView.edgesToSuperview(excluding: [.bottom, .top, .left], insets: .right(20), usingSafeArea: true)
195− bannerView.height(50)
196− bannerView.width(50)
197− }
198−
199− // when table is scrolling no deletion is availiable
200− @objc func handleTap(sender: UITapGestureRecognizer? = nil) {
201− let indexPath = IndexPath(row: 0, section: 0)
202− self.tableView.scrollToRow(at: indexPath, at: .top, animated: true)
203−// isBannerVisible = false
204−// changeConstraint(isVisible: false)
205− }
206−
207− // animation for banner
208− func changeConstraint(isVisible: Bool){
209− topConstraint?.constant = isVisible ? 50 : -300
210−
211− UIView.animate(withDuration: 0.5, delay: 0, options: .curveEaseOut, animations: {
212− self.view.layoutIfNeeded()
213− }) { (completed) in
214−
215− }
216− }
217−
218− var isBannerVisible: Bool = false
219−
220− func scrollViewDidScroll(_ scrollView: UIScrollView) {
221− print(scrollView.contentOffset.y)
222− if scrollView.contentOffset.y >= 50 && !isBannerVisible{
223− isBannerVisible = true
224− changeConstraint(isVisible: true)
225− }
226−
227− if isBannerVisible && scrollView.contentOffset.y == 0{
228− isBannerVisible = false
229− changeConstraint(isVisible: false)
230− }
231− }
232121}
GDproject/Controller/ News and channels/NewsVC.swift+29−15
@@ -25,18 +25,29 @@ struct PostCellData{
2525 }
2626}
2727
28−class NewsVC: UIViewController, UITableViewDelegate, UITableViewDataSource{
28+class NewsVC: UIViewController, UITableViewDelegate, UITableViewDataSource {
29+
2930
3031 var onChannelDidChange: ((([Int: Model.Users],[Model.Posts]))->())?
3132
3233 var onFullPost: ((HeaderType, Model.Posts)->())?
3334
34− var dataSourse: [Model.Posts] = [] {
35+ var dictionary: [Int: Model.Users] = [:] {
3536 didSet {
36− cellDataSourse = []
37− dataSourse.forEach { (item) in
38− cellDataSourse.append(PostCellData(attributedData: PostCellData.create(with: item.body)))
37+
38+ dataSourse = dataSourse.map {
39+ var copy = $0
40+ copy.user = dictionary[$0.authorId]
41+ return copy
3942 }
43+
44+ (viewController as? NewsController)?.tableView.reloadData()
45+ }
46+ }
47+
48+ var dataSourse: [Model.Posts] = [] {
49+ didSet {
50+ cellDataSourse = dataSourse.map { PostCellData(attributedData: PostCellData.create(with: $0.body)) }
4051 }
4152 }
4253
@@ -96,18 +107,21 @@ class NewsVC: UIViewController, UITableViewDelegate, UITableViewDataSource{
96107 func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
97108 return 100.0
98109 }
110+
111+ func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath)
112+ {
113+ if indexPath.row == cellDataSourse.count - 1
114+ {
115+ // check this!
116+ Model.getLast(on: 10, from: dataSourse.last?.id ?? 0)
117+ { [weak self] in
118+ self?.dataSourse.append(contentsOf: $0.posts)
119+ $0.users.forEach { self?.dictionary[$0.key] = $0.value }
120+ }
121+ }
122+ }
99123}
100124
101−//extension NewsVC {
102−// override func prepare(for segue: UIStoryboardSegue, sender: Any?)
103−// {
104−// if let currentCell = sender as? PostViewCell,
105−// let vc = segue.destination as? FullPostController {
106−//
107−// }
108−// }
109−//}
110−
111125enum HeaderType {
112126 case NONE
113127 case NEWS
GDproject/Controller/Coordinators/ChannelsCoordinator.swift+3−2
@@ -74,8 +74,9 @@ class ChannelsCoordinator: BaseCoordinator{
7474 [weak self, weak mainContentVC] (tuple) in print("hep")
7575 switch mainContentVC!.news.type {
7676 case .ANONYMOUS:
77− mainContentVC!.posts = tuple.1
78− mainContentVC!.dictionary = tuple.0
77+ print("nothing to diplay")
78+ // mainContentVC!.posts = tuple.1
79+ //mainContentVC!.dictionary = tuple.0
7980 default:
8081 let vc = self!.presentNewsController()
8182 (vc.primaryContentViewController as! NewsController).anonymousChannel = tuple
GDproject/Simple model/Model.swift+24−4
@@ -45,6 +45,7 @@ class Model{
4545 }
4646
4747 struct Posts: Codable {
48+
4849 var body: [Attachments]
4950 var authorId: Int
5051 var id: Int
@@ -205,15 +206,34 @@ class Model{
205206 }
206207 }
207208
209+ struct PostsLastRequest: Codable {
210+ var limit: Int
211+ var exclusiveFrom: Int?
212+ var request: [Int] = []
213+
214+ enum CodingKeys: String, CodingKey {
215+ case limit
216+ case exclusiveFrom
217+ case request
218+ }
219+
220+ func encode(to encoder: Encoder) throws {
221+ var container = encoder.container(keyedBy: CodingKeys.self)
222+ try container.encode(limit, forKey: .limit)
223+ try container.encode(exclusiveFrom, forKey: .exclusiveFrom)
224+ try container.encode(request, forKey: .request)
225+ }
226+ }
208227
209− static func getLast(completion: @escaping (((users:[Int: Users], posts:[Posts]))->())){
210− let jsonString = "30"
211− var request = URLRequest(url: postsLastURL)
228+ static func getLast(on limit: Int = 10, from pointInTime: Int? = nil, completion: @escaping (((users:[Int: Users], posts:[Posts]))->()))
229+ {
230+ let postRequest = PostsLastRequest(limit: limit, exclusiveFrom: pointInTime, request: [])
212231
232+ var request = URLRequest(url: postsLastURL)
233+ request.httpBody = try? JSONEncoder().encode(postRequest)
213234 request.httpMethod = "POST"
214235
215236 // insert json data to the request
216− request.httpBody = jsonString.data(using: .utf8)
217237 request.setValue("application/json; charset=utf-8", forHTTPHeaderField: "Content-Type")
218238
219239 AF.request(request).responseJSON {
GDproject/Simple model/Post.swift−26
@@ -9,31 +9,6 @@
99import Foundation
1010import UIKit
1111
12−struct Post {
13− var dataArray: [Media]
14− var fromUser: User
15− var atDate: String
16− var comments: [Comment] = []
17−
18− var hashtags: [String] = ["ФКН", "Подбельский", "НИУВШЭ", "Шершаков", "ПАД", "Интересное","Мемы","Забавное","Учеба","Наука"]
19−
20− init(dataArray: [Media], from: User, date: String, comments: [Comment] = [])
21− {
22− self.dataArray = dataArray
23− fromUser = from
24− atDate = date
25− self.comments = comments
26− }
27−
28− init(dataArray: [Media]) {
29− self.dataArray = dataArray
30− fromUser = User(name: "vbogomazova", id: 2, fullName: "Богомазова Вероника Львовна")
31− atDate = "23.03.19 в 23:33"
32− }
33−
34−}
35−
36−
3712enum Media{
3813 case text(String)
3914 case image([UIImage])
@@ -41,7 +16,6 @@ enum Media{
4116}
4217
4318struct Comment {
44− var from: User
4519 var atTime: String
4620 var withData: String
4721}
GDproject/Simple model/User.swiftdeleted−41
@@ -1,41 +0,0 @@
1−//
2−// User.swift
3−// NewsFeed
4−//
5−// Created by cstore on 12/01/2019.
6−// Copyright © 2019 drHSE. All rights reserved.
7−//
8−
9−import Foundation
10−import UIKit
11−
12−struct User {
13− //var photo: UIImage? = #imageLiteral(resourceName: "image")
14− var login: String
15− var id: Int
16− var fullName: String
17− var initials: (surname: String, name: String, optional: String?) = ("Богомазова","Вероника","Львовна")
18− var placeOfWork: String?
19− var faculty: String?
20− let posts: [Post] = []
21−
22−
23− init(name: String, id: Int, fullName: String) {
24− self.login = name
25− self.id = id
26− self.fullName = fullName
27− }
28−
29− init(surname: String, name: String, optional: String?, emailName: String, id: Int, place: String?, faculty: String?)
30− {
31− self.id = id
32− self.login = emailName
33− self.initials = (surname, name, optional)
34−
35− self.fullName = "\(surname) \(name) \(optional ?? "")"
36− self.placeOfWork = place
37− if let f = faculty {
38− self.faculty = f
39− }
40− }
41−}