diff --git a/.github/workflows/buildAndTest.yaml b/.github/workflows/buildAndTest.yaml index b1cc75c2232..672b286f46e 100644 --- a/.github/workflows/buildAndTest.yaml +++ b/.github/workflows/buildAndTest.yaml @@ -19,9 +19,9 @@ jobs: build: runs-on: macos-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v6 - name: Set up JDK 17 - uses: actions/setup-java@v3 + uses: actions/setup-java@v5 with: java-version: '17' distribution: 'temurin' diff --git a/.github/workflows/kotlin_checker.yml b/.github/workflows/kotlin_checker.yml index 0bbc9703ef3..7b1bbb8041e 100644 --- a/.github/workflows/kotlin_checker.yml +++ b/.github/workflows/kotlin_checker.yml @@ -4,14 +4,15 @@ jobs: build: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v1 + - uses: actions/checkout@v6 + with: + fetch-depth: 0 - name: Setup ruby uses: ruby/setup-ruby@v1 with: ruby-version: "3.0" - architecture: "x64" - name: Setup JDK - uses: actions/setup-java@v3 + uses: actions/setup-java@v5 with: java-version: "17" distribution: "temurin" diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index f7c487e9b48..8de75a6e6ff 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -9,17 +9,17 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout main - uses: actions/checkout@v3 + uses: actions/checkout@v6 with: path: main ref: ${{ github.event.release.tag_name }} - name: Checkout gh-pages - uses: actions/checkout@v3 + uses: actions/checkout@v6 with: path: gh-pages ref: gh-pages - name: Set up JDK 17 - uses: actions/setup-java@v3 + uses: actions/setup-java@v5 with: java-version: "17" distribution: "temurin" diff --git a/.github/workflows/test-flutter.yaml b/.github/workflows/test-flutter.yaml index 8f4091f9958..f70196516d4 100644 --- a/.github/workflows/test-flutter.yaml +++ b/.github/workflows/test-flutter.yaml @@ -11,7 +11,7 @@ jobs: build: runs-on: macos-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: flutter uses: subosito/flutter-action@v2 with: diff --git a/.github/workflows/test-kmp.yaml b/.github/workflows/test-kmp.yaml index 71bbf96e6f3..b1d41272463 100644 --- a/.github/workflows/test-kmp.yaml +++ b/.github/workflows/test-kmp.yaml @@ -11,9 +11,9 @@ jobs: build: runs-on: macos-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v6 - name: Set up JDK 17 - uses: actions/setup-java@v3 + uses: actions/setup-java@v5 with: java-version: '17' distribution: 'temurin' diff --git a/.github/workflows/test-rn.yaml b/.github/workflows/test-rn.yaml index 07bfd1e32e6..d0377995cde 100644 --- a/.github/workflows/test-rn.yaml +++ b/.github/workflows/test-rn.yaml @@ -11,11 +11,11 @@ jobs: build: runs-on: macos-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v6 - name: Use Node.js - uses: actions/setup-node@v3 + uses: actions/setup-node@v6 with: - node-version: '18.x' + node-version: '22.x' - name: test-rn run: | cd ./react-native diff --git a/README.md b/README.md index 2e5b4745ecb..431a69a4a59 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ [![Kotlin](https://img.shields.io/badge/Kotlin-1.9.10-navy.svg?style=flat&logo=kotlin)](https://kotlinlang.org) [![Swift](https://img.shields.io/badge/for_Swift-5-FF9900.svg)](https://kotlinlang.org) [![Flutter](https://img.shields.io/badge/for_Flutter->=2.5.0-blue.svg)](https://ricohapi.github.io/theta-client/) -[![React Native](https://img.shields.io/badge/for_React_Native-0.70.8-aqua.svg)](https://ricohapi.github.io/theta-client/) +[![React Native](https://img.shields.io/badge/for_React_Native-0.78.2-aqua.svg)](https://ricohapi.github.io/theta-client/) This library provides a way to control RICOH THETA using [RICOH THETA API v2.1](https://github.com/ricohapi/theta-api-specs/tree/main/theta-web-api-v2.1). @@ -23,6 +23,14 @@ Your app can perform the following actions: * React Native * Flutter +##### React Native + +| Version | React Native | Legacy Architecture | New Architecture | +|------------|------------|---------------------|------------------| +| 1.14.0 or later | 0.78.2 | Not supported | Supported | +| 1.13.1 or earlier | 0.71.19 | Supported | Not supported | + + ## Supported Models * THETA X * THETA Z1 @@ -78,5 +86,3 @@ Using this verification tool, you can select and send a command with its paramet [MIT License](LICENSE) -## Useful guides -* [THETA SDK docs | help](https://theta360developers.github.io/sdk/) diff --git a/demos/demo-android/app/build.gradle b/demos/demo-android/app/build.gradle index 284441a17a2..b92b12e8bf0 100755 --- a/demos/demo-android/app/build.gradle +++ b/demos/demo-android/app/build.gradle @@ -76,7 +76,7 @@ dependencies { implementation 'com.jakewharton.timber:timber:5.0.1' implementation 'io.coil-kt:coil-compose:2.2.2' implementation "io.ktor:ktor-client-cio:$ktor_version" - implementation "com.ricoh360.thetaclient:theta-client:1.13.2" + implementation "com.ricoh360.thetaclient:theta-client:1.14.0" testImplementation 'org.junit.jupiter:junit-jupiter:5.9.0' testImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-test:$coroutines_version" diff --git a/demos/demo-ios/Podfile b/demos/demo-ios/Podfile index c365e40458a..4f3679c5480 100644 --- a/demos/demo-ios/Podfile +++ b/demos/demo-ios/Podfile @@ -7,5 +7,5 @@ target 'SdkSample' do use_frameworks! # Pods for SdkSample - pod 'THETAClient', '1.13.2' + pod 'THETAClient', '1.14.0' end diff --git a/demos/demo-react-native/.buckconfig b/demos/demo-react-native/.buckconfig deleted file mode 100644 index 934256cb29d..00000000000 --- a/demos/demo-react-native/.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/demos/demo-react-native/.eslintignore b/demos/demo-react-native/.eslintignore new file mode 100644 index 00000000000..92f213efe28 --- /dev/null +++ b/demos/demo-react-native/.eslintignore @@ -0,0 +1,13 @@ +node_modules/ +android/ +ios/ +build/ +.bundle/ +dist/ +vendor/ +coverage/ +web/ +*.bundle.* +.git/ +*.lock +Gemfile* diff --git a/demos/demo-react-native/.eslintrc.js b/demos/demo-react-native/.eslintrc.js index 1f10b3ae487..187894b6af2 100644 --- a/demos/demo-react-native/.eslintrc.js +++ b/demos/demo-react-native/.eslintrc.js @@ -1,17 +1,4 @@ module.exports = { root: true, - extends: '@react-native-community', - parser: '@typescript-eslint/parser', - plugins: ['@typescript-eslint'], - overrides: [ - { - files: ['*.ts', '*.tsx'], - rules: { - '@typescript-eslint/no-shadow': ['error'], - 'no-shadow': 'off', - 'no-undef': 'off', - }, - }, - ], - ignorePatterns: ['marzipano.js'], + extends: '@react-native', }; diff --git a/demos/demo-react-native/.gitignore b/demos/demo-react-native/.gitignore index 0efef7b48e3..de99955957c 100644 --- a/demos/demo-react-native/.gitignore +++ b/demos/demo-react-native/.gitignore @@ -20,7 +20,7 @@ DerivedData *.hmap *.ipa *.xcuserstate -ios/.xcode.env.local +**/.xcode.env.local # Android/IntelliJ # @@ -31,6 +31,9 @@ local.properties *.iml *.hprof .cxx/ +*.keystore +!debug.keystore +.kotlin/ # node.js # @@ -38,12 +41,6 @@ node_modules/ npm-debug.log yarn-error.log -# BUCK -buck-out/ -\.buckd/ -*.keystore -!debug.keystore - # fastlane # # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the @@ -60,8 +57,19 @@ buck-out/ *.jsbundle # Ruby / CocoaPods -/ios/Pods/ +**/Pods/ /vendor/bundle/ -# live preview -marzipano.js +# Temporary files created by Metro to check the health of the file watcher +.metro-health-check* + +# testing +/coverage + +# Yarn +.yarn/* +!.yarn/patches +!.yarn/plugins +!.yarn/releases +!.yarn/sdks +!.yarn/versions diff --git a/demos/demo-react-native/.node-version b/demos/demo-react-native/.node-version deleted file mode 100644 index b6a7d89c68e..00000000000 --- a/demos/demo-react-native/.node-version +++ /dev/null @@ -1 +0,0 @@ -16 diff --git a/demos/demo-react-native/.ruby-version b/demos/demo-react-native/.ruby-version deleted file mode 100644 index a603bb50a29..00000000000 --- a/demos/demo-react-native/.ruby-version +++ /dev/null @@ -1 +0,0 @@ -2.7.5 diff --git a/demos/demo-react-native/.watchmanconfig b/demos/demo-react-native/.watchmanconfig index 9e26dfeeb6e..0967ef424bc 100644 --- a/demos/demo-react-native/.watchmanconfig +++ b/demos/demo-react-native/.watchmanconfig @@ -1 +1 @@ -{} \ No newline at end of file +{} diff --git a/demos/demo-react-native/Gemfile b/demos/demo-react-native/Gemfile index 5efda89f452..10789062b6e 100644 --- a/demos/demo-react-native/Gemfile +++ b/demos/demo-react-native/Gemfile @@ -1,6 +1,6 @@ source 'https://rubygems.org' # You may use http://rbenv.org/ or https://rvm.io/ to install and use this version -ruby '2.7.5' +ruby '>= 3.0' gem 'cocoapods', '~> 1.11', '>= 1.11.2' diff --git a/demos/demo-react-native/Gemfile.lock b/demos/demo-react-native/Gemfile.lock index a83e9963f7f..d2c05b7ccec 100644 --- a/demos/demo-react-native/Gemfile.lock +++ b/demos/demo-react-native/Gemfile.lock @@ -1,26 +1,35 @@ GEM remote: https://rubygems.org/ specs: - CFPropertyList (3.0.6) - rexml - activesupport (7.0.4.3) - concurrent-ruby (~> 1.0, >= 1.0.2) + CFPropertyList (3.0.9) + activesupport (7.2.3) + base64 + benchmark (>= 0.3) + bigdecimal + concurrent-ruby (~> 1.0, >= 1.3.1) + connection_pool (>= 2.2.5) + drb i18n (>= 1.6, < 2) + logger (>= 1.4.2) minitest (>= 5.1) - tzinfo (~> 2.0) - addressable (2.8.4) - public_suffix (>= 2.0.2, < 6.0) + securerandom (>= 0.3) + tzinfo (~> 2.0, >= 2.0.5) + addressable (2.8.9) + public_suffix (>= 2.0.2, < 8.0) algoliasearch (1.27.5) httpclient (~> 2.8, >= 2.8.3) json (>= 1.5.1) atomos (0.1.3) + base64 (0.3.0) + benchmark (0.5.0) + bigdecimal (4.0.1) claide (1.1.0) - cocoapods (1.12.1) + cocoapods (1.16.2) addressable (~> 2.8) claide (>= 1.0.2, < 2.0) - cocoapods-core (= 1.12.1) + cocoapods-core (= 1.16.2) cocoapods-deintegrate (>= 1.0.3, < 2.0) - cocoapods-downloader (>= 1.6.0, < 2.0) + cocoapods-downloader (>= 2.1, < 3.0) cocoapods-plugins (>= 1.0.0, < 2.0) cocoapods-search (>= 1.0.0, < 2.0) cocoapods-trunk (>= 1.6.0, < 2.0) @@ -32,8 +41,8 @@ GEM molinillo (~> 0.8.0) nap (~> 1.0) ruby-macho (>= 2.3.0, < 3.0) - xcodeproj (>= 1.21.0, < 2.0) - cocoapods-core (1.12.1) + xcodeproj (>= 1.27.0, < 2.0) + cocoapods-core (1.16.2) activesupport (>= 5.0, < 8) addressable (~> 2.8) algoliasearch (~> 1.0) @@ -44,7 +53,7 @@ GEM public_suffix (~> 4.0) typhoeus (~> 1.0) cocoapods-deintegrate (1.0.5) - cocoapods-downloader (1.6.3) + cocoapods-downloader (2.1) cocoapods-plugins (1.0.0) nap cocoapods-search (1.0.1) @@ -53,37 +62,43 @@ GEM netrc (~> 0.11) cocoapods-try (1.2.0) colored2 (3.1.2) - concurrent-ruby (1.2.2) + concurrent-ruby (1.3.6) + connection_pool (2.5.5) + drb (2.2.3) escape (0.0.4) - ethon (0.16.0) + ethon (0.15.0) ffi (>= 1.15.0) - ffi (1.15.5) + ffi (1.17.3) fourflusher (2.3.1) fuzzy_match (2.0.4) gh_inspector (1.1.3) - httpclient (2.8.3) - i18n (1.13.0) + httpclient (2.9.0) + mutex_m + i18n (1.14.8) concurrent-ruby (~> 1.0) - json (2.6.3) - minitest (5.18.0) + json (2.18.1) + logger (1.7.0) + minitest (5.27.0) molinillo (0.8.0) - nanaimo (0.3.0) + mutex_m (0.3.0) + nanaimo (0.4.0) nap (1.1.0) netrc (0.11.0) public_suffix (4.0.7) - rexml (3.2.5) + rexml (3.4.4) ruby-macho (2.5.1) - typhoeus (1.4.0) - ethon (>= 0.9.0) + securerandom (0.4.1) + typhoeus (1.5.0) + ethon (>= 0.9.0, < 0.16.0) tzinfo (2.0.6) concurrent-ruby (~> 1.0) - xcodeproj (1.22.0) + xcodeproj (1.27.0) CFPropertyList (>= 2.3.3, < 4.0) atomos (~> 0.1.3) claide (>= 1.0.2, < 2.0) colored2 (~> 3.1) - nanaimo (~> 0.3.0) - rexml (~> 3.2.4) + nanaimo (~> 0.4.0) + rexml (>= 3.3.6, < 4.0) PLATFORMS ruby @@ -92,7 +107,7 @@ DEPENDENCIES cocoapods (~> 1.11, >= 1.11.2) RUBY VERSION - ruby 2.7.5p203 + ruby 3.1.3p185 BUNDLED WITH - 2.4.10 + 2.3.26 diff --git a/demos/demo-react-native/__tests__/App-test.tsx b/demos/demo-react-native/__tests__/App-test.tsx deleted file mode 100644 index 178476699b6..00000000000 --- a/demos/demo-react-native/__tests__/App-test.tsx +++ /dev/null @@ -1,14 +0,0 @@ -/** - * @format - */ - -import 'react-native'; -import React from 'react'; -import App from '../App'; - -// Note: test renderer must be required after react-native. -import renderer from 'react-test-renderer'; - -it('renders correctly', () => { - renderer.create(); -}); diff --git a/demos/demo-react-native/android/app/_BUCK b/demos/demo-react-native/android/app/_BUCK deleted file mode 100644 index 148354dc922..00000000000 --- a/demos/demo-react-native/android/app/_BUCK +++ /dev/null @@ -1,55 +0,0 @@ -# To learn about Buck see [Docs](https://buckbuild.com/). -# To run your application with Buck: -# - install Buck -# - `npm start` - to start the packager -# - `cd android` -# - `keytool -genkey -v -keystore keystores/debug.keystore -storepass android -alias androiddebugkey -keypass android -dname "CN=Android Debug,O=Android,C=US"` -# - `./gradlew :app:copyDownloadableDepsToLibs` - make all Gradle compile dependencies available to Buck -# - `buck install -r android/app` - compile, install and run application -# - -load(":build_defs.bzl", "create_aar_targets", "create_jar_targets") - -lib_deps = [] - -create_aar_targets(glob(["libs/*.aar"])) - -create_jar_targets(glob(["libs/*.jar"])) - -android_library( - name = "all-libs", - exported_deps = lib_deps, -) - -android_library( - name = "app-code", - srcs = glob([ - "src/main/java/**/*.java", - ]), - deps = [ - ":all-libs", - ":build_config", - ":res", - ], -) - -android_build_config( - name = "build_config", - package = "com.demoreactnative", -) - -android_resource( - name = "res", - package = "com.demoreactnative", - res = "src/main/res", -) - -android_binary( - name = "app", - keystore = "//android/keystores:debug", - manifest = "src/main/AndroidManifest.xml", - package_type = "debug", - deps = [ - ":app-code", - ], -) diff --git a/demos/demo-react-native/android/app/build.gradle b/demos/demo-react-native/android/app/build.gradle index 9c95436efcf..66307d098e5 100644 --- a/demos/demo-react-native/android/app/build.gradle +++ b/demos/demo-react-native/android/app/build.gradle @@ -1,216 +1,89 @@ apply plugin: "com.android.application" +apply plugin: "org.jetbrains.kotlin.android" apply plugin: "com.facebook.react" -import com.android.build.OutputFile - -/** - * 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: [] - * ] - */ - -project.ext.react = [ - enableHermes: true, // 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. + * 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. */ -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"] + + /* Autolinking */ + autolinkLibrariesWithApp() +} /** - * 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:+'` + * `def jscFlavor = io.github.react-native-community:jsc-android-intl:2026004.+` * * 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"] -} +def jscFlavor = 'io.github.react-native-community:jsc-android:2026004.+' android { ndkVersion rootProject.ext.ndkVersion + buildToolsVersion rootProject.ext.buildToolsVersion + compileSdk rootProject.ext.compileSdkVersion - compileSdkVersion rootProject.ext.compileSdkVersion - + namespace "com.demoreactnative" defaultConfig { applicationId "com.demoreactnative" minSdkVersion rootProject.ext.minSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion versionCode 1 versionName "1.0" - buildConfigField "boolean", "IS_NEW_ARCHITECTURE_ENABLED", isNewArchitectureEnabled().toString() - - if (isNewArchitectureEnabled()) { - // We configure the CMake build only if you decide to opt-in for the New Architecture. - externalNativeBuild { - cmake { - arguments "-DPROJECT_BUILD_DIR=$buildDir", - "-DREACT_ANDROID_DIR=$rootDir/../node_modules/react-native/ReactAndroid", - "-DREACT_ANDROID_BUILD_DIR=$rootDir/../node_modules/react-native/ReactAndroid/build", - "-DNODE_MODULES_DIR=$rootDir/../node_modules", - "-DANDROID_STL=c++_shared" - } - } - if (!enableSeparateBuildPerCPUArchitecture) { - ndk { - //noinspection ChromeOsAbiSupport - abiFilters (*reactNativeArchitectures()) - } - } - } - } - - if (isNewArchitectureEnabled()) { - // We configure the NDK build only if you decide to opt-in for the New Architecture. - externalNativeBuild { - cmake { - path "$projectDir/src/main/jni/CMakeLists.txt" - } - } - 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 configureCMakeDebug* tasks and the preBuild tasks. - // This can be removed once this is solved: https://issuetracker.google.com/issues/207403732 - configureCMakeRelWithDebInfo.dependsOn(preReleaseBuild) - configureCMakeDebug.dependsOn(preDebugBuild) - reactNativeArchitectures().each { architecture -> - tasks.findByName("configureCMakeDebug[${architecture}]")?.configure { - dependsOn("preDebugBuild") - } - tasks.findByName("configureCMakeRelWithDebInfo[${architecture}]")?.configure { - dependsOn("preReleaseBuild") - } - } - } - } - - splits { - abi { - reset() - enable enableSeparateBuildPerCPUArchitecture - universalApk false // If true, also generate a universal APK - //noinspection ChromeOsAbiSupport - include (*reactNativeArchitectures()) - } } signingConfigs { debug { @@ -232,87 +105,31 @@ android { proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.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) - } - - } - } - sourceSets { main { - assets.srcDirs = ["../../web/Web.bundle"] + assets.srcDirs += ["../../web/Web.bundle"] } } } -dependencies { - implementation fileTree(dir: "libs", include: ["*.jar"]) +configurations.all { + resolutionStrategy { + force 'androidx.core:core:1.13.1' + force 'androidx.core:core-ktx:1.13.1' + } +} +dependencies { // The version of react-native is set by the React Native Gradle Plugin implementation("com.facebook.react:react-android") - implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.1.0" - - debugImplementation("com.facebook.flipper:flipper:${FLIPPER_VERSION}") { - exclude group:'com.facebook.fbjni' - } - - 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' - } + // Force androidx.core to version 1.13.1 to avoid AGP 8.9.1 requirement + implementation("androidx.core:core:1.13.1") + implementation("androidx.core:core-ktx:1.13.1") - if (enableHermes) { + 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.configureEach { - 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 -tasks.register('copyDownloadableDepsToLibs', 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/demos/demo-react-native/android/app/build_defs.bzl b/demos/demo-react-native/android/app/build_defs.bzl deleted file mode 100644 index fff270f8d1d..00000000000 --- a/demos/demo-react-native/android/app/build_defs.bzl +++ /dev/null @@ -1,19 +0,0 @@ -"""Helper definitions to glob .aar and .jar targets""" - -def create_aar_targets(aarfiles): - for aarfile in aarfiles: - name = "aars__" + aarfile[aarfile.rindex("/") + 1:aarfile.rindex(".aar")] - lib_deps.append(":" + name) - android_prebuilt_aar( - name = name, - aar = aarfile, - ) - -def create_jar_targets(jarfiles): - for jarfile in jarfiles: - name = "jars__" + jarfile[jarfile.rindex("/") + 1:jarfile.rindex(".jar")] - lib_deps.append(":" + name) - prebuilt_jar( - name = name, - binary_jar = jarfile, - ) diff --git a/demos/demo-react-native/android/app/src/debug/AndroidManifest.xml b/demos/demo-react-native/android/app/src/debug/AndroidManifest.xml index 4b185bc1597..eb98c01afd7 100644 --- a/demos/demo-react-native/android/app/src/debug/AndroidManifest.xml +++ b/demos/demo-react-native/android/app/src/debug/AndroidManifest.xml @@ -2,12 +2,8 @@ - - - - + tools:ignore="GoogleAppIndexingWarning"/> diff --git a/demos/demo-react-native/android/app/src/debug/java/com/demoreactnative/ReactNativeFlipper.java b/demos/demo-react-native/android/app/src/debug/java/com/demoreactnative/ReactNativeFlipper.java deleted file mode 100644 index 08897824e5e..00000000000 --- a/demos/demo-react-native/android/app/src/debug/java/com/demoreactnative/ReactNativeFlipper.java +++ /dev/null @@ -1,73 +0,0 @@ -/** - * 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. - */ -package com.demoreactnative; - -import android.content.Context; -import com.facebook.flipper.android.AndroidFlipperClient; -import com.facebook.flipper.android.utils.FlipperUtils; -import com.facebook.flipper.core.FlipperClient; -import com.facebook.flipper.plugins.crashreporter.CrashReporterPlugin; -import com.facebook.flipper.plugins.databases.DatabasesFlipperPlugin; -import com.facebook.flipper.plugins.fresco.FrescoFlipperPlugin; -import com.facebook.flipper.plugins.inspector.DescriptorMapping; -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; -import com.facebook.react.bridge.ReactContext; -import com.facebook.react.modules.network.NetworkingModule; -import okhttp3.OkHttpClient; - -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()); - - NetworkFlipperPlugin networkFlipperPlugin = new NetworkFlipperPlugin(); - NetworkingModule.setCustomClientBuilder( - new NetworkingModule.CustomClientBuilder() { - @Override - public void apply(OkHttpClient.Builder builder) { - builder.addNetworkInterceptor(new FlipperOkhttpInterceptor(networkFlipperPlugin)); - } - }); - client.addPlugin(networkFlipperPlugin); - client.start(); - - // Fresco Plugin needs to ensure that ImagePipelineFactory is initialized - // Hence we run if after all native modules have been initialized - ReactContext reactContext = reactInstanceManager.getCurrentReactContext(); - if (reactContext == null) { - reactInstanceManager.addReactInstanceEventListener( - new ReactInstanceEventListener() { - @Override - public void onReactContextInitialized(ReactContext reactContext) { - reactInstanceManager.removeReactInstanceEventListener(this); - reactContext.runOnNativeModulesQueueThread( - new Runnable() { - @Override - public void run() { - client.addPlugin(new FrescoFlipperPlugin()); - } - }); - } - }); - } else { - client.addPlugin(new FrescoFlipperPlugin()); - } - } - } -} diff --git a/demos/demo-react-native/android/app/src/main/AndroidManifest.xml b/demos/demo-react-native/android/app/src/main/AndroidManifest.xml index 2b045f08616..e1892528b8d 100644 --- a/demos/demo-react-native/android/app/src/main/AndroidManifest.xml +++ b/demos/demo-react-native/android/app/src/main/AndroidManifest.xml @@ -1,5 +1,4 @@ - + @@ -9,7 +8,8 @@ android:icon="@mipmap/ic_launcher" android:roundIcon="@mipmap/ic_launcher_round" android:allowBackup="false" - android:theme="@style/AppTheme"> + android:theme="@style/AppTheme" + android:supportsRtl="true"> getPackages() { - @SuppressWarnings("UnnecessaryLocalVariable") - List packages = new PackageList(this).getPackages(); - // Packages that cannot be autolinked yet can be added manually here, for example: - // packages.add(new MyReactNativePackage()); - return packages; - } - - @Override - protected String getJSMainModuleName() { - return "index"; - } - }; - - private final ReactNativeHost mNewArchitectureNativeHost = - new MainApplicationReactNativeHost(this); - - @Override - public ReactNativeHost getReactNativeHost() { - if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) { - return mNewArchitectureNativeHost; - } else { - 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.demoreactnative.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(); - } - } - } -} diff --git a/demos/demo-react-native/android/app/src/main/java/com/demoreactnative/MainApplication.kt b/demos/demo-react-native/android/app/src/main/java/com/demoreactnative/MainApplication.kt new file mode 100644 index 00000000000..911ce45af4b --- /dev/null +++ b/demos/demo-react-native/android/app/src/main/java/com/demoreactnative/MainApplication.kt @@ -0,0 +1,44 @@ +package com.demoreactnative + +import android.app.Application +import com.facebook.react.PackageList +import com.facebook.react.ReactApplication +import com.facebook.react.ReactHost +import com.facebook.react.ReactNativeHost +import com.facebook.react.ReactPackage +import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint.load +import com.facebook.react.defaults.DefaultReactHost.getDefaultReactHost +import com.facebook.react.defaults.DefaultReactNativeHost +import com.facebook.react.soloader.OpenSourceMergedSoMapping +import com.facebook.soloader.SoLoader + +class MainApplication : Application(), ReactApplication { + + override val reactNativeHost: ReactNativeHost = + object : DefaultReactNativeHost(this) { + override fun getPackages(): List = + PackageList(this).packages.apply { + // Packages that cannot be autolinked yet can be added manually here, for example: + // add(MyReactNativePackage()) + } + + override fun getJSMainModuleName(): String = "index" + + override fun getUseDeveloperSupport(): Boolean = BuildConfig.DEBUG + + override val isNewArchEnabled: Boolean = BuildConfig.IS_NEW_ARCHITECTURE_ENABLED + override val isHermesEnabled: Boolean = BuildConfig.IS_HERMES_ENABLED + } + + override val reactHost: ReactHost + get() = getDefaultReactHost(applicationContext, reactNativeHost) + + override fun onCreate() { + super.onCreate() + SoLoader.init(this, OpenSourceMergedSoMapping) + if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) { + // If you opted-in for the New Architecture, we load the native entry point for this app. + load() + } + } +} diff --git a/demos/demo-react-native/android/app/src/main/java/com/demoreactnative/newarchitecture/MainApplicationReactNativeHost.java b/demos/demo-react-native/android/app/src/main/java/com/demoreactnative/newarchitecture/MainApplicationReactNativeHost.java deleted file mode 100644 index 0d6a82b0e09..00000000000 --- a/demos/demo-react-native/android/app/src/main/java/com/demoreactnative/newarchitecture/MainApplicationReactNativeHost.java +++ /dev/null @@ -1,116 +0,0 @@ -package com.demoreactnative.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.demoreactnative.BuildConfig; -import com.demoreactnative.newarchitecture.components.MainComponentsRegistry; -import com.demoreactnative.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; - } - }; - } -} diff --git a/demos/demo-react-native/android/app/src/main/java/com/demoreactnative/newarchitecture/components/MainComponentsRegistry.java b/demos/demo-react-native/android/app/src/main/java/com/demoreactnative/newarchitecture/components/MainComponentsRegistry.java deleted file mode 100644 index b9fbec5af10..00000000000 --- a/demos/demo-react-native/android/app/src/main/java/com/demoreactnative/newarchitecture/components/MainComponentsRegistry.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.demoreactnative.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/demos/demo-react-native/android/app/src/main/java/com/demoreactnative/newarchitecture/modules/MainApplicationTurboModuleManagerDelegate.java b/demos/demo-react-native/android/app/src/main/java/com/demoreactnative/newarchitecture/modules/MainApplicationTurboModuleManagerDelegate.java deleted file mode 100644 index aee857c0671..00000000000 --- a/demos/demo-react-native/android/app/src/main/java/com/demoreactnative/newarchitecture/modules/MainApplicationTurboModuleManagerDelegate.java +++ /dev/null @@ -1,48 +0,0 @@ -package com.demoreactnative.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("demoreactnative_appmodules"); - sIsSoLibraryLoaded = true; - } - } -} diff --git a/demos/demo-react-native/android/app/src/main/jni/CMakeLists.txt b/demos/demo-react-native/android/app/src/main/jni/CMakeLists.txt deleted file mode 100644 index 3e3249da2b1..00000000000 --- a/demos/demo-react-native/android/app/src/main/jni/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -cmake_minimum_required(VERSION 3.13) - -# Define the library name here. -project(demoreactnative_appmodules) - -# This file includes all the necessary to let you build your application with the New Architecture. -include(${REACT_ANDROID_DIR}/cmake-utils/ReactNative-application.cmake) diff --git a/demos/demo-react-native/android/app/src/main/jni/MainApplicationModuleProvider.cpp b/demos/demo-react-native/android/app/src/main/jni/MainApplicationModuleProvider.cpp deleted file mode 100644 index 26162dd8723..00000000000 --- a/demos/demo-react-native/android/app/src/main/jni/MainApplicationModuleProvider.cpp +++ /dev/null @@ -1,32 +0,0 @@ -#include "MainApplicationModuleProvider.h" - -#include -#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); - - // Module providers autolinked by RN CLI - auto rncli_module = rncli_ModuleProvider(moduleName, params); - if (rncli_module != nullptr) { - return rncli_module; - } - - return rncore_ModuleProvider(moduleName, params); -} - -} // namespace react -} // namespace facebook diff --git a/demos/demo-react-native/android/app/src/main/jni/MainApplicationModuleProvider.h b/demos/demo-react-native/android/app/src/main/jni/MainApplicationModuleProvider.h deleted file mode 100644 index b38ccf53fd4..00000000000 --- a/demos/demo-react-native/android/app/src/main/jni/MainApplicationModuleProvider.h +++ /dev/null @@ -1,16 +0,0 @@ -#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/demos/demo-react-native/android/app/src/main/jni/MainApplicationTurboModuleManagerDelegate.cpp b/demos/demo-react-native/android/app/src/main/jni/MainApplicationTurboModuleManagerDelegate.cpp deleted file mode 100644 index 5fd688c509d..00000000000 --- a/demos/demo-react-native/android/app/src/main/jni/MainApplicationTurboModuleManagerDelegate.cpp +++ /dev/null @@ -1,45 +0,0 @@ -#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( - const std::string &name) { - return getTurboModule(name, nullptr) != nullptr || - getTurboModule(name, {.moduleName = name}) != nullptr; -} - -} // namespace react -} // namespace facebook diff --git a/demos/demo-react-native/android/app/src/main/jni/MainApplicationTurboModuleManagerDelegate.h b/demos/demo-react-native/android/app/src/main/jni/MainApplicationTurboModuleManagerDelegate.h deleted file mode 100644 index 75a42a6f944..00000000000 --- a/demos/demo-react-native/android/app/src/main/jni/MainApplicationTurboModuleManagerDelegate.h +++ /dev/null @@ -1,38 +0,0 @@ -#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/demoreactnative/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(const std::string &name); -}; - -} // namespace react -} // namespace facebook diff --git a/demos/demo-react-native/android/app/src/main/jni/MainComponentsRegistry.cpp b/demos/demo-react-native/android/app/src/main/jni/MainComponentsRegistry.cpp deleted file mode 100644 index 54f598a486a..00000000000 --- a/demos/demo-react-native/android/app/src/main/jni/MainComponentsRegistry.cpp +++ /dev/null @@ -1,65 +0,0 @@ -#include "MainComponentsRegistry.h" - -#include -#include -#include -#include -#include - -namespace facebook { -namespace react { - -MainComponentsRegistry::MainComponentsRegistry(ComponentFactory *delegate) {} - -std::shared_ptr -MainComponentsRegistry::sharedProviderRegistry() { - auto providerRegistry = CoreComponentsRegistry::sharedProviderRegistry(); - - // Autolinked providers registered by RN CLI - rncli_registerProviders(providerRegistry); - - // 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/demos/demo-react-native/android/app/src/main/jni/MainComponentsRegistry.h b/demos/demo-react-native/android/app/src/main/jni/MainComponentsRegistry.h deleted file mode 100644 index 8a1ac146172..00000000000 --- a/demos/demo-react-native/android/app/src/main/jni/MainComponentsRegistry.h +++ /dev/null @@ -1,32 +0,0 @@ -#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/demoreactnative/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/demos/demo-react-native/android/app/src/main/jni/OnLoad.cpp b/demos/demo-react-native/android/app/src/main/jni/OnLoad.cpp deleted file mode 100644 index c569b6e865d..00000000000 --- a/demos/demo-react-native/android/app/src/main/jni/OnLoad.cpp +++ /dev/null @@ -1,11 +0,0 @@ -#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/demos/demo-react-native/android/app/src/main/res/drawable/rn_edit_text_material.xml b/demos/demo-react-native/android/app/src/main/res/drawable/rn_edit_text_material.xml index f35d9962026..5c25e728ea2 100644 --- a/demos/demo-react-native/android/app/src/main/res/drawable/rn_edit_text_material.xml +++ b/demos/demo-react-native/android/app/src/main/res/drawable/rn_edit_text_material.xml @@ -17,10 +17,11 @@ android:insetLeft="@dimen/abc_edit_text_inset_horizontal_material" android:insetRight="@dimen/abc_edit_text_inset_horizontal_material" android:insetTop="@dimen/abc_edit_text_inset_top_material" - android:insetBottom="@dimen/abc_edit_text_inset_bottom_material"> + android:insetBottom="@dimen/abc_edit_text_inset_bottom_material" + > - + NSAllowsArbitraryLoads + + NSAllowsLocalNetworking + NSLocationWhenInUseUsageDescription @@ -41,7 +38,7 @@ LaunchScreen UIRequiredDeviceCapabilities - armv7 + arm64 UISupportedInterfaceOrientations diff --git a/react-native/verification-tool/ios/ThetaClientVerificationTool/PrivacyInfo.xcprivacy b/react-native/verification-tool/ios/ThetaClientVerificationTool/PrivacyInfo.xcprivacy new file mode 100644 index 00000000000..41b8317f065 --- /dev/null +++ b/react-native/verification-tool/ios/ThetaClientVerificationTool/PrivacyInfo.xcprivacy @@ -0,0 +1,37 @@ + + + + + NSPrivacyAccessedAPITypes + + + NSPrivacyAccessedAPIType + NSPrivacyAccessedAPICategoryFileTimestamp + NSPrivacyAccessedAPITypeReasons + + C617.1 + + + + NSPrivacyAccessedAPIType + NSPrivacyAccessedAPICategoryUserDefaults + NSPrivacyAccessedAPITypeReasons + + CA92.1 + + + + NSPrivacyAccessedAPIType + NSPrivacyAccessedAPICategorySystemBootTime + NSPrivacyAccessedAPITypeReasons + + 35F9.1 + + + + NSPrivacyCollectedDataTypes + + NSPrivacyTracking + + + diff --git a/react-native/verification-tool/ios/ThetaClientVerificationTool/main.m b/react-native/verification-tool/ios/ThetaClientVerificationTool/main.m deleted file mode 100644 index d645c7246c4..00000000000 --- a/react-native/verification-tool/ios/ThetaClientVerificationTool/main.m +++ /dev/null @@ -1,10 +0,0 @@ -#import - -#import "AppDelegate.h" - -int main(int argc, char *argv[]) -{ - @autoreleasepool { - return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); - } -} diff --git a/react-native/verification-tool/ios/ThetaClientVerificationToolTests/Info.plist b/react-native/verification-tool/ios/ThetaClientVerificationToolTests/Info.plist deleted file mode 100644 index ba72822e872..00000000000 --- a/react-native/verification-tool/ios/ThetaClientVerificationToolTests/Info.plist +++ /dev/null @@ -1,24 +0,0 @@ - - - - - CFBundleDevelopmentRegion - en - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIdentifier - $(PRODUCT_BUNDLE_IDENTIFIER) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - $(PRODUCT_NAME) - CFBundlePackageType - BNDL - CFBundleShortVersionString - 1.0 - CFBundleSignature - ???? - CFBundleVersion - 1 - - diff --git a/react-native/verification-tool/ios/ThetaClientVerificationToolTests/ThetaClientReactNativeExampleTests.m b/react-native/verification-tool/ios/ThetaClientVerificationToolTests/ThetaClientReactNativeExampleTests.m deleted file mode 100644 index c1d86dc8ef9..00000000000 --- a/react-native/verification-tool/ios/ThetaClientVerificationToolTests/ThetaClientReactNativeExampleTests.m +++ /dev/null @@ -1,66 +0,0 @@ -#import -#import - -#import -#import - -#define TIMEOUT_SECONDS 600 -#define TEXT_TO_LOOK_FOR @"Welcome to React" - -@interface ThetaClientVerificationToolTest : XCTestCase - -@end - -@implementation ThetaClientVerificationToolTest - -- (BOOL)findSubviewInView:(UIView *)view matching:(BOOL (^)(UIView *view))test -{ - if (test(view)) { - return YES; - } - for (UIView *subview in [view subviews]) { - if ([self findSubviewInView:subview matching:test]) { - return YES; - } - } - return NO; -} - -- (void)testRendersWelcomeScreen -{ - UIViewController *vc = [[[RCTSharedApplication() delegate] window] rootViewController]; - NSDate *date = [NSDate dateWithTimeIntervalSinceNow:TIMEOUT_SECONDS]; - BOOL foundElement = NO; - - __block NSString *redboxError = nil; -#ifdef DEBUG - RCTSetLogFunction( - ^(RCTLogLevel level, RCTLogSource source, NSString *fileName, NSNumber *lineNumber, NSString *message) { - if (level >= RCTLogLevelError) { - redboxError = message; - } - }); -#endif - - while ([date timeIntervalSinceNow] > 0 && !foundElement && !redboxError) { - [[NSRunLoop mainRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]]; - [[NSRunLoop mainRunLoop] runMode:NSRunLoopCommonModes beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]]; - - foundElement = [self findSubviewInView:vc.view - matching:^BOOL(UIView *view) { - if ([view.accessibilityLabel isEqualToString:TEXT_TO_LOOK_FOR]) { - return YES; - } - return NO; - }]; - } - -#ifdef DEBUG - RCTSetLogFunction(RCTDefaultLogFunction); -#endif - - XCTAssertNil(redboxError, @"RedBox error: %@", redboxError); - XCTAssertTrue(foundElement, @"Couldn't find element with text '%@' in %d seconds", TEXT_TO_LOOK_FOR, TIMEOUT_SECONDS); -} - -@end diff --git a/react-native/verification-tool/jest.config.js b/react-native/verification-tool/jest.config.js new file mode 100644 index 00000000000..8eb675e9bc6 --- /dev/null +++ b/react-native/verification-tool/jest.config.js @@ -0,0 +1,3 @@ +module.exports = { + preset: 'react-native', +}; diff --git a/react-native/verification-tool/metro.config.js b/react-native/verification-tool/metro.config.js index b5c0064bb93..bff64248649 100644 --- a/react-native/verification-tool/metro.config.js +++ b/react-native/verification-tool/metro.config.js @@ -2,6 +2,7 @@ const path = require('path'); const escape = require('escape-string-regexp'); const exclusionList = require('metro-config/src/defaults/exclusionList'); const pak = require('../package.json'); +const { getDefaultConfig, mergeConfig } = require('@react-native/metro-config'); const root = path.resolve(__dirname, '..'); @@ -9,14 +10,14 @@ const modules = Object.keys({ ...pak.peerDependencies, }); -module.exports = { +const config = { projectRoot: __dirname, watchFolders: [root], // We need to make sure that only one version is loaded for peerDependencies // So we block them at the root, and alias them to the versions in example's node_modules resolver: { - blacklistRE: exclusionList( + blockList: exclusionList( modules.map( (m) => new RegExp(`^${escape(path.join(root, 'node_modules', m))}\\/.*$`) @@ -26,7 +27,9 @@ module.exports = { extraNodeModules: modules.reduce((acc, name) => { acc[name] = path.join(__dirname, 'node_modules', name); return acc; - }, {}), + }, { + 'theta-client-react-native': root, + }), }, transformer: { @@ -38,3 +41,5 @@ module.exports = { }), }, }; + +module.exports = mergeConfig(getDefaultConfig(__dirname), config); diff --git a/react-native/verification-tool/package.json b/react-native/verification-tool/package.json index 022a79aa1f2..010483832e3 100644 --- a/react-native/verification-tool/package.json +++ b/react-native/verification-tool/package.json @@ -1,30 +1,48 @@ { - "name": "verification-tool", + "name": "ThetaClientVerificationTool", "version": "0.0.1", "private": true, "scripts": { "android": "react-native run-android", "ios": "react-native run-ios", + "lint": "eslint .", "start": "react-native start", - "pods": "pod-install --quiet", + "test": "jest", + "pods": "cd ios && pod install", "postinstall": "./scripts/copy-npm-module-to-web-bundles.sh" }, "dependencies": { - "@react-navigation/native": "^6.1.7", - "@react-navigation/native-stack": "^6.9.13", + "babel-plugin-module-resolver": "^5.0.2", "marzipano": "0.10.2", - "react": "18.2.0", - "react-native": "0.71.19", - "react-native-safe-area-context": "^4.7.1", - "react-native-screens": "^3.24.0", - "react-native-webview": "^13.6.0" + "react": "19.0.0", + "react-native": "0.78.2", + "react-native-svg": "15.11.2", + "react-native-webview": "^13.16.0" }, "devDependencies": { - "@babel/core": "^7.20.0", - "@babel/preset-env": "^7.20.0", - "@babel/runtime": "^7.20.0", - "@types/lodash": "^4.14.200", - "babel-plugin-module-resolver": "^4.1.0", - "metro-react-native-babel-preset": "0.73.9" + "@babel/core": "^7.25.2", + "@babel/preset-env": "^7.25.3", + "@babel/runtime": "^7.25.0", + "@react-native-community/cli": "15.0.1", + "@react-native-community/cli-platform-android": "15.0.1", + "@react-native-community/cli-platform-ios": "15.0.1", + "@react-native/babel-preset": "0.78.2", + "@react-native/eslint-config": "0.78.2", + "@react-native/metro-config": "0.78.2", + "@react-native/typescript-config": "0.78.2", + "@types/jest": "^29.5.13", + "@types/react": "^19.0.0", + "@types/react-test-renderer": "^19.0.0", + "@typescript-eslint/eslint-plugin": "^7.0.0", + "@typescript-eslint/parser": "^7.0.0", + "eslint": "^8.19.0", + "jest": "^29.6.3", + "prettier": "2.8.8", + "react-native-svg-transformer": "^1.5.3", + "react-test-renderer": "19.0.0", + "typescript": "^5.7.2" + }, + "engines": { + "node": ">=22" } } diff --git a/react-native/verification-tool/react-native.config.js b/react-native/verification-tool/react-native.config.js index a5166956f49..d870039571b 100644 --- a/react-native/verification-tool/react-native.config.js +++ b/react-native/verification-tool/react-native.config.js @@ -1,9 +1,12 @@ const path = require('path'); -const pak = require('../package.json'); +/** + * theta-client-react-native is referenced via file:.., + * so we explicitly set the root to ensure autolinking detects it correctly. + */ module.exports = { dependencies: { - [pak.name]: { + 'theta-client-react-native': { root: path.join(__dirname, '..'), }, }, diff --git a/react-native/verification-tool/src/App.tsx b/react-native/verification-tool/src/App.tsx index ee4f57a9722..73559a0e448 100644 --- a/react-native/verification-tool/src/App.tsx +++ b/react-native/verification-tool/src/App.tsx @@ -1,85 +1,106 @@ -import React from 'react'; -import { NavigationContainer } from '@react-navigation/native'; -import { - NativeStackNavigationOptions, - createNativeStackNavigator, -} from '@react-navigation/native-stack'; +import React, { useState, useEffect } from 'react'; +import { View, Text, TouchableOpacity, StyleSheet, StatusBar, Platform, SafeAreaView, Button } from 'react-native'; +import Svg, { Path } from 'react-native-svg'; import MenuScreen from './screen/menu-screen'; -import VideoConvertScreen from './screen/video-convert-screen'; +import GetInfoScreen from './screen/get-info-screen'; +import PhotoCaptureScreen from './screen/photo-capture-screen'; +import OptionsScreen from './screen/options-screen'; +import ListFilesScreen from './screen/list-files-screen'; +import GetMetadataScreen from './screen/get-metadata-screen'; +import DeleteFilesScreen from './screen/delete-files-screen'; +import VideoCaptureScreen from './screen/video-capture-screen'; +import TimeShiftCaptureScreen from './screen/time-shift-capture-screen'; +import TimeShiftManualCaptureScreen from './screen/time-shift-manual-capture-screen'; +import LimitlessIntervalCaptureScreen from './screen/limitless-interval-capture-screen'; +import CompositeIntervalCaptureScreen from './screen/composite-interval-capture-screen'; +import ShotCountSpecifiedIntervalCaptureScreen from './screen/shot-count-specified-interval-capture-screen'; +import BurstCaptureScreen from './screen/burst-capture-screen'; +import MultiBracketCaptureScreen from './screen/multi-bracket-capture-screen'; +import ContinuousCaptureScreen from './screen/continuous-capture-screen'; import LivePreviewScreen from './screen/live-preview-screen'; -import OptionsScreen from './screen/options-screen/options-screen'; +import VideoConvertScreen from './screen/video-convert-screen'; import CommandsScreen from './screen/commands-screen'; -import PhotoCaptureScreen from './screen/photo-capture-screen'; import FilePreviewScreen from './screen/file-preview-screen'; -import ListFilesScreen from './screen/list-files-screen'; -import VideoCaptureScreen from './screen/video-capture-screen/video-capture-screen'; -import DeleteFilesScreen from './screen/delete-files-screen/delete-files-screen'; -import GetMetadataScreen from './screen/get-metadata-screen/get-metadata-screen'; -import GetInfoScreen from './screen/get-info-screen/get-info-screen'; -import TimeShiftCaptureScreen from './screen/time-shift-capture-screen/time-shift-capture-screen'; -import TimeShiftManualCaptureScreen from './screen/time-shift-manual-capture-screen/time-shift-manual-capture-screen'; -import LimitlessIntervalCaptureScreen from './screen/limitless-interval-capture-screen/limitless-interval-capture-screen'; -import ShotCountSpecifiedIntervalCaptureScreen from './screen/shot-count-specified-interval-capture-screen/shot-count-specified-interval-capture-screen'; -import CompositeIntervalCaptureScreen from './screen/composite-interval-capture-screen/composite-interval-capture-screen'; -import BurstCaptureScreen from './screen/burst-capture-screen/burst-capture-screen'; -import ContinuousCaptureScreen from './screen/continuous-capture-screen/continuous-capture-screen'; -import MultiBracketCaptureScreen from './screen/multi-bracket-capture-screen/multi-bracket-capture-screen'; -import { setApiLogListener, type FileInfo } from './modules/theta-client'; -import { Button } from 'react-native'; import LogPopupView from './components/log-popup-view/log-popup-view'; +import { FileTypeEnum, setApiLogListener } from './modules/theta-client'; -export type RootStackParamList = { - menu: undefined; - getInfo: undefined; - listFiles: undefined; - deleteFiles: undefined; - getMetadata: undefined; - livePreview: undefined; - videoConvert: undefined; - options: undefined; - commands: undefined; - photoCapture: undefined; - videoCapture: undefined; - limitlessIntervalCapture: undefined; - timeShiftCapture: undefined; - timeShiftManualCapture: undefined; - shotCountSpecifiedIntervalCapture: undefined; - compositeIntervalCapture: undefined; - burstCapture: undefined; - continuousCapture: undefined; - multiBracketCapture: undefined; - filePreview: { - item: FileInfo; - }; -}; +const BackIcon = () => ( + + + +); -const Stack = createNativeStackNavigator(); +type ScreenName = + | 'menu' + | 'getInfo' + | 'listFiles' + | 'deleteFiles' + | 'getMetadata' + | 'livePreview' + | 'videoConvert' + | 'options' + | 'commands' + | 'photoCapture' + | 'videoCapture' + | 'limitlessIntervalCapture' + | 'timeShiftCapture' + | 'timeShiftManualCapture' + | 'shotCountSpecifiedIntervalCapture' + | 'compositeIntervalCapture' + | 'burstCapture' + | 'continuousCapture' + | 'multiBracketCapture' + | 'filePreview'; -const screenOptions = { - headerStyle: { - backgroundColor: '#6200ee', - }, - headerTintColor: '#fff', - headerTitleStyle: { - fontWeight: 'bold', - }, - headerBackTitle: '', -} as NativeStackNavigationOptions; +const screenTitles: Record = { + menu: 'Menu', + getInfo: 'Get Info', + listFiles: 'List Files', + deleteFiles: 'Delete Files', + getMetadata: 'Get Metadata', + livePreview: 'Live Preview', + videoConvert: 'Video Convert', + options: 'Options', + commands: 'Commands', + photoCapture: 'Photo Capture', + videoCapture: 'Video Capture', + limitlessIntervalCapture: 'Limitless Interval Capture', + timeShiftCapture: 'Time Shift Capture', + timeShiftManualCapture: 'Time Shift Manual Capture', + shotCountSpecifiedIntervalCapture: 'Shot Count Specified Interval Capture', + compositeIntervalCapture: 'Composite Interval Capture', + burstCapture: 'Burst Capture', + continuousCapture: 'Continuous Capture', + multiBracketCapture: 'Multi Bracket Capture', + filePreview: 'Preview', +}; const App = () => { - const [log, setLog] = React.useState(''); - const [isShowLog, setShowLog] = React.useState(false); - const headerRight = () => ( - <> -