From c291b6a047f97f9ea7e642614f6b6adc3fb077bc Mon Sep 17 00:00:00 2001 From: jakobsbode <jakobsbode@mi.fu-berlin.de> Date: Mon, 31 Jul 2017 21:09:30 +0200 Subject: [PATCH] added subfolder support --- EnzevalosContact+CoreDataClass.swift | 2 +- enzevalos_iphone/AddressHandler.swift | 2 +- enzevalos_iphone/AppDelegate.swift | 2 +- enzevalos_iphone/DataHandler.swift | 34 ++++++---- enzevalos_iphone/Folder+CoreDataClass.swift | 14 ++++- .../Folder+CoreDataProperties.swift | 18 ------ enzevalos_iphone/FolderViewController.swift | 24 +++---- enzevalos_iphone/InboxViewController.swift | 6 +- enzevalos_iphone/ListViewController.swift | 4 +- enzevalos_iphone/MailHandler.swift | 43 ++++++------- enzevalos_iphone/ReadViewController.swift | 6 +- enzevalos_iphone/UserData.swift | 63 ++++++++++--------- .../enzevalos_iphone.xcdatamodel/contents | 7 +-- 13 files changed, 112 insertions(+), 113 deletions(-) diff --git a/EnzevalosContact+CoreDataClass.swift b/EnzevalosContact+CoreDataClass.swift index 785e0780..dd2ae17c 100644 --- a/EnzevalosContact+CoreDataClass.swift +++ b/EnzevalosContact+CoreDataClass.swift @@ -134,7 +134,7 @@ open class EnzevalosContact: NSManagedObject, Contact, Comparable { get { var myrecords = [KeyRecord]() for folder in DataHandler.handler.allFolders{ - for r in DataHandler.handler.folderRecords(folder: folder.name) { + for r in DataHandler.handler.folderRecords(folderPath: folder.path) { if r.ezContact == self { myrecords.append(r) } diff --git a/enzevalos_iphone/AddressHandler.swift b/enzevalos_iphone/AddressHandler.swift index 1b65cfdf..af8b9850 100644 --- a/enzevalos_iphone/AddressHandler.swift +++ b/enzevalos_iphone/AddressHandler.swift @@ -76,7 +76,7 @@ class AddressHandler { static var freqAlgorithm2: ([String]) -> [(UIImage, String, String, UIImage?, UIColor)] = { (inserted: [String]) -> [(UIImage, String, String, UIImage?, UIColor)] in - var cons = DataHandler.handler.folderRecords() + var cons = DataHandler.handler.folderRecords(folderPath: UserManager.backendInboxFolderPath) var list: [(UIImage, String, String, UIImage?, UIColor)] = [] var localInserted = inserted diff --git a/enzevalos_iphone/AppDelegate.swift b/enzevalos_iphone/AppDelegate.swift index d8642d05..abe940e8 100644 --- a/enzevalos_iphone/AppDelegate.swift +++ b/enzevalos_iphone/AppDelegate.swift @@ -88,7 +88,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate { if UserDefaults.standard.bool(forKey: "reset") { if UserManager.loadUserValue(Attribute.userAddr) as! String == "ullimuelle@web.de" { let mailhandler = MailHandler.init() - mailhandler.move(mails: DataHandler.handler.findFolder(name: "INBOX").mailsOfFolder, from: "INBOX", to: "Archive") + //mailhandler.move(mails: DataHandler.handler.findFolder(name: "INBOX").mailsOfFolder, from: "INBOX", to: "Archive") } DataHandler.handler.reset() Onboarding.credentials = nil diff --git a/enzevalos_iphone/DataHandler.swift b/enzevalos_iphone/DataHandler.swift index a225515f..7dab64ba 100644 --- a/enzevalos_iphone/DataHandler.swift +++ b/enzevalos_iphone/DataHandler.swift @@ -56,7 +56,17 @@ class DataHandler { } return folders } + } + //All Folders, which are not a subfolder + var allRootFolders: [Folder] { + var root: [Folder] = [] + for f in allFolders { + if !f.path.contains(f.delimiter) { + root.append(f) + } + } + return root } @@ -71,8 +81,8 @@ class DataHandler { if let newFolders = array{ for new in newFolders{ if case let folder as MCOIMAPFolder = new{ - let f = self.findFolder(name: folder.path) //FIXME: this should take the full path instead of the name - f.delimiter = folder.delimiter.description + let f = self.findFolder(with: folder.path) //FIXME: this should take the full path instead of the name + f.delimiter = String(Character(UnicodeScalar(UInt8(folder.delimiter)))) f.flags = folder.flags } } @@ -249,19 +259,19 @@ class DataHandler { } - func findFolder(name: String) -> Folder{ - if let search = find("Folder", type: "path", search:name){ + func findFolder(with path: String) -> Folder{ + if let search = find("Folder", type: "path", search:path){ if search.count > 0{ return search[0] as! Folder } } let folder = NSEntityDescription.insertNewObject(forEntityName: "Folder", into: managedObjectContext) as! Folder - folder.path = name + folder.path = path return folder } - func existsFolder(with name: String) -> Bool { - if let search = find("Folder", type: "path", search:name), search.count > 0{ + func existsFolder(with path: String) -> Bool { + if let search = find("Folder", type: "path", search:path), search.count > 0{ return true } return false @@ -414,7 +424,7 @@ class DataHandler { // -------- End handle to, cc, from addresses -------- - func createMail(_ uid: UInt64, sender: MCOAddress?, receivers: [MCOAddress], cc: [MCOAddress], time: Date, received: Bool, subject: String, body: String?, flags: MCOMessageFlag, record: KeyRecord?, autocrypt: AutocryptContact?, decryptedData: DecryptedData?, folder: String = "INBOX") { + func createMail(_ uid: UInt64, sender: MCOAddress?, receivers: [MCOAddress], cc: [MCOAddress], time: Date, received: Bool, subject: String, body: String?, flags: MCOMessageFlag, record: KeyRecord?, autocrypt: AutocryptContact?, decryptedData: DecryptedData?, folderPath: String) { let finding = findNum("PersistentMail", type: "uid", search: uid) let mail: PersistentMail @@ -485,8 +495,8 @@ class DataHandler { return } - let myfolder = findFolder(name: folder) as Folder - print("DataHAndler around line 455: ", folder) + let myfolder = findFolder(with: folderPath) as Folder + print("DataHAndler around line 455: ", folderPath) myfolder.addToMails(mail) if mail.uid > myfolder.maxID{ myfolder.maxID = mail.uid @@ -547,8 +557,8 @@ class DataHandler { - func folderRecords(folder: String = "INBOX") -> [KeyRecord]{ - let folder = findFolder(name: folder) as Folder + func folderRecords(folderPath: String) -> [KeyRecord]{ + let folder = findFolder(with: folderPath) as Folder return folder.records } diff --git a/enzevalos_iphone/Folder+CoreDataClass.swift b/enzevalos_iphone/Folder+CoreDataClass.swift index e6fe707f..eac4b96c 100644 --- a/enzevalos_iphone/Folder+CoreDataClass.swift +++ b/enzevalos_iphone/Folder+CoreDataClass.swift @@ -23,7 +23,7 @@ public class Folder: NSManagedObject { var frontendName: String { get { - return UserManager.convertToFrontendFoldername(from: name) + return UserManager.convertToFrontendFolderPath(from: name) } } @@ -67,6 +67,18 @@ public class Folder: NSManagedObject { } } + var subfolders: [Folder] { + get { + var folders: [Folder] = [] + for f in DataHandler.handler.allFolders { + if f.path.hasPrefix(path+delimiter) && f.path != path { + folders.append(f) + } + } + return folders + } + } + private func addToRecords(_ m: PersistentMail, records: inout [KeyRecord]) { var found = false diff --git a/enzevalos_iphone/Folder+CoreDataProperties.swift b/enzevalos_iphone/Folder+CoreDataProperties.swift index b63d2752..ca845025 100644 --- a/enzevalos_iphone/Folder+CoreDataProperties.swift +++ b/enzevalos_iphone/Folder+CoreDataProperties.swift @@ -17,7 +17,6 @@ extension Folder { } @NSManaged public var parent: Folder? - @NSManaged public var subfolder: NSSet? @NSManaged public var mails: NSSet? @NSManaged public var path: String @NSManaged public var delimiter: String @@ -98,23 +97,6 @@ extension Folder { } -// MARK: Generated accessors for subfolder -extension Folder { - - @objc(addSubfolderObject:) - @NSManaged public func addToSubfolder(_ value: Folder) - - @objc(removeSubfolderObject:) - @NSManaged public func removeFromSubfolder(_ value: Folder) - - @objc(addSubfolder:) - @NSManaged public func addToSubfolder(_ values: NSSet) - - @objc(removeSubfolder:) - @NSManaged public func removeFromSubfolder(_ values: NSSet) - -} - extension Folder: Comparable { public static func <(lhs: Folder, rhs: Folder) -> Bool { return lhs.name < rhs.name diff --git a/enzevalos_iphone/FolderViewController.swift b/enzevalos_iphone/FolderViewController.swift index 986e2bff..9e15e6c0 100644 --- a/enzevalos_iphone/FolderViewController.swift +++ b/enzevalos_iphone/FolderViewController.swift @@ -19,7 +19,7 @@ class FolderViewController: UITableViewController { self.refreshControl?.addTarget(self, action: #selector(FolderViewController.refresh), for: UIControlEvents.valueChanged) if isFirstFolderViewController { - folders = DataHandler.handler.allFolders.sorted().filter { $0.name != NSLocalizedString("INBOX", comment: "") } + folders = DataHandler.handler.allRootFolders.sorted().filter { $0.path != UserManager.backendInboxFolderPath } DataHandler.handler.callForFolders(done: endRefreshing) navigationItem.title = NSLocalizedString("Folders", comment: "") } @@ -27,12 +27,10 @@ class FolderViewController: UITableViewController { navigationItem.setLeftBarButton(navigationItem.backBarButtonItem, animated: false) } if let thisFolder = presentedFolder { - navigationItem.title = (AppDelegate.getAppDelegate().mailHandler.IMAPSession.defaultNamespace.components(fromPath: thisFolder.name) as! [String])[0] + navigationItem.title = UserManager.convertToFrontendFolderPath(from: thisFolder.name) refreshControl?.beginRefreshing() AppDelegate.getAppDelegate().mailHandler.firstLookUp(thisFolder.path, newMailCallback: newMails, completionCallback: endRefreshing) - if let set = thisFolder.subfolder, let subFolders = set.allObjects as? [Folder] { - folders = subFolders.sorted() - } + folders = thisFolder.subfolders.sorted() } } override func viewDidAppear(_ animated: Bool) { @@ -132,7 +130,7 @@ class FolderViewController: UITableViewController { } else if indexPath.row < folders.count { cell.folderName.text = folders[indexPath.row].frontendName - cell.folderImage.image = getImage(for: folders[indexPath.row].frontendName) + cell.folderImage.image = getImage(for: UserManager.convertToFrontendFolderPath(from: folders[indexPath.row].path, with: folders[indexPath.row].delimiter)) } return cell @@ -163,7 +161,7 @@ class FolderViewController: UITableViewController { let destinationVC = segue.destination as! ReadViewController if let mail = sender as? PersistentMail { destinationVC.mail = mail - if presentedFolder?.name == UserManager.backendDraftFolderName { + if let presFolder = presentedFolder, presFolder.path.hasPrefix(UserManager.backendDraftFolderPath) { destinationVC.isDraft = true } } @@ -186,13 +184,11 @@ class FolderViewController: UITableViewController { } func endRefreshing(_ error: Bool) { if let thisFolder = presentedFolder { - if let set = thisFolder.subfolder, let subFolders = set.allObjects as? [Folder] { - folders = subFolders.sorted() - presentedFolder = thisFolder - } + folders = thisFolder.subfolders.sorted() + presentedFolder = thisFolder } if isFirstFolderViewController { - folders = DataHandler.handler.allFolders.sorted().filter { $0.name != NSLocalizedString("INBOX", comment: "") } + folders = DataHandler.handler.allRootFolders.sorted().filter { $0.path != UserManager.backendInboxFolderPath } } tableView.reloadData() refreshControl?.endRefreshing() @@ -201,8 +197,8 @@ class FolderViewController: UITableViewController { print("newMails") } - func getImage(for name: String) -> UIImage { - if name == UserManager.frontendInboxFolderName { + func getImage(for path: String) -> UIImage { + if path == UserManager.frontendInboxFolderPath { return #imageLiteral(resourceName: "Inbox") } /* TODO: Add more in here*/ diff --git a/enzevalos_iphone/InboxViewController.swift b/enzevalos_iphone/InboxViewController.swift index a2872f2c..8cb8c569 100644 --- a/enzevalos_iphone/InboxViewController.swift +++ b/enzevalos_iphone/InboxViewController.swift @@ -91,7 +91,7 @@ class InboxViewController: UITableViewController, InboxCellDelegator { func refresh(_ refreshControl: UIRefreshControl) { lastUpdateText = NSLocalizedString("Updating", comment: "Getting new data") - AppDelegate.getAppDelegate().mailHandler.firstLookUp(newMailCallback: addNewMail, completionCallback: getMailCompleted) + AppDelegate.getAppDelegate().mailHandler.firstLookUp(UserManager.backendInboxFolderPath, newMailCallback: addNewMail, completionCallback: getMailCompleted) } @@ -123,7 +123,7 @@ class InboxViewController: UITableViewController, InboxCellDelegator { let cell = tableView.dequeueReusableCell(withIdentifier: "inboxCell", for: indexPath) as! InboxTableViewCell cell.delegate = self - cell.enzContact = DataHandler.handler.folderRecords()[indexPath.section] + cell.enzContact = DataHandler.handler.folderRecords(folderPath: UserManager.backendInboxFolderPath)[indexPath.section] @@ -131,7 +131,7 @@ class InboxViewController: UITableViewController, InboxCellDelegator { } override func numberOfSections(in tableView: UITableView) -> Int { - return DataHandler.handler.folderRecords().count + return DataHandler.handler.folderRecords(folderPath: UserManager.backendInboxFolderPath).count } // set top and bottom seperator height diff --git a/enzevalos_iphone/ListViewController.swift b/enzevalos_iphone/ListViewController.swift index 2017fc75..29de6d67 100644 --- a/enzevalos_iphone/ListViewController.swift +++ b/enzevalos_iphone/ListViewController.swift @@ -52,7 +52,7 @@ class ListViewController: UITableViewController { self.title = contact!.name if contact!.mails.count < 20 { loading = true - AppDelegate.getAppDelegate().mailHandler.loadMoreMails(contact!, newMailCallback: addNewMail, completionCallback: doneLoading) + AppDelegate.getAppDelegate().mailHandler.loadMoreMails(contact!, folderPath: UserManager.backendInboxFolderPath, newMailCallback: addNewMail, completionCallback: doneLoading) } } } @@ -211,7 +211,7 @@ class ListViewController: UITableViewController { if y > h + reload_distance && !loading { print("loading new mail because we scrolled to the bottom") loading = true - AppDelegate.getAppDelegate().mailHandler.loadMoreMails(contact!, newMailCallback: addNewMail, completionCallback: doneLoading) + AppDelegate.getAppDelegate().mailHandler.loadMoreMails(contact!, folderPath: UserManager.backendInboxFolderPath, newMailCallback: addNewMail, completionCallback: doneLoading) tableView.reloadData() } } diff --git a/enzevalos_iphone/MailHandler.swift b/enzevalos_iphone/MailHandler.swift index 1ce30ae2..a7223680 100644 --- a/enzevalos_iphone/MailHandler.swift +++ b/enzevalos_iphone/MailHandler.swift @@ -281,7 +281,7 @@ class MailHandler { } fileprivate func createSendCopy(sendData: Data) { - let sentFolder = UserManager.backendSentFolderName + let sentFolder = UserManager.backendSentFolderPath if !DataHandler.handler.existsFolder(with: sentFolder) { let op = IMAPSession.createFolderOperation(sentFolder) op?.start({ error in @@ -319,7 +319,7 @@ class MailHandler { if let encData = encryption.signAndEncrypt("\n" + message, mailaddresses: [useraddr]) { //ohne "\n" wird der erste Teil der Nachricht, bis sich ein einzelnen \n in einer Zeile befindet nicht in die Nachricht getan sendData = builder.openPGPEncryptedMessageData(withEncryptedData: encData) - let drafts = UserManager.backendDraftFolderName + let drafts = UserManager.backendDraftFolderPath if !DataHandler.handler.existsFolder(with: drafts) { let op = IMAPSession.createFolderOperation(drafts) @@ -335,7 +335,7 @@ class MailHandler { } fileprivate func saveDraft(data: Data, callback: @escaping (Error?) -> Void) { - let op = IMAPSession.appendMessageOperation(withFolder: UserManager.backendDraftFolderName, messageData: data, flags: MCOMessageFlag.draft) + let op = IMAPSession.appendMessageOperation(withFolder: UserManager.backendDraftFolderPath, messageData: data, flags: MCOMessageFlag.draft) op?.start({_,_ in callback(nil)}) } @@ -390,11 +390,8 @@ class MailHandler { } } - func firstLookUp(_ folder: String = "INBOX", newMailCallback: @escaping (() -> ()), completionCallback: @escaping ((_ error: Bool) -> ())) { - - let folderName = folder - - findMaxUID(folderName){max in + func firstLookUp(_ folderPath: String, newMailCallback: @escaping (() -> ()), completionCallback: @escaping ((_ error: Bool) -> ())) { + findMaxUID(folderPath){max in var uids: MCOIndexSet print("Max uid: \(max)") var (min, overflow) = UInt64.subtractWithOverflow(max, UInt64(MailHandler.MAXMAILS)) @@ -403,38 +400,38 @@ class MailHandler { } uids = MCOIndexSet(range: MCORangeMake(min, UInt64(MailHandler.MAXMAILS))) // DataHandler.handler.maxUID print("call for #\(uids.count()) uids \(uids.rangesCount()); min \(min); max \(max)") - uids.remove(DataHandler.handler.findFolder(name: folderName).uids) - self.loadMessagesFromServer(uids, folder: folderName, record: nil, newMailCallback: newMailCallback, completionCallback: completionCallback) + uids.remove(DataHandler.handler.findFolder(with: folderPath).uids) + self.loadMessagesFromServer(uids, folderPath: folderPath, record: nil, newMailCallback: newMailCallback, completionCallback: completionCallback) } } - func olderMailsFolder(_ folder: String = "INBOX", newMailCallback: @escaping (() -> ()), completionCallback: @escaping ((_ error: Bool) -> ())) { + func olderMails(with folderPath: String, newMailCallback: @escaping (() -> ()), completionCallback: @escaping ((_ error: Bool) -> ())) { var uids: MCOIndexSet - let myfolder = DataHandler.handler.findFolder(name: folder) + let myfolder = DataHandler.handler.findFolder(with: folderPath) if myfolder.maxID <= 1{ - return firstLookUp(newMailCallback: newMailCallback, completionCallback: completionCallback) + return firstLookUp(folderPath, newMailCallback: newMailCallback, completionCallback: completionCallback) } print("look for more mails: \(myfolder.lastID) to \(myfolder.maxID)") uids = MCOIndexSet(range: MCORangeMake(myfolder.lastID, myfolder.maxID)) uids.remove(myfolder.uids) - self.loadMessagesFromServer(uids, folder: folder, record: nil, newMailCallback: newMailCallback, completionCallback: completionCallback) + self.loadMessagesFromServer(uids, folderPath: folderPath, record: nil, newMailCallback: newMailCallback, completionCallback: completionCallback) } - func loadMoreMails(_ record: KeyRecord, folder: String = "INBOX", newMailCallback: @escaping (() -> ()), completionCallback: @escaping ((_ error: Bool) -> ())) { + func loadMoreMails(_ record: KeyRecord, folderPath: String, newMailCallback: @escaping (() -> ()), completionCallback: @escaping ((_ error: Bool) -> ())) { let addresses: [MailAddress] addresses = record.addresses for adr in addresses { let searchExpr: MCOIMAPSearchExpression = MCOIMAPSearchExpression.search(from: adr.mailAddress) - let searchOperation: MCOIMAPSearchOperation = self.IMAPSession.searchExpressionOperation(withFolder: folder, expression: searchExpr) + let searchOperation: MCOIMAPSearchOperation = self.IMAPSession.searchExpressionOperation(withFolder: folderPath, expression: searchExpr) searchOperation.start { (err, indices) -> Void in guard err == nil else { @@ -453,15 +450,15 @@ class MailHandler { } setOfIndices = self.cutIndexSet(setOfIndices) - self.loadMessagesFromServer(setOfIndices, record: record, newMailCallback: newMailCallback, completionCallback: completionCallback) + self.loadMessagesFromServer(setOfIndices, folderPath: folderPath, record: record, newMailCallback: newMailCallback, completionCallback: completionCallback) } } } } - func loadMessagesFromServer(_ uids: MCOIndexSet, folder: String = "INBOX", maxLoad: Int = MailHandler.MAXMAILS,record: KeyRecord?, newMailCallback: @escaping (() -> ()), completionCallback: @escaping ((_ error: Bool) -> ())) { + func loadMessagesFromServer(_ uids: MCOIndexSet, folderPath: String, maxLoad: Int = MailHandler.MAXMAILS,record: KeyRecord?, newMailCallback: @escaping (() -> ()), completionCallback: @escaping ((_ error: Bool) -> ())) { let requestKind = MCOIMAPMessagesRequestKind(rawValue: MCOIMAPMessagesRequestKind.headers.rawValue | MCOIMAPMessagesRequestKind.flags.rawValue) - let fetchOperation: MCOIMAPFetchMessagesOperation = self.IMAPSession.fetchMessagesOperation(withFolder: folder, requestKind: requestKind, uids: uids) + let fetchOperation: MCOIMAPFetchMessagesOperation = self.IMAPSession.fetchMessagesOperation(withFolder: folderPath, requestKind: requestKind, uids: uids) fetchOperation.extraHeaders = [AUTOCRYPTHEADER] fetchOperation.start { (err, msg, vanished) -> Void in @@ -478,8 +475,8 @@ class MailHandler { let message: MCOIMAPMessage = m as! MCOIMAPMessage dispatchGroup.enter() - let op = self.IMAPSession.fetchParsedMessageOperation(withFolder: folder, uid: message.uid) - op?.start { err, data in self.parseMail(err, parser: data, message: message, record: record, folder: folder, newMailCallback: newMailCallback) + let op = self.IMAPSession.fetchParsedMessageOperation(withFolder: folderPath, uid: message.uid) + op?.start { err, data in self.parseMail(err, parser: data, message: message, record: record, folderPath: folderPath, newMailCallback: newMailCallback) dispatchGroup.leave() } calledMails += 1 @@ -496,7 +493,7 @@ class MailHandler { } } - func parseMail(_ error: Error?, parser: MCOMessageParser?, message: MCOIMAPMessage, record: KeyRecord?, folder: String, newMailCallback: (() -> ())) { + func parseMail(_ error: Error?, parser: MCOMessageParser?, message: MCOIMAPMessage, record: KeyRecord?, folderPath: String, newMailCallback: (() -> ())) { guard error == nil else { print("Error while fetching mail: \(String(describing: error))") return @@ -586,7 +583,7 @@ class MailHandler { } if let header = header, let from = header.from, let date = header.date { - _ = DataHandler.handler.createMail(UInt64(message.uid), sender: from, receivers: rec, cc: cc, time: date, received: true, subject: header.subject ?? "", body: body, flags: message.flags, record: record, autocrypt: autocrypt, decryptedData: dec, folder: folder) //TODO @Olli: fatal error: unexpectedly found nil while unwrapping an Optional value //crash wenn kein header vorhanden ist + _ = DataHandler.handler.createMail(UInt64(message.uid), sender: from, receivers: rec, cc: cc, time: date, received: true, subject: header.subject ?? "", body: body, flags: message.flags, record: record, autocrypt: autocrypt, decryptedData: dec, folderPath: folderPath) //TODO @Olli: fatal error: unexpectedly found nil while unwrapping an Optional value //crash wenn kein header vorhanden ist newMailCallback() } } diff --git a/enzevalos_iphone/ReadViewController.swift b/enzevalos_iphone/ReadViewController.swift index 5240fdf6..a6a9b879 100644 --- a/enzevalos_iphone/ReadViewController.swift +++ b/enzevalos_iphone/ReadViewController.swift @@ -222,8 +222,8 @@ class ReadViewController: UITableViewController { @IBAction func deleteButton(_ sender: AnyObject) { if let mail = mail { - let trashFolder = UserManager.loadUserValue(Attribute.trashFolderName) as? String ?? NSLocalizedString("Trash", comment: "") - if mail.folder.name == trashFolder { + let trashFolder = UserManager.backendTrashFolderPath + if mail.folder.path == trashFolder { AppDelegate.getAppDelegate().mailHandler.addFlag(mail.uid, flags: MCOMessageFlag.deleted, folder: mail.folder.path) } else { AppDelegate.getAppDelegate().mailHandler.move(mails: [mail], from: mail.folder.path, to: trashFolder) @@ -234,7 +234,7 @@ class ReadViewController: UITableViewController { @IBAction func archiveButton(_ sender: AnyObject) { if let mail = mail { - let archiveFolder = UserManager.loadUserValue(Attribute.archiveFolderName) as? String ?? NSLocalizedString("Archive", comment: "") + let archiveFolder = UserManager.backendArchiveFolderPath AppDelegate.getAppDelegate().mailHandler.move(mails: [mail], from: mail.folder.path, to: archiveFolder) } _ = navigationController?.popViewController(animated: true) diff --git a/enzevalos_iphone/UserData.swift b/enzevalos_iphone/UserData.swift index fc91c50d..a85ba240 100644 --- a/enzevalos_iphone/UserData.swift +++ b/enzevalos_iphone/UserData.swift @@ -11,7 +11,7 @@ import Foundation enum Attribute: Int{ - case accountname, userName, userAddr, userPW, smtpHostname, smtpPort, imapHostname, imapPort, prefEncryption, publicKey, autocryptType, imapConnectionType, imapAuthType, smtpConnectionType, smtpAuthType, sentFolderName, draftFolderName, trashFolderName, inboxFolderName, archiveFolderName + case accountname, userName, userAddr, userPW, smtpHostname, smtpPort, imapHostname, imapPort, prefEncryption, publicKey, autocryptType, imapConnectionType, imapAuthType, smtpConnectionType, smtpAuthType, sentFolderPath, draftFolderPath, trashFolderPath, inboxFolderPath, archiveFolderPath var defaultValue:AnyObject? { switch self { @@ -42,15 +42,15 @@ enum Attribute: Int{ case .smtpConnectionType: return MCOConnectionType.TLS.rawValue as AnyObject?//startTLS.rawValue //return MCOConnectionType.startTLS.rawValue as AnyObject?//startTLS.rawValue - case .sentFolderName: + case .sentFolderPath: return NSLocalizedString("Sent", comment: "Default name for the sentFolder") as AnyObject? - case .draftFolderName: + case .draftFolderPath: return NSLocalizedString("Drafts", comment: "Default name for the draftFolder") as AnyObject? - case .trashFolderName: + case .trashFolderPath: return NSLocalizedString("Trash", comment: "Default name for the trashFolder") as AnyObject? - case .inboxFolderName: + case .inboxFolderPath: return NSLocalizedString("INBOX", comment: "Default name for the inboxFolder") as AnyObject? - case .archiveFolderName: + case .archiveFolderPath: return NSLocalizedString("Archive", comment: "Default name for the archiveFolder") as AnyObject? case .smtpAuthType: @@ -85,72 +85,75 @@ struct UserManager{ //Frontend (GUI and providers.json) uses UTF-8 String-Encoding //The backend uses because of the definition of IMAP UTF-7 String-Encoding - static var frontendDraftFolderName: String { + static var frontendDraftFolderPath: String { get { - return loadUserValue(Attribute.draftFolderName) as? String ?? NSLocalizedString("Drafts", comment: "") + return loadUserValue(Attribute.draftFolderPath) as? String ?? NSLocalizedString("Drafts", comment: "") } } - static var frontendInboxFolderName: String { + static var frontendInboxFolderPath: String { get { - return loadUserValue(Attribute.inboxFolderName) as? String ?? NSLocalizedString("INBOX", comment: "") + return loadUserValue(Attribute.inboxFolderPath) as? String ?? NSLocalizedString("INBOX", comment: "") } } - static var frontendSentFolderName: String { + static var frontendSentFolderPath: String { get { - return loadUserValue(Attribute.sentFolderName) as? String ?? NSLocalizedString("Sent", comment: "") + return loadUserValue(Attribute.sentFolderPath) as? String ?? NSLocalizedString("Sent", comment: "") } } - static var frontendArchiveFolderName: String { + static var frontendArchiveFolderPath + : String { get { - return loadUserValue(Attribute.archiveFolderName) as? String ?? NSLocalizedString("Archive", comment: "") + return loadUserValue(Attribute.archiveFolderPath) as? String ?? NSLocalizedString("Archive", comment: "") } } - static var frontendTrashFolderName: String { + static var frontendTrashFolderPath: String { get { - return loadUserValue(Attribute.trashFolderName) as? String ?? NSLocalizedString("Trash", comment: "") + return loadUserValue(Attribute.trashFolderPath) as? String ?? NSLocalizedString("Trash", comment: "") } } - static var backendDraftFolderName: String { + static var backendDraftFolderPath: String { get { - return convertToBackendFoldername(from: frontendDraftFolderName) + return convertToBackendFolderPath(from: frontendDraftFolderPath) } } - static var backendSentFolderName: String { + static var backendSentFolderPath: String { get { - return convertToBackendFoldername(from: frontendSentFolderName) + return convertToBackendFolderPath(from: frontendSentFolderPath) } } - static var backendArchiveFolderName: String { + static var backendArchiveFolderPath: String { get { - return convertToBackendFoldername(from: frontendArchiveFolderName) + return convertToBackendFolderPath(from: frontendArchiveFolderPath) } } - static var backendTrashFolderName: String { + static var backendTrashFolderPath: String { get { - return convertToBackendFoldername(from: frontendTrashFolderName) + return convertToBackendFolderPath(from: frontendTrashFolderPath) } } - static var backendInboxFolderName: String { + static var backendInboxFolderPath: String { get { - return convertToBackendFoldername(from: frontendInboxFolderName) + return convertToBackendFolderPath(from: frontendInboxFolderPath) } } - static func convertToFrontendFoldername(from backendFolderName: String) -> String{ - return (AppDelegate.getAppDelegate().mailHandler.IMAPSession.defaultNamespace.components(fromPath: backendFolderName) as! [String])[0] + //Usable for paths too + static func convertToFrontendFolderPath(from backendFolderPath: String, with delimiter: String = ".") -> String{ + return (AppDelegate.getAppDelegate().mailHandler.IMAPSession.defaultNamespace.components(fromPath: backendFolderPath) as! [String]).joined(separator: delimiter) } - static func convertToBackendFoldername(from frontendFolderName: String) -> String { - return AppDelegate.getAppDelegate().mailHandler.IMAPSession.defaultNamespace.path(forComponents: [frontendFolderName]) + //Usable for paths too + static func convertToBackendFolderPath(from frontendFolderPath: String) -> String { + return AppDelegate.getAppDelegate().mailHandler.IMAPSession.defaultNamespace.path(forComponents: [frontendFolderPath]) } static func storeUserValue(_ value: AnyObject?, attribute: Attribute) { diff --git a/enzevalos_iphone/enzevalos_iphone.xcdatamodeld/enzevalos_iphone.xcdatamodel/contents b/enzevalos_iphone/enzevalos_iphone.xcdatamodeld/enzevalos_iphone.xcdatamodel/contents index 4ca13000..180e78bb 100644 --- a/enzevalos_iphone/enzevalos_iphone.xcdatamodeld/enzevalos_iphone.xcdatamodel/contents +++ b/enzevalos_iphone/enzevalos_iphone.xcdatamodeld/enzevalos_iphone.xcdatamodel/contents @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" standalone="yes"?> -<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="12141" systemVersion="16F73" minimumToolsVersion="Automatic" sourceLanguage="Swift" userDefinedModelVersionIdentifier=""> +<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="12141" systemVersion="16G29" minimumToolsVersion="Automatic" sourceLanguage="Swift" userDefinedModelVersionIdentifier=""> <entity name="Account" representedClassName="Account" syncable="YES" codeGenerationType="class"> <attribute name="accountname" attributeType="String" syncable="YES"/> <attribute name="dispalyname" attributeType="String" syncable="YES"/> @@ -20,8 +20,7 @@ <attribute name="maxID" optional="YES" attributeType="Decimal" defaultValueString="1" syncable="YES"/> <attribute name="path" attributeType="String" syncable="YES"/> <relationship name="mails" optional="YES" toMany="YES" deletionRule="Nullify" destinationEntity="PersistentMail" inverseName="folder" inverseEntity="PersistentMail" syncable="YES"/> - <relationship name="parent" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="Folder" inverseName="subfolder" inverseEntity="Folder" syncable="YES"/> - <relationship name="subfolder" optional="YES" toMany="YES" deletionRule="Nullify" destinationEntity="Folder" inverseName="parent" inverseEntity="Folder" syncable="YES"/> + <relationship name="parent" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="Folder" syncable="YES"/> </entity> <entity name="Mail_Address" representedClassName="Mail_Address" syncable="YES"> <attribute name="address" attributeType="String" defaultValueString="""" syncable="YES"/> @@ -70,7 +69,7 @@ <elements> <element name="Account" positionX="-288" positionY="-9" width="128" height="135"/> <element name="EnzevalosContact" positionX="-209" positionY="198" width="128" height="90"/> - <element name="Folder" positionX="-297" positionY="-18" width="128" height="165"/> + <element name="Folder" positionX="-297" positionY="-18" width="128" height="150"/> <element name="Mail_Address" positionX="-297" positionY="-18" width="128" height="195"/> <element name="PersistentMail" positionX="-416" positionY="-189" width="128" height="315"/> <element name="Server" positionX="-279" positionY="0" width="128" height="105"/> -- GitLab