Files
orca/mobile/modules/orca-mobile-web-shell/ios/MobileWebShellImageActions.swift
T
Kelvin Amoaba c884428609 feat(mobile): copy, save and share an image from the full-screen image viewer (#38303)
* feat(mobile): copy, save and share an image from the chat image viewer

* refactor(mobile): pass image viewer actions in so diagrams skip them

* fix(mobile): name the image verb native.image.act and serialize image actions

* fix(mobile): queue image actions per page and skip SVG links

* refactor(mobile): share the cache-folder helper and table the viewer's image actions

* fix(mobile): keep the toast's live region mounted so screen readers hear it

* test(mobile): re-record agent history goldens for the always-mounted toast region

* test(mobile): import the declared routes in the moved routes test
2026-11-05 22:44:36 +00:00

41 lines
1.6 KiB
Swift

import ExpoModulesCore
import Photos
import UIKit
/// Presents the system share sheet for one image file; its Save Image row needs NSPhotoLibraryAddUsageDescription.
func presentImageShareSheet(url: URL, from presenter: UIViewController) {
let controller = UIActivityViewController(activityItems: [url], applicationActivities: nil)
// iPad shows the sheet as a popover, which needs an anchor; centre it with no arrow.
if let popover = controller.popoverPresentationController {
popover.sourceView = presenter.view
popover.sourceRect = CGRect(x: presenter.view.bounds.midX, y: presenter.view.bounds.midY, width: 0, height: 0)
popover.permittedArrowDirections = []
}
presenter.present(controller, animated: true)
}
/// Adds the file to Photos with add-only access, which never shows the user's library to Orca.
func saveImageToPhotoLibrary(url: URL, promise: Promise) {
PHPhotoLibrary.requestAuthorization(for: .addOnly) { status in
guard status == .authorized || status == .limited else {
promise.reject("native_image_permission_denied", "Orca is not allowed to add to Photos")
return
}
PHPhotoLibrary.shared().performChanges({
PHAssetCreationRequest.forAsset().addResource(with: .photo, fileURL: url, options: nil)
}) { saved, error in
if saved {
promise.resolve(nil)
} else {
promise.reject("native_verb_failed", error?.localizedDescription ?? "Photos did not save the image")
}
}
}
}
final class ImagePresenterUnavailableException: Exception {
override var reason: String {
"No screen is available to present the share sheet"
}
}