Bluesky app fork with some witchin' additions 💫
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

at main 136 lines 5.1 kB view raw
1diff --git a/node_modules/expo-paste-input/ios/ExpoPasteInputView.swift b/node_modules/expo-paste-input/ios/ExpoPasteInputView.swift 2index 2164aec4ec1d..d216db6d2927 100644 3--- a/node_modules/expo-paste-input/ios/ExpoPasteInputView.swift 4+++ b/node_modules/expo-paste-input/ios/ExpoPasteInputView.swift 5@@ -511,14 +511,17 @@ class ExpoPasteInputView: ExpoView { 6 var attachmentRanges: [NSRange] = [] 7 var mediaPayloads: [MediaPayload] = [] 8 9+ // Only track ranges for attachments we successfully extract a real payload 10+ // from. Attachments without a payload (e.g. iOS dictation placeholders) 11+ // are left alone — sanitizing them would delete characters the system 12+ // manages itself, and emitting "unsupported" would raise a spurious error. 13 attributedText.enumerateAttribute(.attachment, in: NSRange(location: 0, length: attributedText.length), options: []) { value, range, _ in 14 guard let attachment = value as? NSTextAttachment else { 15 return 16 } 17 18- attachmentRanges.append(range) 19- 20 if let payload = self.extractMediaPayload(from: attachment, textView: textView, range: range) { 21+ attachmentRanges.append(range) 22 mediaPayloads.append(payload) 23 } 24 } 25@@ -529,9 +532,8 @@ class ExpoPasteInputView: ExpoView { 26 return 27 } 28 29- attachmentRanges.append(range) 30- 31 if let payload = self.extractMediaPayload(from: adaptiveGlyph) { 32+ attachmentRanges.append(range) 33 mediaPayloads.append(payload) 34 } 35 } 36@@ -539,17 +541,12 @@ class ExpoPasteInputView: ExpoView { 37 38 attachmentRanges = uniqueRanges(attachmentRanges) 39 40- guard !attachmentRanges.isEmpty else { 41- return 42- } 43- 44- sanitizeAttachments(in: textView, ranges: attachmentRanges) 45- 46 guard !mediaPayloads.isEmpty else { 47- handleUnsupportedPaste() 48 return 49 } 50 51+ sanitizeAttachments(in: textView, ranges: attachmentRanges) 52+ 53 emitImagesAsync(for: mediaPayloads) 54 } 55 56@@ -651,6 +648,11 @@ class ExpoPasteInputView: ExpoView { 57 } 58 59 private func extractMediaPayload(from attachment: NSTextAttachment, textView: UITextView, range: NSRange) -> MediaPayload? { 60+ // Only accept attachments that carry real image payloads. We intentionally 61+ // do not fall back to `image(forBounds:)` or rendering the text view's 62+ // hierarchy, because system-inserted attachments (e.g. the iOS dictation 63+ // placeholder) draw themselves via those paths and would cause us to 64+ // emit a screenshot of the composer as a "pasted image". 65 if let fileWrapperData = attachment.fileWrapper?.regularFileContents, 66 let payload = extractMediaPayload(fromData: fileWrapperData) { 67 return payload 68@@ -667,20 +669,6 @@ class ExpoPasteInputView: ExpoView { 69 return .image(image) 70 } 71 72- let attachmentBounds = attachment.bounds.size.width > 0 && attachment.bounds.size.height > 0 73- ? attachment.bounds 74- : CGRect(origin: .zero, size: CGSize(width: 128, height: 128)) 75- 76- if let image = attachment.image(forBounds: attachmentBounds, textContainer: textView.textContainer, characterIndex: range.location), 77- image.size.width > 0, 78- image.size.height > 0 { 79- return .image(image) 80- } 81- 82- if let renderedImage = renderTextAttachment(in: textView, range: range) { 83- return .image(renderedImage) 84- } 85- 86 return nil 87 } 88 89@@ -701,47 +689,6 @@ class ExpoPasteInputView: ExpoView { 90 return .imageData(data) 91 } 92 93- private func renderTextAttachment(in textView: UITextView, range: NSRange) -> UIImage? { 94- let glyphRange = textView.layoutManager.glyphRange(forCharacterRange: range, actualCharacterRange: nil) 95- var rect = textView.layoutManager.boundingRect(forGlyphRange: glyphRange, in: textView.textContainer) 96- 97- rect.origin.x += textView.textContainerInset.left - textView.contentOffset.x 98- rect.origin.y += textView.textContainerInset.top - textView.contentOffset.y 99- rect = rect.integral 100- 101- guard rect.width > 1, rect.height > 1 else { 102- return nil 103- } 104- 105- let format = UIGraphicsImageRendererFormat.default() 106- format.scale = textView.window?.screen.scale ?? UIScreen.main.scale 107- format.opaque = false 108- 109- let image = UIGraphicsImageRenderer(size: rect.size, format: format).image { _ in 110- let drawRect = CGRect( 111- origin: CGPoint(x: -rect.origin.x, y: -rect.origin.y), 112- size: textView.bounds.size 113- ) 114- 115- if textView.window != nil { 116- textView.drawHierarchy(in: drawRect, afterScreenUpdates: false) 117- } else { 118- guard let context = UIGraphicsGetCurrentContext() else { 119- return 120- } 121- 122- context.translateBy(x: -rect.origin.x, y: -rect.origin.y) 123- textView.layer.render(in: context) 124- } 125- } 126- 127- guard image.size.width > 0, image.size.height > 0 else { 128- return nil 129- } 130- 131- return image 132- } 133- 134 @available(iOS 18.0, *) 135 private func handleAdaptiveImageGlyphInsertion(_ adaptiveGlyph: NSAdaptiveImageGlyph) -> Bool { 136 guard let payload = extractMediaPayload(from: adaptiveGlyph) else {