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