-
Notifications
You must be signed in to change notification settings - Fork 3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[HybridApp] Add HybridApp turbomodule #57406
base: main
Are you sure you want to change the base?
Changes from all commits
6406e0d
c128b40
9e744e5
56b171b
c19b951
73d1b3a
ef370cc
91a78a2
70223f9
ad70f0c
2860064
4b8151d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
require "json" | ||
|
||
package = JSON.parse(File.read(File.join(__dir__, "package.json"))) | ||
|
||
Pod::Spec.new do |s| | ||
s.name = "ReactNativeHybridApp" | ||
s.version = package["version"] | ||
s.summary = package["description"] | ||
s.homepage = package["homepage"] | ||
s.license = package["license"] | ||
s.authors = package["author"] | ||
|
||
s.platforms = { :ios => min_ios_version_supported } | ||
s.source = { :git => ".git", :tag => "#{s.version}" } | ||
|
||
s.source_files = "ios/**/*.{h,m,mm,cpp}" | ||
s.pod_target_xcconfig = { | ||
"CLANG_CXX_LANGUAGE_STANDARD" => "c++20", | ||
} | ||
|
||
install_modules_dependencies(s) | ||
end |
Original file line number | Diff line number | Diff line change | ||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,111 @@ | ||||||||||||||||
buildscript { | ||||||||||||||||
ext.getExtOrDefault = {name -> | ||||||||||||||||
return rootProject.ext.has(name) ? rootProject.ext.get(name) : project.properties['ReactNativeHybridApp_' + name] | ||||||||||||||||
} | ||||||||||||||||
|
||||||||||||||||
repositories { | ||||||||||||||||
google() | ||||||||||||||||
mavenCentral() | ||||||||||||||||
} | ||||||||||||||||
|
||||||||||||||||
dependencies { | ||||||||||||||||
classpath "com.android.tools.build:gradle:8.7.2" | ||||||||||||||||
// noinspection DifferentKotlinGradleVersion | ||||||||||||||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:${getExtOrDefault('kotlinVersion')}" | ||||||||||||||||
} | ||||||||||||||||
} | ||||||||||||||||
|
||||||||||||||||
|
||||||||||||||||
def isNewArchitectureEnabled() { | ||||||||||||||||
return rootProject.hasProperty("newArchEnabled") && rootProject.getProperty("newArchEnabled") == "true" | ||||||||||||||||
} | ||||||||||||||||
|
||||||||||||||||
apply plugin: "com.android.library" | ||||||||||||||||
apply plugin: "kotlin-android" | ||||||||||||||||
|
||||||||||||||||
if (isNewArchitectureEnabled()) { | ||||||||||||||||
apply plugin: "com.facebook.react" | ||||||||||||||||
} | ||||||||||||||||
|
||||||||||||||||
def getExtOrIntegerDefault(name) { | ||||||||||||||||
return rootProject.ext.has(name) ? rootProject.ext.get(name) : (project.properties["ReactNativeHybridApp_" + name]).toInteger() | ||||||||||||||||
} | ||||||||||||||||
|
||||||||||||||||
def supportsNamespace() { | ||||||||||||||||
def parsed = com.android.Version.ANDROID_GRADLE_PLUGIN_VERSION.tokenize('.') | ||||||||||||||||
def major = parsed[0].toInteger() | ||||||||||||||||
def minor = parsed[1].toInteger() | ||||||||||||||||
|
||||||||||||||||
// Namespace support was added in 7.3.0 | ||||||||||||||||
return (major == 7 && minor >= 3) || major >= 8 | ||||||||||||||||
} | ||||||||||||||||
|
||||||||||||||||
android { | ||||||||||||||||
if (supportsNamespace()) { | ||||||||||||||||
namespace "com.expensify.reactnativehybridapp" | ||||||||||||||||
|
||||||||||||||||
sourceSets { | ||||||||||||||||
main { | ||||||||||||||||
manifest.srcFile "src/main/AndroidManifestNew.xml" | ||||||||||||||||
} | ||||||||||||||||
} | ||||||||||||||||
} | ||||||||||||||||
|
||||||||||||||||
compileSdkVersion getExtOrIntegerDefault("compileSdkVersion") | ||||||||||||||||
|
||||||||||||||||
defaultConfig { | ||||||||||||||||
minSdkVersion getExtOrIntegerDefault("minSdkVersion") | ||||||||||||||||
targetSdkVersion getExtOrIntegerDefault("targetSdkVersion") | ||||||||||||||||
buildConfigField "boolean", "IS_NEW_ARCHITECTURE_ENABLED", isNewArchitectureEnabled().toString() | ||||||||||||||||
} | ||||||||||||||||
|
||||||||||||||||
buildFeatures { | ||||||||||||||||
buildConfig true | ||||||||||||||||
} | ||||||||||||||||
|
||||||||||||||||
buildTypes { | ||||||||||||||||
release { | ||||||||||||||||
minifyEnabled false | ||||||||||||||||
} | ||||||||||||||||
} | ||||||||||||||||
|
||||||||||||||||
lintOptions { | ||||||||||||||||
disable "GradleCompatible" | ||||||||||||||||
} | ||||||||||||||||
|
||||||||||||||||
compileOptions { | ||||||||||||||||
sourceCompatibility JavaVersion.VERSION_1_8 | ||||||||||||||||
targetCompatibility JavaVersion.VERSION_1_8 | ||||||||||||||||
} | ||||||||||||||||
|
||||||||||||||||
sourceSets { | ||||||||||||||||
main { | ||||||||||||||||
if (isNewArchitectureEnabled()) { | ||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We are always having new arch so we could remove it but w/e |
||||||||||||||||
java.srcDirs += [ | ||||||||||||||||
"generated/java", | ||||||||||||||||
"generated/jni" | ||||||||||||||||
] | ||||||||||||||||
} | ||||||||||||||||
} | ||||||||||||||||
} | ||||||||||||||||
} | ||||||||||||||||
|
||||||||||||||||
repositories { | ||||||||||||||||
mavenCentral() | ||||||||||||||||
google() | ||||||||||||||||
} | ||||||||||||||||
|
||||||||||||||||
def kotlin_version = getExtOrDefault("kotlinVersion") | ||||||||||||||||
|
||||||||||||||||
dependencies { | ||||||||||||||||
implementation "com.facebook.react:react-android" | ||||||||||||||||
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" | ||||||||||||||||
} | ||||||||||||||||
|
||||||||||||||||
if (isNewArchitectureEnabled()) { | ||||||||||||||||
react { | ||||||||||||||||
jsRootDir = file("../src/") | ||||||||||||||||
libraryName = "ReactNativeHybridApp" | ||||||||||||||||
codegenJavaPackageName = "com.expensify.reactnativehybridapp" | ||||||||||||||||
} | ||||||||||||||||
} | ||||||||||||||||
Comment on lines
+105
to
+111
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
These lines are not needed |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
ReactNativeHybridApp_kotlinVersion=2.0.21 | ||
ReactNativeHybridApp_minSdkVersion=24 | ||
ReactNativeHybridApp_targetSdkVersion=34 | ||
ReactNativeHybridApp_compileSdkVersion=35 | ||
ReactNativeHybridApp_ndkVersion=27.1.12297006 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why are those manifests needed? |
||
package="com.expensify.reactnativehybridapp"> | ||
</manifest> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"> | ||
</manifest> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
package com.expensify.reactnativehybridapp | ||
|
||
import com.facebook.react.bridge.ReactApplicationContext | ||
import com.facebook.react.module.annotations.ReactModule | ||
|
||
@ReactModule(name = ReactNativeHybridAppModule.NAME) | ||
class ReactNativeHybridAppModule(reactContext: ReactApplicationContext) : | ||
NativeReactNativeHybridAppSpec(reactContext) { | ||
|
||
override fun getName(): String { | ||
return NAME | ||
} | ||
|
||
override fun isHybridApp(): Boolean { | ||
return false | ||
} | ||
|
||
override fun closeReactNativeApp(shouldSignOut: Boolean, shouldSetNVP: Boolean) {} | ||
|
||
override fun completeOnboarding(status: Boolean) {} | ||
|
||
override fun switchAccount( | ||
newDotCurrentAccountEmail: String?, | ||
authToken: String?, | ||
policyID: String?, | ||
accountID: String? | ||
) {} | ||
|
||
companion object { | ||
const val NAME = "ReactNativeHybridAppModule" | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
package com.expensify.reactnativehybridapp | ||
|
||
import com.facebook.react.BaseReactPackage | ||
import com.facebook.react.bridge.NativeModule | ||
import com.facebook.react.bridge.ReactApplicationContext | ||
import com.facebook.react.module.model.ReactModuleInfo | ||
import com.facebook.react.module.model.ReactModuleInfoProvider | ||
import java.util.HashMap | ||
|
||
class ReactNativeHybridAppPackage : BaseReactPackage() { | ||
override fun getModule(name: String, reactContext: ReactApplicationContext): NativeModule? { | ||
return if (name == ReactNativeHybridAppModule.NAME) { | ||
ReactNativeHybridAppModule(reactContext) | ||
} else { | ||
null | ||
} | ||
} | ||
|
||
override fun getReactModuleInfoProvider(): ReactModuleInfoProvider { | ||
return ReactModuleInfoProvider { | ||
val moduleInfos: MutableMap<String, ReactModuleInfo> = HashMap() | ||
moduleInfos[ReactNativeHybridAppModule.NAME] = ReactModuleInfo( | ||
ReactNativeHybridAppModule.NAME, | ||
ReactNativeHybridAppModule.NAME, | ||
false, // canOverrideExistingModule | ||
false, // needsEagerInit | ||
false, // isCxxModule | ||
true // isTurboModule | ||
) | ||
moduleInfos | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
|
||
#import "RNReactNativeHybridAppSpec/RNReactNativeHybridAppSpec.h" | ||
|
||
@interface ReactNativeHybridApp : NSObject <NativeReactNativeHybridAppSpec> | ||
|
||
@end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
#import "ReactNativeHybridApp.h" | ||
|
||
@implementation ReactNativeHybridApp | ||
RCT_EXPORT_MODULE() | ||
|
||
- (NSNumber *)isHybridApp { | ||
return @false; | ||
} | ||
|
||
- (void)closeReactNativeApp:(BOOL)shouldSignOut shouldSetNVP:(BOOL)shouldSetNVP {} | ||
|
||
- (void)completeOnboarding:(BOOL)status {} | ||
|
||
- (void)switchAccount:(NSString *)newDotCurrentAccountEmail authToken:(NSString *)authToken policyID:(NSString *)policyID accountID:(NSString *)accountID {} | ||
|
||
- (std::shared_ptr<facebook::react::TurboModule>)getTurboModule: | ||
(const facebook::react::ObjCTurboModule::InitParams &)params | ||
{ | ||
return std::make_shared<facebook::react::NativeReactNativeHybridAppSpecJSI>(params); | ||
} | ||
|
||
@end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
{ | ||
"name": "@expensify/react-native-hybrid-app", | ||
"version": "0.0.0", | ||
"description": "HybridApp", | ||
"main": "src/index", | ||
"codegenConfig": { | ||
"name": "RNReactNativeHybridAppSpec", | ||
"type": "modules", | ||
"jsSrcsDir": "src" | ||
}, | ||
"author": " <> ()", | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe we want to fill those fields too? |
||
"license": "UNLICENSED", | ||
"homepage": "#readme", | ||
"create-react-native-library": { | ||
"type": "turbo-module", | ||
"languages": "kotlin-objc", | ||
"version": "0.48.1" | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
/** | ||
* @type {import('@react-native-community/cli-types').UserDependencyConfig} | ||
*/ | ||
module.exports = { | ||
dependency: { | ||
platforms: { | ||
android: { | ||
cmakeListsPath: 'build/generated/source/codegen/jni/CMakeLists.txt', | ||
}, | ||
}, | ||
}, | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
import type {TurboModule} from 'react-native'; | ||
import {TurboModuleRegistry} from 'react-native'; | ||
|
||
// eslint-disable-next-line rulesdir/no-inline-named-export, @typescript-eslint/consistent-type-definitions | ||
export interface Spec extends TurboModule { | ||
isHybridApp: () => boolean; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would even store this value somewhere in order not to do a call to native code each time it is checked. It won't change during the lifetime of app so it should be safe I guess. |
||
closeReactNativeApp: (shouldSignOut: boolean, shouldSetNVP: boolean) => void; | ||
completeOnboarding: (status: boolean) => void; | ||
switchAccount: (newDotCurrentAccountEmail: string, authToken: string, policyID: string, accountID: string) => void; | ||
} | ||
|
||
export default TurboModuleRegistry.getEnforcing<Spec>('ReactNativeHybridApp'); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
import ReactNativeHybridApp from './NativeReactNativeHybridApp'; | ||
|
||
const HybridAppModule = ReactNativeHybridApp; | ||
|
||
export default HybridAppModule; |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We know that we have higher version of gradle so we could remove it too.