Skip to content
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -309,7 +309,7 @@ private final class ComposerTextView: UITextView {
}

group.notify(queue: .main) { [weak self] in
guard let self, !self.isReadOnly else {
guard let self, self.isEditable, !self.isReadOnly else {
return
}
let urls = images.compactMap { $0 }.compactMap(Self.writeTemporaryImage)
Expand Down Expand Up @@ -437,7 +437,7 @@ private final class ComposerTextView: UITextView {
}
}

public final class T3ComposerEditorView: ExpoView, UITextViewDelegate, UITextDropDelegate, UIGestureRecognizerDelegate {
public final class T3ComposerEditorView: ExpoView, UITextViewDelegate, UITextDropDelegate, UIDropInteractionDelegate, UIGestureRecognizerDelegate {
private let textView = ComposerTextView()
private let placeholderLabel = UILabel()
private var value = ""
Expand Down Expand Up @@ -488,6 +488,7 @@ public final class T3ComposerEditorView: ExpoView, UITextViewDelegate, UITextDro
clipsToBounds = false
textView.delegate = self
textView.textDropDelegate = self
textView.addInteraction(UIDropInteraction(delegate: self))
textView.backgroundColor = .clear
textView.textContainerInset = .zero
textView.textContainer.lineFragmentPadding = 0
Expand Down Expand Up @@ -797,7 +798,7 @@ public final class T3ComposerEditorView: ExpoView, UITextViewDelegate, UITextDro
guard !isReadOnly else {
return UITextDropProposal(operation: .cancel)
}
guard droppedImageProviders(in: drop) != nil else {
guard droppedImageProviders(in: drop.dropSession) != nil else {
return drop.suggestedProposal
}

Expand All @@ -816,14 +817,36 @@ public final class T3ComposerEditorView: ExpoView, UITextViewDelegate, UITextDro
guard !isReadOnly else {
return
}
guard let imageProviders = droppedImageProviders(in: drop) else {
guard let imageProviders = droppedImageProviders(in: drop.dropSession) else {
return
}
textView.loadImages(from: imageProviders)
}

private func droppedImageProviders(in drop: UITextDropRequest) -> [NSItemProvider]? {
let providers = drop.dropSession.items.map(\.itemProvider)
// Support image drops that do not reach UITextDropDelegate.
public func dropInteraction(_ interaction: UIDropInteraction, canHandle session: UIDropSession) -> Bool {
textView.isEditable && !isReadOnly && droppedImageProviders(in: session) != nil
}

public func dropInteraction(
_ interaction: UIDropInteraction,
sessionDidUpdate session: UIDropSession
) -> UIDropProposal {
guard textView.isEditable, !isReadOnly, droppedImageProviders(in: session) != nil else {
return UIDropProposal(operation: .cancel)
}
return UIDropProposal(operation: .copy)
}

public func dropInteraction(_ interaction: UIDropInteraction, performDrop session: UIDropSession) {
guard textView.isEditable, !isReadOnly, let imageProviders = droppedImageProviders(in: session) else {
return
}
textView.loadImages(from: imageProviders)
}

private func droppedImageProviders(in session: UIDropSession) -> [NSItemProvider]? {
let providers = session.items.map(\.itemProvider)
guard !providers.isEmpty,
providers.allSatisfy({ $0.canLoadObject(ofClass: UIImage.self) }) else {
return nil
Expand Down
Loading