From 59277ec64f85a584dc46da5ca566331f7a51ddff Mon Sep 17 00:00:00 2001 From: Shadowfacts Date: Mon, 20 Jan 2020 15:26:25 -0500 Subject: [PATCH] Change drafts to store which accounts was used to create them When loading a draft: If the draft was created from a different account than the current one: If the draft was in reply to a status, don't allow it to be loaded. If the draft was not in reply to a status, prompt the user whether or not to load the draft. If the draft was in reply to a different status than the current one: Prompt the user whether or not to load the draft. Otherwise, load the draft. Draft replies created from other accounts can't be loaded from different accounts because the status for inReplyToID of the draft will have a different instance-local ID if the two accounts are on different instances. See #16 --- Tusker/DraftsManager.swift | 11 +++-- Tusker/LocalData.swift | 4 ++ .../Compose/ComposeViewController.swift | 47 +++++++++++++++++-- 3 files changed, 54 insertions(+), 8 deletions(-) diff --git a/Tusker/DraftsManager.swift b/Tusker/DraftsManager.swift index 23e9a5ebb5..39d182cabe 100644 --- a/Tusker/DraftsManager.swift +++ b/Tusker/DraftsManager.swift @@ -39,8 +39,8 @@ class DraftsManager: Codable { return drafts.sorted(by: { $0.lastModified > $1.lastModified }) } - func create(text: String, contentWarning: String?, inReplyToID: String?, attachments: [DraftAttachment]) -> Draft { - let draft = Draft(text: text, contentWarning: contentWarning, inReplyToID: inReplyToID, attachments: attachments) + func create(accountID: String, text: String, contentWarning: String?, inReplyToID: String?, attachments: [DraftAttachment]) -> Draft { + let draft = Draft(accountID: accountID, text: text, contentWarning: contentWarning, inReplyToID: inReplyToID, attachments: attachments) drafts.append(draft) return draft } @@ -55,14 +55,16 @@ class DraftsManager: Codable { extension DraftsManager { class Draft: Codable, Equatable { let id: UUID + private(set) var accountID: String private(set) var text: String private(set) var contentWarning: String? private(set) var attachments: [DraftAttachment] private(set) var inReplyToID: String? private(set) var lastModified: Date - init(text: String, contentWarning: String?, inReplyToID: String?, attachments: [DraftAttachment], lastModified: Date = Date()) { + init(accountID: String, text: String, contentWarning: String?, inReplyToID: String?, attachments: [DraftAttachment], lastModified: Date = Date()) { self.id = UUID() + self.accountID = accountID self.text = text self.contentWarning = contentWarning self.inReplyToID = inReplyToID @@ -70,7 +72,8 @@ extension DraftsManager { self.lastModified = lastModified } - func update(text: String, contentWarning: String?, attachments: [DraftAttachment]) { + func update(accountID: String, text: String, contentWarning: String?, attachments: [DraftAttachment]) { + self.accountID = accountID self.text = text self.contentWarning = contentWarning self.lastModified = Date() diff --git a/Tusker/LocalData.swift b/Tusker/LocalData.swift index 7aafa46144..f1fbfbd386 100644 --- a/Tusker/LocalData.swift +++ b/Tusker/LocalData.swift @@ -101,6 +101,10 @@ class LocalData: ObservableObject { accounts.removeAll(where: { $0.id == info.id }) } + func getAccount(id: String) -> UserAccountInfo? { + return accounts.first(where: { $0.id == id }) + } + func getMostRecentAccount() -> UserAccountInfo? { guard onboardingComplete else { return nil } let mostRecent: UserAccountInfo? diff --git a/Tusker/Screens/Compose/ComposeViewController.swift b/Tusker/Screens/Compose/ComposeViewController.swift index 7efb15cc2e..5e96dc2206 100644 --- a/Tusker/Screens/Compose/ComposeViewController.swift +++ b/Tusker/Screens/Compose/ComposeViewController.swift @@ -368,10 +368,11 @@ class ComposeViewController: UIViewController { attachments.append(.init(attachment: attachment, description: description)) } let cw = contentWarningEnabled ? contentWarningTextField.text : nil + let account = mastodonController.accountInfo! if let currentDraft = self.currentDraft { - currentDraft.update(text: self.statusTextView.text, contentWarning: cw, attachments: attachments) + currentDraft.update(accountID: account.id, text: self.statusTextView.text, contentWarning: cw, attachments: attachments) } else { - self.currentDraft = DraftsManager.shared.create(text: self.statusTextView.text, contentWarning: cw, inReplyToID: inReplyToID, attachments: attachments) + self.currentDraft = DraftsManager.shared.create(accountID: account.id, text: self.statusTextView.text, contentWarning: cw, inReplyToID: inReplyToID, attachments: attachments) } DraftsManager.save() } @@ -622,8 +623,46 @@ extension ComposeViewController: DraftsTableViewControllerDelegate { } func shouldSelectDraft(_ draft: DraftsManager.Draft, completion: @escaping (Bool) -> Void) { - if draft.inReplyToID != self.inReplyToID { - // todo: better text for this + if draft.accountID != mastodonController.accountInfo!.id { + let currentAccount = mastodonController.accountInfo! + let currentAcct = "\(currentAccount.username)@\(currentAccount.instanceURL.host!)" + let otherAccount = LocalData.shared.getAccount(id: draft.accountID) + let otherAcct: String! + if let otherAccount = otherAccount { + otherAcct = "\(otherAccount.username)@\(otherAccount.instanceURL.host!)" + } else { + otherAcct = nil + } + + if draft.inReplyToID != nil { + let message: String + if otherAccount != nil { + message = "The selected draft is a reply from a different account, it cannot be loaded from this account. To use it, switch accounts to \(otherAcct!)" + } else { + message = "The selected draft is a reply from an account that has been logged-out of. It cannot be loaded." + } + let alertController = UIAlertController(title: "Reply from Different Account", message: message, preferredStyle: .alert) + alertController.addAction(UIAlertAction(title: "OK", style: .default, handler: { (_) in + completion(false) + })) + presentedViewController!.present(alertController, animated: true) + } else { + let message: String + if otherAccount != nil { + message = "The selected draft is from a different account (\(otherAcct!)) than your currently active account (\(currentAcct)). Do you wish to load it anyway?" + } else { + message = "The selected draft from an account that has been logged-out of." + } + let alertController = UIAlertController(title: "Draft from Different Account", message: message, preferredStyle: .alert) + alertController.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: { (_) in + completion(false) + })) + alertController.addAction(UIAlertAction(title: "Load Draft", style: .default, handler: { (_) in + completion(true) + })) + presentedViewController!.present(alertController, animated: true) + } + } else if draft.inReplyToID != self.inReplyToID { let alertController = UIAlertController(title: "Different Reply", message: "The selected draft is a reply to a different status, do you wish to use it?", preferredStyle: .alert) alertController.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: { (_) in completion(false)