Fix various issues when dealing with multiple Compose/Drafts screens simultaneously

This commit is contained in:
Shadowfacts 2023-05-15 22:57:07 -04:00
parent f004c82302
commit d84d402271
6 changed files with 33 additions and 16 deletions

View File

@ -10,6 +10,7 @@ import Combine
import Pachyderm
import TuskerComponents
import MatchedGeometryPresentation
import CoreData
public final class ComposeController: ViewController {
public typealias FetchAttachment = (URL) async -> UIImage?
@ -54,6 +55,9 @@ public final class ComposeController: ViewController {
@Published public private(set) var didPostSuccessfully = false
@Published var hasChangedLanguageSelection = false
private var isDisappearing = false
private var userConfirmedDelete = false
var isPosting: Bool {
poster != nil
}
@ -119,6 +123,7 @@ public final class ComposeController: ViewController {
if #available(iOS 16.0, *) {
NotificationCenter.default.addObserver(self, selector: #selector(currentInputModeChanged), name: UITextInputMode.currentInputModeDidChangeNotification, object: nil)
}
NotificationCenter.default.addObserver(self, selector: #selector(managedObjectsDidChange), name: .NSManagedObjectContextObjectsDidChange, object: DraftsPersistentContainer.shared.viewContext)
}
public var view: some View {
@ -129,6 +134,15 @@ public final class ComposeController: ViewController {
.environment(\.composeUIConfig, config)
}
@MainActor
@objc private func managedObjectsDidChange(_ notification: Foundation.Notification) {
if let deleted = notification.userInfo?[NSDeletedObjectsKey] as? Set<NSManagedObject>,
deleted.contains(where: { $0.objectID == self.draft.objectID }),
!isDisappearing {
self.config.dismiss(.cancel)
}
}
public func canPaste(itemProviders: [NSItemProvider]) -> Bool {
guard itemProviders.allSatisfy({ $0.canLoadObject(ofClass: DraftAttachment.self) }) else {
return false
@ -172,6 +186,7 @@ public final class ComposeController: ViewController {
@MainActor
func cancel(deleteDraft: Bool) {
deleteDraftOnDisappear = true
userConfirmedDelete = true
config.dismiss(.cancel)
}
@ -216,16 +231,18 @@ public final class ComposeController: ViewController {
}
func selectDraft(_ newDraft: Draft) {
if !self.draft.hasContent {
DraftsPersistentContainer.shared.viewContext.delete(self.draft)
let oldDraft = self.draft
self.draft = newDraft
if !oldDraft.hasContent {
DraftsPersistentContainer.shared.viewContext.delete(oldDraft)
}
DraftsPersistentContainer.shared.save()
self.draft = newDraft
}
func onDisappear() {
if deleteDraftOnDisappear && (!draft.hasContent || didPostSuccessfully) {
isDisappearing = true
if deleteDraftOnDisappear && (!draft.hasContent || didPostSuccessfully || userConfirmedDelete) {
DraftsPersistentContainer.shared.viewContext.delete(draft)
}
DraftsPersistentContainer.shared.save()

View File

@ -7,6 +7,7 @@
import SwiftUI
import TuskerComponents
import CoreData
class DraftsController: ViewController {
@ -152,12 +153,14 @@ private struct DraftRow: View {
Spacer()
Text(draft.lastModified.formatted(.abbreviatedTimeAgo))
if let lastModified = draft.lastModified {
Text(lastModified.formatted(.abbreviatedTimeAgo))
.font(.body)
.foregroundColor(.secondary)
}
}
}
}
private extension View {
@ViewBuilder

View File

@ -108,7 +108,7 @@ private struct DismissFocusedAttachmentButtonStyle: ButtonStyle {
}
struct AttachmentDescriptionTextViewID: Hashable {
let attachmentID: UUID
let attachmentID: UUID!
init(_ attachment: DraftAttachment) {
self.attachmentID = attachment.id

View File

@ -28,7 +28,7 @@ public class Draft: NSManagedObject, Identifiable {
@NSManaged public var initialText: String
@NSManaged public var inReplyToID: String?
@NSManaged public var language: String? // ISO 639 language code
@NSManaged public var lastModified: Date
@NSManaged public var lastModified: Date!
@NSManaged public var localOnly: Bool
@NSManaged public var text: String
@NSManaged private var visibilityStr: String

View File

@ -26,7 +26,7 @@ public final class DraftAttachment: NSManagedObject, Identifiable {
@NSManaged public var editedAttachmentURL: URL?
@NSManaged public var fileURL: URL?
@NSManaged internal var fileType: String?
@NSManaged public var id: UUID
@NSManaged public var id: UUID!
@NSManaged internal var draft: Draft

View File

@ -18,10 +18,6 @@ struct PollOptionView: View {
self.remove = remove
}
private var optionIndex: Int {
poll.options.index(of: option)
}
var body: some View {
HStack(spacing: 4) {
Checkbox(radiusFraction: poll.multiple ? 0.1 : 0.5, background: controller.parent.config.backgroundColor)
@ -41,7 +37,8 @@ struct PollOptionView: View {
}
private var textField: some View {
let placeholder = "Option \(optionIndex + 1)"
let index = poll.options.index(of: option)
let placeholder = index != NSNotFound ? "Option \(index + 1)" : ""
let maxLength = controller.parent.mastodonController.instanceFeatures.maxPollOptionChars
return EmojiTextField(text: $option.text, placeholder: placeholder, maxLength: maxLength)
}