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