diff --git a/android/src/main/cpp/LiveMarkdownModule.cpp b/android/src/main/cpp/LiveMarkdownModule.cpp new file mode 100644 index 000000000..f4d5e906c --- /dev/null +++ b/android/src/main/cpp/LiveMarkdownModule.cpp @@ -0,0 +1,25 @@ +#include "LiveMarkdownModule.h" +#include "RuntimeDecorator.h" + +namespace expensify::livemarkdown { + +// static +void LiveMarkdownModule::registerNatives() { + javaClassLocal()->registerNatives({ + makeNativeMethod( + "getBindingsInstaller", + LiveMarkdownModule::getBindingsInstaller), + }); +} + +// static +jni::local_ref +LiveMarkdownModule::getBindingsInstaller( + jni::alias_ref /*jobj*/) { + return react::BindingsInstallerHolder::newObjectCxxArgs( + [](jsi::Runtime& runtime, const std::shared_ptr&) { + expensify::livemarkdown::injectJSIBindings(runtime); + }); +} + +} // namespace expensify::livemarkdown diff --git a/android/src/main/cpp/LiveMarkdownModule.h b/android/src/main/cpp/LiveMarkdownModule.h new file mode 100644 index 000000000..821d75e22 --- /dev/null +++ b/android/src/main/cpp/LiveMarkdownModule.h @@ -0,0 +1,24 @@ +#pragma once + +#include +#include + +using namespace facebook; + +namespace expensify::livemarkdown { + +class LiveMarkdownModule : public jni::JavaClass { + public: + static constexpr auto kJavaDescriptor = + "Lcom/expensify/livemarkdown/LiveMarkdownModule;"; + + LiveMarkdownModule() = default; + + static void registerNatives(); + + private: + static jni::local_ref + getBindingsInstaller(jni::alias_ref jobj); +}; + +} // namespace expensify::livemarkdown diff --git a/android/src/main/cpp/OnLoad.cpp b/android/src/main/cpp/OnLoad.cpp index 7daa4a33b..0f6a2d09b 100644 --- a/android/src/main/cpp/OnLoad.cpp +++ b/android/src/main/cpp/OnLoad.cpp @@ -1,14 +1,11 @@ #include +#include "LiveMarkdownModule.h" #include "MarkdownParser.h" -#include "RuntimeDecorator.h" JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) { - return facebook::jni::initialize( - vm, [] { expensify::livemarkdown::MarkdownParser::registerNatives(); }); -} - -extern "C" JNIEXPORT void JNICALL Java_com_expensify_livemarkdown_LiveMarkdownModule_injectJSIBindings(JNIEnv *env, jobject thiz, jlong jsiRuntime) { - jsi::Runtime &rt = *reinterpret_cast(jsiRuntime); - expensify::livemarkdown::injectJSIBindings(rt); + return facebook::jni::initialize(vm, [] { + expensify::livemarkdown::LiveMarkdownModule::registerNatives(); + expensify::livemarkdown::MarkdownParser::registerNatives(); + }); } diff --git a/android/src/main/java/com/expensify/livemarkdown/LiveMarkdownModule.java b/android/src/main/java/com/expensify/livemarkdown/LiveMarkdownModule.java index cf6021ea4..ed12c55fb 100644 --- a/android/src/main/java/com/expensify/livemarkdown/LiveMarkdownModule.java +++ b/android/src/main/java/com/expensify/livemarkdown/LiveMarkdownModule.java @@ -1,11 +1,14 @@ package com.expensify.livemarkdown; +import androidx.annotation.NonNull; + +import com.facebook.proguard.annotations.DoNotStrip; import com.facebook.react.bridge.ReactApplicationContext; +import com.facebook.react.turbomodule.core.interfaces.BindingsInstallerHolder; +import com.facebook.react.turbomodule.core.interfaces.TurboModuleWithJSIBindings; import com.facebook.soloader.SoLoader; -import java.util.Objects; - -public class LiveMarkdownModule extends NativeLiveMarkdownModuleSpec { +public class LiveMarkdownModule extends NativeLiveMarkdownModuleSpec implements TurboModuleWithJSIBindings { static { SoLoader.loadLibrary("livemarkdown"); } @@ -14,13 +17,8 @@ public LiveMarkdownModule(ReactApplicationContext reactContext) { super(reactContext); } + @DoNotStrip + @NonNull @Override - public boolean install() { - long jsiRuntime = Objects.requireNonNull(getReactApplicationContext().getJavaScriptContextHolder(), "[react-native-live-markdown] JavaScriptContextHolder is null").get(); - injectJSIBindings(jsiRuntime); - - return true; - } - - private native void injectJSIBindings(long jsiRuntime); + public native BindingsInstallerHolder getBindingsInstaller(); } diff --git a/apple/LiveMarkdownModule.h b/apple/LiveMarkdownModule.h index 28c768c70..2beccb2d6 100644 --- a/apple/LiveMarkdownModule.h +++ b/apple/LiveMarkdownModule.h @@ -1,8 +1,9 @@ #import #import +#import // Without inheriting after RCTEventEmitter we don't get access to bridge -@interface LiveMarkdownModule : RCTEventEmitter +@interface LiveMarkdownModule : RCTEventEmitter @end diff --git a/apple/LiveMarkdownModule.mm b/apple/LiveMarkdownModule.mm index 4cd3970dd..06115e634 100644 --- a/apple/LiveMarkdownModule.mm +++ b/apple/LiveMarkdownModule.mm @@ -11,12 +11,10 @@ @implementation LiveMarkdownModule RCT_EXPORT_MODULE() -RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(install) +- (void)installJSIBindingsWithRuntime:(facebook::jsi::Runtime &)runtime + callInvoker:(const std::shared_ptr &)callinvoker { - RCTCxxBridge *cxxBridge = (RCTCxxBridge *)self.bridge; - jsi::Runtime &rt = *(jsi::Runtime *)cxxBridge.runtime; - expensify::livemarkdown::injectJSIBindings(rt); - return @(1); + expensify::livemarkdown::injectJSIBindings(runtime); } - (std::shared_ptr)getTurboModule: diff --git a/src/MarkdownTextInput.tsx b/src/MarkdownTextInput.tsx index 82ee8953e..71975ad20 100644 --- a/src/MarkdownTextInput.tsx +++ b/src/MarkdownTextInput.tsx @@ -37,8 +37,8 @@ function initializeLiveMarkdownIfNeeded() { if (initialized) { return; } - if (NativeLiveMarkdownModule) { - NativeLiveMarkdownModule.install(); + if (!NativeLiveMarkdownModule) { + throw new Error('[react-native-live-markdown] NativeLiveMarkdownModule is not available'); } if (!global.jsi_setMarkdownRuntime) { throw new Error('[react-native-live-markdown] global.jsi_setMarkdownRuntime is not available'); diff --git a/src/NativeLiveMarkdownModule.ts b/src/NativeLiveMarkdownModule.ts index c847838fb..7e467d6e5 100644 --- a/src/NativeLiveMarkdownModule.ts +++ b/src/NativeLiveMarkdownModule.ts @@ -1,8 +1,7 @@ import type {TurboModule} from 'react-native'; import {TurboModuleRegistry} from 'react-native'; -interface Spec extends TurboModule { - install: () => boolean; -} +// eslint-disable-next-line @typescript-eslint/no-empty-interface +interface Spec extends TurboModule {} export default TurboModuleRegistry.get('LiveMarkdownModule');