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