diff --git a/.eslintrc.js b/.eslintrc.js index f08d477670..2fe32e7f1b 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -5,8 +5,6 @@ module.exports = { 'plugin:import/warnings', 'plugin:react/recommended', 'prettier', - 'prettier/react', - 'prettier/standard', ], plugins: ['react-native', 'react-hooks'], @@ -51,10 +49,12 @@ module.exports = { { files: ['*.{ts,tsx}'], parser: '@typescript-eslint/parser', + parserOptions: { + project: ['./tsconfig.json'], + }, extends: [ 'plugin:@typescript-eslint/recommended', 'plugin:import/typescript', - 'prettier/@typescript-eslint', ], settings: { 'import/parsers': { @@ -62,6 +62,7 @@ module.exports = { }, }, rules: { + '@typescript-eslint/no-explicit-any': 'warn', '@typescript-eslint/array-type': 'error', '@typescript-eslint/consistent-type-assertions': [ 'error', diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 0000000000..ffc9f6c4e6 --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1 @@ +github: software-mansion diff --git a/.github/workflows/android-build-test-fabric.yml b/.github/workflows/android-build-test-fabric.yml index 39b8a8f72b..95a071c2db 100644 --- a/.github/workflows/android-build-test-fabric.yml +++ b/.github/workflows/android-build-test-fabric.yml @@ -17,6 +17,7 @@ on: jobs: build: runs-on: ubuntu-latest + timeout-minutes: 60 env: WORKING_DIRECTORY: FabricTestExample concurrency: diff --git a/.github/workflows/android-build-test.yml b/.github/workflows/android-build-test.yml index e9383b03ae..b39c65c9ea 100644 --- a/.github/workflows/android-build-test.yml +++ b/.github/workflows/android-build-test.yml @@ -15,6 +15,7 @@ on: jobs: build: runs-on: ubuntu-latest + timeout-minutes: 60 env: WORKING_DIRECTORY: TestsExample concurrency: diff --git a/.github/workflows/android-e2e-test.yml b/.github/workflows/android-e2e-test.yml index 0049581fa4..c791a3e2a8 100644 --- a/.github/workflows/android-e2e-test.yml +++ b/.github/workflows/android-e2e-test.yml @@ -24,10 +24,12 @@ jobs: steps: - name: Checkout uses: actions/checkout@v3 - - name: Set up JDK 11 - uses: actions/setup-java@v1 + - name: Set up JDK 17 + uses: actions/setup-java@v3 with: - java-version: '11' + java-version: '17' + distribution: 'zulu' + cache: 'gradle' - name: Use Node.js 18 uses: actions/setup-node@v3 with: diff --git a/.github/workflows/ios-build-test-fabric.yml b/.github/workflows/ios-build-test-fabric.yml index b5b4045909..4c66e41aa5 100644 --- a/.github/workflows/ios-build-test-fabric.yml +++ b/.github/workflows/ios-build-test-fabric.yml @@ -18,6 +18,7 @@ on: jobs: build: runs-on: macos-12 + timeout-minutes: 60 env: WORKING_DIRECTORY: FabricTestExample concurrency: diff --git a/.github/workflows/ios-build-test.yml b/.github/workflows/ios-build-test.yml index f1b8a8f5e0..dda2d6eee6 100644 --- a/.github/workflows/ios-build-test.yml +++ b/.github/workflows/ios-build-test.yml @@ -17,6 +17,7 @@ on: jobs: build: runs-on: macos-12 + timeout-minutes: 60 env: WORKING_DIRECTORY: TestsExample concurrency: diff --git a/.github/workflows/tv-os-build-test.yml b/.github/workflows/tv-os-build-test.yml index aa08c7a5d8..e598de968d 100644 --- a/.github/workflows/tv-os-build-test.yml +++ b/.github/workflows/tv-os-build-test.yml @@ -17,6 +17,7 @@ on: jobs: build: runs-on: macos-12 + timeout-minutes: 60 env: WORKING_DIRECTORY: TVOSExample concurrency: diff --git a/.prettierrc.js b/.prettierrc.js index 98b4db777a..c9e8393426 100644 --- a/.prettierrc.js +++ b/.prettierrc.js @@ -1,4 +1,7 @@ module.exports = { + arrowParens: 'avoid', + bracketSameLine: true, + bracketSpacing: true, singleQuote: true, - jsxBracketSameLine: true, + trailingComma: 'es5', }; diff --git a/Example/.buckconfig b/Example/.buckconfig deleted file mode 100644 index 934256cb29..0000000000 --- a/Example/.buckconfig +++ /dev/null @@ -1,6 +0,0 @@ - -[android] - target = Google Inc.:Google APIs:23 - -[maven_repositories] - central = https://repo1.maven.org/maven2 diff --git a/Example/.eslintrc.js b/Example/.eslintrc.js new file mode 100644 index 0000000000..15cca67849 --- /dev/null +++ b/Example/.eslintrc.js @@ -0,0 +1,4 @@ +module.export = { + root: true, + extends: '@react-native', +}; diff --git a/Example/.flowconfig b/Example/.flowconfig deleted file mode 100644 index e7f1ae5594..0000000000 --- a/Example/.flowconfig +++ /dev/null @@ -1,67 +0,0 @@ -[ignore] -; We fork some components by platform -.*/*[.]android.js - -; Ignore "BUCK" generated dirs -/\.buckd/ - -; Ignore polyfills -node_modules/react-native/Libraries/polyfills/.* - -; Flow doesn't support platforms -.*/Libraries/Utilities/LoadingView.js - -.*/node_modules/resolve/test/resolver/malformed_package_json/package\.json$ - -[untyped] -.*/node_modules/@react-native-community/cli/.*/.* - -[include] - -[libs] -node_modules/react-native/interface.js -node_modules/react-native/flow/ - -[options] -emoji=true - -exact_by_default=true - -format.bracket_spacing=false - -module.file_ext=.js -module.file_ext=.json -module.file_ext=.ios.js - -munge_underscores=true - -module.name_mapper='^react-native/\(.*\)$' -> '/node_modules/react-native/\1' -module.name_mapper='^@?[./a-zA-Z0-9$_-]+\.\(bmp\|gif\|jpg\|jpeg\|png\|psd\|svg\|webp\|m4v\|mov\|mp4\|mpeg\|mpg\|webm\|aac\|aiff\|caf\|m4a\|mp3\|wav\|html\|pdf\)$' -> '/node_modules/react-native/Libraries/Image/RelativeImageStub' - -suppress_type=$FlowIssue -suppress_type=$FlowFixMe -suppress_type=$FlowFixMeProps -suppress_type=$FlowFixMeState - -[lints] -sketchy-null-number=warn -sketchy-null-mixed=warn -sketchy-number=warn -untyped-type-import=warn -nonstrict-import=warn -deprecated-type=warn -unsafe-getters-setters=warn -unnecessary-invariant=warn -signature-verification-failure=warn - -[strict] -deprecated-type -nonstrict-import -sketchy-null -unclear-type -unsafe-getters-setters -untyped-import -untyped-type-import - -[version] -^0.176.3 \ No newline at end of file diff --git a/Example/.gitignore b/Example/.gitignore index 9f850b868f..c99c32bce8 100644 --- a/Example/.gitignore +++ b/Example/.gitignore @@ -30,6 +30,9 @@ build/ local.properties *.iml *.hprof +.cxx/ +*.keystore +!debug.keystore # node.js # @@ -37,11 +40,6 @@ node_modules/ npm-debug.log yarn-error.log -# BUCK -buck-out/ -\.buckd/ -*.keystore - # fastlane # # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the @@ -61,6 +59,12 @@ buck-out/ /ios/Pods/ /vendor/bundle/ +# Temporary files created by Metro to check the health of the file watcher +.metro-health-check* + +# testing +/coverage + # Android cpatures /android/captures diff --git a/Example/.ruby-version b/Example/.ruby-version deleted file mode 100644 index a603bb50a2..0000000000 --- a/Example/.ruby-version +++ /dev/null @@ -1 +0,0 @@ -2.7.5 diff --git a/Example/Gemfile b/Example/Gemfile index efd98cadaf..d046415bd5 100644 --- a/Example/Gemfile +++ b/Example/Gemfile @@ -1,4 +1,4 @@ source 'https://rubygems.org' # 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' \ No newline at end of file +ruby '>= 2.6.10' +gem 'cocoapods', '~> 1.12' diff --git a/Example/android/app/build.gradle b/Example/android/app/build.gradle index f91b896590..6402db07c6 100644 --- a/Example/android/app/build.gradle +++ b/Example/android/app/build.gradle @@ -1,223 +1,87 @@ apply plugin: "com.android.application" - -import com.android.build.OutputFile +apply plugin: "com.facebook.react" /** - * The react.gradle file registers a task for each build variant (e.g. bundleDebugJsAndAssets - * and bundleReleaseJsAndAssets). - * These basically call `react-native bundle` with the correct arguments during the Android build - * cycle. By default, bundleDebugJsAndAssets is skipped, as in debug/dev mode we prefer to load the - * bundle directly from the development server. Below you can see all the possible configurations - * and their defaults. If you decide to add a configuration block, make sure to add it before the - * `apply from: "../../node_modules/react-native/react.gradle"` line. - * - * project.ext.react = [ - * // the name of the generated asset file containing your JS bundle - * bundleAssetName: "index.android.bundle", - * - * // the entry file for bundle generation. If none specified and - * // "index.android.js" exists, it will be used. Otherwise "index.js" is - * // default. Can be overridden with ENTRY_FILE environment variable. - * entryFile: "index.android.js", - * - * // https://reactnative.dev/docs/performance#enable-the-ram-format - * bundleCommand: "ram-bundle", - * - * // whether to bundle JS and assets in debug mode - * bundleInDebug: false, - * - * // whether to bundle JS and assets in release mode - * bundleInRelease: true, - * - * // whether to bundle JS and assets in another build variant (if configured). - * // See http://tools.android.com/tech-docs/new-build-system/user-guide#TOC-Build-Variants - * // The configuration property can be in the following formats - * // 'bundleIn${productFlavor}${buildType}' - * // 'bundleIn${buildType}' - * // bundleInFreeDebug: true, - * // bundleInPaidRelease: true, - * // bundleInBeta: true, - * - * // whether to disable dev mode in custom build variants (by default only disabled in release) - * // for example: to disable dev mode in the staging build type (if configured) - * devDisabledInStaging: true, - * // The configuration property can be in the following formats - * // 'devDisabledIn${productFlavor}${buildType}' - * // 'devDisabledIn${buildType}' - * - * // the root of your project, i.e. where "package.json" lives - * root: "../../", - * - * // where to put the JS bundle asset in debug mode - * jsBundleDirDebug: "$buildDir/intermediates/assets/debug", - * - * // where to put the JS bundle asset in release mode - * jsBundleDirRelease: "$buildDir/intermediates/assets/release", - * - * // where to put drawable resources / React Native assets, e.g. the ones you use via - * // require('./image.png')), in debug mode - * resourcesDirDebug: "$buildDir/intermediates/res/merged/debug", - * - * // where to put drawable resources / React Native assets, e.g. the ones you use via - * // require('./image.png')), in release mode - * resourcesDirRelease: "$buildDir/intermediates/res/merged/release", - * - * // by default the gradle tasks are skipped if none of the JS files or assets change; this means - * // that we don't look at files in android/ or ios/ to determine whether the tasks are up to - * // date; if you have any other folders that you want to ignore for performance reasons (gradle - * // indexes the entire tree), add them here. Alternatively, if you have JS files in android/ - * // for example, you might want to remove it from here. - * inputExcludes: ["android/**", "ios/**"], - * - * // override which node gets called and with what additional arguments - * nodeExecutableAndArgs: ["node"], - * - * // supply additional arguments to the packager - * extraPackagerArgs: [] - * ] + * This is the configuration block to customize your React Native Android app. + * By default you don't need to apply any configuration, just uncomment the lines you need. */ - -project.ext.react = [ - enableHermes: false, // clean and rebuild if changing -] - -apply from: "../../node_modules/react-native/react.gradle" - -/** - * Set this to true to create two separate APKs instead of one: - * - An APK that only works on ARM devices - * - An APK that only works on x86 devices - * The advantage is the size of the APK is reduced by about 4MB. - * Upload all the APKs to the Play Store and people will download - * the correct one based on the CPU architecture of their device. - */ -def enableSeparateBuildPerCPUArchitecture = false +react { + /* Folders */ + // The root of your project, i.e. where "package.json" lives. Default is '..' + // root = file("../") + // The folder where the react-native NPM package is. Default is ../node_modules/react-native + // reactNativeDir = file("../node_modules/react-native") + // The folder where the react-native Codegen package is. Default is ../node_modules/@react-native/codegen + // codegenDir = file("../node_modules/@react-native/codegen") + // The cli.js file which is the React Native CLI entrypoint. Default is ../node_modules/react-native/cli.js + // cliFile = file("../node_modules/react-native/cli.js") + + /* Variants */ + // The list of variants to that are debuggable. For those we're going to + // skip the bundling of the JS bundle and the assets. By default is just 'debug'. + // If you add flavors like lite, prod, etc. you'll have to list your debuggableVariants. + // debuggableVariants = ["liteDebug", "prodDebug"] + + /* Bundling */ + // A list containing the node command and its flags. Default is just 'node'. + // nodeExecutableAndArgs = ["node"] + // + // The command to run when bundling. By default is 'bundle' + // bundleCommand = "ram-bundle" + // + // The path to the CLI configuration file. Default is empty. + // bundleConfig = file(../rn-cli.config.js) + // + // The name of the generated asset file containing your JS bundle + // bundleAssetName = "MyApplication.android.bundle" + // + // The entry file for bundle generation. Default is 'index.android.js' or 'index.js' + // entryFile = file("../js/MyApplication.android.js") + // + // A list of extra flags to pass to the 'bundle' commands. + // See https://github.com/react-native-community/cli/blob/main/docs/commands.md#bundle + // extraPackagerArgs = [] + + /* Hermes Commands */ + // The hermes compiler command to run. By default it is 'hermesc' + // hermesCommand = "$rootDir/my-custom-hermesc/bin/hermesc" + // + // The list of flags to pass to the Hermes compiler. By default is "-O", "-output-source-map" + // hermesFlags = ["-O", "-output-source-map"] +} /** - * Run Proguard to shrink the Java bytecode in release builds. + * Set this to true to Run Proguard on Release builds to minify the Java bytecode */ def enableProguardInReleaseBuilds = false /** - * The preferred build flavor of JavaScriptCore. + * The preferred build flavor of JavaScriptCore (JSC) * * For example, to use the international variant, you can use: * `def jscFlavor = 'org.webkit:android-jsc-intl:+'` * * The international variant includes ICU i18n library and necessary data * allowing to use e.g. `Date.toLocaleString` and `String.localeCompare` that - * give correct results when using with locales other than en-US. Note that + * give correct results when using with locales other than en-US. Note that * this variant is about 6MiB larger per architecture than default. */ def jscFlavor = 'org.webkit:android-jsc:+' -/** - * Whether to enable the Hermes VM. - * - * 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); - -/** - * Architectures to build native code for. - */ -def reactNativeArchitectures() { - def value = project.getProperties().get("reactNativeArchitectures") - return value ? value.split(",") : ["armeabi-v7a", "x86", "x86_64", "arm64-v8a"] -} - android { ndkVersion rootProject.ext.ndkVersion compileSdkVersion rootProject.ext.compileSdkVersion + namespace "com.swmansion.rnscreens.example" defaultConfig { applicationId "com.swmansion.rnscreens.example" minSdkVersion rootProject.ext.minSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion versionCode 1 versionName "1.0" - buildConfigField "boolean", "IS_NEW_ARCHITECTURE_ENABLED", isNewArchitectureEnabled().toString() - testBuildType System.getProperty('testBuildType', 'debug') // This will later be used to control the test apk build type + testBuildType System.getProperty('testBuildType', 'release') testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner' - - 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 (*reactNativeArchitectures()) - } } signingConfigs { debug { @@ -248,22 +112,6 @@ android { proguardFile "${rootProject.projectDir}/../node_modules/detox/android/detox/proguard-rules-app.pro" } } - - // applicationVariants are e.g. debug, release - applicationVariants.all { variant -> - variant.outputs.each { output -> - // For each separate APK per architecture, set a unique version code as described here: - // https://developer.android.com/studio/build/configure-apk-splits.html - // Example: versionCode 1 will generate 1001 for armeabi-v7a, 1002 for x86, etc. - def versionCodes = ["armeabi-v7a": 1, "x86": 2, "arm64-v8a": 3, "x86_64": 4] - def abi = output.getFilter(OutputFile.ABI) - if (abi != null) { // null for the universal-debug, universal-release variants - output.versionCodeOverride = - defaultConfig.versionCode * 1000 + versionCodes.get(abi) - } - - } - } } dependencies { @@ -272,67 +120,22 @@ dependencies { // https://github.com/wix/Detox/issues/2848 exclude group: 'com.google.android.material' } - implementation "androidx.appcompat:appcompat:1.1.0" - - implementation fileTree(dir: "libs", include: ["*.jar"]) - - //noinspection GradleDynamicVersion - implementation "com.facebook.react:react-native:+" // From node_modules - - implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.0.0" - - debugImplementation("com.facebook.flipper:flipper:${FLIPPER_VERSION}") { - exclude group:'com.facebook.fbjni' - } + implementation "androidx.appcompat:appcompat:1.6.1" + + // The version of react-native is set by the React Native Gradle Plugin + implementation("com.facebook.react:react-android") + debugImplementation("com.facebook.flipper:flipper:${FLIPPER_VERSION}") debugImplementation("com.facebook.flipper:flipper-network-plugin:${FLIPPER_VERSION}") { - exclude group:'com.facebook.flipper' exclude group:'com.squareup.okhttp3', module:'okhttp' } - debugImplementation("com.facebook.flipper:flipper-fresco-plugin:${FLIPPER_VERSION}") { - exclude group:'com.facebook.flipper' - } - - if (enableHermes) { - //noinspection GradleDynamicVersion - implementation("com.facebook.react:hermes-engine:+") { // From node_modules - exclude group:'com.facebook.fbjni' - } + debugImplementation("com.facebook.flipper:flipper-fresco-plugin:${FLIPPER_VERSION}") + if (hermesEnabled.toBoolean()) { + implementation("com.facebook.react:hermes-android") } else { implementation jscFlavor } } -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) { - from configurations.implementation - into 'libs' -} - apply from: file("../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesAppBuildGradle(project) - -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/Example/android/app/debug.keystore b/Example/android/app/debug.keystore new file mode 100644 index 0000000000..364e105ed3 Binary files /dev/null and b/Example/android/app/debug.keystore differ diff --git a/Example/android/app/src/debug/java/com/swmansion/rnscreens/example/ReactNativeFlipper.java b/Example/android/app/src/debug/java/com/swmansion/rnscreens/example/ReactNativeFlipper.java index 77b3896033..002a48f1db 100644 --- a/Example/android/app/src/debug/java/com/swmansion/rnscreens/example/ReactNativeFlipper.java +++ b/Example/android/app/src/debug/java/com/swmansion/rnscreens/example/ReactNativeFlipper.java @@ -17,7 +17,6 @@ import com.facebook.flipper.plugins.inspector.InspectorFlipperPlugin; import com.facebook.flipper.plugins.network.FlipperOkhttpInterceptor; 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; @@ -25,13 +24,16 @@ import com.facebook.react.modules.network.NetworkingModule; import okhttp3.OkHttpClient; +/** + * Class responsible of loading Flipper inside your React Native application. This is the debug + * flavor of it. Here you can add your own plugins and customize the Flipper setup. + */ public class ReactNativeFlipper { public static void initializeFlipper(Context context, ReactInstanceManager reactInstanceManager) { if (FlipperUtils.shouldEnableFlipper(context)) { final FlipperClient client = AndroidFlipperClient.getInstance(context); client.addPlugin(new InspectorFlipperPlugin(context, DescriptorMapping.withDefaults())); - client.addPlugin(new ReactFlipperPlugin()); client.addPlugin(new DatabasesFlipperPlugin(context)); client.addPlugin(new SharedPreferencesFlipperPlugin(context)); client.addPlugin(CrashReporterPlugin.getInstance()); @@ -70,4 +72,4 @@ public void run() { } } } -} \ No newline at end of file +} diff --git a/Example/android/app/src/main/AndroidManifest.xml b/Example/android/app/src/main/AndroidManifest.xml index b44cbf3079..b60a68d9bf 100644 --- a/Example/android/app/src/main/AndroidManifest.xml +++ b/Example/android/app/src/main/AndroidManifest.xml @@ -1,5 +1,4 @@ - + diff --git a/Example/android/app/src/main/java/com/swmansion/rnscreens/example/LifecycleAwareView.java b/Example/android/app/src/main/java/com/swmansion/rnscreens/example/LifecycleAwareView.java deleted file mode 100644 index d6196b923c..0000000000 --- a/Example/android/app/src/main/java/com/swmansion/rnscreens/example/LifecycleAwareView.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.swmansion.rnscreens.example; - -import android.content.Context; -import android.util.Log; - -import androidx.lifecycle.Lifecycle; -import androidx.lifecycle.LifecycleObserver; -import androidx.lifecycle.OnLifecycleEvent; - -import com.facebook.react.views.view.ReactViewGroup; - -public class LifecycleAwareView extends ReactViewGroup implements LifecycleObserver { - public LifecycleAwareView(Context context) { - super(context); - } - - @OnLifecycleEvent(Lifecycle.Event.ON_RESUME) - public void onResume() { - Log.e("CAT", "VIEW RESUME " + this); - } - - @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE) - public void onPause() { - Log.e("CAT", "VIEW PAUSE " + this); - } -} diff --git a/Example/android/app/src/main/java/com/swmansion/rnscreens/example/MainActivity.java b/Example/android/app/src/main/java/com/swmansion/rnscreens/example/MainActivity.java index 3b840c0c8c..4e94e0aaa0 100644 --- a/Example/android/app/src/main/java/com/swmansion/rnscreens/example/MainActivity.java +++ b/Example/android/app/src/main/java/com/swmansion/rnscreens/example/MainActivity.java @@ -3,8 +3,8 @@ import android.os.Bundle; import com.facebook.react.ReactActivity; import com.facebook.react.ReactActivityDelegate; -import com.facebook.react.ReactRootView; -import com.swmansion.gesturehandler.react.RNGestureHandlerEnabledRootView; +import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint; +import com.facebook.react.defaults.DefaultReactActivityDelegate; public class MainActivity extends ReactActivity { @@ -18,41 +18,21 @@ protected String getMainComponentName() { } /** - * Returns the instance of the {@link ReactActivityDelegate}. There the RootView is created and - * you can specify the renderer you wish to use - the new renderer (Fabric) or the old renderer - * (Paper). + * Returns the instance of the {@link ReactActivityDelegate}. Here we use a util class {@link + * DefaultReactActivityDelegate} which allows you to easily enable Fabric and Concurrent React + * (aka React 18) with two boolean flags. */ @Override protected ReactActivityDelegate createReactActivityDelegate() { - return new MainActivityDelegate(this, getMainComponentName()); + return new DefaultReactActivityDelegate( + this, + getMainComponentName(), + // If you opted-in for the New Architecture, we enable the Fabric Renderer. + DefaultNewArchitectureEntryPoint.getFabricEnabled()); } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(null); } - - public static class MainActivityDelegate extends ReactActivityDelegate { - public MainActivityDelegate(ReactActivity activity, String mainComponentName) { - super(activity, mainComponentName); - } - - @Override - protected ReactRootView createRootView() { - // @kkafar: commented out, as we do not use Fabric here & I need to run RNGH v1 for some time - ReactRootView reactRootView = new ReactRootView(getContext()); - // // If you opted-in for the New Architecture, we enable the Fabric Renderer. - reactRootView.setIsFabric(BuildConfig.IS_NEW_ARCHITECTURE_ENABLED); - return reactRootView; - - // return new RNGestureHandlerEnabledRootView(MainActivity.this); - } - - @Override - protected boolean isConcurrentRootEnabled() { - // If you opted-in for the New Architecture, we enable Concurrent Root (i.e. React 18). - // More on this on https://reactjs.org/blog/2022/03/29/react-v18.html - return BuildConfig.IS_NEW_ARCHITECTURE_ENABLED; - } - } } diff --git a/Example/android/app/src/main/java/com/swmansion/rnscreens/example/MainApplication.java b/Example/android/app/src/main/java/com/swmansion/rnscreens/example/MainApplication.java index d401b726f3..e39d3de73c 100644 --- a/Example/android/app/src/main/java/com/swmansion/rnscreens/example/MainApplication.java +++ b/Example/android/app/src/main/java/com/swmansion/rnscreens/example/MainApplication.java @@ -1,22 +1,19 @@ package com.swmansion.rnscreens.example; import android.app.Application; -import android.content.Context; import com.facebook.react.PackageList; import com.facebook.react.ReactApplication; -import com.facebook.react.ReactInstanceManager; import com.facebook.react.ReactNativeHost; import com.facebook.react.ReactPackage; -import com.facebook.react.config.ReactFeatureFlags; +import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint; +import com.facebook.react.defaults.DefaultReactNativeHost; import com.facebook.soloader.SoLoader; -import com.swmansion.rnscreens.example.newarchitecture.MainApplicationReactNativeHost; -import java.lang.reflect.InvocationTargetException; import java.util.List; public class MainApplication extends Application implements ReactApplication { private final ReactNativeHost mReactNativeHost = - new ReactNativeHost(this) { + new DefaultReactNativeHost(this) { @Override public boolean getUseDeveloperSupport() { return BuildConfig.DEBUG; @@ -28,7 +25,6 @@ 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()); - // packages.add(new RNScreensPackage()); return packages; } @@ -36,57 +32,32 @@ protected List getPackages() { protected String getJSMainModuleName() { return "index"; } + + @Override + protected boolean isNewArchEnabled() { + return BuildConfig.IS_NEW_ARCHITECTURE_ENABLED; + } + + @Override + protected Boolean isHermesEnabled() { + return BuildConfig.IS_HERMES_ENABLED; + } }; - private final ReactNativeHost mNewArchitectureNativeHost = - new MainApplicationReactNativeHost(this); @Override public ReactNativeHost getReactNativeHost() { - if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) { - return mNewArchitectureNativeHost; - } else { - return mReactNativeHost; - } + return mReactNativeHost; } @Override public void onCreate() { super.onCreate(); - // If you opted-in for the New Architecture, we enable the TurboModule system - ReactFeatureFlags.useTurboModules = BuildConfig.IS_NEW_ARCHITECTURE_ENABLED; SoLoader.init(this, /* native exopackage */ false); - initializeFlipper(this, getReactNativeHost().getReactInstanceManager()); - } - - /** - * Loads Flipper in React Native templates. Call this in the onCreate method with something like - * initializeFlipper(this, getReactNativeHost().getReactInstanceManager()); - * - * @param context - * @param reactInstanceManager - */ - private static void initializeFlipper( - Context context, ReactInstanceManager reactInstanceManager) { - if (BuildConfig.DEBUG) { - try { - /* - We use reflection here to pick up the class that initializes Flipper, - since Flipper library is not available in release mode - */ - Class aClass = Class.forName("com.swmansion.rnscreens.example.ReactNativeFlipper"); - aClass - .getMethod("initializeFlipper", Context.class, ReactInstanceManager.class) - .invoke(null, context, reactInstanceManager); - } catch (ClassNotFoundException e) { - e.printStackTrace(); - } catch (NoSuchMethodException e) { - e.printStackTrace(); - } catch (IllegalAccessException e) { - e.printStackTrace(); - } catch (InvocationTargetException e) { - e.printStackTrace(); - } + if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) { + // If you opted-in for the New Architecture, we load the native entry point for this app. + DefaultNewArchitectureEntryPoint.load(); } + ReactNativeFlipper.initializeFlipper(this, getReactNativeHost().getReactInstanceManager()); } } diff --git a/Example/android/app/src/main/java/com/swmansion/rnscreens/example/SampleLifecycleAwareViewManager.java b/Example/android/app/src/main/java/com/swmansion/rnscreens/example/SampleLifecycleAwareViewManager.java deleted file mode 100644 index 338b0c2955..0000000000 --- a/Example/android/app/src/main/java/com/swmansion/rnscreens/example/SampleLifecycleAwareViewManager.java +++ /dev/null @@ -1,34 +0,0 @@ -package com.swmansion.rnscreens.example; - -import android.util.Log; - -import com.facebook.react.module.annotations.ReactModule; -import com.facebook.react.uimanager.ThemedReactContext; -import com.facebook.react.uimanager.ViewGroupManager; -import com.swmansion.rnscreens.LifecycleHelper; - -@ReactModule(name = SampleLifecycleAwareViewManager.REACT_CLASS) -public class SampleLifecycleAwareViewManager extends ViewGroupManager { - - protected static final String REACT_CLASS = "RNSLifecycleAwareView"; - - private LifecycleHelper mLifecycleHelper = new LifecycleHelper(); - - @Override - public String getName() { - return REACT_CLASS; - } - - @Override - protected LifecycleAwareView createViewInstance(ThemedReactContext reactContext) { - LifecycleAwareView view = new LifecycleAwareView(reactContext); - mLifecycleHelper.register(view); - return view; - } - - @Override - public void onDropViewInstance(LifecycleAwareView view) { - mLifecycleHelper.unregister(view); - super.onDropViewInstance(view); - } -} diff --git a/Example/android/app/src/main/java/com/swmansion/rnscreens/example/newarchitecture/MainApplicationReactNativeHost.java b/Example/android/app/src/main/java/com/swmansion/rnscreens/example/newarchitecture/MainApplicationReactNativeHost.java deleted file mode 100644 index a80c7c0968..0000000000 --- a/Example/android/app/src/main/java/com/swmansion/rnscreens/example/newarchitecture/MainApplicationReactNativeHost.java +++ /dev/null @@ -1,116 +0,0 @@ -package com.swmansion.rnscreens.example.newarchitecture; - -import android.app.Application; -import androidx.annotation.NonNull; -import com.facebook.react.PackageList; -import com.facebook.react.ReactInstanceManager; -import com.facebook.react.ReactNativeHost; -import com.facebook.react.ReactPackage; -import com.facebook.react.ReactPackageTurboModuleManagerDelegate; -import com.facebook.react.bridge.JSIModulePackage; -import com.facebook.react.bridge.JSIModuleProvider; -import com.facebook.react.bridge.JSIModuleSpec; -import com.facebook.react.bridge.JSIModuleType; -import com.facebook.react.bridge.JavaScriptContextHolder; -import com.facebook.react.bridge.ReactApplicationContext; -import com.facebook.react.bridge.UIManager; -import com.facebook.react.fabric.ComponentFactory; -import com.facebook.react.fabric.CoreComponentsRegistry; -import com.facebook.react.fabric.FabricJSIModuleProvider; -import com.facebook.react.fabric.ReactNativeConfig; -import com.facebook.react.uimanager.ViewManagerRegistry; -import com.swmansion.rnscreens.example.BuildConfig; -import com.swmansion.rnscreens.example.newarchitecture.components.MainComponentsRegistry; -import com.swmansion.rnscreens.example.newarchitecture.modules.MainApplicationTurboModuleManagerDelegate; -import java.util.ArrayList; -import java.util.List; - -/** - * A {@link ReactNativeHost} that helps you load everything needed for the New Architecture, both - * TurboModule delegates and the Fabric Renderer. - * - *

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; - } - }; - } -} \ No newline at end of file diff --git a/Example/android/app/src/main/java/com/swmansion/rnscreens/example/newarchitecture/components/MainComponentsRegistry.java b/Example/android/app/src/main/java/com/swmansion/rnscreens/example/newarchitecture/components/MainComponentsRegistry.java deleted file mode 100644 index c1b43b80b9..0000000000 --- a/Example/android/app/src/main/java/com/swmansion/rnscreens/example/newarchitecture/components/MainComponentsRegistry.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.swmansion.rnscreens.example.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); - } -} \ No newline at end of file diff --git a/Example/android/app/src/main/java/com/swmansion/rnscreens/example/newarchitecture/modules/MainApplicationTurboModuleManagerDelegate.java b/Example/android/app/src/main/java/com/swmansion/rnscreens/example/newarchitecture/modules/MainApplicationTurboModuleManagerDelegate.java deleted file mode 100644 index f6602a1781..0000000000 --- a/Example/android/app/src/main/java/com/swmansion/rnscreens/example/newarchitecture/modules/MainApplicationTurboModuleManagerDelegate.java +++ /dev/null @@ -1,48 +0,0 @@ -package com.swmansion.rnscreens.example.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("screensexample_appmodules"); - sIsSoLibraryLoaded = true; - } - } -} \ No newline at end of file diff --git a/Example/android/app/src/main/res/drawable/rn_edit_text_material.xml b/Example/android/app/src/main/res/drawable/rn_edit_text_material.xml index bb6f578c3f..4f7fb5f9c7 100644 --- a/Example/android/app/src/main/res/drawable/rn_edit_text_material.xml +++ b/Example/android/app/src/main/res/drawable/rn_edit_text_material.xml @@ -16,7 +16,7 @@ android:insetTop="@dimen/abc_edit_text_inset_top_material" android:insetBottom="@dimen/abc_edit_text_inset_bottom_material"> -