pEpForiOS/UI/EmailDisplay/EmailListViewController.swift
author Xavier Algarra <xavier@pep-project.org>
Wed, 06 Sep 2017 19:16:21 +0200
changeset 2979 1e54293a326b
parent 2967 3eee0287a880
child 3042 a9e8ff283a44
permissions -rw-r--r--
IOS-684 disabling filter if no filters are selected
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@810
    12
import MessageModel
dirk@810
    13
igor@1260
    14
struct EmailListConfig {
andreas@2838
    15
    var appConfig: AppConfig
dirk@2854
    16
igor@1260
    17
    /** The folder to display, if it exists */
igor@1260
    18
    var folder: Folder?
dirk@1906
    19
dirk@1906
    20
    let imageProvider = IdentityImageProvider()
igor@1260
    21
}
dirk@30
    22
andreas@2838
    23
class EmailListViewController: TableViewControllerBase {
andreas@2838
    24
    public static let storyboardId = "EmailListViewController"
dirk@583
    25
    struct UIState {
dirk@583
    26
        var isSynching: Bool = false
dirk@583
    27
    }
dirk@30
    28
dirk@1344
    29
    var config: EmailListConfig?
xavier@2362
    30
    var viewModel: EmailListViewModel?
dirk@275
    31
    var state = UIState()
igor@1301
    32
    let searchController = UISearchController(searchResultsController: nil)
dirk@719
    33
dirk@1724
    34
    /**
dirk@1724
    35
     After trustwords have been invoked, this will be the partner identity that
dirk@1724
    36
     was either confirmed or mistrusted.
dirk@1724
    37
     */
dirk@1724
    38
    var partnerIdentity: Identity?
dirk@1724
    39
dirk@2067
    40
    @IBOutlet weak var enableFilterButton: UIBarButtonItem!
dirk@2067
    41
    @IBOutlet weak var textFilterButton: UIBarButtonItem!
dirk@2067
    42
xavier@2585
    43
    @IBOutlet var showFoldersButton: UIBarButtonItem!
dirk@2067
    44
dirk@275
    45
    override func viewDidLoad() {
ylandert@935
    46
        super.viewDidLoad()
dirk@2189
    47
        title = NSLocalizedString("Inbox", comment: "General name for (unified) inbox")
igor@1284
    48
        UIHelper.emailListTableHeight(self.tableView)
igor@1301
    49
        addSearchBar()
dirk@275
    50
    }
dirk@31
    51
dirk@784
    52
    override func viewWillAppear(_ animated: Bool) {
igor@1301
    53
        super.viewWillAppear(animated)
xavier@2325
    54
        self.navigationController?.setToolbarHidden(false, animated: true)
dirk@1344
    55
        if MiscUtil.isUnitTest() {
dirk@1344
    56
            return
dirk@1344
    57
        }
dirk@1344
    58
xavier@2363
    59
        if let vm = viewModel {
xavier@2363
    60
            self.textFilterButton.isEnabled = vm.filterEnabled
xavier@2967
    61
            updateFilterText()
xavier@2363
    62
        } else {
xavier@2363
    63
            self.textFilterButton.isEnabled = false
xavier@2363
    64
        }
xavier@1832
    65
dirk@1826
    66
        setDefaultColors()
andreas@2683
    67
        setupConfig()
dirk@854
    68
        updateModel()
dirk@1348
    69
dirk@2191
    70
        // Mark this folder as having been looked at by the user
andreas@2683
    71
        if let folder = config?.folder {
andreas@2683
    72
            updateLastLookAt(on: folder)
dirk@2191
    73
        }
xavier@2437
    74
        if viewModel == nil {
xavier@2437
    75
            viewModel = EmailListViewModel(config: config, delegate: self)
xavier@2437
    76
        }
dirk@1348
    77
        MessageModelConfig.messageFolderDelegate = self
xavier@2585
    78
xavier@2585
    79
        if let size = navigationController?.viewControllers.count, size > 1 {
xavier@2585
    80
            self.showFoldersButton.isEnabled = false
xavier@2585
    81
        } else {
xavier@2585
    82
            self.showFoldersButton.isEnabled = true
xavier@2585
    83
        }
andreas@2838
    84
dirk@1348
    85
    }
dirk@1348
    86
andreas@2683
    87
    private func updateLastLookAt(on folder: Folder) {
andreas@2683
    88
        if folder.isUnified {
andreas@2683
    89
            folder.updateLastLookAt()
andreas@2683
    90
        } else {
andreas@2683
    91
            folder.updateLastLookAtAndSave()
andreas@2683
    92
        }
andreas@2683
    93
    }
xavier@1948
    94
dirk@1348
    95
    override func viewWillDisappear(_ animated: Bool) {
dirk@1348
    96
        super.viewWillDisappear(animated)
dirk@1348
    97
        MessageModelConfig.messageFolderDelegate = nil
igor@1301
    98
    }
xavier@1623
    99
andreas@2683
   100
    func setupConfig() {
andreas@2838
   101
        guard let saveAppConfig = appConfig else {
andreas@2838
   102
            Log.shared.errorAndCrash(component: #function, errorString: "No AppConfig!")
igor@1338
   103
            return
igor@1338
   104
        }
xavier@2132
   105
        if config == nil {
andreas@2838
   106
            config = EmailListConfig(appConfig: saveAppConfig,
dirk@2191
   107
                                     folder: Folder.unifiedInbox())
xavier@2132
   108
        }
xavier@2362
   109
dirk@2240
   110
        if Account.all().isEmpty {
dirk@2240
   111
            performSegue(withIdentifier:.segueAddNewAccount, sender: self)
dirk@2240
   112
        }
andreas@2683
   113
andreas@2697
   114
        guard let folder = config?.folder else {
andreas@2697
   115
            return
andreas@2697
   116
        }
andreas@2697
   117
        self.title = realName(of: folder)
igor@1338
   118
    }
xavier@1623
   119
igor@1301
   120
    func addSearchBar() {
igor@1301
   121
        searchController.searchResultsUpdater = self
igor@1301
   122
        searchController.dimsBackgroundDuringPresentation = false
igor@1301
   123
        searchController.delegate = self
igor@1301
   124
        definesPresentationContext = true
igor@1301
   125
        tableView.tableHeaderView = searchController.searchBar
igor@1301
   126
        tableView.setContentOffset(CGPoint(x: 0.0, y: 40.0), animated: false)
igor@1301
   127
    }
dirk@705
   128
dirk@854
   129
    func updateModel() {
igor@1318
   130
        tableView.reloadData()
dirk@31
   131
    }
dirk@31
   132
xavier@1832
   133
    @IBAction func showUnreadButtonTapped(_ sender: UIBarButtonItem) {
xavier@2979
   134
        handlefilter()
xavier@2979
   135
    }
xavier@2979
   136
xavier@2979
   137
    func handlefilter() {
xavier@2363
   138
        if let vm = viewModel {
xavier@2363
   139
            if vm.filterEnabled {
xavier@2363
   140
                vm.filterEnabled = false
xavier@2979
   141
                handleButtonFilter(enabled: false)
xavier@2425
   142
                if config != nil {
xavier@2425
   143
                    vm.resetFilters()
xavier@2425
   144
                }
xavier@2363
   145
            } else {
xavier@2363
   146
                vm.filterEnabled = true
xavier@2363
   147
                if config != nil {
xavier@2369
   148
                    vm.updateFilter(filter: Filter.unread())
xavier@2363
   149
                }
xavier@2979
   150
                handleButtonFilter(enabled: true)
xavier@1832
   151
            }
xavier@2363
   152
            self.textFilterButton.isEnabled = vm.filterEnabled
xavier@1832
   153
        }
andreas@2697
   154
    }
xavier@2363
   155
xavier@2979
   156
    func handleButtonFilter(enabled: Bool) {
xavier@2979
   157
        if enabled == false {
xavier@2979
   158
            textFilterButton.title = ""
xavier@2979
   159
            enableFilterButton.image = UIImage(named: "unread-icon")
xavier@2979
   160
        } else {
xavier@2979
   161
            enableFilterButton.image = UIImage(named: "unread-icon-active")
xavier@2979
   162
            updateFilterText()
xavier@2979
   163
        }
xavier@2979
   164
    }
xavier@2979
   165
xavier@2967
   166
    func updateFilterText() {
xavier@2967
   167
        if let vm = viewModel, let txt = vm.enabledFilters?.text {
xavier@2967
   168
            textFilterButton.title = "Filter by: " + txt
xavier@2967
   169
        }
xavier@2967
   170
    }
xavier@2967
   171
andreas@2697
   172
    // MARK: - Private
xavier@1832
   173
andreas@2697
   174
    private func realName(of folder: Folder) -> String? {
andreas@2697
   175
        if folder.isUnified {
andreas@2697
   176
            return folder.name
andreas@2697
   177
        } else {
andreas@2697
   178
            return folder.realName
andreas@2697
   179
        }
xavier@1832
   180
    }
xavier@1832
   181
dirk@58
   182
    // MARK: - UI State
dirk@58
   183
dirk@58
   184
    func updateUI() {
dirk@784
   185
        UIApplication.shared.isNetworkActivityIndicatorVisible = state.isSynching
dirk@748
   186
        if !state.isSynching {
igor@1260
   187
            refreshControl?.endRefreshing()
dirk@58
   188
        }
dirk@58
   189
    }
dirk@58
   190
dirk@31
   191
    // MARK: - UITableViewDataSource
dirk@31
   192
dirk@784
   193
    override func numberOfSections(in tableView: UITableView) -> Int {
xavier@2362
   194
        if let _ = viewModel?.folderToShow {
dirk@854
   195
            return 1
dirk@209
   196
        }
dirk@854
   197
        return 0
dirk@31
   198
    }
dirk@31
   199
dirk@784
   200
    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
xavier@2362
   201
        if let vm = viewModel {
xavier@2362
   202
            return vm.count
dirk@31
   203
        }
dirk@31
   204
        return 0
dirk@31
   205
    }
dirk@31
   206
dirk@784
   207
    override func tableView(_ tableView: UITableView,
dirk@784
   208
                            cellForRowAt indexPath: IndexPath) -> UITableViewCell {
dirk@784
   209
        let cell = tableView.dequeueReusableCell(
dirk@784
   210
            withIdentifier: "EmailListViewCell", for: indexPath) as! EmailListViewCell
xavier@2344
   211
        //mantener el configure cell para tal de no generar un vm para celdas
andreas@2838
   212
        let _ = cell.configureCell(config: config, indexPath: indexPath, session: session)
xavier@2404
   213
        viewModel?.associate(cell: cell, position: indexPath.row)
dirk@31
   214
        return cell
dirk@31
   215
    }
dirk@31
   216
dirk@719
   217
    // MARK: - UITableViewDelegate
dirk@719
   218
dirk@784
   219
    override func tableView(_ tableView: UITableView, editActionsForRowAt
dirk@784
   220
        indexPath: IndexPath)-> [UITableViewRowAction]? {
xavier@1623
   221
dirk@784
   222
        let cell = tableView.cellForRow(at: indexPath) as! EmailListViewCell
igor@1260
   223
        if let email = cell.messageAt(indexPath: indexPath, config: config) {
igor@1576
   224
            let flagAction = createFlagAction(message: email, cell: cell)
dirk@1507
   225
            let deleteAction = createDeleteAction(message: email, cell: cell)
igor@1242
   226
            let moreAction = createMoreAction(message: email, cell: cell)
igor@1576
   227
            return [deleteAction, flagAction, moreAction]
dirk@855
   228
        }
dirk@855
   229
        return nil
dirk@744
   230
    }
dirk@744
   231
dirk@719
   232
    // MARK: - Misc
dirk@719
   233
dirk@1507
   234
    func createRowAction(cell: EmailListViewCell,
xavier@1623
   235
                         image: UIImage?, action: @escaping (UITableViewRowAction, IndexPath) -> Void,
xavier@1623
   236
                         title: String) -> UITableViewRowAction {
dirk@1510
   237
        let rowAction = UITableViewRowAction(
dirk@1510
   238
            style: .normal, title: title, handler: action)
dirk@1507
   239
dirk@1507
   240
        if let theImage = image {
dirk@1507
   241
            let iconColor = UIColor(patternImage: theImage)
dirk@1507
   242
            rowAction.backgroundColor = iconColor
dirk@744
   243
        }
dirk@744
   244
dirk@1507
   245
        return rowAction
dirk@744
   246
    }
dirk@744
   247
dirk@1507
   248
    func createFlagAction(message: Message, cell: EmailListViewCell) -> UITableViewRowAction {
dirk@1507
   249
        func action(action: UITableViewRowAction, indexPath: IndexPath) -> Void {
dirk@1522
   250
            if message.imapFlags == nil {
dirk@1522
   251
                Log.warn(component: #function, content: "message.imapFlags == nil")
dirk@1522
   252
            }
dirk@1605
   253
            if cell.isFlagged(message: message) {
dirk@1507
   254
                message.imapFlags?.flagged = false
dirk@1507
   255
            } else {
dirk@1507
   256
                message.imapFlags?.flagged = true
dirk@1507
   257
            }
dirk@1507
   258
            message.save()
dirk@1507
   259
            self.tableView.reloadRows(at: [indexPath], with: .none)
dirk@1507
   260
        }
dirk@1510
   261
dirk@2639
   262
        let flagString = NSLocalizedString("Flag", comment: "Message action (on swipe)")
dirk@2639
   263
        var title = "\n\n\(flagString)"
dirk@2639
   264
        let unflagString = NSLocalizedString("Unflag", comment: "Message action (on swipe)")
dirk@1605
   265
        if message.imapFlags?.flagged ?? true {
dirk@2639
   266
            title = "\n\n\(unflagString)"
dirk@744
   267
        }
dirk@744
   268
dirk@1510
   269
        return createRowAction(
dirk@1510
   270
            cell: cell, image: UIImage(named: "swipe-flag"), action: action, title: title)
dirk@744
   271
    }
dirk@744
   272
dirk@1507
   273
    func createDeleteAction(message: Message, cell: EmailListViewCell) -> UITableViewRowAction {
dirk@1507
   274
        func action(action: UITableViewRowAction, indexPath: IndexPath) -> Void {
dirk@1507
   275
            guard let message = cell.messageAt(indexPath: indexPath, config: self.config) else {
dirk@1507
   276
                return
dirk@1507
   277
            }
xavier@1623
   278
dirk@1650
   279
            message.delete() // mark for deletion/trash
igor@1576
   280
            self.tableView.reloadData()
dirk@1507
   281
        }
dirk@744
   282
dirk@2639
   283
        let title = NSLocalizedString("Delete", comment: "Message action (on swipe)")
dirk@1510
   284
        return createRowAction(
dirk@1510
   285
            cell: cell, image: UIImage(named: "swipe-trash"), action: action,
dirk@2639
   286
            title: "\n\n\(title)")
dirk@1507
   287
    }
dirk@1507
   288
dirk@1507
   289
    func createMarkAsReadAction(message: Message, cell: EmailListViewCell) -> UITableViewRowAction {
dirk@1507
   290
        func action(action: UITableViewRowAction, indexPath: IndexPath) -> Void {
dirk@1605
   291
            if cell.haveSeen(message: message) {
dirk@1507
   292
                message.imapFlags?.seen = false
dirk@1507
   293
            } else {
dirk@1507
   294
                message.imapFlags?.seen = true
dirk@1507
   295
            }
dirk@1507
   296
            self.tableView.reloadRows(at: [indexPath], with: .none)
dirk@744
   297
        }
dirk@1510
   298
dirk@1510
   299
        var title = NSLocalizedString(
dirk@2190
   300
            "Unread", comment: "Message action (on swipe)")
dirk@1605
   301
        if !cell.haveSeen(message: message) {
dirk@1510
   302
            title = NSLocalizedString(
dirk@2190
   303
                "Read", comment: "Message action (on swipe)")
dirk@1507
   304
        }
dirk@1507
   305
dirk@1507
   306
        let isReadAction = createRowAction(cell: cell, image: nil, action: action,
dirk@1510
   307
                                           title: title)
dirk@784
   308
        isReadAction.backgroundColor = UIColor.blue
dirk@744
   309
dirk@744
   310
        return isReadAction
dirk@744
   311
    }
xavier@1623
   312
igor@1242
   313
    func createMoreAction(message: Message, cell: EmailListViewCell) -> UITableViewRowAction {
dirk@1510
   314
        func action(action: UITableViewRowAction, indexPath: IndexPath) -> Void {
igor@1242
   315
            self.showMoreActionSheet(cell: cell)
igor@1242
   316
        }
dirk@1510
   317
dirk@2639
   318
        let title = NSLocalizedString("More", comment: "Message action (on swipe)")
dirk@1510
   319
        return createRowAction(
dirk@1510
   320
            cell: cell, image: UIImage(named: "swipe-more"), action: action,
dirk@2639
   321
            title: "\n\n\(title)")
igor@1242
   322
    }
xavier@1623
   323
igor@1242
   324
    // MARK: - Action Sheet
xavier@1623
   325
igor@1242
   326
    func showMoreActionSheet(cell: EmailListViewCell) {
igor@1242
   327
        let alertControler = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)
igor@1438
   328
        alertControler.view.tintColor = .pEpGreen
igor@1242
   329
        let cancelAction = createCancelAction()
igor@1242
   330
        let replyAction = createReplyAction(cell: cell)
xavier@1623
   331
        let replyAllAction = createReplyAllAction(cell: cell)
igor@1242
   332
        let forwardAction = createForwardAction(cell: cell)
igor@1242
   333
        alertControler.addAction(cancelAction)
igor@1242
   334
        alertControler.addAction(replyAction)
xavier@1620
   335
        alertControler.addAction(replyAllAction)
igor@1242
   336
        alertControler.addAction(forwardAction)
igor@1414
   337
        if let popoverPresentationController = alertControler.popoverPresentationController {
igor@1414
   338
            popoverPresentationController.sourceView = cell
igor@1414
   339
        }
igor@1242
   340
        present(alertControler, animated: true, completion: nil)
igor@1242
   341
    }
xavier@1623
   342
igor@1242
   343
    // MARK: - Action Sheet Actions
igor@1242
   344
igor@1242
   345
    func createCancelAction() -> UIAlertAction {
xavier@1623
   346
        return  UIAlertAction(title: "Cancel", style: .cancel) { (action) in}
igor@1242
   347
    }
xavier@1623
   348
igor@1242
   349
    func createReplyAction(cell: EmailListViewCell) ->  UIAlertAction {
igor@1242
   350
        return UIAlertAction(title: "Reply", style: .default) { (action) in
xavier@2715
   351
            self.performSegue(withIdentifier: .segueReply, sender: cell)
igor@1242
   352
        }
igor@1242
   353
    }
xavier@1620
   354
xavier@1620
   355
    func createReplyAllAction(cell: EmailListViewCell) ->  UIAlertAction {
xavier@1623
   356
        return UIAlertAction(title: "Reply All", style: .default) { (action) in
xavier@1623
   357
            self.performSegue(withIdentifier: .segueReplyAll, sender: cell)
xavier@1620
   358
        }
xavier@1620
   359
    }
xavier@1620
   360
igor@1242
   361
    func createForwardAction(cell: EmailListViewCell) -> UIAlertAction {
igor@1242
   362
        return UIAlertAction(title: "Forward", style: .default) { (action) in
xavier@1664
   363
            self.performSegue(withIdentifier: .segueForward, sender: cell)
igor@1242
   364
        }
igor@1242
   365
    }
xavier@1623
   366
dirk@784
   367
}
igor@1301
   368
igor@1301
   369
extension EmailListViewController: UISearchResultsUpdating, UISearchControllerDelegate {
igor@1301
   370
    public func updateSearchResults(for searchController: UISearchController) {
xavier@2369
   371
        if let vm = viewModel {
xavier@2369
   372
            vm.filterContentForSearchText(searchText: searchController.searchBar.text!, clear: false)
xavier@2369
   373
        }
igor@1301
   374
    }
xavier@1623
   375
igor@1301
   376
    func didDismissSearchController(_ searchController: UISearchController) {
xavier@2369
   377
        if let vm = viewModel {
xavier@2369
   378
            vm.filterContentForSearchText(clear: true)
xavier@2369
   379
        }
igor@1301
   380
    }
igor@1301
   381
}
igor@1338
   382
igor@1338
   383
// MARK: - Navigation
igor@1338
   384
igor@1338
   385
extension EmailListViewController: SegueHandlerType {
xavier@1623
   386
igor@1338
   387
    // MARK: - SegueHandlerType
xavier@1623
   388
igor@1338
   389
    enum SegueIdentifier: String {
igor@1338
   390
        case segueAddNewAccount
igor@1338
   391
        case segueShowEmail
igor@1338
   392
        case segueCompose
xavier@2715
   393
        case segueReply
xavier@1623
   394
        case segueReplyAll
xavier@1664
   395
        case segueForward
xavier@1865
   396
        case segueFilter
xavier@2248
   397
        case segueFolderViews
igor@1338
   398
        case noSegue
igor@1338
   399
    }
xavier@1623
   400
dirk@2957
   401
    func currentMessage(senderCell: Any?) -> (Message, IndexPath)? {
dirk@2957
   402
        if let cell = senderCell as? EmailListViewCell,
dirk@2957
   403
            let indexPath = self.tableView.indexPath(for: cell),
dirk@2957
   404
            let message = cell.messageAt(indexPath: indexPath, config: config) {
dirk@2957
   405
            return (message, indexPath)
dirk@2957
   406
        }
dirk@2957
   407
        return nil
dirk@2957
   408
    }
dirk@2957
   409
igor@1338
   410
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
igor@1338
   411
        switch segueIdentifier(for: segue) {
xavier@2715
   412
        case .segueReply:
andreas@2850
   413
            guard let nav = segue.destination as? UINavigationController,
xavier@2715
   414
                let destination = nav.topViewController as? ComposeTableViewController,
dirk@2957
   415
                let (theMessage, _) = currentMessage(senderCell: sender) else {
andreas@2850
   416
                    Log.shared.errorAndCrash(component: #function, errorString: "Segue issue")
andreas@2850
   417
                    return
xavier@2715
   418
            }
andreas@2850
   419
            destination.appConfig = appConfig
andreas@2850
   420
            destination.composeMode = .replyFrom
dirk@2957
   421
            destination.originalMessage = theMessage
xavier@1623
   422
        case .segueReplyAll:
andreas@2850
   423
            guard let nav = segue.destination as? UINavigationController,
xavier@1623
   424
                let destination = nav.topViewController as? ComposeTableViewController,
dirk@2957
   425
                let (theMessage, _) = currentMessage(senderCell: sender)  else {
andreas@2850
   426
                    Log.shared.errorAndCrash(component: #function, errorString: "Segue issue")
andreas@2850
   427
                    return
xavier@1623
   428
            }
andreas@2850
   429
            destination.appConfig = appConfig
andreas@2850
   430
            destination.composeMode = .replyAll
dirk@2957
   431
            destination.originalMessage = theMessage
igor@1338
   432
        case .segueShowEmail:
andreas@2850
   433
            guard let vc = segue.destination as? EmailViewController,
dirk@2957
   434
                let (theMessage, indexPath) = currentMessage(senderCell: sender) else {
andreas@2850
   435
                    Log.shared.errorAndCrash(component: #function, errorString: "Segue issue")
andreas@2850
   436
                    return
igor@1338
   437
            }
andreas@2850
   438
            vc.appConfig = appConfig
dirk@2957
   439
            vc.message = theMessage
andreas@2850
   440
            vc.folderShow = viewModel?.folderToShow
andreas@2850
   441
            vc.messageId = indexPath.row
xavier@1664
   442
        case .segueForward:
andreas@2850
   443
            guard let nav = segue.destination as? UINavigationController,
xavier@1664
   444
                let destination = nav.topViewController as? ComposeTableViewController,
dirk@2957
   445
                let (theMessage, _) = currentMessage(senderCell: sender) else {
andreas@2850
   446
                    Log.shared.errorAndCrash(component: #function, errorString: "Segue issue")
andreas@2850
   447
                    return
xavier@1664
   448
            }
andreas@2850
   449
            destination.composeMode = .forward
andreas@2850
   450
            destination.appConfig = appConfig
dirk@2957
   451
            destination.originalMessage = theMessage
andreas@2850
   452
        case .segueFilter:
andreas@2850
   453
            guard let destiny = segue.destination as? FilterTableViewController  else {
andreas@2850
   454
                Log.shared.errorAndCrash(component: #function, errorString: "Segue issue")
andreas@2850
   455
                return
andreas@2850
   456
            }
andreas@2850
   457
            destiny.appConfig = appConfig
andreas@2850
   458
            destiny.filterDelegate = viewModel
andreas@2850
   459
            destiny.inFolder = false
andreas@2850
   460
            destiny.filterEnabled = viewModel?.folderToShow?.filter
andreas@2850
   461
            destiny.hidesBottomBarWhenPushed = true
andreas@2850
   462
        case .segueAddNewAccount:
andreas@2850
   463
            guard let vc = segue.destination as? LoginTableViewController  else {
andreas@2850
   464
                Log.shared.errorAndCrash(component: #function, errorString: "Segue issue")
andreas@2850
   465
                return
andreas@2850
   466
            }
andreas@2850
   467
            vc.appConfig = appConfig
andreas@2850
   468
            vc.hidesBottomBarWhenPushed = true
xavier@1664
   469
            break
andreas@2850
   470
        case .segueFolderViews:
andreas@2850
   471
            guard let vC = segue.destination as? FolderTableViewController  else {
andreas@2850
   472
                Log.shared.errorAndCrash(component: #function, errorString: "Segue issue")
andreas@2850
   473
                return
xavier@1865
   474
            }
andreas@2850
   475
            vC.appConfig = appConfig
andreas@2850
   476
            vC.hidesBottomBarWhenPushed = true
xavier@1865
   477
            break
andreas@2850
   478
        case .segueCompose:
andreas@2850
   479
            guard let nav = segue.destination as? UINavigationController,
dirk@2957
   480
                let destination = nav.rootViewController as? ComposeTableViewController else {
andreas@2850
   481
                    Log.shared.errorAndCrash(component: #function, errorString: "Segue issue")
andreas@2850
   482
                    return
dirk@2240
   483
            }
andreas@2850
   484
            destination.appConfig = appConfig
dirk@2959
   485
            destination.composeMode = .normal
andreas@2850
   486
        default:
andreas@2850
   487
            Log.shared.errorAndCrash(component: #function, errorString: "Unhandled segue")
dirk@1694
   488
            break
igor@1338
   489
        }
andreas@2838
   490
    }
xavier@1865
   491
xavier@2254
   492
    @IBAction func segueUnwindAccountAdded(segue: UIStoryboardSegue) {
xavier@2254
   493
    }
xavier@2254
   494
dirk@1350
   495
    func didChangeInternal(messageFolder: MessageFolder) {
dirk@1350
   496
        if let folder = config?.folder,
dirk@1350
   497
            let message = messageFolder as? Message,
dirk@1558
   498
            folder.contains(message: message, deletedMessagesAreContained: true) {
dirk@2181
   499
            if message.isOriginal {
dirk@2181
   500
                // new message has arrived
dirk@2181
   501
                if let index = folder.indexOf(message: message) {
dirk@2181
   502
                    let ip = IndexPath(row: index, section: 0)
dirk@2181
   503
                    Log.info(
dirk@2181
   504
                        component: #function,
dirk@2181
   505
                        content: "insert message at \(index), \(folder.messageCount()) messages")
dirk@2181
   506
                    tableView.insertRows(at: [ip], with: .automatic)
dirk@1535
   507
                } else {
dirk@2181
   508
                    tableView.reloadData()
dirk@2181
   509
                }
dirk@2181
   510
            } else if message.isGhost {
xavier@2363
   511
                if let vm = viewModel, let cell = vm.cellFor(message: message), let ip = tableView.indexPath(for: cell) {
dirk@2181
   512
                    Log.info(
dirk@2181
   513
                        component: #function,
dirk@2181
   514
                        content: "delete message at \(index), \(folder.messageCount()) messages")
dirk@2181
   515
                    tableView.deleteRows(at: [ip], with: .automatic)
dirk@2181
   516
                } else {
dirk@2181
   517
                    tableView.reloadData()
dirk@2181
   518
                }
dirk@2181
   519
            } else {
dirk@2181
   520
                // other flags than delete must have been changed
xavier@2363
   521
                if let vm = viewModel, let cell = vm.cellFor(message: message) {
dirk@2181
   522
                    cell.updateFlags(message: message)
dirk@2181
   523
                } else {
dirk@2181
   524
                    tableView.reloadData()
dirk@1350
   525
                }
dirk@1350
   526
            }
dirk@1350
   527
        }
dirk@1350
   528
    }
dirk@1737
   529
igor@1338
   530
}
dirk@1348
   531
dirk@1348
   532
// MARK: - MessageFolderDelegate
dirk@1348
   533
dirk@1348
   534
extension EmailListViewController: MessageFolderDelegate {
dirk@1348
   535
    func didChange(messageFolder: MessageFolder) {
dirk@1675
   536
        GCD.onMainWait {
dirk@1350
   537
            self.didChangeInternal(messageFolder: messageFolder)
dirk@1348
   538
        }
dirk@1348
   539
    }
dirk@1348
   540
}
xavier@2369
   541
dirk@2818
   542
extension EmailListViewController: TableViewUpdate {
xavier@2369
   543
    func updateView() {
xavier@2979
   544
        if let vm = self.viewModel, let filter = vm.folderToShow?.filter, filter.isDefault() {
xavier@2979
   545
            vm.filterEnabled = false
xavier@2979
   546
            handleButtonFilter(enabled: false)
xavier@2979
   547
        }
xavier@2369
   548
        self.tableView.reloadData()
xavier@2369
   549
    }
xavier@2369
   550
}