react-native-picture-selector 1.0.11 → 1.0.13

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.
@@ -10,10 +10,29 @@ add_library(${CMAKE_PROJECT_NAME} SHARED)
10
10
  # Autolinking cmake handles: find_package, target_sources, target_link_libraries
11
11
  include(${CMAKE_SOURCE_DIR}/../nitrogen/generated/android/NitroPictureSelector+autolinking.cmake)
12
12
 
13
+ # cpp-adapter.cpp defines JNI_OnLoad — the entry point called by the JVM when
14
+ # System.loadLibrary("NitroPictureSelector") is invoked from Kotlin.
15
+ # It calls facebook::jni::initialize(vm, ...) and then registerAllNatives(),
16
+ # which inserts "PictureSelector" into Nitro's HybridObjectRegistry.
17
+ # Without this file the library loads silently but nothing gets registered.
18
+ target_sources(${CMAKE_PROJECT_NAME} PRIVATE
19
+ src/main/cpp/cpp-adapter.cpp
20
+ )
21
+
13
22
  # Directly link libNitroModules.so from its stable cmake build output path.
14
23
  # The prefab for react-native-nitro-modules is header-only at CMake configure
15
24
  # time (fix-prefab.gradle updates it only after native build), so we link
16
25
  # the .so directly to avoid undefined symbol errors on fresh builds.
26
+ #
27
+ # Use a generator expression so the correct variant (debug/release) is picked
28
+ # automatically — avoids breaking assembleRelease / EAS production builds.
29
+ string(TOLOWER "${CMAKE_BUILD_TYPE}" _build_type_lower)
30
+ if(_build_type_lower STREQUAL "release")
31
+ set(NITRO_BUILD_VARIANT "release")
32
+ else()
33
+ set(NITRO_BUILD_VARIANT "debug")
34
+ endif()
35
+
17
36
  target_link_libraries(${CMAKE_PROJECT_NAME}
18
- ${CMAKE_SOURCE_DIR}/../../react-native-nitro-modules/android/build/intermediates/cmake/debug/obj/${ANDROID_ABI}/libNitroModules.so
37
+ ${CMAKE_SOURCE_DIR}/../../react-native-nitro-modules/android/build/intermediates/cmake/${NITRO_BUILD_VARIANT}/obj/${ANDROID_ABI}/libNitroModules.so
19
38
  )
@@ -0,0 +1,26 @@
1
+ ///
2
+ /// cpp-adapter.cpp
3
+ /// Entry point for the NitroPictureSelector shared library.
4
+ ///
5
+ /// Defines JNI_OnLoad so that when Kotlin calls
6
+ /// System.loadLibrary("NitroPictureSelector")
7
+ /// the JVM invokes this function with the JavaVM*, which:
8
+ /// 1. Initialises fbjni (facebook::jni::initialize)
9
+ /// 2. Calls registerAllNatives() — which registers JNI methods and
10
+ /// inserts "PictureSelector" into Nitro's HybridObjectRegistry.
11
+ ///
12
+ /// Without this entry point System.loadLibrary succeeds silently but
13
+ /// nothing ever gets registered, so every call to
14
+ /// NitroModules.createHybridObject("PictureSelector")
15
+ /// throws "It has not yet been registered in the HybridObjectRegistry".
16
+ ///
17
+
18
+ #include <jni.h>
19
+ #include <fbjni/fbjni.h>
20
+ #include "NitroPictureSelectorOnLoad.hpp"
21
+
22
+ JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void*) {
23
+ return facebook::jni::initialize(vm, []() {
24
+ margelo::pictureselector::registerAllNatives();
25
+ });
26
+ }
@@ -6,6 +6,7 @@ import com.luck.picture.lib.basic.PictureSelector
6
6
  import com.luck.picture.lib.config.SelectMimeType
7
7
  import com.luck.picture.lib.entity.LocalMedia
8
8
  import com.luck.picture.lib.interfaces.OnResultCallbackListener
9
+ import com.margelo.nitro.NitroModules
9
10
  import com.margelo.nitro.core.Promise
10
11
  import com.margelo.nitro.com.margelo.pictureselector.HybridHybridPictureSelectorSpec
11
12
  import com.margelo.nitro.com.margelo.pictureselector.MediaAsset
@@ -34,20 +35,29 @@ import kotlin.coroutines.suspendCoroutine
34
35
  * Nitro HybridObject implementation for the Android side.
35
36
  *
36
37
  * Extends the nitrogen-generated [HybridHybridPictureSelectorSpec] which provides
37
- * the JSI bridge. The [reactContext] is injected by [NitroPictureSelectorPackage].
38
+ * the JSI bridge.
39
+ *
40
+ * No-arg constructor — the [ReactApplicationContext] is obtained lazily from
41
+ * [NitroModules.applicationContext], which is set during Nitro initialisation
42
+ * (before any JS call can reach this object). This allows the C++ factory in
43
+ * NitroPictureSelectorOnLoad.cpp to register us with a zero-argument lambda
44
+ * as required by [HybridObjectRegistry.registerHybridObjectConstructor].
38
45
  *
39
46
  * Threading contract:
40
47
  * - [openPicker] and [openCamera] are called on the JS thread.
41
48
  * - PictureSelector.create(...).openGallery() must be called on the Main thread.
42
49
  * - We switch to Main via [withContext(Dispatchers.Main)] inside Promise.async.
43
- *
44
- * API REQUIRES VERIFICATION:
45
- * - Confirm Promise.async accepts a CoroutineContext parameter in the version
46
- * of react-native-nitro-modules used.
47
50
  */
48
- class HybridPictureSelector(
49
- private val reactContext: ReactApplicationContext,
50
- ) : HybridHybridPictureSelectorSpec() {
51
+ class HybridPictureSelector : HybridHybridPictureSelectorSpec() {
52
+
53
+ // Obtained lazily — NitroModules sets applicationContext during module init,
54
+ // which always happens before the first JS call to openPicker / openCamera.
55
+ private val reactContext: ReactApplicationContext
56
+ get() = NitroModules.applicationContext
57
+ ?: throw PictureSelectorException(
58
+ "UNKNOWN",
59
+ "NitroModules is not yet initialised. Make sure NitroModules is set up in your app."
60
+ )
51
61
 
52
62
  // ─────────────────────────────────────────────────────────────────────────
53
63
  // Public API
@@ -35,7 +35,29 @@ void registerAllNatives() {
35
35
  margelo::pictureselector::JHybridHybridPictureSelectorSpec::CxxPart::registerNatives();
36
36
 
37
37
  // Register Nitro Hybrid Objects
38
-
38
+ //
39
+ // HybridPictureSelector has a no-arg constructor and obtains its
40
+ // ReactApplicationContext from NitroModules.applicationContext (set during
41
+ // Nitro initialisation, before any JS call can reach this factory).
42
+ HybridObjectRegistry::registerHybridObjectConstructor(
43
+ "PictureSelector",
44
+ []() -> std::shared_ptr<HybridObject> {
45
+ // Locate the concrete Kotlin implementation class
46
+ static const auto klass =
47
+ jni::findClassStatic("com/margelo/pictureselector/HybridPictureSelector");
48
+ // Invoke the no-arg constructor.
49
+ // fbjni deduces the return type of newObject() from the template argument of
50
+ // getConstructor<F>(). Using void() would produce local_ref<void> which is not
51
+ // a valid fbjni reference type. Using jni::JObject::javaobject() makes newObject()
52
+ // return local_ref<JObject>, which can then be safely cast with dynamic_ref_cast.
53
+ static const auto ctor = klass->getConstructor<jni::JObject::javaobject()>();
54
+ auto javaInstance = klass->newObject(ctor);
55
+ // Downcast to the spec JavaPart so JHybridHybridPictureSelectorSpec can wrap it
56
+ auto javaPart =
57
+ jni::dynamic_ref_cast<JHybridHybridPictureSelectorSpec::JavaPart>(javaInstance);
58
+ return std::make_shared<JHybridHybridPictureSelectorSpec>(javaPart);
59
+ }
60
+ );
39
61
  }
40
62
 
41
63
  } // namespace margelo::pictureselector
@@ -62,8 +62,9 @@ namespace margelo::pictureselector {
62
62
  void loadHybridMethods() override;
63
63
 
64
64
  protected:
65
- // Tag for logging
66
- static constexpr auto TAG = "HybridPictureSelector";
65
+ // Tag for logging — must match the key used in registerHybridObjectConstructor()
66
+ // and in NitroModules.createHybridObject() on the JS side ("PictureSelector").
67
+ static constexpr auto TAG = "PictureSelector";
67
68
  };
68
69
 
69
70
  } // namespace margelo::pictureselector
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-picture-selector",
3
- "version": "1.0.11",
3
+ "version": "1.0.13",
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",