pEpForiOS/UI/EmailDisplay/EmailListViewController.swift
author Dirk Zimmermann <dirk@pep-project.org>
Thu, 15 Dec 2016 15:34:19 +0100
changeset 1333 e2d44f2578df
parent 1330 e411dbeb6048
child 1338 6535c688c480
permissions -rw-r--r--
IOS-354 cleanup
dirk@30
     1
//
dirk@30
     2
//  EmailListViewController.swift
dirk@30
     3
//  pEpForiOS
dirk@30
     4
//
dirk@30
     5
//  Created by Dirk Zimmermann on 16/04/16.
dirk@30
     6
//  Copyright © 2016 p≡p Security S.A. All rights reserved.
dirk@30
     7
//
dirk@30
     8
dirk@30
     9
import Foundation
dirk@30
    10
import UIKit
dirk@31
    11
import CoreData
dirk@808
    12
dirk@810
    13
import MessageModel
dirk@810
    14
igor@1260
    15
struct EmailListConfig {
igor@1260
    16
    let appConfig: AppConfig
dirk@1333
    17
igor@1260
    18
    /** The folder to display, if it exists */
igor@1260
    19
    var folder: Folder?
igor@1260
    20
}
dirk@30
    21
dirk@854
    22
class EmailListViewController: UITableViewController {
igor@1260
    23
    
dirk@854
    24
    var comp = "EmailListViewController"
dirk@58
    25
dirk@583
    26
    struct UIState {
dirk@583
    27
        var isSynching: Bool = false
dirk@583
    28
    }
dirk@583
    29
    
dirk@273
    30
    let segueShowEmail = "segueShowEmail"
dirk@397
    31
    let segueCompose = "segueCompose"
dirk@397
    32
    let segueUserSettings = "segueUserSettings"
dirk@30
    33
dirk@583
    34
    var config: EmailListConfig!
dirk@583
    35
dirk@275
    36
    var state = UIState()
igor@1260
    37
    
igor@1301
    38
    let searchController = UISearchController(searchResultsController: nil)
dirk@719
    39
dirk@745
    40
    required init?(coder aDecoder: NSCoder) {
dirk@745
    41
        super.init(coder: aDecoder)
dirk@745
    42
        self.comp = "EmailListViewController"
dirk@745
    43
    }
dirk@745
    44
dirk@275
    45
    override func viewDidLoad() {
ylandert@935
    46
        super.viewDidLoad()
igor@1301
    47
        
igor@1284
    48
        UIHelper.emailListTableHeight(self.tableView)
igor@1301
    49
        addSearchBar()
igor@1301
    50
        addRefreshControl()
dirk@275
    51
    }
dirk@31
    52
dirk@784
    53
    override func viewWillAppear(_ animated: Bool) {
igor@1301
    54
        super.viewWillAppear(animated)
igor@1301
    55
        
dirk@854
    56
        updateModel()
igor@1301
    57
    }
igor@1301
    58
    
igor@1301
    59
    func addSearchBar() {
igor@1301
    60
        searchController.searchResultsUpdater = self
igor@1301
    61
        searchController.dimsBackgroundDuringPresentation = false
igor@1301
    62
        searchController.delegate = self
igor@1301
    63
        definesPresentationContext = true
igor@1301
    64
        tableView.tableHeaderView = searchController.searchBar
igor@1301
    65
        tableView.setContentOffset(CGPoint(x: 0.0, y: 40.0), animated: false)
igor@1301
    66
    }
igor@1301
    67
    
igor@1301
    68
    func addRefreshControl() {
igor@1301
    69
        refreshControl?.addTarget(self, action: #selector(refreshTableData), for: UIControlEvents.valueChanged)
ana@207
    70
    }
ana@152
    71
dirk@784
    72
    @IBAction func mailSentSegue(_ segue: UIStoryboardSegue) {
dirk@452
    73
    }
dirk@452
    74
dirk@784
    75
    @IBAction func backFromComposeWithoutSavingDraftSegue(_ segue: UIStoryboardSegue) {
dirk@705
    76
    }
dirk@705
    77
dirk@784
    78
    @IBAction func backFromComposeSaveDraftSegue(_ segue: UIStoryboardSegue) {
dirk@705
    79
    }
dirk@705
    80
igor@941
    81
    
dirk@1330
    82
    @IBAction func showUnreadButtonTapped(_ sender: UIBarButtonItem) {}
igor@941
    83
    
dirk@854
    84
    func updateModel() {
igor@1318
    85
        tableView.reloadData()
dirk@31
    86
    }
dirk@31
    87
dirk@58
    88
    // MARK: - UI State
dirk@58
    89
dirk@58
    90
    func updateUI() {
dirk@784
    91
        UIApplication.shared.isNetworkActivityIndicatorVisible = state.isSynching
dirk@748
    92
        if !state.isSynching {
igor@1260
    93
            refreshControl?.endRefreshing()
dirk@58
    94
        }
dirk@58
    95
    }
dirk@58
    96
dirk@31
    97
    // MARK: - UITableViewDataSource
dirk@31
    98
dirk@784
    99
    override func numberOfSections(in tableView: UITableView) -> Int {
dirk@854
   100
        if let _ = config.folder {
dirk@854
   101
            return 1
dirk@209
   102
        }
dirk@854
   103
        return 0
dirk@31
   104
    }
dirk@31
   105
dirk@784
   106
    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
igor@1318
   107
        if let fol = config.folder  {
dirk@854
   108
            return fol.messageCount()
dirk@31
   109
        }
dirk@31
   110
        return 0
dirk@31
   111
    }
dirk@31
   112
dirk@784
   113
    override func tableView(_ tableView: UITableView,
dirk@784
   114
                            cellForRowAt indexPath: IndexPath) -> UITableViewCell {
dirk@784
   115
        let cell = tableView.dequeueReusableCell(
dirk@784
   116
            withIdentifier: "EmailListViewCell", for: indexPath) as! EmailListViewCell
igor@1260
   117
        cell.configureCell(indexPath: indexPath, config: config)
dirk@31
   118
        return cell
dirk@31
   119
    }
dirk@31
   120
dirk@719
   121
    // MARK: - UITableViewDelegate
dirk@719
   122
dirk@1333
   123
    override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
igor@1260
   124
        let cell = tableView.cellForRow(at: indexPath) as! EmailListViewCell
dirk@719
   125
dirk@855
   126
        if let fol = config.folder {
dirk@855
   127
            if fol.folderType == .drafts {
dirk@784
   128
                performSegue(withIdentifier: segueCompose, sender: cell)
dirk@719
   129
                return
dirk@719
   130
            }
dirk@719
   131
        }
dirk@719
   132
dirk@784
   133
        performSegue(withIdentifier: segueShowEmail, sender: cell)
dirk@719
   134
    }
dirk@719
   135
dirk@784
   136
    override func tableView(_ tableView: UITableView, editActionsForRowAt
dirk@784
   137
        indexPath: IndexPath)-> [UITableViewRowAction]? {
dirk@784
   138
        let cell = tableView.cellForRow(at: indexPath) as! EmailListViewCell
igor@1260
   139
        if let email = cell.messageAt(indexPath: indexPath, config: config) {
dirk@855
   140
            let isFlagAction = createIsFlagAction(message: email, cell: cell)
dirk@855
   141
            let deleteAction = createDeleteAction(cell)
igor@1242
   142
            //let isReadAction = createIsReadAction(message: email, cell: cell)
igor@1242
   143
            let moreAction = createMoreAction(message: email, cell: cell)
igor@1242
   144
            return [deleteAction,isFlagAction,moreAction]
dirk@855
   145
        }
dirk@855
   146
        return nil
dirk@744
   147
    }
dirk@744
   148
dirk@719
   149
    // MARK: - Misc
dirk@719
   150
dirk@784
   151
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
dirk@361
   152
        if segue.identifier == segueCompose {
yves@1278
   153
            //let destination = segue.destination as! ComposeTableViewController
yves@1278
   154
            // destination.appConfig = config.appConfig
yves@1278
   155
//            if let draft = draftMessageToCompose {
yves@1278
   156
//                draft.imapFlags?.seen = true
yves@1278
   157
//
yves@1278
   158
//                destination.originalMessage = draft
yves@1278
   159
//                destination.composeMode = .draft
yves@1278
   160
//            }
dirk@273
   161
        } else if segue.identifier == segueShowEmail {
dirk@273
   162
            guard
dirk@784
   163
                let vc = segue.destination as? EmailViewController,
igor@1260
   164
                let cell = sender as? EmailListViewCell,
dirk@784
   165
                let indexPath = self.tableView.indexPath(for: cell),
igor@1260
   166
                let email = cell.messageAt(indexPath: indexPath, config: config) else {
dirk@273
   167
                    return
dirk@273
   168
            }
dirk@583
   169
            vc.appConfig = config.appConfig
dirk@273
   170
            vc.message = email
ana@246
   171
        }
ana@246
   172
    }
dirk@744
   173
dirk@855
   174
    func createIsFlagAction(message: Message, cell: EmailListViewCell) -> UITableViewRowAction {
dirk@744
   175
        // preparing action to trigger when user swipe
dirk@784
   176
        let isFlagCompletionHandler: (UITableViewRowAction, IndexPath) -> Void =
dirk@744
   177
            { (action, indexPath) in
igor@1260
   178
                if (cell.isImportant(message: message)) {
dirk@965
   179
                    message.imapFlags?.flagged = false
dirk@744
   180
dirk@744
   181
                } else {
dirk@965
   182
                    message.imapFlags?.flagged = true
dirk@744
   183
                }
dirk@784
   184
                self.tableView.reloadRows(at: [indexPath], with: .none)
dirk@744
   185
        }
dirk@744
   186
        // creating the action
igor@1242
   187
        let isFlagAction = UITableViewRowAction(style: .normal, title: "          ",
dirk@744
   188
                                                handler: isFlagCompletionHandler)
dirk@744
   189
        // changing default action color
igor@1242
   190
        let swipeFlagImage = UIImage(named: "swipe-flag")
igor@1242
   191
        let flagIconColor = UIColor(patternImage: swipeFlagImage!)
igor@1242
   192
        isFlagAction.backgroundColor = flagIconColor
dirk@744
   193
dirk@744
   194
        return isFlagAction
dirk@744
   195
    }
dirk@744
   196
dirk@784
   197
    func createDeleteAction (_ cell: EmailListViewCell) -> UITableViewRowAction {
dirk@744
   198
dirk@744
   199
        // preparing the title action to show when user swipe
dirk@744
   200
dirk@784
   201
        let deleteCompletionHandler: (UITableViewRowAction, IndexPath) -> Void =
dirk@744
   202
            { (action, indexPath) in
igor@1260
   203
                let message = cell.messageAt(indexPath: indexPath, config: self.config)
dirk@965
   204
                message?.imapFlags?.deleted = true
dirk@744
   205
        }
dirk@744
   206
dirk@744
   207
        // creating the action
igor@1242
   208
        let deleteAction = UITableViewRowAction(style: .normal, title: "          ",
dirk@744
   209
                                                handler: deleteCompletionHandler)
igor@1242
   210
        let swipeTrashImage = UIImage(named: "swipe-trash")
igor@1242
   211
        let trashIconColor = UIColor(patternImage: swipeTrashImage!)
igor@1242
   212
        deleteAction.backgroundColor = trashIconColor
dirk@744
   213
        return deleteAction
dirk@744
   214
    }
dirk@744
   215
dirk@855
   216
    func createIsReadAction(message: Message, cell: EmailListViewCell) -> UITableViewRowAction {
dirk@744
   217
        // preparing the title action to show when user swipe
dirk@744
   218
        var localizedisReadTitle = " "
igor@1260
   219
        if (cell.isRead(message: message)) {
dirk@855
   220
            localizedisReadTitle = NSLocalizedString(
dirk@855
   221
                "Unread",
dirk@855
   222
                comment: "Unread button title in swipe action on EmailListViewController")
dirk@744
   223
        } else {
dirk@855
   224
            localizedisReadTitle = NSLocalizedString(
dirk@855
   225
                "Read",
dirk@855
   226
                comment: "Read button title in swipe action on EmailListViewController")
dirk@744
   227
        }
dirk@744
   228
dirk@744
   229
        // creating the action
dirk@784
   230
        let isReadCompletionHandler: (UITableViewRowAction, IndexPath) -> Void =
dirk@744
   231
            { (action, indexPath) in
igor@1260
   232
                if (cell.isRead(message: message)) {
dirk@965
   233
                    message.imapFlags?.seen = false
dirk@744
   234
                } else {
dirk@965
   235
                    message.imapFlags?.seen = true
dirk@744
   236
                }
dirk@784
   237
                self.tableView.reloadRows(at: [indexPath], with: .none)
dirk@744
   238
        }
dirk@784
   239
        let isReadAction = UITableViewRowAction(style: .default, title: localizedisReadTitle,
dirk@744
   240
                                                handler: isReadCompletionHandler)
dirk@784
   241
        isReadAction.backgroundColor = UIColor.blue
dirk@744
   242
dirk@744
   243
        return isReadAction
dirk@744
   244
    }
igor@1242
   245
    
igor@1242
   246
    func createMoreAction(message: Message, cell: EmailListViewCell) -> UITableViewRowAction {
igor@1242
   247
        let moreCompletitionHandler :(UITableViewRowAction, IndexPath) -> Void = {(action, indexPath) in
igor@1242
   248
            self.showMoreActionSheet(cell: cell)
igor@1242
   249
        }
igor@1242
   250
        let moreAction = UITableViewRowAction(style: .normal, title: "          ", handler: moreCompletitionHandler)
igor@1242
   251
        let swipeMoreImage = UIImage(named: "swipe-more")
igor@1242
   252
        let moreIconColor = UIColor(patternImage: swipeMoreImage!)
igor@1242
   253
        moreAction.backgroundColor = moreIconColor
igor@1242
   254
        return moreAction
igor@1242
   255
    }
igor@1242
   256
    
igor@1242
   257
    // MARK: - Action Sheet
igor@1242
   258
    
igor@1242
   259
    func showMoreActionSheet(cell: EmailListViewCell) {
igor@1242
   260
        let alertControler = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)
igor@1242
   261
        let cancelAction = createCancelAction()
igor@1242
   262
        let replyAction = createReplyAction(cell: cell)
igor@1242
   263
        let forwardAction = createForwardAction(cell: cell)
igor@1242
   264
        let markAction = createMarkAction()
igor@1242
   265
        alertControler.addAction(cancelAction)
igor@1242
   266
        alertControler.addAction(replyAction)
igor@1242
   267
        alertControler.addAction(forwardAction)
igor@1242
   268
        alertControler.addAction(markAction)
igor@1242
   269
        present(alertControler, animated: true, completion: nil)
igor@1242
   270
    }
igor@1242
   271
    
igor@1242
   272
    // MARK: - Action Sheet Actions
igor@1242
   273
igor@1242
   274
    func createCancelAction() -> UIAlertAction {
igor@1242
   275
      return  UIAlertAction(title: "Cancel", style: .cancel) { (action) in}
igor@1242
   276
    }
igor@1242
   277
    
igor@1242
   278
    func createReplyAction(cell: EmailListViewCell) ->  UIAlertAction {
igor@1242
   279
        return UIAlertAction(title: "Reply", style: .default) { (action) in
igor@1242
   280
            self.performSegue(withIdentifier: self.segueCompose, sender: cell)
igor@1242
   281
        }
igor@1242
   282
    }
igor@1242
   283
    
igor@1242
   284
    func createForwardAction(cell: EmailListViewCell) -> UIAlertAction {
igor@1242
   285
        return UIAlertAction(title: "Forward", style: .default) { (action) in
igor@1242
   286
            self.performSegue(withIdentifier: self.segueCompose, sender: cell)
igor@1242
   287
        }
igor@1242
   288
    }
igor@1242
   289
    
igor@1242
   290
    func createMarkAction() -> UIAlertAction {
igor@1242
   291
        return UIAlertAction(title: "Mark", style: .default) { (action) in
igor@1242
   292
        }
igor@1242
   293
    }
igor@1301
   294
    
igor@1301
   295
    // MARK: - Content Search
igor@1301
   296
    
igor@1301
   297
    func filterContentForSearchText(searchText: String) {
igor@1301
   298
        
igor@1301
   299
    }
igor@1301
   300
    
igor@1301
   301
    // MARK: - Refresh Table Data
igor@1301
   302
    
igor@1301
   303
    func refreshTableData() {
igor@1301
   304
        refreshControl?.beginRefreshing()
igor@1301
   305
        refreshControl?.endRefreshing()
igor@1301
   306
    }
igor@1301
   307
dirk@784
   308
}
igor@1301
   309
igor@1301
   310
extension EmailListViewController: UISearchResultsUpdating, UISearchControllerDelegate {
igor@1301
   311
    public func updateSearchResults(for searchController: UISearchController) {
igor@1301
   312
        filterContentForSearchText(searchText: searchController.searchBar.text!)
igor@1301
   313
    }
igor@1301
   314
    
igor@1301
   315
    func didDismissSearchController(_ searchController: UISearchController) {
igor@1301
   316
    }
igor@1301
   317
}