88
99import Foundation
1010import SignalProtocolFramework
11+ import RealmSwift
1112
1213class FeedViewController : UIViewController {
1314 let HEADER_HEIGHT : CGFloat = 42.0
1415 var feedsData = FeedsData ( )
1516 @IBOutlet weak var noFeedsView : UIView !
1617 @IBOutlet weak var feedsTableView : UITableView !
18+ var newFeedsToken : NotificationToken ?
19+ var oldFeedsToken : NotificationToken ?
20+
1721 var mailboxVC : InboxViewController ! {
1822 get {
1923 return self . navigationDrawerController? . rootViewController. childViewControllers. first as? InboxViewController
@@ -40,35 +44,48 @@ class FeedViewController: UIViewController{
4044 }
4145 }
4246
43- func loadFeeds( clear: Bool = false ) {
44- let date = clear ? Date ( ) : feedsData. oldFeeds. last? . date ?? ( feedsData. newFeeds. last? . date ?? Date ( ) )
45- let feeds = DBManager . getFeeds ( since: date, limit: 20 , lastSeen: lastSeen)
46- if ( clear) {
47- feedsData. newFeeds = feeds. 0
48- feedsData. oldFeeds = feeds. 1
49- } else {
50- feedsData. newFeeds. append ( contentsOf: feeds. 0 )
51- feedsData. oldFeeds. append ( contentsOf: feeds. 1 )
47+ func loadFeeds( ) {
48+ let feeds = DBManager . getFeeds ( since: Date ( ) , limit: 20 , lastSeen: lastSeen)
49+ feedsData. newFeeds = feeds. 0
50+ feedsData. oldFeeds = feeds. 1
51+ newFeedsToken = feedsData. newFeeds. observe { [ weak self] changes in
52+ guard let tableView = self ? . feedsTableView else {
53+ return
54+ }
55+ switch ( changes) {
56+ case . initial:
57+ tableView. reloadData ( )
58+ case . update( _, let deletions, let insertions, let modifications) :
59+ tableView. applyChanges ( section: 0 , deletions: deletions, insertions: insertions, updates: modifications)
60+ default :
61+ break
62+ }
5263 }
53- self . feedsData. loadingFeeds = false
54- if ( feeds. 0 . isEmpty && feeds. 1 . isEmpty) {
55- self . feedsData. reachedEnd = true
64+ oldFeedsToken = feedsData. oldFeeds. observe { [ weak self] changes in
65+ guard let tableView = self ? . feedsTableView else {
66+ return
67+ }
68+ switch ( changes) {
69+ case . initial:
70+ tableView. reloadData ( )
71+ case . update( _, let deletions, let insertions, let modifications) :
72+ tableView. applyChanges ( section: 1 , deletions: deletions, insertions: insertions, updates: modifications)
73+ default :
74+ break
75+ }
5676 }
5777 checkIfFeedsEmpty ( )
5878 feedsTableView. reloadData ( )
5979 }
6080
6181 func viewClosed( ) {
62- loadFeeds ( clear : true )
82+ loadFeeds ( )
6383 }
6484}
6585
6686extension FeedViewController : UITableViewDelegate , UITableViewDataSource {
6787
6888 func tableView( _ tableView: UITableView , cellForRowAt indexPath: IndexPath ) -> UITableViewCell {
69- if ( indexPath. section > 0 && indexPath. row == feedsData. oldFeeds. count) {
70- return buildLastRow ( )
71- }
7289 let cell = tableView. dequeueReusableCell ( withIdentifier: " feedTableCellView " , for: indexPath) as! FeedTableViewCell
7390 let feed = ( indexPath. section == 0 ? feedsData. newFeeds [ indexPath. row] : feedsData. oldFeeds [ indexPath. row] )
7491 cell. setLabels ( feed. header, feed. subject, feed. formattedDate)
@@ -81,7 +98,7 @@ extension FeedViewController: UITableViewDelegate, UITableViewDataSource{
8198 if ( section == 0 ) {
8299 return feedsData. newFeeds. count
83100 }
84- return feedsData. oldFeeds. count + 1
101+ return feedsData. oldFeeds. count
85102 }
86103
87104 func tableView( _ tableView: UITableView , heightForRowAt indexPath: IndexPath ) -> CGFloat {
@@ -101,17 +118,10 @@ extension FeedViewController: UITableViewDelegate, UITableViewDataSource{
101118 }
102119
103120 func tableView( _ tableView: UITableView , trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath ) -> UISwipeActionsConfiguration ? {
104- guard !isLoaderRow( indexPath) else {
105- return nil
106- }
107121 let delete = deleteAction ( tableView, indexPath: indexPath)
108122 return UISwipeActionsConfiguration ( actions: [ delete] )
109123 }
110124
111- func tableView( _ tableView: UITableView , canEditRowAt indexPath: IndexPath ) -> Bool {
112- return !isLoaderRow( indexPath)
113- }
114-
115125 func muteAction( _ tableView: UITableView , indexPath: IndexPath ) -> UIContextualAction {
116126 let feed = ( indexPath. section == 0 ? feedsData. newFeeds [ indexPath. row] : feedsData. oldFeeds [ indexPath. row] )
117127 let action = UIContextualAction ( style: . normal, title: feed. isMuted ? " Unmute " : " Mute " ) {
@@ -125,21 +135,7 @@ extension FeedViewController: UITableViewDelegate, UITableViewDataSource{
125135 return action
126136 }
127137
128- func buildLastRow( ) -> UITableViewCell {
129- let footerView = feedsTableView. dequeueReusableCell ( withIdentifier: " EndCell " ) as! TableEndViewCell
130- if ( feedsData. reachedEnd) {
131- footerView. displayMessage ( " " )
132- } else {
133- footerView. displayLoader ( )
134- }
135- return footerView
136- }
137-
138138 func tableView( _ tableView: UITableView , didSelectRowAt indexPath: IndexPath ) {
139- guard !isLoaderRow( indexPath) else {
140- tableView. deselectRow ( at: indexPath, animated: false )
141- return
142- }
143139 let feed = ( indexPath. section == 0 ? feedsData. newFeeds [ indexPath. row] : feedsData. oldFeeds [ indexPath. row] )
144140 let workingLabel = feed. email. isSpam ? SystemLabel . spam. id : ( feed. email. isTrash ? SystemLabel . trash. id : SystemLabel . sent. id)
145141 guard let selectedThread = DBManager . getThread ( threadId: feed. email. threadId, label: workingLabel) else {
@@ -154,32 +150,14 @@ extension FeedViewController: UITableViewDelegate, UITableViewDataSource{
154150 let feed : FeedItem
155151 if ( indexPath. section == 0 ) {
156152 feed = self . feedsData. newFeeds [ indexPath. row]
157- self . feedsData. newFeeds. remove ( at: indexPath. row)
158153 } else {
159154 feed = self . feedsData. oldFeeds [ indexPath. row]
160- self . feedsData. oldFeeds. remove ( at: indexPath. row)
161155 }
162- tableView. deleteRows ( at: [ indexPath] , with: . automatic)
163156 DBManager . delete ( feed: feed)
164157 completion ( true )
165158 }
166159 action. image = #imageLiteral( resourceName: " delete-icon " )
167160 action. backgroundColor = UIColor ( red: 220 / 255 , green: 77 / 255 , blue: 72 / 255 , alpha: 1 )
168161 return action
169162 }
170-
171- func tableView( _ tableView: UITableView , willDisplay cell: UITableViewCell , forRowAt indexPath: IndexPath ) {
172- guard !feedsData. loadingFeeds && !feedsData. reachedEnd && isLoaderRow ( indexPath) else {
173- return
174- }
175- feedsData. loadingFeeds = true
176- tableView. reloadRows ( at: [ indexPath] , with: . automatic)
177- DispatchQueue . main. asyncAfter ( deadline: . now( ) + . seconds( 1 ) ) {
178- self . loadFeeds ( )
179- }
180- }
181-
182- func isLoaderRow( _ indexPath: IndexPath ) -> Bool {
183- return indexPath. section == 1 && indexPath. row == feedsData. oldFeeds. count
184- }
185163}
0 commit comments