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