react-native-picture-selector 1.0.21 → 1.0.23

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -16,7 +16,7 @@ High-performance photo and video picker for React Native, built on **Nitro Modul
16
16
  - **Cropping** — fixed ratio, free-style, circular (iOS)
17
17
  - **Compression** — JPEG quality + max dimensions
18
18
  - **Video duration limits** — min / max in seconds
19
- - **Pre-selected assets** — restore a previous selection
19
+ - **Pre-selected assets** — restore a previous selection (Android only)
20
20
  - **Themes** — WeChat / White / Dark (Android), hex accent color (iOS)
21
21
  - **Strict TypeScript** — fully typed API and result objects
22
22
  - **Promise-based** — async/await friendly, cancel → rejection
@@ -360,6 +360,8 @@ openPicker({ themeColor: '#E91E63' }) // Pink
360
360
 
361
361
  ### Pre-selected assets
362
362
 
363
+ > **iOS limitation**: `selectedAssets` is not yet implemented on iOS. The option is accepted but has no effect. See Android usage below.
364
+
363
365
  Pass `file://` URIs of previously selected files to pre-check them in the gallery grid.
364
366
 
365
367
  ```ts
@@ -638,6 +640,8 @@ export default ChatInput
638
640
 
639
641
  ### Profile settings — restore previous selection
640
642
 
643
+ > **Note**: `selectedAssets` pre-selection works on Android only. On iOS the picker opens without any pre-checked items.
644
+
641
645
  ```tsx
642
646
  function ProfilePhotoScreen() {
643
647
  const [photo, setPhoto] = useState<MediaAsset | null>(null)
@@ -693,6 +697,7 @@ function ProfilePhotoScreen() {
693
697
  - `bucketName` is only populated on Android.
694
698
  - `themeColor` sets HXPhotoPicker's global `themeColor` property (navigation bar, selection indicators).
695
699
  - `theme` enum values (`WECHAT`, `WHITE`, `DARK`) are ignored on iOS — use `themeColor` instead.
700
+ - `selectedAssets` pre-selection is **not yet implemented** on iOS — the option is accepted but has no effect. Resolving `file://` URIs back to `PHAsset` objects is required for this feature.
696
701
 
697
702
  ---
698
703
 
@@ -723,6 +728,7 @@ function ProfilePhotoScreen() {
723
728
 
724
729
  | Feature | Status |
725
730
  |---------|--------|
731
+ | `selectedAssets` pre-selection (iOS) | Not yet implemented — Android only |
726
732
  | Audio file selection | Not supported |
727
733
  | iCloud Photos (iOS) | Partial — depends on HXPhotoPicker internals |
728
734
  | Live Photos | Not exposed |
@@ -48,12 +48,19 @@ final class HybridPictureSelector: HybridHybridPictureSelectorSpec_base, HybridH
48
48
 
49
49
  func openPicker(options: PictureSelectorOptions) -> Promise<[MediaAsset]> {
50
50
  return Promise { [weak self] resolver in
51
- guard let self = self else {
52
- resolver.reject(PictureSelectorError.unknown("Instance deallocated"))
51
+ guard let self else {
52
+ resolver.reject(PictureSelectorError.unknown("openPicker: native module was deallocated"))
53
53
  return
54
54
  }
55
55
 
56
56
  DispatchQueue.main.async {
57
+ if self.session != nil {
58
+ resolver.reject(PictureSelectorError.unknown(
59
+ "A picker or camera session is already active. Dismiss it before opening a new one."
60
+ ))
61
+ return
62
+ }
63
+
57
64
  guard let topVC = self.topViewController() else {
58
65
  resolver.reject(PictureSelectorError.unknown(
59
66
  "No active UIViewController. Ensure the picker is called from a mounted component."
@@ -85,22 +92,26 @@ final class HybridPictureSelector: HybridHybridPictureSelectorSpec_base, HybridH
85
92
 
86
93
  func openCamera(options: PictureSelectorOptions) -> Promise<[MediaAsset]> {
87
94
  return Promise { [weak self] resolver in
88
- guard let self = self else {
89
- resolver.reject(PictureSelectorError.unknown("Instance deallocated"))
95
+ guard let self else {
96
+ resolver.reject(PictureSelectorError.unknown("openCamera: native module was deallocated"))
90
97
  return
91
98
  }
92
99
 
93
100
  DispatchQueue.main.async {
101
+ if self.session != nil {
102
+ resolver.reject(PictureSelectorError.unknown(
103
+ "A picker or camera session is already active. Dismiss it before opening a new one."
104
+ ))
105
+ return
106
+ }
107
+
94
108
  guard let topVC = self.topViewController() else {
95
109
  resolver.reject(PictureSelectorError.unknown("No active UIViewController."))
96
110
  return
97
111
  }
98
112
 
99
113
  var cameraConfig = CameraConfiguration()
100
- switch options.mediaType {
101
- case "video": cameraConfig.mediaType = .video
102
- default: cameraConfig.mediaType = .photo
103
- }
114
+ cameraConfig.mediaType = (options.mediaType == .video) ? .video : .photo
104
115
  if let maxDur = options.maxVideoDuration {
105
116
  cameraConfig.videoMaximumDuration = maxDur
106
117
  }
@@ -115,7 +126,10 @@ final class HybridPictureSelector: HybridHybridPictureSelectorSpec_base, HybridH
115
126
  cameraConfig,
116
127
  fromViewController: topVC
117
128
  ) { [weak self] result, _ in
118
- guard let self = self else { return }
129
+ guard let self else {
130
+ resolver.reject(PictureSelectorError.unknown("openCamera: native module was deallocated"))
131
+ return
132
+ }
119
133
  guard let photoAsset = result?.photoAsset else {
120
134
  resolver.reject(PictureSelectorError.cancelled)
121
135
  return
@@ -146,9 +160,9 @@ final class HybridPictureSelector: HybridHybridPictureSelectorSpec_base, HybridH
146
160
 
147
161
  // Media type
148
162
  switch options.mediaType {
149
- case "video":
163
+ case .video:
150
164
  config.selectOptions = [.video]
151
- case "all":
165
+ case .all:
152
166
  config.selectOptions = [.photo, .video]
153
167
  default:
154
168
  config.selectOptions = [.photo]
@@ -196,6 +210,13 @@ final class HybridPictureSelector: HybridHybridPictureSelectorSpec_base, HybridH
196
210
  config.themeColor = color
197
211
  }
198
212
 
213
+ // selectedAssets: pre-selecting assets by file:// URI requires resolving each URI
214
+ // back to a PHAsset via PHPhotoLibrary and wrapping it in a PhotoAsset object.
215
+ // This is not yet implemented. Callers should not rely on this option on iOS.
216
+ // TODO: implement pre-selection using PHAsset.fetchAssets(withALAssetURLs:options:)
217
+ // or localIdentifier lookup, then set config.preSelectedAssets (verify field name
218
+ // in HXPhotoPicker v5.0.5 before enabling).
219
+
199
220
  return config
200
221
  }
201
222
 
@@ -330,7 +351,11 @@ extension HybridPictureSelector: PhotoPickerControllerDelegate {
330
351
  activePicker = nil
331
352
 
332
353
  pickerController.dismiss(animated: true) { [weak self] in
333
- guard let self = self, let s = captured else { return }
354
+ guard let s = captured else { return }
355
+ guard let self else {
356
+ s.resolver(.failure(PictureSelectorError.unknown("pickerController: native module was deallocated")))
357
+ return
358
+ }
334
359
  Task {
335
360
  do {
336
361
  let assets = try await self.mapResults(result, compress: s.options.compress)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-picture-selector",
3
- "version": "1.0.21",
3
+ "version": "1.0.23",
4
4
  "description": "High-performance photo/video picker for React Native using Nitro Modules",
5
5
  "main": "lib/commonjs/index.js",
6
6
  "module": "lib/module/index.js",