Skip to content
Merged
Show file tree
Hide file tree
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
1 change: 1 addition & 0 deletions RELEASE-NOTES.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
1.15.2
------
* Fix issue when copy/paste photos from other apps, was not inserting an image on the post.
* Fix issue where the block inserter layout wasn't correct after device rotation.

1.15.0
Expand Down
18 changes: 10 additions & 8 deletions ios/gutenberg/GutenbergViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -74,15 +74,17 @@ extension GutenbergViewController: GutenbergBridgeDelegate {
switch currentFilter {
case .image:
if(allowMultipleSelection) {
callback([(1, "https://cldup.com/cXyG__fTLN.jpg", "image"), (3, "https://cldup.com/cXyG__fTLN.jpg", "image")])
callback([MediaInfo(id: 1, url: "https://cldup.com/cXyG__fTLN.jpg", type: "image"),
MediaInfo(id: 3, url: "https://cldup.com/cXyG__fTLN.jpg", type: "image")])
} else {
callback([(1, "https://cldup.com/cXyG__fTLN.jpg", "image")])
callback([MediaInfo(id: 1, url: "https://cldup.com/cXyG__fTLN.jpg", type: "image")])
}
case .video:
if(allowMultipleSelection) {
callback([(2, "https://i.cloudup.com/YtZFJbuQCE.mov", "video"), (4, "https://i.cloudup.com/YtZFJbuQCE.mov", "video")])
callback([MediaInfo(id: 2, url: "https://i.cloudup.com/YtZFJbuQCE.mov", type: "video"),
MediaInfo(id: 4, url: "https://i.cloudup.com/YtZFJbuQCE.mov", type: "video")])
} else {
callback([(2, "https://i.cloudup.com/YtZFJbuQCE.mov", "video")])
callback([MediaInfo(id: 2, url: "https://i.cloudup.com/YtZFJbuQCE.mov", type: "video")])
}
default:
break
Expand All @@ -96,18 +98,18 @@ extension GutenbergViewController: GutenbergBridgeDelegate {
}
}

func gutenbergDidRequestImport(from url: URL, with callback: @escaping MediaPickerDidPickMediaCallback) {
func gutenbergDidRequestImport(from url: URL, with callback: @escaping MediaImportCallback) {
let id = mediaUploadCoordinator.upload(url: url)
callback([(id, url.absoluteString, "image")])
callback(MediaInfo(id: id, url: url.absoluteString, type: "image"))
}

func pickAndUpload(from source: UIImagePickerController.SourceType, filter: MediaFilter, callback: @escaping MediaPickerDidPickMediaCallback) {
mediaPickCoordinator = MediaPickCoordinator(presenter: self, filter: filter, callback: { (url) in
guard let url = url, let mediaID = self.mediaUploadCoordinator.upload(url: url) else {
callback([(nil, nil, nil)])
callback([MediaInfo(id: nil, url: nil, type: nil)])
return
}
callback([(mediaID, url.absoluteString, "image")])
callback([MediaInfo(id: mediaID, url: url.absoluteString, type: "image")])
self.mediaPickCoordinator = nil
} )
mediaPickCoordinator?.pick(from: source)
Expand Down
18 changes: 16 additions & 2 deletions react-native-gutenberg-bridge/ios/GutenbergBridgeDelegate.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,18 @@
public typealias MediaPickerDidPickMediaCallback = (_ media: [(Int32?,String?,String?)]?) -> Void
public struct MediaInfo {
public let id: Int32?
public let url: String?
public let type: String?

public init(id: Int32?, url: String?, type: String?) {
self.id = id
self.url = url
self.type = type
}
}

public typealias MediaPickerDidPickMediaCallback = (_ media: [MediaInfo]?) -> Void
Comment on lines +1 to +13
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you think we could avoid some of the optionals?
Not sure if in the callback a nil has a different meaning over an empty array (error maybe?).
And perhaps a MediaInfo should always have a proper type? and/or an id?

Of course we can leave these improvements for another round 👍

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought that too, but we will need to check the code on the JS side and see what are the implications of sending nil or not.

Can we do this in the follow up PR?


public typealias MediaImportCallback = (_ media: MediaInfo?) -> Void

public enum MediaPickerSource: String {
case mediaLibrary = "SITE_MEDIA_LIBRARY"
Expand Down Expand Up @@ -71,7 +85,7 @@ public protocol GutenbergBridgeDelegate: class {
/// - url: the url to import
/// - callback: A callback block to be called with an array of upload mediaIdentifiers and a placeholder images file url, use nil on both parameters to signal that the action has failed.
//
func gutenbergDidRequestImport(from url: URL, with callback: @escaping MediaPickerDidPickMediaCallback)
func gutenbergDidRequestImport(from url: URL, with callback: @escaping MediaImportCallback)

/// Tells the delegate that an image block requested to reconnect with media uploads coordinator.
///
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,17 +27,20 @@ public class RNReactNativeGutenbergBridge: RCTEventEmitter {
callback(nil)
return
}
if (allowMultipleSelection) {
let formattedMedia = media.map { (id, url, type) in
return [mediaDictKeys.IDKey: id, mediaDictKeys.URLKey: url, mediaDictKeys.TypeKey: type]
}
callback([formattedMedia])
let mediaToReturn: [MediaInfo]
if allowMultipleSelection {
mediaToReturn = media
} else {
guard let (mediaID, mediaURL, mediaType) = media.first else {
callback(nil)
return
}
callback([[mediaDictKeys.IDKey: mediaID, mediaDictKeys.URLKey: mediaURL, mediaDictKeys.TypeKey: mediaType]])
mediaToReturn = Array(media.prefix(1))
}

let jsFormattedMedia = mediaToReturn.map { mediaInfo in
return mediaInfo.encodeForJS()
}
if allowMultipleSelection {
callback([jsFormattedMedia])
} else {
callback(jsFormattedMedia)
Comment on lines +40 to +43
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might be good to merge this and send the full array. If multi select is false, the callback should bring just one media item. Maybe we can enforce that via the callback signature, and keep the bridge simpler 🤔

Again, thinking about the future!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't have control on the callback interface it's defined by RN library.
It's always expecting an array where each item is an argument of the JS function.
What we can do is to cleanup the callback functions on the other side to always expect an array of media.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's do that! On another PR someday in the future 😬
It might be good to create a ticket with all these little cleanup tasks to keep track of them.

}
})
}
Expand All @@ -50,12 +53,12 @@ public class RNReactNativeGutenbergBridge: RCTEventEmitter {
return
}
DispatchQueue.main.async {
self.delegate?.gutenbergDidRequestImport(from: url, with: { mediaList in
guard let mediaList = mediaList else {
self.delegate?.gutenbergDidRequestImport(from: url, with: { mediaInfo in
guard let mediaInfo = mediaInfo else {
callback(nil)
return
}
callback(mediaList)
}
callback([mediaInfo.id as Any, mediaInfo.url as Any])
})
}
}
Expand Down Expand Up @@ -197,3 +200,14 @@ extension RNReactNativeGutenbergBridge {
static let TypeKey = "type"
}
}

extension MediaInfo {

func encodeForJS() -> [String: Any] {
return [
RNReactNativeGutenbergBridge.mediaDictKeys.IDKey: id as Any,
RNReactNativeGutenbergBridge.mediaDictKeys.URLKey: url as Any,
RNReactNativeGutenbergBridge.mediaDictKeys.TypeKey: type as Any
]
}
}