From 78c3862978ef0d6e9bbfe8383618a28c4a4f529f Mon Sep 17 00:00:00 2001 From: Oliver Wiese <oliver.wiese@fu-berlin.de> Date: Sat, 10 Apr 2021 11:48:17 +0200 Subject: [PATCH] fix bug: delete/read flag --- enzevalos_iphone/MailHandler.swift | 90 ++----------------- enzevalos_iphone/OutgoingMail.swift | 2 +- .../SwiftUI/Inbox/MailListView.swift | 3 +- .../SwiftUI/Read/ReadMainView.swift | 5 +- enzevalos_iphone/SwiftUI/Read/ReadModel.swift | 31 ++++--- .../Read/Tabbed Views/MessageViewMain.swift | 8 +- .../persistentData/MailRecord.swift | 37 ++++++-- .../PersistentDataProvider.swift | 21 +---- 8 files changed, 67 insertions(+), 130 deletions(-) diff --git a/enzevalos_iphone/MailHandler.swift b/enzevalos_iphone/MailHandler.swift index 06e01d27..f7d8dfc2 100644 --- a/enzevalos_iphone/MailHandler.swift +++ b/enzevalos_iphone/MailHandler.swift @@ -519,105 +519,25 @@ } func move(mails: [UInt64], fromPath: String, toPath: String) { - // 1. Check IMAP session - guard let session = IMAPSession else { - return - } - // 2. Check if we have to create a folder. + // 1. Check if we have to create a folder. createFolders(of: [fromPath, toPath], completionHandler: {error in guard error == nil else { return } - // 3. Move mail on server + // 2. Move mail on server guard let fromFolder = self.dataProvider.generateFetchedFolderResultsController(folderpath: fromPath, moc: nil).fetchedObjects?.first else { return } if let uidValidity = fromFolder.uidValidity as? UInt32 { self.moveOnServer(uidValidity: uidValidity, mails: mails, fromPath: fromPath, toPath: toPath, completionHandler: {error in - print("Move mails from \(fromFolder) to \(toPath) complete with error \(String(describing: error))")}) - // 4. Move mail in core data + // 3. Move mail in core data self.dataProvider.moveMails(with: mails, from: fromPath, to: toPath) + }) + } }) } - /* TODO - func move(mails: [MailRecord], from: String, to: String, folderCreated: Bool = false) { - guard IMAPSession != nil else { - return - } - let uids = MCOIndexSet() - let provider = PersistentDataProvider.dataProvider - guard let toFolders = provider.generateFetchedFolderResultsController(folderpath: to).fetchedObjects else { - return - } - guard let fromFolder = provider.generateFetchedFolderResultsController(folderpath: from).fetchedObjects?.first else { - return - } - // Create a folder -> Do we have to check if the folder exists on the server? - guard toFolders.isEmpty && !folderCreated else { - let op = IMAPSession?.createFolderOperation(to) - op?.start({[unowned self] error in - guard error == nil else { - let conError = MailServerConnectionError.findErrorCode(error: error!) - self.errorhandling(error: conError, originalCall: {self.move(mails: mails, from: from, to: to)}, completionCallback: nil) - return - } - self.move(mails: mails, from: from, to: to, folderCreated: true) - }) - return - } - let folderstatusFrom = IMAPSession?.folderStatusOperation(from) - folderstatusFrom?.start {[unowned self] (error, status) -> Void in - guard error == nil else { - let conerror = MailServerConnectionError.findErrorCode(error: error!) - self.errorhandling(error: conerror, originalCall: {self.move(mails: mails, from: from, to: to)}, completionCallback: nil) - return - } - if let statusFrom = status, let currentUidValidity = fromFolder.uidValidity as? UInt32 { - let uidValidity = statusFrom.uidValidity - var uids = MCOIndexSet() - if uidValidity == currentUidValidity { - for mail in mails { - uids.add(mail.uID) - mail.folder.removeFromMails(mail) - if let record = mail.record { - record.removeFromPersistentMails(mail) - if record.mailsInFolder(folder: f).count == 0 { - f.removeFromKeyRecords(record) - } - } - DataHandler.handler.delete(mail: mail) - } - let op = self.IMAPSession?.moveMessagesOperation(withFolder: from, uids: uids, destFolder: to) - op?.start {[unowned self] - (err, vanished) -> Void in - guard err == nil else { - let conerror = MailServerConnectionError.findErrorCode(error: err!) - self.errorhandling(error: conerror, originalCall: {self.move(mails: mails, from: from, to: to)}, completionCallback: { err in - guard err != nil else { - return - } - let op = self.IMAPSession?.copyMessagesOperation(withFolder: from, uids: uids, destFolder: to) - op?.start({[unowned self] error, _ in - guard error == nil else { - return - } - uids.enumerate({uid in - self.setFlag(uid, flags: MCOMessageFlag.deleted, folder: from) - }) - }) - }) - return - } - } - } else { - f.uidvalidity = uidValidity - } - } - } - } - */ func allFolders(_ completion: @escaping (Error?) -> Void) { guard IMAPSession != nil else { diff --git a/enzevalos_iphone/OutgoingMail.swift b/enzevalos_iphone/OutgoingMail.swift index 2e375ff1..56dc93e3 100644 --- a/enzevalos_iphone/OutgoingMail.swift +++ b/enzevalos_iphone/OutgoingMail.swift @@ -190,7 +190,7 @@ class OutgoingMail { func send(informUser: Bool = false) { self.informUser = informUser if let mail = mail { - LetterboxModel.instance.dataProvider.deleteMail(mail: mail) + mail.delete() } LetterboxModel.instance.mailHandler.sendSMTP(mail: self, callback: { error in if error != nil { diff --git a/enzevalos_iphone/SwiftUI/Inbox/MailListView.swift b/enzevalos_iphone/SwiftUI/Inbox/MailListView.swift index 577caca4..18c7d5cd 100644 --- a/enzevalos_iphone/SwiftUI/Inbox/MailListView.swift +++ b/enzevalos_iphone/SwiftUI/Inbox/MailListView.swift @@ -54,11 +54,10 @@ struct MailListView: View { private func deleteMails(at offsets: IndexSet) { var ids = [UInt64]() for index in offsets { - //PersistentDataProvider.dataProvider.delete(object: mails[index]) let mail = mails[index] ids.append(UInt64(mail.uID)) } - MailHandler.init().move(mails: ids, fromPath: folderPath, toPath: UserManager.backendTrashFolderPath) + MailRecord.delete(with: ids, folderPath: folderPath) } func filterKeyRecord(keyRecord: MailRecord) -> Bool { diff --git a/enzevalos_iphone/SwiftUI/Read/ReadMainView.swift b/enzevalos_iphone/SwiftUI/Read/ReadMainView.swift index 27d7620e..24d47ee2 100644 --- a/enzevalos_iphone/SwiftUI/Read/ReadMainView.swift +++ b/enzevalos_iphone/SwiftUI/Read/ReadMainView.swift @@ -18,7 +18,7 @@ import SwiftUI struct ReadMainView <M: DisplayMail>: View { - @ObservedObject var model: ReadModel<M> + @StateObject var model: ReadModel<M> var body: some View { TabView(selection: $model.currentTab) { @@ -32,6 +32,9 @@ struct ReadMainView <M: DisplayMail>: View { } } .navigationBarTitle(subject) + .onDisappear(perform: { + model.onDisappear() + }) } var subject: Text { diff --git a/enzevalos_iphone/SwiftUI/Read/ReadModel.swift b/enzevalos_iphone/SwiftUI/Read/ReadModel.swift index 8b78a307..41724da7 100644 --- a/enzevalos_iphone/SwiftUI/Read/ReadModel.swift +++ b/enzevalos_iphone/SwiftUI/Read/ReadModel.swift @@ -35,17 +35,35 @@ enum ReadPart { class ReadModel <M: DisplayMail>: ObservableObject { - @Published var dismissView = false @Published var currentTab = ReadPart.Security.value - private var userAction: UserAction? var mail: M init(mail: M) { self.mail = mail - mail.markAsRead(isRead: true) + } + + func onDisappear() { + if let action = userAction { + switch action { + case .Delete: + if let mail = mail as? MailRecord { + mail.delete() + } + case .Archive: + if let mail = mail as? MailRecord { + mail.archive() + } + case .Unread: + mail.markAsRead(isRead: false) + default: + mail.markAsRead(isRead: true) + } + } else { + mail.markAsRead(isRead: true) + } } func newUserAction(action: UserAction) -> PreMailData? { @@ -55,9 +73,6 @@ class ReadModel <M: DisplayMail>: ObservableObject { // TODO return nil case .Delete: - if let mail = mail as? MailRecord { - PersistentDataProvider.dataProvider.deleteMail(mail: mail) - } dismissView = true return nil case .Move: @@ -70,13 +85,9 @@ class ReadModel <M: DisplayMail>: ObservableObject { case .Forward: return PreMailData(body: mail.preparePreviousMailBody(), subject: ResponseType.Reply.addPrefix(subject: mail.subject), to: [], cc: [], bcc: []) case .Archive: - if let mail = mail as? MailRecord { - PersistentDataProvider.dataProvider.archiveMail(mail: mail) - } dismissView = true return nil case .Unread: - mail.markAsRead(isRead: !mail.isRead) dismissView = true return nil } diff --git a/enzevalos_iphone/SwiftUI/Read/Tabbed Views/MessageViewMain.swift b/enzevalos_iphone/SwiftUI/Read/Tabbed Views/MessageViewMain.swift index ba80bae9..b0d34670 100644 --- a/enzevalos_iphone/SwiftUI/Read/Tabbed Views/MessageViewMain.swift +++ b/enzevalos_iphone/SwiftUI/Read/Tabbed Views/MessageViewMain.swift @@ -26,9 +26,13 @@ struct MessageViewMain <M: DisplayMail>: View { self.showExtraButtons = false } FloatingReplyButtons - }.onAppear(perform: {self.model.mail.markAsRead(isRead: true)}) + } .sheet(item: $newMail, content: {mail in ComposeView(preData: mail)}) - + .onChange(of: model.dismissView, perform: { value in + if value { + presentationMode.wrappedValue.dismiss() + } + }) } var Subjectbar: some View{ diff --git a/enzevalos_iphone/persistentData/MailRecord.swift b/enzevalos_iphone/persistentData/MailRecord.swift index 7abc53e8..fcca5026 100644 --- a/enzevalos_iphone/persistentData/MailRecord.swift +++ b/enzevalos_iphone/persistentData/MailRecord.swift @@ -140,7 +140,12 @@ extension MailRecord: DisplayMail { set { var mcoflag = MCOMessageFlag.init(rawValue: Int(flag)) - mcoflag = mcoflag.update(with: .seen) ?? mcoflag + if newValue { + mcoflag = mcoflag.update(with: .seen) ?? mcoflag + } else { + mcoflag.subtract(.seen) + } + self.flag = Int16(mcoflag.rawValue) if let moc = self.managedObjectContext { @@ -210,14 +215,7 @@ extension MailRecord: DisplayMail { } func markAsRead(isRead: Bool) { - - // TODO: FIX! Faults the current objects... -// if let context = self.managedObjectContext { -// var newFlag = self.messageFlag -// newFlag.insert(.seen) -// flag = Int16(newFlag.rawValue) -// try? PersistentDataProvider.dataProvider.save(taskContext: context) // <- later? -// } + self.isRead = isRead return } @@ -256,4 +254,25 @@ extension MailRecord { return request } } +/// Functions to manipulate mails +extension MailRecord { + + static func delete(with ids: [UInt64], folderPath: String) { + MailHandler.init().move(mails: ids, fromPath: folderPath, toPath: UserManager.backendTrashFolderPath) + } + + func archive() { + guard let folder = self.inFolder?.path else { + return + } + MailHandler.init().move(mails: [UInt64(self.uID)], fromPath: folder, toPath: UserManager.backendArchiveFolderPath) + } + + func delete() { + guard let folder = self.inFolder?.path else { + return + } + MailHandler.init().move(mails: [UInt64(self.uID)], fromPath: folder, toPath: UserManager.backendTrashFolderPath) + } +} diff --git a/enzevalos_iphone/persistentData/PersistentDataProvider.swift b/enzevalos_iphone/persistentData/PersistentDataProvider.swift index 9cfdc3ce..ca757f27 100644 --- a/enzevalos_iphone/persistentData/PersistentDataProvider.swift +++ b/enzevalos_iphone/persistentData/PersistentDataProvider.swift @@ -475,26 +475,7 @@ class PersistentDataProvider { completionHandler(nil) } } - - func deleteMail(mail: MailRecord) { - guard let folder = mail.inFolder?.path else { - let taskContext = newTaskContext() - taskContext.perform { - taskContext.delete(mail) - try? self.save(taskContext: taskContext) - } - return - } - moveMails(with: [UInt64(mail.uID)], from: folder, to: UserManager.backendTrashFolderPath) - } - - func archiveMail(mail: MailRecord) { - guard let folder = mail.inFolder?.path else { - return - } - moveMails(with: [UInt64(mail.uID)], from: folder, to: UserManager.backendArchiveFolderPath) - } - + func moveMails(with uids: [UInt64], from: String, to: String) { guard let rfc = try? lookUp(entityName: MailRecord.entityName, sorting: ["uID": true], equalPredicates: ["inFolder.path": from], differentPredicates: nil, inPredicates: ["uID": uids.map({"\($0)"})]) else { return -- GitLab