diff --git a/.bundle/config b/.bundle/config
new file mode 100644
index 000000000000..848943bb5274
--- /dev/null
+++ b/.bundle/config
@@ -0,0 +1,2 @@
+BUNDLE_PATH: "vendor/bundle"
+BUNDLE_FORCE_RUBY_PLATFORM: 1
diff --git a/.gitignore b/.gitignore
index ffd6dbf69bca..591494786a66 100644
--- a/.gitignore
+++ b/.gitignore
@@ -62,15 +62,17 @@ android/app/android-fastlane-json-key.json
# For more information about the recommended setup visit:
# https://docs.fastlane.tools/best-practices/source-control/
-fastlane/report.xml
-fastlane/Preview.html
-fastlane/screenshots
+**/fastlane/report.xml
+**/fastlane/Preview.html
+**/fastlane/screenshots
+**/fastlane/test_output
# Bundle artifact
*.jsbundle
-# CocoaPods
+# Ruby / CocoaPods
/ios/Pods/
+/vendor/bundle/
# Local DEV config
/.env
diff --git a/.ruby-version b/.ruby-version
new file mode 100644
index 000000000000..a603bb50a29e
--- /dev/null
+++ b/.ruby-version
@@ -0,0 +1 @@
+2.7.5
diff --git a/Gemfile b/Gemfile
index 4638bcacbb71..2d5dcafaeef4 100644
--- a/Gemfile
+++ b/Gemfile
@@ -1,5 +1,8 @@
source "https://rubygems.org"
-gem "cocoapods", "~> 1"
+# You may use http://rbenv.org/ or https://rvm.io/ to install and use this version
+ruby '2.7.5'
+
+gem "cocoapods", "~> 1.11", ">= 1.11.2"
gem "fastlane", "~> 2"
gem "xcpretty", "~> 0"
diff --git a/android/app/build.gradle b/android/app/build.gradle
index 4196ac8a5291..6de66ef273e8 100644
--- a/android/app/build.gradle
+++ b/android/app/build.gradle
@@ -121,16 +121,19 @@ def jscFlavor = 'org.webkit:android-jsc:+'
/**
* Whether to enable the Hermes VM.
*
- * This should be set on project.ext.react and mirrored here. If it is not set
+ * This should be set on project.ext.react and that value will be read here. If it is not set
* on project.ext.react, JavaScript will not be compiled to Hermes Bytecode
* and the benefits of using Hermes will therefore be sharply reduced.
*/
def enableHermes = project.ext.react.get("enableHermes", false);
/**
- * Required in order to build native code for debug builds
+ * Architectures to build native code for.
*/
-def nativeArchitectures = project.getProperties().get("reactNativeDebugArchitectures")
+def reactNativeArchitectures() {
+ def value = project.getProperties().get("reactNativeArchitectures")
+ return value ? value.split(",") : ["armeabi-v7a", "x86", "x86_64", "arm64-v8a"]
+}
android {
compileSdkVersion rootProject.ext.compileSdkVersion
@@ -154,13 +157,81 @@ android {
multiDexEnabled rootProject.ext.multiDexEnabled
versionCode 1001018708
versionName "1.1.87-8"
+ buildConfigField "boolean", "IS_NEW_ARCHITECTURE_ENABLED", isNewArchitectureEnabled().toString()
+
+ if (isNewArchitectureEnabled()) {
+ // We configure the NDK build only if you decide to opt-in for the New Architecture.
+ externalNativeBuild {
+ ndkBuild {
+ arguments "APP_PLATFORM=android-21",
+ "APP_STL=c++_shared",
+ "NDK_TOOLCHAIN_VERSION=clang",
+ "GENERATED_SRC_DIR=$buildDir/generated/source",
+ "PROJECT_BUILD_DIR=$buildDir",
+ "REACT_ANDROID_DIR=$rootDir/../node_modules/react-native/ReactAndroid",
+ "REACT_ANDROID_BUILD_DIR=$rootDir/../node_modules/react-native/ReactAndroid/build",
+ "NODE_MODULES_DIR=$rootDir/../node_modules"
+ cFlags "-Wall", "-Werror", "-fexceptions", "-frtti", "-DWITH_INSPECTOR=1"
+ cppFlags "-std=c++17"
+ // Make sure this target name is the same you specify inside the
+ // src/main/jni/Android.mk file for the `LOCAL_MODULE` variable.
+ targets "rndiffapp_appmodules"
+ }
+ }
+ if (!enableSeparateBuildPerCPUArchitecture) {
+ ndk {
+ abiFilters (*reactNativeArchitectures())
+ }
+ }
+ }
+ }
+
+ if (isNewArchitectureEnabled()) {
+ // We configure the NDK build only if you decide to opt-in for the New Architecture.
+ externalNativeBuild {
+ ndkBuild {
+ path "$projectDir/src/main/jni/Android.mk"
+ }
+ }
+ def reactAndroidProjectDir = project(':ReactAndroid').projectDir
+ def packageReactNdkDebugLibs = tasks.register("packageReactNdkDebugLibs", Copy) {
+ dependsOn(":ReactAndroid:packageReactNdkDebugLibsForBuck")
+ from("$reactAndroidProjectDir/src/main/jni/prebuilt/lib")
+ into("$buildDir/react-ndk/exported")
+ }
+ def packageReactNdkReleaseLibs = tasks.register("packageReactNdkReleaseLibs", Copy) {
+ dependsOn(":ReactAndroid:packageReactNdkReleaseLibsForBuck")
+ from("$reactAndroidProjectDir/src/main/jni/prebuilt/lib")
+ into("$buildDir/react-ndk/exported")
+ }
+ afterEvaluate {
+ // If you wish to add a custom TurboModule or component locally,
+ // you should uncomment this line.
+ // preBuild.dependsOn("generateCodegenArtifactsFromSchema")
+ preDebugBuild.dependsOn(packageReactNdkDebugLibs)
+ preReleaseBuild.dependsOn(packageReactNdkReleaseLibs)
+ // Due to a bug inside AGP, we have to explicitly set a dependency
+ // between configureNdkBuild* tasks and the preBuild tasks.
+ // This can be removed once this is solved: https://issuetracker.google.com/issues/207403732
+ configureNdkBuildRelease.dependsOn(preReleaseBuild)
+ configureNdkBuildDebug.dependsOn(preDebugBuild)
+ reactNativeArchitectures().each { architecture ->
+ tasks.findByName("configureNdkBuildDebug[${architecture}]")?.configure {
+ dependsOn("preDebugBuild")
+ }
+ tasks.findByName("configureNdkBuildRelease[${architecture}]")?.configure {
+ dependsOn("preReleaseBuild")
+ }
+ }
+ }
}
+
splits {
abi {
reset()
enable enableSeparateBuildPerCPUArchitecture
universalApk false // If true, also generate a universal APK
- include "armeabi-v7a", "x86", "arm64-v8a", "x86_64"
+ include (*reactNativeArchitectures())
}
}
signingConfigs {
@@ -182,11 +253,6 @@ android {
buildTypes {
debug {
signingConfig signingConfigs.debug
- if (nativeArchitectures) {
- ndk {
- abiFilters nativeArchitectures.split(',')
- }
- }
}
release {
signingConfig signingConfigs.release
@@ -213,6 +279,7 @@ android {
dependencies {
implementation fileTree(dir: "libs", include: ["*.jar"])
+
//noinspection GradleDynamicVersion
implementation "com.facebook.react:react-native:+" // From node_modules
@@ -232,15 +299,16 @@ dependencies {
}
if (enableHermes) {
- def hermesPath = "../../node_modules/hermes-engine/android/";
- debugImplementation files(hermesPath + "hermes-debug.aar")
- releaseImplementation files(hermesPath + "hermes-release.aar")
+ //noinspection GradleDynamicVersion
+ implementation("com.facebook.react:hermes-engine:+") { // From node_modules
+ exclude group:'com.facebook.fbjni'
+ }
} else {
implementation jscFlavor
}
// Firebase libraries (using the Firebase BoM for consistency - see https://firebase.google.com/docs/android/learn-more#bom)
- implementation platform("com.google.firebase:firebase-bom:29.0.3")
+ implementation platform("com.google.firebase:firebase-bom:30.3.1")
implementation "com.google.firebase:firebase-perf"
implementation "com.google.firebase:firebase-crashlytics"
@@ -260,6 +328,22 @@ dependencies {
implementation "com.squareup.okhttp3:okhttp-urlconnection:4.+"
}
+if (isNewArchitectureEnabled()) {
+ // If new architecture is enabled, we let you build RN from source
+ // Otherwise we fallback to a prebuilt .aar bundled in the NPM package.
+ // This will be applied to all the imported transtitive dependency.
+ configurations.all {
+ resolutionStrategy.dependencySubstitution {
+ substitute(module("com.facebook.react:react-native"))
+ .using(project(":ReactAndroid"))
+ .because("On New Architecture we're building React Native from source")
+ substitute(module("com.facebook.react:hermes-engine"))
+ .using(project(":ReactAndroid:hermes-engine"))
+ .because("On New Architecture we're building Hermes from source")
+ }
+ }
+}
+
// Run this once to be able to run the application with BUCK
// puts all compile dependencies into folder libs for BUCK to use
task copyDownloadableDepsToLibs(type: Copy) {
@@ -274,4 +358,10 @@ if (googleServicesFile.exists()) {
}
apply plugin: 'com.google.firebase.crashlytics'
-
+def isNewArchitectureEnabled() {
+ // To opt-in for the New Architecture, you can either:
+ // - Set `newArchEnabled` to true inside the `gradle.properties` file
+ // - Invoke gradle with `-newArchEnabled=true`
+ // - Set an environment variable `ORG_GRADLE_PROJECT_newArchEnabled=true`
+ return project.hasProperty("newArchEnabled") && project.newArchEnabled == "true"
+}
diff --git a/android/app/src/debug/AndroidManifest.xml b/android/app/src/debug/AndroidManifest.xml
index 912a6f110cb4..7e1870e8b30b 100644
--- a/android/app/src/debug/AndroidManifest.xml
+++ b/android/app/src/debug/AndroidManifest.xml
@@ -9,5 +9,6 @@
android:name="firebase_performance_logcat_enabled"
android:value="true"
/>
+
diff --git a/android/app/src/debug/java/com/reactnativechat/ReactNativeFlipper.java b/android/app/src/debug/java/com/reactnativechat/ReactNativeFlipper.java
index ae2d14ce9b67..a035517eb727 100644
--- a/android/app/src/debug/java/com/reactnativechat/ReactNativeFlipper.java
+++ b/android/app/src/debug/java/com/reactnativechat/ReactNativeFlipper.java
@@ -1,5 +1,5 @@
/**
- * Copyright (c) Facebook, Inc. and its affiliates.
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
*
*
This source code is licensed under the MIT license found in the LICENSE file in the root
* directory of this source tree.
@@ -19,6 +19,7 @@
import com.facebook.flipper.plugins.network.NetworkFlipperPlugin;
import com.facebook.flipper.plugins.react.ReactFlipperPlugin;
import com.facebook.flipper.plugins.sharedpreferences.SharedPreferencesFlipperPlugin;
+import com.facebook.react.ReactInstanceEventListener;
import com.facebook.react.ReactInstanceManager;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.modules.network.NetworkingModule;
@@ -51,7 +52,7 @@ public void apply(OkHttpClient.Builder builder) {
ReactContext reactContext = reactInstanceManager.getCurrentReactContext();
if (reactContext == null) {
reactInstanceManager.addReactInstanceEventListener(
- new ReactInstanceManager.ReactInstanceEventListener() {
+ new ReactInstanceEventListener() {
@Override
public void onReactContextInitialized(ReactContext reactContext) {
reactInstanceManager.removeReactInstanceEventListener(this);
diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml
index a5d23081f6f2..57f6e31a1aca 100644
--- a/android/app/src/main/AndroidManifest.xml
+++ b/android/app/src/main/AndroidManifest.xml
@@ -8,7 +8,7 @@
+ android:windowSoftInputMode="adjustResize"
+ android:exported="true">
Please note that this class is used ONLY if you opt-in for the New Architecture (see the
+ * `newArchEnabled` property). Is ignored otherwise.
+ */
+public class MainApplicationReactNativeHost extends ReactNativeHost {
+ public MainApplicationReactNativeHost(Application application) {
+ super(application);
+ }
+
+ @Override
+ public boolean getUseDeveloperSupport() {
+ return BuildConfig.DEBUG;
+ }
+
+ @Override
+ protected List getPackages() {
+ List packages = new PackageList(this).getPackages();
+ // Packages that cannot be autolinked yet can be added manually here, for example:
+ // packages.add(new MyReactNativePackage());
+ // TurboModules must also be loaded here providing a valid TurboReactPackage implementation:
+ // packages.add(new TurboReactPackage() { ... });
+ // If you have custom Fabric Components, their ViewManagers should also be loaded here
+ // inside a ReactPackage.
+ return packages;
+ }
+
+ @Override
+ protected String getJSMainModuleName() {
+ return "index";
+ }
+
+ @NonNull
+ @Override
+ protected ReactPackageTurboModuleManagerDelegate.Builder
+ getReactPackageTurboModuleManagerDelegateBuilder() {
+ // Here we provide the ReactPackageTurboModuleManagerDelegate Builder. This is necessary
+ // for the new architecture and to use TurboModules correctly.
+ return new MainApplicationTurboModuleManagerDelegate.Builder();
+ }
+
+ @Override
+ protected JSIModulePackage getJSIModulePackage() {
+ return new JSIModulePackage() {
+ @Override
+ public List getJSIModules(
+ final ReactApplicationContext reactApplicationContext,
+ final JavaScriptContextHolder jsContext) {
+ final List specs = new ArrayList<>();
+
+ // Here we provide a new JSIModuleSpec that will be responsible of providing the
+ // custom Fabric Components.
+ specs.add(
+ new JSIModuleSpec() {
+ @Override
+ public JSIModuleType getJSIModuleType() {
+ return JSIModuleType.UIManager;
+ }
+
+ @Override
+ public JSIModuleProvider getJSIModuleProvider() {
+ final ComponentFactory componentFactory = new ComponentFactory();
+ CoreComponentsRegistry.register(componentFactory);
+
+ // Here we register a Components Registry.
+ // The one that is generated with the template contains no components
+ // and just provides you the one from React Native core.
+ MainComponentsRegistry.register(componentFactory);
+
+ final ReactInstanceManager reactInstanceManager = getReactInstanceManager();
+
+ ViewManagerRegistry viewManagerRegistry =
+ new ViewManagerRegistry(
+ reactInstanceManager.getOrCreateViewManagers(reactApplicationContext));
+
+ return new FabricJSIModuleProvider(
+ reactApplicationContext,
+ componentFactory,
+ ReactNativeConfig.DEFAULT_CONFIG,
+ viewManagerRegistry);
+ }
+ });
+ return specs;
+ }
+ };
+ }
+}
diff --git a/android/app/src/main/java/com/expensify/chat/newarchitecture/components/MainComponentsRegistry.java b/android/app/src/main/java/com/expensify/chat/newarchitecture/components/MainComponentsRegistry.java
new file mode 100644
index 000000000000..a5cf79a4950c
--- /dev/null
+++ b/android/app/src/main/java/com/expensify/chat/newarchitecture/components/MainComponentsRegistry.java
@@ -0,0 +1,36 @@
+package com.expensify.chat.newarchitecture.components;
+
+import com.facebook.jni.HybridData;
+import com.facebook.proguard.annotations.DoNotStrip;
+import com.facebook.react.fabric.ComponentFactory;
+import com.facebook.soloader.SoLoader;
+
+/**
+ * Class responsible to load the custom Fabric Components. This class has native methods and needs a
+ * corresponding C++ implementation/header file to work correctly (already placed inside the jni/
+ * folder for you).
+ *
+ * Please note that this class is used ONLY if you opt-in for the New Architecture (see the
+ * `newArchEnabled` property). Is ignored otherwise.
+ */
+@DoNotStrip
+public class MainComponentsRegistry {
+ static {
+ SoLoader.loadLibrary("fabricjni");
+ }
+
+ @DoNotStrip private final HybridData mHybridData;
+
+ @DoNotStrip
+ private native HybridData initHybrid(ComponentFactory componentFactory);
+
+ @DoNotStrip
+ private MainComponentsRegistry(ComponentFactory componentFactory) {
+ mHybridData = initHybrid(componentFactory);
+ }
+
+ @DoNotStrip
+ public static MainComponentsRegistry register(ComponentFactory componentFactory) {
+ return new MainComponentsRegistry(componentFactory);
+ }
+}
diff --git a/android/app/src/main/java/com/expensify/chat/newarchitecture/modules/MainApplicationTurboModuleManagerDelegate.java b/android/app/src/main/java/com/expensify/chat/newarchitecture/modules/MainApplicationTurboModuleManagerDelegate.java
new file mode 100644
index 000000000000..1781cfd57ca3
--- /dev/null
+++ b/android/app/src/main/java/com/expensify/chat/newarchitecture/modules/MainApplicationTurboModuleManagerDelegate.java
@@ -0,0 +1,48 @@
+package com.expensify.chat.newarchitecture.modules;
+
+import com.facebook.jni.HybridData;
+import com.facebook.react.ReactPackage;
+import com.facebook.react.ReactPackageTurboModuleManagerDelegate;
+import com.facebook.react.bridge.ReactApplicationContext;
+import com.facebook.soloader.SoLoader;
+import java.util.List;
+
+/**
+ * Class responsible to load the TurboModules. This class has native methods and needs a
+ * corresponding C++ implementation/header file to work correctly (already placed inside the jni/
+ * folder for you).
+ *
+ *
Please note that this class is used ONLY if you opt-in for the New Architecture (see the
+ * `newArchEnabled` property). Is ignored otherwise.
+ */
+public class MainApplicationTurboModuleManagerDelegate
+ extends ReactPackageTurboModuleManagerDelegate {
+
+ private static volatile boolean sIsSoLibraryLoaded;
+
+ protected MainApplicationTurboModuleManagerDelegate(
+ ReactApplicationContext reactApplicationContext, List packages) {
+ super(reactApplicationContext, packages);
+ }
+
+ protected native HybridData initHybrid();
+
+ native boolean canCreateTurboModule(String moduleName);
+
+ public static class Builder extends ReactPackageTurboModuleManagerDelegate.Builder {
+ protected MainApplicationTurboModuleManagerDelegate build(
+ ReactApplicationContext context, List packages) {
+ return new MainApplicationTurboModuleManagerDelegate(context, packages);
+ }
+ }
+
+ @Override
+ protected synchronized void maybeLoadOtherSoLibraries() {
+ if (!sIsSoLibraryLoaded) {
+ // If you change the name of your application .so file in the Android.mk file,
+ // make sure you update the name here as well.
+ SoLoader.loadLibrary("rndiffapp_appmodules");
+ sIsSoLibraryLoaded = true;
+ }
+ }
+}
diff --git a/android/app/src/main/jni/Android.mk b/android/app/src/main/jni/Android.mk
new file mode 100644
index 000000000000..842579d5ed94
--- /dev/null
+++ b/android/app/src/main/jni/Android.mk
@@ -0,0 +1,48 @@
+THIS_DIR := $(call my-dir)
+
+include $(REACT_ANDROID_DIR)/Android-prebuilt.mk
+
+# If you wish to add a custom TurboModule or Fabric component in your app you
+# will have to include the following autogenerated makefile.
+# include $(GENERATED_SRC_DIR)/codegen/jni/Android.mk
+include $(CLEAR_VARS)
+
+LOCAL_PATH := $(THIS_DIR)
+
+# You can customize the name of your application .so file here.
+LOCAL_MODULE := rndiffapp_appmodules
+
+LOCAL_C_INCLUDES := $(LOCAL_PATH)
+LOCAL_SRC_FILES := $(wildcard $(LOCAL_PATH)/*.cpp)
+LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)
+
+# If you wish to add a custom TurboModule or Fabric component in your app you
+# will have to uncomment those lines to include the generated source
+# files from the codegen (placed in $(GENERATED_SRC_DIR)/codegen/jni)
+#
+# LOCAL_C_INCLUDES += $(GENERATED_SRC_DIR)/codegen/jni
+# LOCAL_SRC_FILES += $(wildcard $(GENERATED_SRC_DIR)/codegen/jni/*.cpp)
+# LOCAL_EXPORT_C_INCLUDES += $(GENERATED_SRC_DIR)/codegen/jni
+
+# Here you should add any native library you wish to depend on.
+LOCAL_SHARED_LIBRARIES := \
+ libfabricjni \
+ libfbjni \
+ libfolly_runtime \
+ libglog \
+ libjsi \
+ libreact_codegen_rncore \
+ libreact_debug \
+ libreact_nativemodule_core \
+ libreact_render_componentregistry \
+ libreact_render_core \
+ libreact_render_debug \
+ libreact_render_graphics \
+ librrc_view \
+ libruntimeexecutor \
+ libturbomodulejsijni \
+ libyoga
+
+LOCAL_CFLAGS := -DLOG_TAG=\"ReactNative\" -fexceptions -frtti -std=c++17 -Wall
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/android/app/src/main/jni/MainApplicationModuleProvider.cpp b/android/app/src/main/jni/MainApplicationModuleProvider.cpp
new file mode 100644
index 000000000000..0ac23cc62634
--- /dev/null
+++ b/android/app/src/main/jni/MainApplicationModuleProvider.cpp
@@ -0,0 +1,24 @@
+#include "MainApplicationModuleProvider.h"
+
+#include
+
+namespace facebook {
+namespace react {
+
+std::shared_ptr MainApplicationModuleProvider(
+ const std::string moduleName,
+ const JavaTurboModule::InitParams ¶ms) {
+ // Here you can provide your own module provider for TurboModules coming from
+ // either your application or from external libraries. The approach to follow
+ // is similar to the following (for a library called `samplelibrary`:
+ //
+ // auto module = samplelibrary_ModuleProvider(moduleName, params);
+ // if (module != nullptr) {
+ // return module;
+ // }
+ // return rncore_ModuleProvider(moduleName, params);
+ return rncore_ModuleProvider(moduleName, params);
+}
+
+} // namespace react
+} // namespace facebook
diff --git a/android/app/src/main/jni/MainApplicationModuleProvider.h b/android/app/src/main/jni/MainApplicationModuleProvider.h
new file mode 100644
index 000000000000..0fa43fa69ad4
--- /dev/null
+++ b/android/app/src/main/jni/MainApplicationModuleProvider.h
@@ -0,0 +1,16 @@
+#pragma once
+
+#include
+#include
+
+#include
+
+namespace facebook {
+namespace react {
+
+std::shared_ptr MainApplicationModuleProvider(
+ const std::string moduleName,
+ const JavaTurboModule::InitParams ¶ms);
+
+} // namespace react
+} // namespace facebook
diff --git a/android/app/src/main/jni/MainApplicationTurboModuleManagerDelegate.cpp b/android/app/src/main/jni/MainApplicationTurboModuleManagerDelegate.cpp
new file mode 100644
index 000000000000..dbbdc3d13205
--- /dev/null
+++ b/android/app/src/main/jni/MainApplicationTurboModuleManagerDelegate.cpp
@@ -0,0 +1,45 @@
+#include "MainApplicationTurboModuleManagerDelegate.h"
+#include "MainApplicationModuleProvider.h"
+
+namespace facebook {
+namespace react {
+
+jni::local_ref
+MainApplicationTurboModuleManagerDelegate::initHybrid(
+ jni::alias_ref) {
+ return makeCxxInstance();
+}
+
+void MainApplicationTurboModuleManagerDelegate::registerNatives() {
+ registerHybrid({
+ makeNativeMethod(
+ "initHybrid", MainApplicationTurboModuleManagerDelegate::initHybrid),
+ makeNativeMethod(
+ "canCreateTurboModule",
+ MainApplicationTurboModuleManagerDelegate::canCreateTurboModule),
+ });
+}
+
+std::shared_ptr
+MainApplicationTurboModuleManagerDelegate::getTurboModule(
+ const std::string name,
+ const std::shared_ptr jsInvoker) {
+ // Not implemented yet: provide pure-C++ NativeModules here.
+ return nullptr;
+}
+
+std::shared_ptr
+MainApplicationTurboModuleManagerDelegate::getTurboModule(
+ const std::string name,
+ const JavaTurboModule::InitParams ¶ms) {
+ return MainApplicationModuleProvider(name, params);
+}
+
+bool MainApplicationTurboModuleManagerDelegate::canCreateTurboModule(
+ std::string name) {
+ return getTurboModule(name, nullptr) != nullptr ||
+ getTurboModule(name, {.moduleName = name}) != nullptr;
+}
+
+} // namespace react
+} // namespace facebook
diff --git a/android/app/src/main/jni/MainApplicationTurboModuleManagerDelegate.h b/android/app/src/main/jni/MainApplicationTurboModuleManagerDelegate.h
new file mode 100644
index 000000000000..2dc0d8f514b2
--- /dev/null
+++ b/android/app/src/main/jni/MainApplicationTurboModuleManagerDelegate.h
@@ -0,0 +1,38 @@
+#include
+#include
+
+#include
+#include
+
+namespace facebook {
+namespace react {
+
+class MainApplicationTurboModuleManagerDelegate
+ : public jni::HybridClass<
+ MainApplicationTurboModuleManagerDelegate,
+ TurboModuleManagerDelegate> {
+ public:
+ // Adapt it to the package you used for your Java class.
+ static constexpr auto kJavaDescriptor =
+ "Lcom/expensify/chat/newarchitecture/modules/MainApplicationTurboModuleManagerDelegate;";
+
+ static jni::local_ref initHybrid(jni::alias_ref);
+
+ static void registerNatives();
+
+ std::shared_ptr getTurboModule(
+ const std::string name,
+ const std::shared_ptr jsInvoker) override;
+ std::shared_ptr getTurboModule(
+ const std::string name,
+ const JavaTurboModule::InitParams ¶ms) override;
+
+ /**
+ * Test-only method. Allows user to verify whether a TurboModule can be
+ * created by instances of this class.
+ */
+ bool canCreateTurboModule(std::string name);
+};
+
+} // namespace react
+} // namespace facebook
diff --git a/android/app/src/main/jni/MainComponentsRegistry.cpp b/android/app/src/main/jni/MainComponentsRegistry.cpp
new file mode 100644
index 000000000000..8f7edffd6423
--- /dev/null
+++ b/android/app/src/main/jni/MainComponentsRegistry.cpp
@@ -0,0 +1,61 @@
+#include "MainComponentsRegistry.h"
+
+#include
+#include
+#include
+#include
+
+namespace facebook {
+namespace react {
+
+MainComponentsRegistry::MainComponentsRegistry(ComponentFactory *delegate) {}
+
+std::shared_ptr
+MainComponentsRegistry::sharedProviderRegistry() {
+ auto providerRegistry = CoreComponentsRegistry::sharedProviderRegistry();
+
+ // Custom Fabric Components go here. You can register custom
+ // components coming from your App or from 3rd party libraries here.
+ //
+ // providerRegistry->add(concreteComponentDescriptorProvider<
+ // AocViewerComponentDescriptor>());
+ return providerRegistry;
+}
+
+jni::local_ref
+MainComponentsRegistry::initHybrid(
+ jni::alias_ref,
+ ComponentFactory *delegate) {
+ auto instance = makeCxxInstance(delegate);
+
+ auto buildRegistryFunction =
+ [](EventDispatcher::Weak const &eventDispatcher,
+ ContextContainer::Shared const &contextContainer)
+ -> ComponentDescriptorRegistry::Shared {
+ auto registry = MainComponentsRegistry::sharedProviderRegistry()
+ ->createComponentDescriptorRegistry(
+ {eventDispatcher, contextContainer});
+
+ auto mutableRegistry =
+ std::const_pointer_cast(registry);
+
+ mutableRegistry->setFallbackComponentDescriptor(
+ std::make_shared(
+ ComponentDescriptorParameters{
+ eventDispatcher, contextContainer, nullptr}));
+
+ return registry;
+ };
+
+ delegate->buildRegistryFunction = buildRegistryFunction;
+ return instance;
+}
+
+void MainComponentsRegistry::registerNatives() {
+ registerHybrid({
+ makeNativeMethod("initHybrid", MainComponentsRegistry::initHybrid),
+ });
+}
+
+} // namespace react
+} // namespace facebook
diff --git a/android/app/src/main/jni/MainComponentsRegistry.h b/android/app/src/main/jni/MainComponentsRegistry.h
new file mode 100644
index 000000000000..d38e39614efc
--- /dev/null
+++ b/android/app/src/main/jni/MainComponentsRegistry.h
@@ -0,0 +1,32 @@
+#pragma once
+
+#include
+#include
+#include
+#include
+
+namespace facebook {
+namespace react {
+
+class MainComponentsRegistry
+ : public facebook::jni::HybridClass {
+ public:
+ // Adapt it to the package you used for your Java class.
+ constexpr static auto kJavaDescriptor =
+ "Lcom/expensify/chat/newarchitecture/components/MainComponentsRegistry;";
+
+ static void registerNatives();
+
+ MainComponentsRegistry(ComponentFactory *delegate);
+
+ private:
+ static std::shared_ptr
+ sharedProviderRegistry();
+
+ static jni::local_ref initHybrid(
+ jni::alias_ref,
+ ComponentFactory *delegate);
+};
+
+} // namespace react
+} // namespace facebook
diff --git a/android/app/src/main/jni/OnLoad.cpp b/android/app/src/main/jni/OnLoad.cpp
new file mode 100644
index 000000000000..c569b6e865da
--- /dev/null
+++ b/android/app/src/main/jni/OnLoad.cpp
@@ -0,0 +1,11 @@
+#include
+#include "MainApplicationTurboModuleManagerDelegate.h"
+#include "MainComponentsRegistry.h"
+
+JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *) {
+ return facebook::jni::initialize(vm, [] {
+ facebook::react::MainApplicationTurboModuleManagerDelegate::
+ registerNatives();
+ facebook::react::MainComponentsRegistry::registerNatives();
+ });
+}
diff --git a/android/app/src/main/res/drawable/rn_edit_text_material.xml b/android/app/src/main/res/drawable/rn_edit_text_material.xml
new file mode 100644
index 000000000000..f35d9962026a
--- /dev/null
+++ b/android/app/src/main/res/drawable/rn_edit_text_material.xml
@@ -0,0 +1,36 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/android/app/src/main/res/values/styles.xml b/android/app/src/main/res/values/styles.xml
index a6e0f567f7e0..297b87b433dd 100644
--- a/android/app/src/main/res/values/styles.xml
+++ b/android/app/src/main/res/values/styles.xml
@@ -8,6 +8,7 @@
- @color/accent
- @color/white
- true
+ - @drawable/rn_edit_text_material