pEpForiOS/UI/EmailDisplay/EmailListViewController.swift
author Dirk Zimmermann <dirk@pep-project.org>
Tue, 24 Jan 2017 10:01:42 +0100
changeset 1506 11d3b3dd5865
parent 1438 a95b5815208d
child 1507 7270fb02923c
permissions -rw-r--r--
IOS-417 ws
     1 //
     2 //  EmailListViewController.swift
     3 //  pEpForiOS
     4 //
     5 //  Created by Dirk Zimmermann on 16/04/16.
     6 //  Copyright © 2016 p≡p Security S.A. All rights reserved.
     7 //
     8 
     9 import Foundation
    10 import UIKit
    11 import CoreData
    12 import MessageModel
    13 
    14 struct EmailListConfig {
    15     var appConfig: AppConfig?
    16 
    17     /** The folder to display, if it exists */
    18     var folder: Folder?
    19 }
    20 
    21 class EmailListViewController: UITableViewController {
    22     
    23     struct UIState {
    24         var isSynching: Bool = false
    25     }
    26 
    27     var config: EmailListConfig?
    28     var state = UIState()
    29     let searchController = UISearchController(searchResultsController: nil)
    30 
    31     override func viewDidLoad() {
    32         super.viewDidLoad()
    33         
    34         title = "EmailList.title".localized
    35         UIHelper.emailListTableHeight(self.tableView)
    36         addSearchBar()
    37     }
    38 
    39     override func viewWillAppear(_ animated: Bool) {
    40         super.viewWillAppear(animated)
    41         
    42         if MiscUtil.isUnitTest() {
    43             return
    44         }
    45 
    46         initialConfig()
    47         updateModel()
    48 
    49         MessageModelConfig.messageFolderDelegate = self
    50     }
    51 
    52     override func viewWillDisappear(_ animated: Bool) {
    53         super.viewWillDisappear(animated)
    54         MessageModelConfig.messageFolderDelegate = nil
    55     }
    56     
    57     func initialConfig() {
    58         guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else {
    59             return
    60         }
    61 
    62         if config == nil {
    63             config = EmailListConfig(appConfig: appDelegate.appConfig, folder: Folder.unifiedInbox())
    64         }
    65         if Account.all().isEmpty {
    66             performSegue(withIdentifier:.segueAddNewAccount, sender: self)
    67         }
    68     }
    69     
    70     func addSearchBar() {
    71         searchController.searchResultsUpdater = self
    72         searchController.dimsBackgroundDuringPresentation = false
    73         searchController.delegate = self
    74         definesPresentationContext = true
    75         tableView.tableHeaderView = searchController.searchBar
    76         tableView.setContentOffset(CGPoint(x: 0.0, y: 40.0), animated: false)
    77     }
    78 
    79     
    80     @IBAction func showUnreadButtonTapped(_ sender: UIBarButtonItem) {}
    81     
    82     func updateModel() {
    83         tableView.reloadData()
    84     }
    85 
    86     // MARK: - UI State
    87 
    88     func updateUI() {
    89         UIApplication.shared.isNetworkActivityIndicatorVisible = state.isSynching
    90         if !state.isSynching {
    91             refreshControl?.endRefreshing()
    92         }
    93     }
    94 
    95     // MARK: - UITableViewDataSource
    96 
    97     override func numberOfSections(in tableView: UITableView) -> Int {
    98         if let _ = config?.folder {
    99             return 1
   100         }
   101         return 0
   102     }
   103 
   104     override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
   105         if let fol = config?.folder  {
   106             return fol.messageCount()
   107         }
   108         return 0
   109     }
   110 
   111     override func tableView(_ tableView: UITableView,
   112                             cellForRowAt indexPath: IndexPath) -> UITableViewCell {
   113         let cell = tableView.dequeueReusableCell(
   114             withIdentifier: "EmailListViewCell", for: indexPath) as! EmailListViewCell
   115         cell.configureCell(indexPath: indexPath, config: config)
   116         return cell
   117     }
   118 
   119     // MARK: - UITableViewDelegate
   120 
   121     override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
   122         let cell = tableView.cellForRow(at: indexPath) as! EmailListViewCell
   123 
   124         if let fol = config?.folder {
   125             if fol.folderType == .drafts {
   126                 //performSegue(withIdentifier: .segueCompose, sender: cell)
   127                 return
   128             }
   129         }
   130         //performSegue(withIdentifier: .segueShowEmail, sender: cell)
   131     }
   132 
   133     override func tableView(_ tableView: UITableView, editActionsForRowAt
   134         indexPath: IndexPath)-> [UITableViewRowAction]? {
   135         let cell = tableView.cellForRow(at: indexPath) as! EmailListViewCell
   136         if let email = cell.messageAt(indexPath: indexPath, config: config) {
   137             let isFlagAction = createIsFlagAction(message: email, cell: cell)
   138             let deleteAction = createDeleteAction(cell)
   139             //let isReadAction = createIsReadAction(message: email, cell: cell)
   140             let moreAction = createMoreAction(message: email, cell: cell)
   141             return [deleteAction,isFlagAction,moreAction]
   142         }
   143         return nil
   144     }
   145 
   146     // MARK: - Misc
   147 
   148     func createIsFlagAction(message: Message, cell: EmailListViewCell) -> UITableViewRowAction {
   149         // preparing action to trigger when user swipe
   150         let isFlagCompletionHandler: (UITableViewRowAction, IndexPath) -> Void =
   151             { (action, indexPath) in
   152                 if (cell.isImportant(message: message)) {
   153                     message.imapFlags?.flagged = false
   154                 } else {
   155                     message.imapFlags?.flagged = true
   156                 }
   157                 self.tableView.reloadRows(at: [indexPath], with: .none)
   158         }
   159         // creating the action
   160         let isFlagAction = UITableViewRowAction(style: .normal, title: "          ",
   161                                                 handler: isFlagCompletionHandler)
   162         // changing default action color
   163         let swipeFlagImage = UIImage(named: "swipe-flag")
   164         let flagIconColor = UIColor(patternImage: swipeFlagImage!)
   165         isFlagAction.backgroundColor = flagIconColor
   166 
   167         return isFlagAction
   168     }
   169 
   170     func createDeleteAction (_ cell: EmailListViewCell) -> UITableViewRowAction {
   171         // preparing the title action to show when user swipe
   172         let deleteCompletionHandler: (UITableViewRowAction, IndexPath) -> Void =
   173             { (action, indexPath) in
   174                 let message = cell.messageAt(indexPath: indexPath, config: self.config)
   175                 message?.imapFlags?.deleted = true
   176         }
   177 
   178         // creating the action
   179         let deleteAction = UITableViewRowAction(style: .normal, title: "          ",
   180                                                 handler: deleteCompletionHandler)
   181         let swipeTrashImage = UIImage(named: "swipe-trash")
   182         let trashIconColor = UIColor(patternImage: swipeTrashImage!)
   183         deleteAction.backgroundColor = trashIconColor
   184         return deleteAction
   185     }
   186 
   187     func createIsReadAction(message: Message, cell: EmailListViewCell) -> UITableViewRowAction {
   188         // preparing the title action to show when user swipe
   189         var localizedisReadTitle = " "
   190         if (cell.isRead(message: message)) {
   191             localizedisReadTitle = NSLocalizedString(
   192                 "Unread",
   193                 comment: "Unread button title in swipe action on EmailListViewController")
   194         } else {
   195             localizedisReadTitle = NSLocalizedString(
   196                 "Read",
   197                 comment: "Read button title in swipe action on EmailListViewController")
   198         }
   199 
   200         // creating the action
   201         let isReadCompletionHandler: (UITableViewRowAction, IndexPath) -> Void =
   202             { (action, indexPath) in
   203                 if (cell.isRead(message: message)) {
   204                     message.imapFlags?.seen = false
   205                 } else {
   206                     message.imapFlags?.seen = true
   207                 }
   208                 self.tableView.reloadRows(at: [indexPath], with: .none)
   209         }
   210         let isReadAction = UITableViewRowAction(style: .default, title: localizedisReadTitle,
   211                                                 handler: isReadCompletionHandler)
   212         isReadAction.backgroundColor = UIColor.blue
   213 
   214         return isReadAction
   215     }
   216     
   217     func createMoreAction(message: Message, cell: EmailListViewCell) -> UITableViewRowAction {
   218         let moreCompletitionHandler :(UITableViewRowAction, IndexPath) -> Void = {(action, indexPath) in
   219             self.showMoreActionSheet(cell: cell)
   220         }
   221         let moreAction = UITableViewRowAction(style: .normal, title: "          ", handler: moreCompletitionHandler)
   222         let swipeMoreImage = UIImage(named: "swipe-more")
   223         let moreIconColor = UIColor(patternImage: swipeMoreImage!)
   224         moreAction.backgroundColor = moreIconColor
   225         return moreAction
   226     }
   227     
   228     // MARK: - Action Sheet
   229     
   230     func showMoreActionSheet(cell: EmailListViewCell) {
   231         let alertControler = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)
   232         alertControler.view.tintColor = .pEpGreen
   233         let cancelAction = createCancelAction()
   234         let replyAction = createReplyAction(cell: cell)
   235         let forwardAction = createForwardAction(cell: cell)
   236         let markAction = createMarkAction()
   237         alertControler.addAction(cancelAction)
   238         alertControler.addAction(replyAction)
   239         alertControler.addAction(forwardAction)
   240         alertControler.addAction(markAction)
   241         if let popoverPresentationController = alertControler.popoverPresentationController {
   242             popoverPresentationController.sourceView = cell
   243         }
   244         present(alertControler, animated: true, completion: nil)
   245     }
   246     
   247     // MARK: - Action Sheet Actions
   248 
   249     func createCancelAction() -> UIAlertAction {
   250       return  UIAlertAction(title: "Cancel", style: .cancel) { (action) in}
   251     }
   252     
   253     func createReplyAction(cell: EmailListViewCell) ->  UIAlertAction {
   254         return UIAlertAction(title: "Reply", style: .default) { (action) in
   255            // self.performSegue(withIdentifier: self.segueCompose, sender: cell)
   256             self.performSegue(withIdentifier: .segueCompose, sender: cell)
   257         }
   258     }
   259     
   260     func createForwardAction(cell: EmailListViewCell) -> UIAlertAction {
   261         return UIAlertAction(title: "Forward", style: .default) { (action) in
   262             //self.performSegue(withIdentifier: self.segueCompose, sender: cell)
   263             self.performSegue(withIdentifier: .segueCompose, sender: cell)
   264         }
   265     }
   266     
   267     func createMarkAction() -> UIAlertAction {
   268         return UIAlertAction(title: "Mark", style: .default) { (action) in
   269         }
   270     }
   271     
   272     // MARK: - Content Search
   273     
   274     func filterContentForSearchText(searchText: String) {
   275         
   276     }
   277  
   278     // MARK: - Actions
   279 //    @IBAction func unwindToEmailList(for unwindSegue: UIStoryboardSegue) {
   280 //        
   281 //    }
   282    
   283 }
   284 
   285 extension EmailListViewController: UISearchResultsUpdating, UISearchControllerDelegate {
   286     public func updateSearchResults(for searchController: UISearchController) {
   287         filterContentForSearchText(searchText: searchController.searchBar.text!)
   288     }
   289     
   290     func didDismissSearchController(_ searchController: UISearchController) {
   291     }
   292 }
   293 
   294 // MARK: - Navigation
   295 
   296 extension EmailListViewController: SegueHandlerType {
   297     
   298     // MARK: - SegueHandlerType
   299     
   300     enum SegueIdentifier: String {
   301         case segueAddNewAccount
   302         case segueEditAccounts
   303         case segueShowEmail
   304         case segueCompose
   305         case noSegue
   306     }
   307     
   308     override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
   309         switch segueIdentifier(for: segue) {
   310         case .segueCompose:
   311             //let destination = segue.destination as! ComposeTableViewController
   312             // destination.appConfig = config.appConfig
   313             //            if let draft = draftMessageToCompose {
   314             //                draft.imapFlags?.seen = true
   315             //
   316             //                destination.originalMessage = draft
   317             //                destination.composeMode = .draft
   318         //            }
   319             break
   320         case .segueShowEmail:
   321             guard
   322                 let vc = segue.destination as? EmailViewController,
   323                 let cell = sender as? EmailListViewCell,
   324                 let indexPath = self.tableView.indexPath(for: cell),
   325                 let email = cell.messageAt(indexPath: indexPath, config: config) else {
   326                     return
   327             }
   328             vc.appConfig = config?.appConfig
   329             vc.message = email
   330             break
   331         default: ()
   332         }
   333     }
   334 
   335     func didChangeInternal(messageFolder: MessageFolder) {
   336         if let folder = config?.folder,
   337             let message = messageFolder as? Message,
   338             folder.contains(message: message) {
   339             if let msg = messageFolder as? Message {
   340                 if msg.isOriginal {
   341                     self.tableView.reloadData()
   342                 }
   343             }
   344         }
   345     }
   346 }
   347 
   348 // MARK: - MessageFolderDelegate
   349 
   350 extension EmailListViewController: MessageFolderDelegate {
   351     func didChange(messageFolder: MessageFolder) {
   352         GCD.onMain {
   353             self.didChangeInternal(messageFolder: messageFolder)
   354         }
   355     }
   356 }