mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Compare commits
77
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
38465f2d18 | ||
|
|
aa2b243bc5 | ||
|
|
49c0267b66 | ||
|
|
0d90a44adf | ||
|
|
1739139c7c | ||
|
|
79f785760f | ||
|
|
9979e38c70 | ||
|
|
18b847fa28 | ||
|
|
8f2c7ff9f2 | ||
|
|
a7792da695 | ||
|
|
fc1dbb8f0b | ||
|
|
ba1a9defbb | ||
|
|
6107793fda | ||
|
|
78c8e49d0a | ||
|
|
e809e4b1ec | ||
|
|
67c373ff3a | ||
|
|
ceaebc6975 | ||
|
|
05646f8f38 | ||
|
|
0ad1c53443 | ||
|
|
c9fd1dd56e | ||
|
|
572ada9308 | ||
|
|
362e1974fe | ||
|
|
61baa751c9 | ||
|
|
cd875420e8 | ||
|
|
c36c33c613 | ||
|
|
e5fba33a94 | ||
|
|
16c32f920e | ||
|
|
ea22ee6bf6 | ||
|
|
adfd21e035 | ||
|
|
41c56db95d | ||
|
|
8d11cb4b9c | ||
|
|
5e5d29e43c | ||
|
|
3624b47768 | ||
|
|
99bcbad2b2 | ||
|
|
4eda46f7f5 | ||
|
|
08430bf214 | ||
|
|
adcdb366da | ||
|
|
df737b09b1 | ||
|
|
b310f2b078 | ||
|
|
ea0cd5b7ca | ||
|
|
d02b51332e | ||
|
|
8c488d8757 | ||
|
|
c63ea4c3a0 | ||
|
|
d587e0c2a5 | ||
|
|
79bb531416 | ||
|
|
775d5cd00c | ||
|
|
7ef7d99f1c | ||
|
|
83c8163540 | ||
|
|
229be89121 | ||
|
|
2c26c8fded | ||
|
|
60129ab7ac | ||
|
|
41a80f2ee2 | ||
|
|
94b1165a44 | ||
|
|
e4f23f4783 | ||
|
|
27c32b2d71 | ||
|
|
5c9f160764 | ||
|
|
4d0be144bf | ||
|
|
32931b19b1 | ||
|
|
ea9dd430a6 | ||
|
|
c4a7e46976 | ||
|
|
b8f8ac0e1c | ||
|
|
8e3b62019e | ||
|
|
0f72abfc03 | ||
|
|
c9a3c5749b | ||
|
|
fd5e282290 | ||
|
|
39798cfa91 | ||
|
|
741d102476 | ||
|
|
49278df494 | ||
|
|
e59cf2db64 | ||
|
|
ae677efb57 | ||
|
|
41bf725ada | ||
|
|
becb47ccb6 | ||
|
|
f0054e1e30 | ||
|
|
936d69e7a1 | ||
|
|
151498a122 | ||
|
|
94cea1edda | ||
|
|
5f656e98c9 |
@@ -14,7 +14,7 @@
|
||||
# and build a Android application that can be used to run the
|
||||
# tests specified in the scripts/ directory.
|
||||
#
|
||||
FROM reactnativecommunity/react-native-android:6.0
|
||||
FROM reactnativecommunity/react-native-android:6.1
|
||||
|
||||
LABEL Description="React Native Android Test Image"
|
||||
LABEL maintainer="Héctor Ramos <hector@fb.com>"
|
||||
|
||||
+24
-62
@@ -48,15 +48,15 @@ references:
|
||||
# Anchors for the cache keys
|
||||
|
||||
cache_keys:
|
||||
checkout_cache_key: &checkout_cache_key v1-checkout
|
||||
checkout_cache_key: &checkout_cache_key v5-checkout
|
||||
gems_cache_key: &gems_cache_key v1-gems-{{ checksum "Gemfile.lock" }}
|
||||
gradle_cache_key: &gradle_cache_key v1-gradle-{{ checksum "gradle/wrapper/gradle-wrapper.properties" }}-{{ checksum "ReactAndroid/gradle.properties" }}
|
||||
hermes_workspace_cache_key: &hermes_workspace_cache_key v4-hermes-{{ .Environment.CIRCLE_JOB }}-{{ checksum "/tmp/hermes/hermesversion" }}
|
||||
hermes_workspace_debug_cache_key: &hermes_workspace_debug_cache_key v2-hermes-{{ .Environment.CIRCLE_JOB }}-debug-{{ checksum "/tmp/hermes/hermesversion" }}
|
||||
hermes_workspace_release_cache_key: &hermes_workspace_release_cache_key v2-hermes-{{ .Environment.CIRCLE_JOB }}-release-{{ checksum "/tmp/hermes/hermesversion" }}
|
||||
hermes_windows_cache_key: &hermes_windows_cache_key v3-hermes-{{ .Environment.CIRCLE_JOB }}-{{ checksum "tmp/hermes/hermesversion" }}
|
||||
hermes_tarball_debug_cache_key: &hermes_tarball_debug_cache_key v2-hermes-tarball-debug-{{ checksum "/tmp/hermes/hermesversion" }}
|
||||
hermes_tarball_release_cache_key: &hermes_tarball_release_cache_key v1-hermes-tarball-release-{{ checksum "/tmp/hermes/hermesversion" }}
|
||||
hermes_tarball_debug_cache_key: &hermes_tarball_debug_cache_key v3-hermes-tarball-debug-{{ checksum "/tmp/hermes/hermesversion" }}
|
||||
hermes_tarball_release_cache_key: &hermes_tarball_release_cache_key v2-hermes-tarball-release-{{ checksum "/tmp/hermes/hermesversion" }}
|
||||
pods_cache_key: &pods_cache_key v8-pods-{{ .Environment.CIRCLE_JOB }}-{{ checksum "packages/rn-tester/Podfile.lock.bak" }}-{{ checksum "packages/rn-tester/Podfile" }}
|
||||
windows_yarn_cache_key: &windows_yarn_cache_key v1-win-yarn-cache-{{ arch }}-{{ checksum "yarn.lock" }}
|
||||
yarn_cache_key: &yarn_cache_key v5-yarn-cache-{{ .Environment.CIRCLE_JOB }}
|
||||
@@ -102,7 +102,7 @@ executors:
|
||||
reactnativeandroid:
|
||||
<<: *defaults
|
||||
docker:
|
||||
- image: reactnativecommunity/react-native-android:6.0
|
||||
- image: reactnativecommunity/react-native-android:6.1
|
||||
resource_class: "xlarge"
|
||||
environment:
|
||||
- TERM: "dumb"
|
||||
@@ -132,10 +132,7 @@ commands:
|
||||
type: string
|
||||
steps:
|
||||
- restore_cache:
|
||||
keys:
|
||||
- << parameters.checkout_base_cache_key >>-{{ arch }}-{{ .Branch }}-{{ .Revision }}
|
||||
- << parameters.checkout_base_cache_key >>-{{ arch }}-{{ .Branch }}-
|
||||
- << parameters.checkout_base_cache_key >>-{{ arch }}-
|
||||
key: << parameters.checkout_base_cache_key >>-{{ arch }}-{{ .Branch }}-{{ .Revision }}
|
||||
- checkout
|
||||
- save_cache:
|
||||
key: << parameters.checkout_base_cache_key >>-{{ arch }}-{{ .Branch }}-{{ .Revision }}
|
||||
@@ -306,8 +303,8 @@ commands:
|
||||
exit 0
|
||||
fi
|
||||
|
||||
TARBALL_FILENAME=$(node ~/react-native/scripts/hermes/get-tarball-name.js --buildType "<< parameters.flavor >>" --releaseVersion "*")
|
||||
TARBALL_PATH=$(ls $HERMES_TARBALL_ARTIFACTS_DIR/$TARBALL_FILENAME)
|
||||
TARBALL_FILENAME=$(node ~/react-native/scripts/hermes/get-tarball-name.js --buildType "<< parameters.flavor >>")
|
||||
TARBALL_PATH=$HERMES_TARBALL_ARTIFACTS_DIR/$TARBALL_FILENAME
|
||||
|
||||
echo "Looking for $TARBALL_FILENAME in $HERMES_TARBALL_ARTIFACTS_DIR"
|
||||
echo "$TARBALL_PATH"
|
||||
@@ -855,7 +852,9 @@ jobs:
|
||||
- run:
|
||||
name: Set HERMES_ENGINE_TARBALL_PATH
|
||||
command: |
|
||||
echo "export HERMES_ENGINE_TARBALL_PATH=$(ls -AU $HERMES_WS_DIR/hermes-runtime-darwin/hermes-runtime-darwin-*.tar.gz | head -1)" >> $BASH_ENV
|
||||
BUILD_TYPE="<< parameters.flavor >>"
|
||||
TARBALL_FILENAME=$(node ./scripts/hermes/get-tarball-name.js --buildType "$BUILD_TYPE")
|
||||
echo "export HERMES_ENGINE_TARBALL_PATH=$HERMES_WS_DIR/hermes-runtime-darwin/$TARBALL_FILENAME" >> $BASH_ENV
|
||||
- run:
|
||||
name: Create iOS template project
|
||||
command: |
|
||||
@@ -967,8 +966,8 @@ jobs:
|
||||
environment:
|
||||
- ANDROID_HOME: "C:\\Android\\android-sdk"
|
||||
- ANDROID_NDK: "C:\\Android\\android-sdk\\ndk\\20.1.5948944"
|
||||
- ANDROID_BUILD_VERSION: 31
|
||||
- ANDROID_TOOLS_VERSION: 31.0.0
|
||||
- ANDROID_BUILD_VERSION: 33
|
||||
- ANDROID_TOOLS_VERSION: 33.0.0
|
||||
- GRADLE_OPTS: -Dorg.gradle.daemon=false
|
||||
steps:
|
||||
- checkout_code_with_cache
|
||||
@@ -1227,20 +1226,13 @@ jobs:
|
||||
|
||||
TARBALL_OUTPUT_DIR=$(mktemp -d /tmp/hermes-tarball-output-XXXXXXXX)
|
||||
|
||||
# get_release_version() is defined in build-apple-framework.sh
|
||||
pushd ./sdks/hermes || exit 1
|
||||
BUILD_TYPE=$BUILD_TYPE source ./utils/build-apple-framework.sh
|
||||
RELEASE_VERSION=$(get_release_version)
|
||||
popd
|
||||
|
||||
TARBALL_FILENAME=$(node ./scripts/hermes/get-tarball-name.js --buildType "$BUILD_TYPE" --releaseVersion "$RELEASE_VERSION")
|
||||
TARBALL_FILENAME=$(node ./scripts/hermes/get-tarball-name.js --buildType "$BUILD_TYPE")
|
||||
|
||||
echo "Packaging Hermes Apple frameworks for $BUILD_TYPE build type"
|
||||
|
||||
TARBALL_OUTPUT_PATH=$(node ./scripts/hermes/create-tarball.js \
|
||||
--inputDir ./sdks/hermes \
|
||||
--buildType "$BUILD_TYPE" \
|
||||
--releaseVersion "$RELEASE_VERSION" \
|
||||
--outputDir $TARBALL_OUTPUT_DIR)
|
||||
|
||||
echo "Hermes tarball saved to $TARBALL_OUTPUT_PATH"
|
||||
@@ -1371,7 +1363,14 @@ jobs:
|
||||
- run:
|
||||
name: "Set new react-native version and commit changes"
|
||||
command: |
|
||||
node ./scripts/prepare-package-for-release.js -v << parameters.version >> -l << parameters.latest >> --dry-run << parameters.dryrun >>
|
||||
VERSION=<< parameters.version >>
|
||||
|
||||
if [[ -z "$VERSION" ]]; then
|
||||
VERSION=$(grep '"version"' package.json | cut -d '"' -f 4 | head -1)
|
||||
echo "Using the version from the package.json: $VERSION"
|
||||
fi
|
||||
|
||||
node ./scripts/prepare-package-for-release.js -v "$VERSION" -l << parameters.latest >> --dry-run << parameters.dryrun >>
|
||||
|
||||
build_npm_package:
|
||||
parameters:
|
||||
@@ -1409,8 +1408,8 @@ jobs:
|
||||
cp -r $HERMES_WS_DIR/win64-bin/* ./sdks/hermesc/win64-bin/.
|
||||
cp -r $HERMES_WS_DIR/linux64-bin/* ./sdks/hermesc/linux64-bin/.
|
||||
mkdir -p ./ReactAndroid/external-artifacts/artifacts/
|
||||
cp $HERMES_WS_DIR/hermes-runtime-darwin/hermes-runtime-darwin-debug-*.tar.gz ./ReactAndroid/external-artifacts/artifacts/hermes-ios-debug.tar.gz
|
||||
cp $HERMES_WS_DIR/hermes-runtime-darwin/hermes-runtime-darwin-release-*.tar.gz ./ReactAndroid/external-artifacts/artifacts/hermes-ios-release.tar.gz
|
||||
cp $HERMES_WS_DIR/hermes-runtime-darwin/hermes-ios-debug.tar.gz ./ReactAndroid/external-artifacts/artifacts/hermes-ios-debug.tar.gz
|
||||
cp $HERMES_WS_DIR/hermes-runtime-darwin/hermes-ios-release.tar.gz ./ReactAndroid/external-artifacts/artifacts/hermes-ios-release.tar.gz
|
||||
|
||||
- run_yarn
|
||||
- download_gradle_dependencies
|
||||
@@ -1495,43 +1494,6 @@ jobs:
|
||||
-d "{\"event_type\": \"publish\", \"client_payload\": { \"version\": \"${CIRCLE_TAG:1}\" }}"
|
||||
# END: Stable releases
|
||||
|
||||
# START: Stables and commitlies
|
||||
- when:
|
||||
condition:
|
||||
or:
|
||||
- equal: [ "release", << parameters.release_type >> ]
|
||||
- equal: [ "dry-run", << parameters.release_type >> ]
|
||||
steps:
|
||||
- run:
|
||||
name: Install dependencies
|
||||
command: apt update && apt install -y jq jo
|
||||
- run:
|
||||
name: Create draft GitHub Release and upload Hermes binaries
|
||||
command: |
|
||||
RELEASE_VERSION=$(cat build/.version)
|
||||
if [[ << parameters.release_type >> == "release" ]]; then
|
||||
GIT_TAG=$CIRCLE_TAG
|
||||
elif [[ << parameters.release_type >> == "dry-run" ]]; then
|
||||
GIT_TAG=v1000.0.0
|
||||
fi
|
||||
|
||||
ARTIFACTS=("")
|
||||
for build_type in "Debug" "Release"; do
|
||||
TARBALL_FILENAME=$(node ./scripts/hermes/get-tarball-name.js \
|
||||
--buildType $build_type \
|
||||
--releaseVersion $RELEASE_VERSION)
|
||||
|
||||
ARTIFACTS+=("$HERMES_WS_DIR/hermes-runtime-darwin/$TARBALL_FILENAME")
|
||||
done
|
||||
|
||||
./scripts/circleci/create_github_release.sh \
|
||||
<< parameters.release_type >> \
|
||||
$GIT_TAG \
|
||||
$RELEASE_VERSION \
|
||||
$GITHUB_TOKEN \
|
||||
"${ARTIFACTS[@]}"
|
||||
# END: Stable and commitlies
|
||||
|
||||
# -------------------------
|
||||
# JOBS: Nightly
|
||||
# -------------------------
|
||||
@@ -1688,7 +1650,7 @@ workflows:
|
||||
jobs:
|
||||
- prepare_package_for_release:
|
||||
name: prepare_package_for_release
|
||||
version: 'v1000.0.1'
|
||||
version: ''
|
||||
latest : false
|
||||
dryrun: true
|
||||
- prepare_hermes_workspace:
|
||||
|
||||
@@ -10,6 +10,9 @@ load(
|
||||
)
|
||||
load(
|
||||
"//tools/build_defs/oss:rn_defs.bzl",
|
||||
"ANDROID",
|
||||
"APPLE",
|
||||
"CXX",
|
||||
"HERMES_BYTECODE_VERSION",
|
||||
"IOS",
|
||||
"RCT_IMAGE_DATA_DECODER_SOCKET",
|
||||
@@ -264,6 +267,7 @@ REACT_PUBLIC_HEADERS = {
|
||||
"React/RCTDevLoadingViewProtocol.h": RCTDEVSUPPORT_PATH + "RCTDevLoadingViewProtocol.h",
|
||||
"React/RCTDevLoadingViewSetEnabled.h": RCTDEVSUPPORT_PATH + "RCTDevLoadingViewSetEnabled.h",
|
||||
"React/RCTDisplayLink.h": RCTBASE_PATH + "RCTDisplayLink.h",
|
||||
"React/RCTDynamicTypeRamp.h": RCTLIB_PATH + "Text/Text/RCTDynamicTypeRamp.h",
|
||||
"React/RCTErrorCustomizer.h": RCTBASE_PATH + "RCTErrorCustomizer.h",
|
||||
"React/RCTErrorInfo.h": RCTBASE_PATH + "RCTErrorInfo.h",
|
||||
# NOTE: RCTEventDispatcher.h is exported from CoreModules:CoreModulesApple
|
||||
@@ -1453,3 +1457,28 @@ rn_xplat_cxx_library2(
|
||||
"//fbobjc/VendorLib/react-native-maps:react-native-maps",
|
||||
],
|
||||
)
|
||||
|
||||
rn_xplat_cxx_library2(
|
||||
name = "RCTWebPerformance",
|
||||
srcs = glob([
|
||||
"Libraries/WebPerformance/**/*.cpp",
|
||||
]),
|
||||
header_namespace = "",
|
||||
exported_headers = subdir_glob(
|
||||
[("Libraries/WebPerformance", "*.h")],
|
||||
prefix = "RCTWebPerformance",
|
||||
),
|
||||
fbandroid_compiler_flags = [
|
||||
"-fexceptions",
|
||||
"-frtti",
|
||||
],
|
||||
labels = [
|
||||
"depslint_never_remove",
|
||||
"pfh:ReactNative_CommonInfrastructurePlaceholder",
|
||||
],
|
||||
platforms = (ANDROID, APPLE, CXX),
|
||||
visibility = ["PUBLIC"],
|
||||
deps = [
|
||||
":FBReactNativeSpecJSI",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -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.6'
|
||||
ruby File.read(File.join(__dir__, '.ruby-version')).strip
|
||||
|
||||
gem 'cocoapods', '~> 1.11', '>= 1.11.3'
|
||||
|
||||
+4
-4
@@ -56,7 +56,7 @@ GEM
|
||||
colored2 (3.1.2)
|
||||
concurrent-ruby (1.1.10)
|
||||
escape (0.0.4)
|
||||
ethon (0.15.0)
|
||||
ethon (0.16.0)
|
||||
ffi (>= 1.15.0)
|
||||
ffi (1.15.5)
|
||||
fourflusher (2.3.1)
|
||||
@@ -85,16 +85,16 @@ GEM
|
||||
colored2 (~> 3.1)
|
||||
nanaimo (~> 0.3.0)
|
||||
rexml (~> 3.2.4)
|
||||
zeitwerk (2.6.0)
|
||||
zeitwerk (2.6.6)
|
||||
|
||||
PLATFORMS
|
||||
ruby
|
||||
|
||||
DEPENDENCIES
|
||||
cocoapods (~> 1.11, >= 1.11.2)
|
||||
cocoapods (~> 1.11, >= 1.11.3)
|
||||
|
||||
RUBY VERSION
|
||||
ruby 2.7.5p203
|
||||
ruby 2.7.6p219
|
||||
|
||||
BUNDLED WITH
|
||||
2.3.22
|
||||
|
||||
@@ -10,8 +10,8 @@
|
||||
*/
|
||||
|
||||
exports.version = {
|
||||
major: 1000,
|
||||
minor: 0,
|
||||
major: 0,
|
||||
minor: 71,
|
||||
patch: 0,
|
||||
prerelease: null,
|
||||
prerelease: 'rc.2',
|
||||
};
|
||||
|
||||
Vendored
-48
@@ -1,48 +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.
|
||||
*
|
||||
* @format
|
||||
*/
|
||||
|
||||
export interface OpenCameraDialogOptions {
|
||||
/** Defaults to false */
|
||||
videoMode?: boolean | undefined;
|
||||
}
|
||||
|
||||
export interface OpenSelectDialogOptions {
|
||||
/** Defaults to true */
|
||||
showImages?: boolean | undefined;
|
||||
/** Defaults to false */
|
||||
showVideos?: boolean | undefined;
|
||||
}
|
||||
|
||||
/** [imageURL|tempImageTag, height, width] */
|
||||
export type ImagePickerResult = [string, number, number];
|
||||
|
||||
export interface ImagePickerIOSStatic {
|
||||
canRecordVideos(callback: (value: boolean) => void): void;
|
||||
canUseCamera(callback: (value: boolean) => void): void;
|
||||
openCameraDialog(
|
||||
config: OpenCameraDialogOptions,
|
||||
successCallback: (args: ImagePickerResult) => void,
|
||||
cancelCallback: (args: any[]) => void,
|
||||
): void;
|
||||
openSelectDialog(
|
||||
config: OpenSelectDialogOptions,
|
||||
successCallback: (args: ImagePickerResult) => void,
|
||||
cancelCallback: (args: any[]) => void,
|
||||
): void;
|
||||
}
|
||||
|
||||
/**
|
||||
* ImagePickerIOS has been extracted from react-native core and will be removed in a future release.
|
||||
* Please upgrade to use either `@react-native-community/react-native-image-picker` or 'expo-image-picker'.
|
||||
* If you cannot upgrade to a different library, please install the deprecated `@react-native-community/image-picker-ios` package.
|
||||
* @see https://github.com/react-native-community/react-native-image-picker-ios
|
||||
* @deprecated
|
||||
*/
|
||||
export const ImagePickerIOS: ImagePickerIOSStatic;
|
||||
export type ImagePickerIOS = ImagePickerIOSStatic;
|
||||
@@ -1,103 +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.
|
||||
*
|
||||
* @format
|
||||
* @flow strict-local
|
||||
*/
|
||||
|
||||
import NativeImagePickerIOS from './NativeImagePickerIOS';
|
||||
import invariant from 'invariant';
|
||||
|
||||
const ImagePickerIOS = {
|
||||
canRecordVideos: function (callback: (result: boolean) => void): void {
|
||||
invariant(NativeImagePickerIOS, 'ImagePickerIOS is not available');
|
||||
return NativeImagePickerIOS.canRecordVideos(callback);
|
||||
},
|
||||
canUseCamera: function (callback: (result: boolean) => void): void {
|
||||
invariant(NativeImagePickerIOS, 'ImagePickerIOS is not available');
|
||||
return NativeImagePickerIOS.canUseCamera(callback);
|
||||
},
|
||||
openCameraDialog: function (
|
||||
config: $ReadOnly<{|
|
||||
unmirrorFrontFacingCamera?: boolean,
|
||||
videoMode?: boolean,
|
||||
|}>,
|
||||
successCallback: (imageURL: string, height: number, width: number) => void,
|
||||
cancelCallback: () => void,
|
||||
): void {
|
||||
invariant(NativeImagePickerIOS, 'ImagePickerIOS is not available');
|
||||
|
||||
var newConfig = {
|
||||
videoMode: true,
|
||||
unmirrorFrontFacingCamera: false,
|
||||
};
|
||||
|
||||
if (config.videoMode != null) {
|
||||
newConfig.videoMode = config.videoMode;
|
||||
}
|
||||
|
||||
if (config.unmirrorFrontFacingCamera != null) {
|
||||
newConfig.unmirrorFrontFacingCamera = config.unmirrorFrontFacingCamera;
|
||||
}
|
||||
|
||||
return NativeImagePickerIOS.openCameraDialog(
|
||||
newConfig,
|
||||
successCallback,
|
||||
cancelCallback,
|
||||
);
|
||||
},
|
||||
openSelectDialog: function (
|
||||
config: $ReadOnly<{|
|
||||
showImages?: boolean,
|
||||
showVideos?: boolean,
|
||||
|}>,
|
||||
successCallback: (imageURL: string, height: number, width: number) => void,
|
||||
cancelCallback: () => void,
|
||||
): void {
|
||||
invariant(NativeImagePickerIOS, 'ImagePickerIOS is not available');
|
||||
|
||||
var newConfig = {
|
||||
showImages: true,
|
||||
showVideos: false,
|
||||
};
|
||||
|
||||
if (config.showImages != null) {
|
||||
newConfig.showImages = config.showImages;
|
||||
}
|
||||
|
||||
if (config.showVideos != null) {
|
||||
newConfig.showVideos = config.showVideos;
|
||||
}
|
||||
|
||||
return NativeImagePickerIOS.openSelectDialog(
|
||||
newConfig,
|
||||
successCallback,
|
||||
cancelCallback,
|
||||
);
|
||||
},
|
||||
/**
|
||||
* In iOS 13, the video URLs returned by the Image Picker are invalidated when
|
||||
* the picker is dismissed, unless reference to it is held. This API allows
|
||||
* the application to signal when it's finished with the video so that the
|
||||
* reference can be cleaned up.
|
||||
* It is safe to call this method for urlsthat aren't video URLs;
|
||||
* it will be a no-op.
|
||||
*/
|
||||
removePendingVideo: function (url: string): void {
|
||||
invariant(NativeImagePickerIOS, 'ImagePickerIOS is not available');
|
||||
NativeImagePickerIOS.removePendingVideo(url);
|
||||
},
|
||||
/**
|
||||
* WARNING: In most cases, removePendingVideo should be used instead because
|
||||
* clearAllPendingVideos could clear out pending videos made by other callers.
|
||||
*/
|
||||
clearAllPendingVideos: function (): void {
|
||||
invariant(NativeImagePickerIOS, 'ImagePickerIOS is not available');
|
||||
NativeImagePickerIOS.clearAllPendingVideos();
|
||||
},
|
||||
};
|
||||
|
||||
module.exports = ImagePickerIOS;
|
||||
@@ -1,39 +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.
|
||||
*
|
||||
* @flow strict
|
||||
* @format
|
||||
*/
|
||||
|
||||
import type {TurboModule} from '../TurboModule/RCTExport';
|
||||
|
||||
import * as TurboModuleRegistry from '../TurboModule/TurboModuleRegistry';
|
||||
|
||||
export interface Spec extends TurboModule {
|
||||
+getConstants: () => {||};
|
||||
+canRecordVideos: (callback: (result: boolean) => void) => void;
|
||||
+canUseCamera: (callback: (result: boolean) => void) => void;
|
||||
+openCameraDialog: (
|
||||
config: {|
|
||||
unmirrorFrontFacingCamera: boolean,
|
||||
videoMode: boolean,
|
||||
|},
|
||||
successCallback: (imageURL: string, height: number, width: number) => void,
|
||||
cancelCallback: () => void,
|
||||
) => void;
|
||||
+openSelectDialog: (
|
||||
config: {|
|
||||
showImages: boolean,
|
||||
showVideos: boolean,
|
||||
|},
|
||||
successCallback: (imageURL: string, height: number, width: number) => void,
|
||||
cancelCallback: () => void,
|
||||
) => void;
|
||||
+clearAllPendingVideos: () => void;
|
||||
+removePendingVideo: (url: string) => void;
|
||||
}
|
||||
|
||||
export default (TurboModuleRegistry.get<Spec>('ImagePickerIOS'): ?Spec);
|
||||
@@ -1,124 +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.
|
||||
*
|
||||
* @format
|
||||
* @flow strict
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
export type Timestamp = number;
|
||||
export type PerformanceEntryType = 'event';
|
||||
|
||||
export class PerformanceEntry {
|
||||
name: string;
|
||||
entryType: PerformanceEntryType;
|
||||
startTime: Timestamp;
|
||||
duration: number;
|
||||
|
||||
// For "event" entries only:
|
||||
processingStart: ?Timestamp;
|
||||
processingEnd: ?Timestamp;
|
||||
interactionId: ?number;
|
||||
|
||||
// $FlowIgnore: Flow(unclear-type)
|
||||
toJSON(): Object {
|
||||
return {
|
||||
name: this.name,
|
||||
entryType: this.entryType,
|
||||
startTime: this.startTime,
|
||||
duration: this.duration,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export type PerformanceEntryList = $ReadOnlyArray<PerformanceEntry>;
|
||||
|
||||
export class PerformanceObserverEntryList {
|
||||
_entries: PerformanceEntryList;
|
||||
|
||||
constructor(entries: PerformanceEntryList) {
|
||||
this._entries = entries;
|
||||
}
|
||||
|
||||
getEntries(): PerformanceEntryList {
|
||||
return this._entries;
|
||||
}
|
||||
|
||||
getEntriesByType(type: PerformanceEntryType): PerformanceEntryList {
|
||||
return this._entries.filter(entry => entry.entryType === type);
|
||||
}
|
||||
|
||||
getEntriesByName(
|
||||
name: string,
|
||||
type?: PerformanceEntryType,
|
||||
): PerformanceEntryList {
|
||||
if (type === undefined) {
|
||||
return this._entries.filter(entry => entry.name === name);
|
||||
} else {
|
||||
return this._entries.filter(
|
||||
entry => entry.name === name && entry.entryType === type,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export type PerformanceObserverCallback = (
|
||||
list: PerformanceObserverEntryList,
|
||||
observer: PerformanceObserver,
|
||||
) => void;
|
||||
|
||||
export type PerformanceObserverInit =
|
||||
| {
|
||||
entryTypes: PerformanceEntryType[],
|
||||
buffered?: boolean,
|
||||
}
|
||||
| {
|
||||
type: PerformanceEntryType,
|
||||
buffered?: boolean,
|
||||
};
|
||||
|
||||
/**
|
||||
* Implementation of the PerformanceObserver interface for RN,
|
||||
* corresponding to the standard in https://www.w3.org/TR/performance-timeline/
|
||||
*
|
||||
* @example
|
||||
* const observer = new PerformanceObserver((list, _observer) => {
|
||||
* const entries = list.getEntries();
|
||||
* entries.forEach(entry => {
|
||||
* reportEvent({
|
||||
* eventName: entry.name,
|
||||
* startTime: entry.startTime,
|
||||
* endTime: entry.startTime + entry.duration,
|
||||
* processingStart: entry.processingStart,
|
||||
* processingEnd: entry.processingEnd,
|
||||
* interactionId: entry.interactionId,
|
||||
* });
|
||||
* });
|
||||
* });
|
||||
* observer.observe({ type: "event" });
|
||||
*/
|
||||
export default class PerformanceObserver {
|
||||
_callback: PerformanceObserverCallback;
|
||||
|
||||
constructor(callback: PerformanceObserverCallback) {
|
||||
this._callback = callback;
|
||||
}
|
||||
|
||||
observe(options: PerformanceObserverInit) {
|
||||
console.log('PerformanceObserver: started observing');
|
||||
}
|
||||
|
||||
disconnect(): void {
|
||||
console.log('PerformanceObserver: stopped observing');
|
||||
}
|
||||
|
||||
takeRecords(): PerformanceEntryList {
|
||||
return [];
|
||||
}
|
||||
|
||||
static supportedEntryTypes: PerformanceEntryType[] = ['event'];
|
||||
}
|
||||
@@ -36,6 +36,7 @@ RCT_REMAP_SHADOW_PROPERTY(fontWeight, textAttributes.fontWeight, NSString)
|
||||
RCT_REMAP_SHADOW_PROPERTY(fontStyle, textAttributes.fontStyle, NSString)
|
||||
RCT_REMAP_SHADOW_PROPERTY(fontVariant, textAttributes.fontVariant, NSArray)
|
||||
RCT_REMAP_SHADOW_PROPERTY(allowFontScaling, textAttributes.allowFontScaling, BOOL)
|
||||
RCT_REMAP_SHADOW_PROPERTY(dynamicTypeRamp, textAttributes.dynamicTypeRamp, RCTDynamicTypeRamp)
|
||||
RCT_REMAP_SHADOW_PROPERTY(maxFontSizeMultiplier, textAttributes.maxFontSizeMultiplier, CGFloat)
|
||||
RCT_REMAP_SHADOW_PROPERTY(letterSpacing, textAttributes.letterSpacing, CGFloat)
|
||||
// Paragraph Styles
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
#import <React/RCTDynamicTypeRamp.h>
|
||||
#import <React/RCTTextDecorationLineType.h>
|
||||
|
||||
#import "RCTTextTransform.h"
|
||||
@@ -36,6 +37,7 @@ extern NSString *const RCTTextAttributesTagAttributeName;
|
||||
@property (nonatomic, copy, nullable) NSString *fontStyle;
|
||||
@property (nonatomic, copy, nullable) NSArray<NSString *> *fontVariant;
|
||||
@property (nonatomic, assign) BOOL allowFontScaling;
|
||||
@property (nonatomic, assign) RCTDynamicTypeRamp dynamicTypeRamp;
|
||||
@property (nonatomic, assign) CGFloat letterSpacing;
|
||||
// Paragraph Styles
|
||||
@property (nonatomic, assign) CGFloat lineHeight;
|
||||
|
||||
@@ -59,6 +59,8 @@ NSString *const RCTTextAttributesTagAttributeName = @"RCTTextAttributesTagAttrib
|
||||
_fontStyle = textAttributes->_fontStyle ?: _fontStyle;
|
||||
_fontVariant = textAttributes->_fontVariant ?: _fontVariant;
|
||||
_allowFontScaling = textAttributes->_allowFontScaling || _allowFontScaling; // *
|
||||
_dynamicTypeRamp = textAttributes->_dynamicTypeRamp != RCTDynamicTypeRampUndefined ? textAttributes->_dynamicTypeRamp
|
||||
: _dynamicTypeRamp;
|
||||
_letterSpacing = !isnan(textAttributes->_letterSpacing) ? textAttributes->_letterSpacing : _letterSpacing;
|
||||
|
||||
// Paragraph Styles
|
||||
@@ -230,6 +232,12 @@ NSString *const RCTTextAttributesTagAttributeName = @"RCTTextAttributesTagAttrib
|
||||
|
||||
if (fontScalingEnabled) {
|
||||
CGFloat fontSizeMultiplier = !isnan(_fontSizeMultiplier) ? _fontSizeMultiplier : 1.0;
|
||||
if (_dynamicTypeRamp != RCTDynamicTypeRampUndefined) {
|
||||
UIFontMetrics *fontMetrics = RCTUIFontMetricsForDynamicTypeRamp(_dynamicTypeRamp);
|
||||
// Using a specific font size reduces rounding errors from -scaledValueForValue:
|
||||
CGFloat requestedSize = isnan(_fontSize) ? RCTBaseSizeForDynamicTypeRamp(_dynamicTypeRamp) : _fontSize;
|
||||
fontSizeMultiplier = [fontMetrics scaledValueForValue:requestedSize] / requestedSize;
|
||||
}
|
||||
CGFloat maxFontSizeMultiplier = !isnan(_maxFontSizeMultiplier) ? _maxFontSizeMultiplier : 0.0;
|
||||
return maxFontSizeMultiplier >= 1.0 ? fminf(maxFontSizeMultiplier, fontSizeMultiplier) : fontSizeMultiplier;
|
||||
} else {
|
||||
@@ -324,7 +332,7 @@ static NSString *capitalizeText(NSString *text)
|
||||
RCTTextAttributesCompareFloats(_fontSizeMultiplier) && RCTTextAttributesCompareFloats(_maxFontSizeMultiplier) &&
|
||||
RCTTextAttributesCompareStrings(_fontWeight) && RCTTextAttributesCompareObjects(_fontStyle) &&
|
||||
RCTTextAttributesCompareObjects(_fontVariant) && RCTTextAttributesCompareOthers(_allowFontScaling) &&
|
||||
RCTTextAttributesCompareFloats(_letterSpacing) &&
|
||||
RCTTextAttributesCompareOthers(_dynamicTypeRamp) && RCTTextAttributesCompareFloats(_letterSpacing) &&
|
||||
// Paragraph Styles
|
||||
RCTTextAttributesCompareFloats(_lineHeight) && RCTTextAttributesCompareFloats(_alignment) &&
|
||||
RCTTextAttributesCompareOthers(_baseWritingDirection) && RCTTextAttributesCompareOthers(_lineBreakStrategy) &&
|
||||
|
||||
Vendored
+17
@@ -26,6 +26,23 @@ export interface TextPropsIOS {
|
||||
*/
|
||||
adjustsFontSizeToFit?: boolean | undefined;
|
||||
|
||||
/**
|
||||
* The Dynamic Text scale ramp to apply to this element on iOS.
|
||||
*/
|
||||
dynamicTypeRamp?:
|
||||
| 'caption2'
|
||||
| 'caption1'
|
||||
| 'footnote'
|
||||
| 'subheadline'
|
||||
| 'callout'
|
||||
| 'body'
|
||||
| 'headline'
|
||||
| 'title3'
|
||||
| 'title2'
|
||||
| 'title1'
|
||||
| 'largeTitle'
|
||||
| undefined;
|
||||
|
||||
/**
|
||||
* Specifies smallest possible scale a font can reach when adjustsFontSizeToFit is enabled. (values 0.01-1.0).
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#import <React/RCTConvert.h>
|
||||
|
||||
typedef NS_ENUM(NSInteger, RCTDynamicTypeRamp) {
|
||||
RCTDynamicTypeRampUndefined,
|
||||
RCTDynamicTypeRampCaption2,
|
||||
RCTDynamicTypeRampCaption1,
|
||||
RCTDynamicTypeRampFootnote,
|
||||
RCTDynamicTypeRampSubheadline,
|
||||
RCTDynamicTypeRampCallout,
|
||||
RCTDynamicTypeRampBody,
|
||||
RCTDynamicTypeRampHeadline,
|
||||
RCTDynamicTypeRampTitle3,
|
||||
RCTDynamicTypeRampTitle2,
|
||||
RCTDynamicTypeRampTitle1,
|
||||
RCTDynamicTypeRampLargeTitle
|
||||
};
|
||||
|
||||
@interface RCTConvert (DynamicTypeRamp)
|
||||
|
||||
+ (RCTDynamicTypeRamp)RCTDynamicTypeRamp:(nullable id)json;
|
||||
|
||||
@end
|
||||
|
||||
/// Generates a `UIFontMetrics` instance representing a particular Dynamic Type ramp.
|
||||
UIFontMetrics *_Nonnull RCTUIFontMetricsForDynamicTypeRamp(RCTDynamicTypeRamp dynamicTypeRamp);
|
||||
/// The "reference" size for a particular font scale ramp, equal to a text element's size under default text size
|
||||
/// settings.
|
||||
CGFloat RCTBaseSizeForDynamicTypeRamp(RCTDynamicTypeRamp dynamicTypeRamp);
|
||||
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#import <React/RCTDynamicTypeRamp.h>
|
||||
|
||||
@implementation RCTConvert (DynamicTypeRamp)
|
||||
|
||||
RCT_ENUM_CONVERTER(
|
||||
RCTDynamicTypeRamp,
|
||||
(@{
|
||||
@"caption2" : @(RCTDynamicTypeRampCaption2),
|
||||
@"caption1" : @(RCTDynamicTypeRampCaption1),
|
||||
@"footnote" : @(RCTDynamicTypeRampFootnote),
|
||||
@"subheadline" : @(RCTDynamicTypeRampSubheadline),
|
||||
@"callout" : @(RCTDynamicTypeRampCallout),
|
||||
@"body" : @(RCTDynamicTypeRampBody),
|
||||
@"headline" : @(RCTDynamicTypeRampHeadline),
|
||||
@"title3" : @(RCTDynamicTypeRampTitle3),
|
||||
@"title2" : @(RCTDynamicTypeRampTitle2),
|
||||
@"title1" : @(RCTDynamicTypeRampTitle1),
|
||||
@"largeTitle" : @(RCTDynamicTypeRampLargeTitle),
|
||||
}),
|
||||
RCTDynamicTypeRampUndefined,
|
||||
integerValue)
|
||||
|
||||
@end
|
||||
|
||||
UIFontMetrics *RCTUIFontMetricsForDynamicTypeRamp(RCTDynamicTypeRamp dynamicTypeRamp)
|
||||
{
|
||||
static NSDictionary<NSNumber *, UIFontTextStyle> *mapping;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
mapping = @{
|
||||
@(RCTDynamicTypeRampCaption2) : UIFontTextStyleCaption2,
|
||||
@(RCTDynamicTypeRampCaption1) : UIFontTextStyleCaption1,
|
||||
@(RCTDynamicTypeRampFootnote) : UIFontTextStyleFootnote,
|
||||
@(RCTDynamicTypeRampSubheadline) : UIFontTextStyleSubheadline,
|
||||
@(RCTDynamicTypeRampCallout) : UIFontTextStyleCallout,
|
||||
@(RCTDynamicTypeRampBody) : UIFontTextStyleBody,
|
||||
@(RCTDynamicTypeRampHeadline) : UIFontTextStyleHeadline,
|
||||
@(RCTDynamicTypeRampTitle3) : UIFontTextStyleTitle3,
|
||||
@(RCTDynamicTypeRampTitle2) : UIFontTextStyleTitle2,
|
||||
@(RCTDynamicTypeRampTitle1) : UIFontTextStyleTitle1,
|
||||
@(RCTDynamicTypeRampLargeTitle) : UIFontTextStyleLargeTitle,
|
||||
};
|
||||
});
|
||||
|
||||
id textStyle =
|
||||
mapping[@(dynamicTypeRamp)] ?: UIFontTextStyleBody; // Default to body if we don't recognize the specified ramp
|
||||
return [UIFontMetrics metricsForTextStyle:textStyle];
|
||||
}
|
||||
|
||||
CGFloat RCTBaseSizeForDynamicTypeRamp(RCTDynamicTypeRamp dynamicTypeRamp)
|
||||
{
|
||||
static NSDictionary<NSNumber *, NSNumber *> *mapping;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
// Values taken from
|
||||
// https://developer.apple.com/design/human-interface-guidelines/foundations/typography/#specifications
|
||||
mapping = @{
|
||||
@(RCTDynamicTypeRampCaption2) : @11,
|
||||
@(RCTDynamicTypeRampCaption1) : @12,
|
||||
@(RCTDynamicTypeRampFootnote) : @13,
|
||||
@(RCTDynamicTypeRampSubheadline) : @15,
|
||||
@(RCTDynamicTypeRampCallout) : @16,
|
||||
@(RCTDynamicTypeRampBody) : @17,
|
||||
@(RCTDynamicTypeRampHeadline) : @17,
|
||||
@(RCTDynamicTypeRampTitle3) : @20,
|
||||
@(RCTDynamicTypeRampTitle2) : @22,
|
||||
@(RCTDynamicTypeRampTitle1) : @28,
|
||||
@(RCTDynamicTypeRampLargeTitle) : @34,
|
||||
};
|
||||
});
|
||||
|
||||
NSNumber *baseSize =
|
||||
mapping[@(dynamicTypeRamp)] ?: @17; // Default to body size if we don't recognize the specified ramp
|
||||
return CGFLOAT_IS_DOUBLE ? [baseSize doubleValue] : [baseSize floatValue];
|
||||
}
|
||||
@@ -34,6 +34,7 @@ const textViewConfig = {
|
||||
numberOfLines: true,
|
||||
ellipsizeMode: true,
|
||||
allowFontScaling: true,
|
||||
dynamicTypeRamp: true,
|
||||
maxFontSizeMultiplier: true,
|
||||
disabled: true,
|
||||
selectable: true,
|
||||
|
||||
@@ -229,6 +229,23 @@ export type TextProps = $ReadOnly<{|
|
||||
*/
|
||||
adjustsFontSizeToFit?: ?boolean,
|
||||
|
||||
/**
|
||||
* The Dynamic Text scale ramp to apply to this element on iOS.
|
||||
*/
|
||||
dynamicTypeRamp?: ?(
|
||||
| 'caption2'
|
||||
| 'caption1'
|
||||
| 'footnote'
|
||||
| 'subheadline'
|
||||
| 'callout'
|
||||
| 'body'
|
||||
| 'headline'
|
||||
| 'title3'
|
||||
| 'title2'
|
||||
| 'title1'
|
||||
| 'largeTitle'
|
||||
),
|
||||
|
||||
/**
|
||||
* Smallest possible scale a font can reach.
|
||||
*
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "NativePerformanceObserver.h"
|
||||
#include <glog/logging.h>
|
||||
|
||||
namespace facebook::react {
|
||||
|
||||
NativePerformanceObserver::NativePerformanceObserver(
|
||||
std::shared_ptr<CallInvoker> jsInvoker)
|
||||
: NativePerformanceObserverCxxSpec(std::move(jsInvoker)) {}
|
||||
|
||||
void NativePerformanceObserver::startReporting(
|
||||
jsi::Runtime &rt,
|
||||
std::string entryType) {
|
||||
LOG(INFO) << "Started reporting perf entry type: " << entryType;
|
||||
}
|
||||
|
||||
void NativePerformanceObserver::stopReporting(
|
||||
jsi::Runtime &rt,
|
||||
std::string entryType) {
|
||||
LOG(INFO) << "Stopped reporting perf entry type: " << entryType;
|
||||
}
|
||||
|
||||
std::vector<RawPerformanceEntry> NativePerformanceObserver::getPendingEntries(
|
||||
jsi::Runtime &rt) {
|
||||
return std::vector<RawPerformanceEntry>{};
|
||||
}
|
||||
|
||||
void NativePerformanceObserver::setOnPerformanceEntryCallback(
|
||||
jsi::Runtime &rt,
|
||||
std::optional<AsyncCallback<>> callback) {
|
||||
callback_ = callback;
|
||||
LOG(INFO) << "setOnPerformanceEntryCallback: "
|
||||
<< (callback ? "non-empty" : "empty");
|
||||
}
|
||||
|
||||
} // namespace facebook::react
|
||||
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <FBReactNativeSpec/FBReactNativeSpecJSI.h>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace facebook::react {
|
||||
|
||||
#pragma mark - Structs
|
||||
|
||||
using RawPerformanceEntry = NativePerformanceObserverCxxBaseRawPerformanceEntry<
|
||||
std::string,
|
||||
int32_t,
|
||||
double,
|
||||
double,
|
||||
// For "event" entries only:
|
||||
std::optional<double>,
|
||||
std::optional<double>,
|
||||
std::optional<double>>;
|
||||
|
||||
template <>
|
||||
struct Bridging<RawPerformanceEntry>
|
||||
: NativePerformanceObserverCxxBaseRawPerformanceEntryBridging<
|
||||
std::string,
|
||||
int32_t,
|
||||
double,
|
||||
double,
|
||||
std::optional<double>,
|
||||
std::optional<double>,
|
||||
std::optional<double>> {};
|
||||
|
||||
#pragma mark - implementation
|
||||
|
||||
class NativePerformanceObserver
|
||||
: public NativePerformanceObserverCxxSpec<NativePerformanceObserver>,
|
||||
std::enable_shared_from_this<NativePerformanceObserver> {
|
||||
public:
|
||||
NativePerformanceObserver(std::shared_ptr<CallInvoker> jsInvoker);
|
||||
|
||||
void startReporting(jsi::Runtime &rt, std::string entryType);
|
||||
|
||||
void stopReporting(jsi::Runtime &rt, std::string entryType);
|
||||
|
||||
std::vector<RawPerformanceEntry> getPendingEntries(jsi::Runtime &rt);
|
||||
|
||||
void setOnPerformanceEntryCallback(
|
||||
jsi::Runtime &rt,
|
||||
std::optional<AsyncCallback<>> callback);
|
||||
|
||||
private:
|
||||
std::optional<AsyncCallback<>> callback_;
|
||||
};
|
||||
|
||||
} // namespace facebook::react
|
||||
@@ -0,0 +1,41 @@
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
* @flow strict
|
||||
* @format
|
||||
*/
|
||||
|
||||
import type {TurboModule} from '../TurboModule/RCTExport';
|
||||
|
||||
import * as TurboModuleRegistry from '../TurboModule/TurboModuleRegistry';
|
||||
|
||||
export const RawPerformanceEntryTypeValues = {
|
||||
UNDEFINED: 0,
|
||||
};
|
||||
|
||||
export type RawPerformanceEntryType = number;
|
||||
|
||||
export type RawPerformanceEntry = {|
|
||||
name: string,
|
||||
entryType: RawPerformanceEntryType,
|
||||
startTime: number,
|
||||
duration: number,
|
||||
// For "event" entries only:
|
||||
processingStart?: number,
|
||||
processingEnd?: number,
|
||||
interactionId?: number,
|
||||
|};
|
||||
|
||||
export interface Spec extends TurboModule {
|
||||
+startReporting: (entryType: string) => void;
|
||||
+stopReporting: (entryType: string) => void;
|
||||
+getPendingEntries: () => $ReadOnlyArray<RawPerformanceEntry>;
|
||||
+setOnPerformanceEntryCallback: (callback?: () => void) => void;
|
||||
}
|
||||
|
||||
export default (TurboModuleRegistry.get<Spec>(
|
||||
'NativePerformanceObserverCxx',
|
||||
): ?Spec);
|
||||
@@ -0,0 +1,223 @@
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
* @format
|
||||
* @flow strict
|
||||
*/
|
||||
|
||||
import type {
|
||||
RawPerformanceEntry,
|
||||
RawPerformanceEntryType,
|
||||
} from './NativePerformanceObserver';
|
||||
|
||||
import warnOnce from '../Utilities/warnOnce';
|
||||
import NativePerformanceObserver from './NativePerformanceObserver';
|
||||
|
||||
export type HighResTimeStamp = number;
|
||||
// TODO: Extend once new types (such as event) are supported.
|
||||
// TODO: Get rid of the "undefined" once there is at least one type supported.
|
||||
export type PerformanceEntryType = 'undefined';
|
||||
|
||||
export class PerformanceEntry {
|
||||
name: string;
|
||||
entryType: PerformanceEntryType;
|
||||
startTime: HighResTimeStamp;
|
||||
duration: number;
|
||||
|
||||
constructor(init: {
|
||||
name: string,
|
||||
entryType: PerformanceEntryType,
|
||||
startTime: HighResTimeStamp,
|
||||
duration: number,
|
||||
}) {
|
||||
this.name = init.name;
|
||||
this.entryType = init.entryType;
|
||||
this.startTime = init.startTime;
|
||||
this.duration = init.duration;
|
||||
}
|
||||
|
||||
// $FlowIgnore: Flow(unclear-type)
|
||||
toJSON(): Object {
|
||||
return {
|
||||
name: this.name,
|
||||
entryType: this.entryType,
|
||||
startTime: this.startTime,
|
||||
duration: this.duration,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
function rawToPerformanceEntryType(
|
||||
type: RawPerformanceEntryType,
|
||||
): PerformanceEntryType {
|
||||
return 'undefined';
|
||||
}
|
||||
|
||||
function rawToPerformanceEntry(entry: RawPerformanceEntry): PerformanceEntry {
|
||||
return new PerformanceEntry({
|
||||
name: entry.name,
|
||||
entryType: rawToPerformanceEntryType(entry.entryType),
|
||||
startTime: entry.startTime,
|
||||
duration: entry.duration,
|
||||
});
|
||||
}
|
||||
|
||||
export type PerformanceEntryList = $ReadOnlyArray<PerformanceEntry>;
|
||||
|
||||
export class PerformanceObserverEntryList {
|
||||
_entries: PerformanceEntryList;
|
||||
|
||||
constructor(entries: PerformanceEntryList) {
|
||||
this._entries = entries;
|
||||
}
|
||||
|
||||
getEntries(): PerformanceEntryList {
|
||||
return this._entries;
|
||||
}
|
||||
|
||||
getEntriesByType(type: PerformanceEntryType): PerformanceEntryList {
|
||||
return this._entries.filter(entry => entry.entryType === type);
|
||||
}
|
||||
|
||||
getEntriesByName(
|
||||
name: string,
|
||||
type?: PerformanceEntryType,
|
||||
): PerformanceEntryList {
|
||||
if (type === undefined) {
|
||||
return this._entries.filter(entry => entry.name === name);
|
||||
} else {
|
||||
return this._entries.filter(
|
||||
entry => entry.name === name && entry.entryType === type,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export type PerformanceObserverCallback = (
|
||||
list: PerformanceObserverEntryList,
|
||||
observer: PerformanceObserver,
|
||||
) => void;
|
||||
|
||||
export type PerformanceObserverInit =
|
||||
| {
|
||||
entryTypes: Array<PerformanceEntryType>,
|
||||
}
|
||||
| {
|
||||
type: PerformanceEntryType,
|
||||
};
|
||||
|
||||
let _observedEntryTypeRefCount: Map<PerformanceEntryType, number> = new Map();
|
||||
|
||||
let _observers: Set<PerformanceObserver> = new Set();
|
||||
|
||||
let _onPerformanceEntryCallbackIsSet: boolean = false;
|
||||
|
||||
function warnNoNativePerformanceObserver() {
|
||||
warnOnce(
|
||||
'missing-native-performance-observer',
|
||||
'Missing native implementation of PerformanceObserver',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of the PerformanceObserver interface for RN,
|
||||
* corresponding to the standard in https://www.w3.org/TR/performance-timeline/
|
||||
*
|
||||
* @example
|
||||
* const observer = new PerformanceObserver((list, _observer) => {
|
||||
* const entries = list.getEntries();
|
||||
* entries.forEach(entry => {
|
||||
* reportEvent({
|
||||
* eventName: entry.name,
|
||||
* startTime: entry.startTime,
|
||||
* endTime: entry.startTime + entry.duration,
|
||||
* processingStart: entry.processingStart,
|
||||
* processingEnd: entry.processingEnd,
|
||||
* interactionId: entry.interactionId,
|
||||
* });
|
||||
* });
|
||||
* });
|
||||
* observer.observe({ type: "event" });
|
||||
*/
|
||||
export default class PerformanceObserver {
|
||||
_callback: PerformanceObserverCallback;
|
||||
_entryTypes: $ReadOnlySet<PerformanceEntryType>;
|
||||
|
||||
constructor(callback: PerformanceObserverCallback) {
|
||||
this._callback = callback;
|
||||
}
|
||||
|
||||
observe(options: PerformanceObserverInit) {
|
||||
if (!NativePerformanceObserver) {
|
||||
warnNoNativePerformanceObserver();
|
||||
return;
|
||||
}
|
||||
if (!_onPerformanceEntryCallbackIsSet) {
|
||||
NativePerformanceObserver.setOnPerformanceEntryCallback(
|
||||
onPerformanceEntry,
|
||||
);
|
||||
_onPerformanceEntryCallbackIsSet = true;
|
||||
}
|
||||
if (options.entryTypes) {
|
||||
this._entryTypes = new Set(options.entryTypes);
|
||||
} else {
|
||||
this._entryTypes = new Set([options.type]);
|
||||
}
|
||||
this._entryTypes.forEach(type => {
|
||||
if (!_observedEntryTypeRefCount.has(type)) {
|
||||
NativePerformanceObserver.startReporting(type);
|
||||
}
|
||||
_observedEntryTypeRefCount.set(
|
||||
type,
|
||||
(_observedEntryTypeRefCount.get(type) ?? 0) + 1,
|
||||
);
|
||||
});
|
||||
_observers.add(this);
|
||||
}
|
||||
|
||||
disconnect(): void {
|
||||
if (!NativePerformanceObserver) {
|
||||
warnNoNativePerformanceObserver();
|
||||
return;
|
||||
}
|
||||
this._entryTypes.forEach(type => {
|
||||
const entryTypeRefCount = _observedEntryTypeRefCount.get(type) ?? 0;
|
||||
if (entryTypeRefCount === 1) {
|
||||
_observedEntryTypeRefCount.delete(type);
|
||||
NativePerformanceObserver.stopReporting(type);
|
||||
} else if (entryTypeRefCount !== 0) {
|
||||
_observedEntryTypeRefCount.set(type, entryTypeRefCount - 1);
|
||||
}
|
||||
});
|
||||
_observers.delete(this);
|
||||
if (_observers.size === 0) {
|
||||
NativePerformanceObserver.setOnPerformanceEntryCallback(undefined);
|
||||
_onPerformanceEntryCallbackIsSet = false;
|
||||
}
|
||||
}
|
||||
|
||||
static supportedEntryTypes: $ReadOnlyArray<PerformanceEntryType> =
|
||||
// TODO: add types once they are fully supported
|
||||
Object.freeze([]);
|
||||
}
|
||||
|
||||
// This is a callback that gets scheduled and periodically called from the native side
|
||||
function onPerformanceEntry() {
|
||||
if (!NativePerformanceObserver) {
|
||||
return;
|
||||
}
|
||||
const rawEntries = NativePerformanceObserver.getPendingEntries();
|
||||
const entries = rawEntries.map(rawToPerformanceEntry);
|
||||
_observers.forEach(observer => {
|
||||
const entriesForObserver: PerformanceEntryList = entries.filter(entry =>
|
||||
observer._entryTypes.has(entry.entryType),
|
||||
);
|
||||
observer._callback(
|
||||
new PerformanceObserverEntryList(entriesForObserver),
|
||||
observer,
|
||||
);
|
||||
});
|
||||
}
|
||||
@@ -21,10 +21,10 @@ NSDictionary* RCTGetReactNativeVersion(void)
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^(void){
|
||||
__rnVersion = @{
|
||||
RCTVersionMajor: @(1000),
|
||||
RCTVersionMinor: @(0),
|
||||
RCTVersionMajor: @(0),
|
||||
RCTVersionMinor: @(71),
|
||||
RCTVersionPatch: @(0),
|
||||
RCTVersionPrerelease: [NSNull null],
|
||||
RCTVersionPrerelease: @"rc.2",
|
||||
};
|
||||
});
|
||||
return __rnVersion;
|
||||
|
||||
@@ -36,7 +36,6 @@ Class RCTCoreModulesClassProvider(const char *name) {
|
||||
{"PerfMonitor", RCTPerfMonitorCls},
|
||||
{"DevMenu", RCTDevMenuCls},
|
||||
{"DevSettings", RCTDevSettingsCls},
|
||||
{"BlobModule", RCTBlobManagerCls},
|
||||
{"RedBox", RCTRedBoxCls},
|
||||
{"LogBox", RCTLogBoxCls},
|
||||
{"WebSocketExecutor", RCTWebSocketExecutorCls},
|
||||
@@ -44,6 +43,7 @@ Class RCTCoreModulesClassProvider(const char *name) {
|
||||
{"DevLoadingView", RCTDevLoadingViewCls},
|
||||
{"DevSplitBundleLoader", RCTDevSplitBundleLoaderCls},
|
||||
{"EventDispatcher", RCTEventDispatcherCls},
|
||||
{"BlobModule", RCTBlobManagerCls},
|
||||
};
|
||||
|
||||
auto p = sCoreModuleClassMap->find(name);
|
||||
|
||||
@@ -363,8 +363,8 @@ task installArchives {
|
||||
}
|
||||
|
||||
android {
|
||||
buildToolsVersion = "31.0.0"
|
||||
compileSdkVersion 31
|
||||
buildToolsVersion = "33.0.0"
|
||||
compileSdkVersion 33
|
||||
|
||||
// Used to override the NDK path/version on internal CI or by allowing
|
||||
// users to customize the NDK path/version from their root project (e.g. for M1 support)
|
||||
@@ -377,7 +377,7 @@ android {
|
||||
|
||||
defaultConfig {
|
||||
minSdkVersion(21)
|
||||
targetSdkVersion(31)
|
||||
targetSdkVersion(33)
|
||||
versionCode(1)
|
||||
versionName("1.0")
|
||||
|
||||
@@ -616,11 +616,13 @@ apply plugin: "org.jetbrains.kotlin.android"
|
||||
apply from: "./publish.gradle"
|
||||
|
||||
// We need to override the artifact ID as this project is called `ReactAndroid` but
|
||||
// the maven coordinates are on `react-native`.
|
||||
// the maven coordinates are on `react-android`.
|
||||
// Please note that the original coordinates, `react-native`, have been voided
|
||||
// as they caused https://github.com/facebook/react-native/issues/35210
|
||||
publishing {
|
||||
publications {
|
||||
getByName("release") {
|
||||
artifactId 'react-native'
|
||||
artifactId 'react-android'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -106,7 +106,7 @@ if(EXISTS ${PROJECT_BUILD_DIR}/generated/rncli/src/main/jni/Android-rncli.cmake)
|
||||
include(${PROJECT_BUILD_DIR}/generated/rncli/src/main/jni/Android-rncli.cmake)
|
||||
target_link_libraries(${CMAKE_PROJECT_NAME} ${AUTOLINKED_LIBRARIES})
|
||||
foreach(autolinked_library ${AUTOLINKED_LIBRARIES})
|
||||
target_link_libraries(autolinked_library common_flags)
|
||||
target_link_libraries(${autolinked_library} common_flags)
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
|
||||
@@ -48,7 +48,14 @@ void registerComponents(
|
||||
rncli_registerProviders(registry);
|
||||
}
|
||||
|
||||
std::shared_ptr<TurboModule> provideModules(
|
||||
std::shared_ptr<TurboModule> cxxModuleProvider(
|
||||
const std::string &name,
|
||||
const std::shared_ptr<CallInvoker> &jsInvoker) {
|
||||
// Not implemented yet: provide pure-C++ NativeModules here.
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::shared_ptr<TurboModule> javaModuleProvider(
|
||||
const std::string &name,
|
||||
const JavaTurboModule::InitParams ¶ms) {
|
||||
// Here you can provide your own module provider for TurboModules coming from
|
||||
@@ -70,8 +77,10 @@ std::shared_ptr<TurboModule> provideModules(
|
||||
|
||||
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *) {
|
||||
return facebook::jni::initialize(vm, [] {
|
||||
facebook::react::DefaultTurboModuleManagerDelegate::
|
||||
moduleProvidersFromEntryPoint = &facebook::react::provideModules;
|
||||
facebook::react::DefaultTurboModuleManagerDelegate::cxxModuleProvider =
|
||||
&facebook::react::cxxModuleProvider;
|
||||
facebook::react::DefaultTurboModuleManagerDelegate::javaModuleProvider =
|
||||
&facebook::react::javaModuleProvider;
|
||||
facebook::react::DefaultComponentsRegistry::
|
||||
registerComponentDescriptorsFromEntryPoint =
|
||||
&facebook::react::registerComponents;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
VERSION_NAME=1000.0.0
|
||||
VERSION_NAME=0.71.0-rc.2
|
||||
GROUP=com.facebook.react
|
||||
|
||||
# JVM Versions
|
||||
|
||||
@@ -234,4 +234,17 @@ afterEvaluate {
|
||||
prepareHeadersForPrefab.dependsOn(buildHermes)
|
||||
}
|
||||
|
||||
/* Publishing Configuration */
|
||||
apply from: "../publish.gradle"
|
||||
|
||||
// We need to override the artifact ID as this project is called `hermes-engine` but
|
||||
// the maven coordinates are on `hermes-android`.
|
||||
// Please note that the original coordinates, `hermes-engine`, have been voided
|
||||
// as they caused https://github.com/facebook/react-native/issues/35210
|
||||
publishing {
|
||||
publications {
|
||||
getByName("release") {
|
||||
artifactId 'hermes-android'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+3
-3
@@ -15,8 +15,8 @@ import java.util.Map;
|
||||
|
||||
public class ReactNativeVersion {
|
||||
public static final Map<String, Object> VERSION = MapBuilder.<String, Object>of(
|
||||
"major", 1000,
|
||||
"minor", 0,
|
||||
"major", 0,
|
||||
"minor", 71,
|
||||
"patch", 0,
|
||||
"prerelease", null);
|
||||
"prerelease", "rc.2");
|
||||
}
|
||||
|
||||
@@ -120,7 +120,9 @@ public class ReactModalHostView extends ViewGroup
|
||||
|
||||
@Override
|
||||
public int getChildCount() {
|
||||
return mHostView.getChildCount();
|
||||
// This method may be called by the parent constructor
|
||||
// before mHostView is initialized.
|
||||
return mHostView == null ? 0 : mHostView.getChildCount();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+15
-6
@@ -12,10 +12,15 @@
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
std::function<std::shared_ptr<TurboModule>(
|
||||
const std::string &,
|
||||
const std::shared_ptr<CallInvoker> &)>
|
||||
DefaultTurboModuleManagerDelegate::cxxModuleProvider{nullptr};
|
||||
|
||||
std::function<std::shared_ptr<TurboModule>(
|
||||
const std::string &,
|
||||
const JavaTurboModule::InitParams &)>
|
||||
DefaultTurboModuleManagerDelegate::moduleProvidersFromEntryPoint{nullptr};
|
||||
DefaultTurboModuleManagerDelegate::javaModuleProvider{nullptr};
|
||||
|
||||
jni::local_ref<DefaultTurboModuleManagerDelegate::jhybriddata>
|
||||
DefaultTurboModuleManagerDelegate::initHybrid(jni::alias_ref<jhybridobject>) {
|
||||
@@ -32,17 +37,21 @@ void DefaultTurboModuleManagerDelegate::registerNatives() {
|
||||
std::shared_ptr<TurboModule> DefaultTurboModuleManagerDelegate::getTurboModule(
|
||||
const std::string &name,
|
||||
const std::shared_ptr<CallInvoker> &jsInvoker) {
|
||||
// Not implemented yet: provide pure-C++ NativeModules here.
|
||||
auto moduleProvider = DefaultTurboModuleManagerDelegate::cxxModuleProvider;
|
||||
if (moduleProvider) {
|
||||
return moduleProvider(name, jsInvoker);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::shared_ptr<TurboModule> DefaultTurboModuleManagerDelegate::getTurboModule(
|
||||
const std::string &name,
|
||||
const JavaTurboModule::InitParams ¶ms) {
|
||||
auto resolvedModule = (DefaultTurboModuleManagerDelegate::
|
||||
moduleProvidersFromEntryPoint)(name, params);
|
||||
if (resolvedModule != nullptr) {
|
||||
return resolvedModule;
|
||||
auto moduleProvider = DefaultTurboModuleManagerDelegate::javaModuleProvider;
|
||||
if (moduleProvider) {
|
||||
if (auto resolvedModule = moduleProvider(name, params)) {
|
||||
return resolvedModule;
|
||||
}
|
||||
}
|
||||
return rncore_ModuleProvider(name, params);
|
||||
}
|
||||
|
||||
@@ -27,10 +27,15 @@ class DefaultTurboModuleManagerDelegate : public jni::HybridClass<
|
||||
|
||||
static void registerNatives();
|
||||
|
||||
static std::function<std::shared_ptr<TurboModule>(
|
||||
const std::string &,
|
||||
const std::shared_ptr<CallInvoker> &)>
|
||||
cxxModuleProvider;
|
||||
|
||||
static std::function<std::shared_ptr<TurboModule>(
|
||||
const std::string &,
|
||||
const JavaTurboModule::InitParams &)>
|
||||
moduleProvidersFromEntryPoint;
|
||||
javaModuleProvider;
|
||||
|
||||
std::shared_ptr<TurboModule> getTurboModule(
|
||||
const std::string &name,
|
||||
|
||||
@@ -1,43 +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.
|
||||
|
||||
require "json"
|
||||
|
||||
package = JSON.parse(File.read(File.join(__dir__, "..", "package.json")))
|
||||
version = package['version']
|
||||
|
||||
source = { :git => 'https://github.com/facebook/react-native.git' }
|
||||
if version == '1000.0.0'
|
||||
# This is an unpublished version, use the latest commit hash of the react-native repo, which we’re presumably in.
|
||||
source[:commit] = `git rev-parse HEAD`.strip if system("git rev-parse --git-dir > /dev/null 2>&1")
|
||||
else
|
||||
source[:tag] = "v#{version}"
|
||||
end
|
||||
|
||||
folly_compiler_flags = '-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1 -Wno-comma -Wno-shorten-64-to-32 -Wno-gnu-zero-variadic-macro-arguments'
|
||||
folly_version = '2021.07.22.00'
|
||||
|
||||
Pod::Spec.new do |s|
|
||||
s.name = "React-bridging"
|
||||
s.version = version
|
||||
s.summary = "-" # TODO
|
||||
s.homepage = "https://reactnative.dev/"
|
||||
s.license = package["license"]
|
||||
s.author = "Facebook, Inc. and its affiliates"
|
||||
s.platforms = { :ios => "12.4" }
|
||||
s.source = source
|
||||
s.source_files = "react/bridging/**/*.{cpp,h}"
|
||||
s.exclude_files = "react/bridging/tests"
|
||||
s.header_dir = "react/bridging"
|
||||
s.header_mappings_dir = "."
|
||||
s.compiler_flags = folly_compiler_flags
|
||||
s.pod_target_xcconfig = { "HEADER_SEARCH_PATHS" => "\"$(PODS_ROOT)/RCT-Folly\"",
|
||||
"USE_HEADERMAP" => "YES",
|
||||
"CLANG_CXX_LANGUAGE_STANDARD" => "c++17",
|
||||
"GCC_WARN_PEDANTIC" => "YES" }
|
||||
|
||||
s.dependency "RCT-Folly", folly_version
|
||||
s.dependency "React-jsi", version
|
||||
end
|
||||
@@ -32,7 +32,7 @@ Pod::Spec.new do |s|
|
||||
s.source = source
|
||||
s.header_dir = "ReactCommon" # Use global header_dir for all subspecs for use_frameworks! compatibility
|
||||
s.compiler_flags = folly_compiler_flags + ' ' + boost_compiler_flags
|
||||
s.pod_target_xcconfig = { "HEADER_SEARCH_PATHS" => "\"$(PODS_ROOT)/boost\" \"$(PODS_ROOT)/RCT-Folly\" \"$(PODS_ROOT)/DoubleConversion\" \"$(PODS_ROOT)/Headers/Private/React-Core\" \"$(PODS_ROOT)/Headers/Private/React-bridging/react/bridging\" \"$(PODS_CONFIGURATION_BUILD_DIR)/React-bridging/react_bridging.framework/Headers\"",
|
||||
s.pod_target_xcconfig = { "HEADER_SEARCH_PATHS" => "\"$(PODS_ROOT)/boost\" \"$(PODS_ROOT)/RCT-Folly\" \"$(PODS_ROOT)/DoubleConversion\" \"$(PODS_ROOT)/Headers/Private/React-Core\"",
|
||||
"USE_HEADERMAP" => "YES",
|
||||
"CLANG_CXX_LANGUAGE_STANDARD" => "c++17",
|
||||
"GCC_WARN_PEDANTIC" => "YES" }
|
||||
@@ -40,7 +40,6 @@ Pod::Spec.new do |s|
|
||||
# TODO (T48588859): Restructure this target to align with dir structure: "react/nativemodule/..."
|
||||
# Note: Update this only when ready to minimize breaking changes.
|
||||
s.subspec "turbomodule" do |ss|
|
||||
ss.dependency "React-bridging", version
|
||||
ss.dependency "React-callinvoker", version
|
||||
ss.dependency "React-perflogger", version
|
||||
ss.dependency "React-Core", version
|
||||
@@ -51,6 +50,14 @@ Pod::Spec.new do |s|
|
||||
ss.dependency "DoubleConversion"
|
||||
ss.dependency "glog"
|
||||
|
||||
ss.subspec "bridging" do |sss|
|
||||
sss.dependency "React-jsi", version
|
||||
sss.source_files = "react/bridging/**/*.{cpp,h}"
|
||||
sss.exclude_files = "react/bridging/tests"
|
||||
sss.header_dir = "react/bridging"
|
||||
sss.pod_target_xcconfig = { "HEADER_SEARCH_PATHS" => "\"$(PODS_TARGET_SRCROOT)/ReactCommon\" \"$(PODS_ROOT)/RCT-Folly\"" }
|
||||
end
|
||||
|
||||
ss.subspec "core" do |sss|
|
||||
sss.source_files = "react/nativemodule/core/ReactCommon/**/*.{cpp,h}",
|
||||
"react/nativemodule/core/platform/ios/**/*.{mm,cpp,h}"
|
||||
|
||||
@@ -15,10 +15,10 @@
|
||||
namespace facebook::react {
|
||||
|
||||
constexpr struct {
|
||||
int32_t Major = 1000;
|
||||
int32_t Minor = 0;
|
||||
int32_t Major = 0;
|
||||
int32_t Minor = 71;
|
||||
int32_t Patch = 0;
|
||||
std::string_view Prerelease = "";
|
||||
std::string_view Prerelease = "rc.2";
|
||||
} ReactNativeVersion;
|
||||
|
||||
} // namespace facebook::react
|
||||
|
||||
@@ -46,6 +46,9 @@ void TextAttributes::apply(TextAttributes textAttributes) {
|
||||
allowFontScaling = textAttributes.allowFontScaling.has_value()
|
||||
? textAttributes.allowFontScaling
|
||||
: allowFontScaling;
|
||||
dynamicTypeRamp = textAttributes.dynamicTypeRamp.has_value()
|
||||
? textAttributes.dynamicTypeRamp
|
||||
: dynamicTypeRamp;
|
||||
letterSpacing = !std::isnan(textAttributes.letterSpacing)
|
||||
? textAttributes.letterSpacing
|
||||
: letterSpacing;
|
||||
@@ -111,6 +114,7 @@ bool TextAttributes::operator==(const TextAttributes &rhs) const {
|
||||
fontStyle,
|
||||
fontVariant,
|
||||
allowFontScaling,
|
||||
dynamicTypeRamp,
|
||||
alignment,
|
||||
baseWritingDirection,
|
||||
lineBreakStrategy,
|
||||
@@ -131,6 +135,7 @@ bool TextAttributes::operator==(const TextAttributes &rhs) const {
|
||||
rhs.fontStyle,
|
||||
rhs.fontVariant,
|
||||
rhs.allowFontScaling,
|
||||
rhs.dynamicTypeRamp,
|
||||
rhs.alignment,
|
||||
rhs.baseWritingDirection,
|
||||
rhs.lineBreakStrategy,
|
||||
@@ -186,6 +191,7 @@ SharedDebugStringConvertibleList TextAttributes::getDebugProps() const {
|
||||
debugStringConvertibleItem("fontStyle", fontStyle),
|
||||
debugStringConvertibleItem("fontVariant", fontVariant),
|
||||
debugStringConvertibleItem("allowFontScaling", allowFontScaling),
|
||||
debugStringConvertibleItem("dynamicTypeRamp", dynamicTypeRamp),
|
||||
debugStringConvertibleItem("letterSpacing", letterSpacing),
|
||||
|
||||
// Paragraph Styles
|
||||
|
||||
@@ -50,6 +50,7 @@ class TextAttributes : public DebugStringConvertible {
|
||||
std::optional<FontStyle> fontStyle{};
|
||||
std::optional<FontVariant> fontVariant{};
|
||||
std::optional<bool> allowFontScaling{};
|
||||
std::optional<DynamicTypeRamp> dynamicTypeRamp{};
|
||||
Float letterSpacing{std::numeric_limits<Float>::quiet_NaN()};
|
||||
std::optional<TextTransform> textTransform{};
|
||||
|
||||
|
||||
@@ -34,6 +34,84 @@
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
inline std::string toString(const DynamicTypeRamp &dynamicTypeRamp) {
|
||||
switch (dynamicTypeRamp) {
|
||||
case DynamicTypeRamp::Caption2:
|
||||
return "caption2";
|
||||
case DynamicTypeRamp::Caption1:
|
||||
return "caption1";
|
||||
case DynamicTypeRamp::Footnote:
|
||||
return "footnote";
|
||||
case DynamicTypeRamp::Subheadline:
|
||||
return "subheadline";
|
||||
case DynamicTypeRamp::Callout:
|
||||
return "callout";
|
||||
case DynamicTypeRamp::Body:
|
||||
return "body";
|
||||
case DynamicTypeRamp::Headline:
|
||||
return "headline";
|
||||
case DynamicTypeRamp::Title3:
|
||||
return "title3";
|
||||
case DynamicTypeRamp::Title2:
|
||||
return "title2";
|
||||
case DynamicTypeRamp::Title1:
|
||||
return "title1";
|
||||
case DynamicTypeRamp::LargeTitle:
|
||||
return "largeTitle";
|
||||
}
|
||||
|
||||
LOG(ERROR) << "Unsupported DynamicTypeRamp value";
|
||||
react_native_assert(false);
|
||||
|
||||
// Sane default in case of parsing errors
|
||||
return "body";
|
||||
}
|
||||
|
||||
inline void fromRawValue(
|
||||
const PropsParserContext &context,
|
||||
const RawValue &value,
|
||||
DynamicTypeRamp &result) {
|
||||
react_native_assert(value.hasType<std::string>());
|
||||
if (value.hasType<std::string>()) {
|
||||
auto string = (std::string)value;
|
||||
if (string == "caption2") {
|
||||
result = DynamicTypeRamp::Caption2;
|
||||
} else if (string == "caption1") {
|
||||
result = DynamicTypeRamp::Caption1;
|
||||
} else if (string == "footnote") {
|
||||
result = DynamicTypeRamp::Footnote;
|
||||
} else if (string == "subheadline") {
|
||||
result = DynamicTypeRamp::Subheadline;
|
||||
} else if (string == "callout") {
|
||||
result = DynamicTypeRamp::Callout;
|
||||
} else if (string == "body") {
|
||||
result = DynamicTypeRamp::Body;
|
||||
} else if (string == "headline") {
|
||||
result = DynamicTypeRamp::Headline;
|
||||
} else if (string == "title3") {
|
||||
result = DynamicTypeRamp::Title3;
|
||||
} else if (string == "title2") {
|
||||
result = DynamicTypeRamp::Title2;
|
||||
} else if (string == "title1") {
|
||||
result = DynamicTypeRamp::Title1;
|
||||
} else if (string == "largeTitle") {
|
||||
result = DynamicTypeRamp::LargeTitle;
|
||||
} else {
|
||||
// sane default
|
||||
LOG(ERROR) << "Unsupported DynamicTypeRamp value: " << string;
|
||||
react_native_assert(false);
|
||||
result = DynamicTypeRamp::Body;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
LOG(ERROR) << "Unsupported DynamicTypeRamp type";
|
||||
react_native_assert(false);
|
||||
|
||||
// Sane default in case of parsing errors
|
||||
result = DynamicTypeRamp::Body;
|
||||
}
|
||||
|
||||
inline std::string toString(const EllipsizeMode &ellipsisMode) {
|
||||
switch (ellipsisMode) {
|
||||
case EllipsizeMode::Clip:
|
||||
|
||||
@@ -46,6 +46,20 @@ enum class FontVariant : int {
|
||||
ProportionalNums = 1 << 5
|
||||
};
|
||||
|
||||
enum class DynamicTypeRamp {
|
||||
Caption2,
|
||||
Caption1,
|
||||
Footnote,
|
||||
Subheadline,
|
||||
Callout,
|
||||
Body,
|
||||
Headline,
|
||||
Title3,
|
||||
Title2,
|
||||
Title1,
|
||||
LargeTitle
|
||||
};
|
||||
|
||||
enum class EllipsizeMode {
|
||||
Clip, // Do not add ellipsize, simply clip.
|
||||
Head, // Truncate at head of line: "...wxyz".
|
||||
@@ -190,6 +204,13 @@ struct hash<facebook::react::FontWeight> {
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct hash<facebook::react::DynamicTypeRamp> {
|
||||
size_t operator()(const facebook::react::DynamicTypeRamp &v) const {
|
||||
return hash<int>()(static_cast<int>(v));
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct hash<facebook::react::EllipsizeMode> {
|
||||
size_t operator()(const facebook::react::EllipsizeMode &v) const {
|
||||
|
||||
@@ -73,6 +73,12 @@ static TextAttributes convertRawProp(
|
||||
"allowFontScaling",
|
||||
sourceTextAttributes.allowFontScaling,
|
||||
defaultTextAttributes.allowFontScaling);
|
||||
textAttributes.dynamicTypeRamp = convertRawProp(
|
||||
context,
|
||||
rawProps,
|
||||
"dynamicTypeRamp",
|
||||
sourceTextAttributes.dynamicTypeRamp,
|
||||
defaultTextAttributes.dynamicTypeRamp);
|
||||
textAttributes.letterSpacing = convertRawProp(
|
||||
context,
|
||||
rawProps,
|
||||
|
||||
@@ -94,6 +94,7 @@ inline bool areTextAttributesEquivalentLayoutWise(
|
||||
lhs.fontStyle,
|
||||
lhs.fontVariant,
|
||||
lhs.allowFontScaling,
|
||||
lhs.dynamicTypeRamp,
|
||||
lhs.alignment) ==
|
||||
std::tie(
|
||||
rhs.fontFamily,
|
||||
@@ -101,6 +102,7 @@ inline bool areTextAttributesEquivalentLayoutWise(
|
||||
rhs.fontStyle,
|
||||
rhs.fontVariant,
|
||||
rhs.allowFontScaling,
|
||||
rhs.dynamicTypeRamp,
|
||||
rhs.alignment) &&
|
||||
floatEquality(lhs.fontSize, rhs.fontSize) &&
|
||||
floatEquality(lhs.fontSizeMultiplier, rhs.fontSizeMultiplier) &&
|
||||
@@ -121,6 +123,7 @@ inline size_t textAttributesHashLayoutWise(
|
||||
textAttributes.fontStyle,
|
||||
textAttributes.fontVariant,
|
||||
textAttributes.allowFontScaling,
|
||||
textAttributes.dynamicTypeRamp,
|
||||
textAttributes.letterSpacing,
|
||||
textAttributes.lineHeight,
|
||||
textAttributes.alignment);
|
||||
|
||||
+78
-9
@@ -55,6 +55,83 @@ inline static UIFontWeight RCTUIFontWeightFromInteger(NSInteger fontWeight)
|
||||
return weights[(fontWeight + 50) / 100 - 1];
|
||||
}
|
||||
|
||||
inline static UIFontTextStyle RCTUIFontTextStyleForDynamicTypeRamp(const DynamicTypeRamp &dynamicTypeRamp)
|
||||
{
|
||||
switch (dynamicTypeRamp) {
|
||||
case DynamicTypeRamp::Caption2:
|
||||
return UIFontTextStyleCaption2;
|
||||
case DynamicTypeRamp::Caption1:
|
||||
return UIFontTextStyleCaption1;
|
||||
case DynamicTypeRamp::Footnote:
|
||||
return UIFontTextStyleFootnote;
|
||||
case DynamicTypeRamp::Subheadline:
|
||||
return UIFontTextStyleSubheadline;
|
||||
case DynamicTypeRamp::Callout:
|
||||
return UIFontTextStyleCallout;
|
||||
case DynamicTypeRamp::Body:
|
||||
return UIFontTextStyleBody;
|
||||
case DynamicTypeRamp::Headline:
|
||||
return UIFontTextStyleHeadline;
|
||||
case DynamicTypeRamp::Title3:
|
||||
return UIFontTextStyleTitle3;
|
||||
case DynamicTypeRamp::Title2:
|
||||
return UIFontTextStyleTitle2;
|
||||
case DynamicTypeRamp::Title1:
|
||||
return UIFontTextStyleTitle1;
|
||||
case DynamicTypeRamp::LargeTitle:
|
||||
return UIFontTextStyleLargeTitle;
|
||||
}
|
||||
}
|
||||
|
||||
inline static CGFloat RCTBaseSizeForDynamicTypeRamp(const DynamicTypeRamp &dynamicTypeRamp)
|
||||
{
|
||||
// Values taken from
|
||||
// https://developer.apple.com/design/human-interface-guidelines/foundations/typography/#specifications
|
||||
switch (dynamicTypeRamp) {
|
||||
case DynamicTypeRamp::Caption2:
|
||||
return 11.0;
|
||||
case DynamicTypeRamp::Caption1:
|
||||
return 12.0;
|
||||
case facebook::react::DynamicTypeRamp::Footnote:
|
||||
return 13.0;
|
||||
case facebook::react::DynamicTypeRamp::Subheadline:
|
||||
return 15.0;
|
||||
case facebook::react::DynamicTypeRamp::Callout:
|
||||
return 16.0;
|
||||
case facebook::react::DynamicTypeRamp::Body:
|
||||
return 17.0;
|
||||
case facebook::react::DynamicTypeRamp::Headline:
|
||||
return 17.0;
|
||||
case facebook::react::DynamicTypeRamp::Title3:
|
||||
return 20.0;
|
||||
case facebook::react::DynamicTypeRamp::Title2:
|
||||
return 22.0;
|
||||
case facebook::react::DynamicTypeRamp::Title1:
|
||||
return 28.0;
|
||||
case facebook::react::DynamicTypeRamp::LargeTitle:
|
||||
return 34.0;
|
||||
}
|
||||
}
|
||||
|
||||
inline static CGFloat RCTEffectiveFontSizeMultiplierFromTextAttributes(const TextAttributes &textAttributes)
|
||||
{
|
||||
if (textAttributes.allowFontScaling.value_or(true)) {
|
||||
if (textAttributes.dynamicTypeRamp.has_value()) {
|
||||
DynamicTypeRamp dynamicTypeRamp = textAttributes.dynamicTypeRamp.value();
|
||||
UIFontMetrics *fontMetrics =
|
||||
[UIFontMetrics metricsForTextStyle:RCTUIFontTextStyleForDynamicTypeRamp(dynamicTypeRamp)];
|
||||
// Using a specific font size reduces rounding errors from -scaledValueForValue:
|
||||
CGFloat requestedSize =
|
||||
isnan(textAttributes.fontSize) ? RCTBaseSizeForDynamicTypeRamp(dynamicTypeRamp) : textAttributes.fontSize;
|
||||
return [fontMetrics scaledValueForValue:requestedSize] / requestedSize;
|
||||
} else {
|
||||
return textAttributes.fontSizeMultiplier;
|
||||
}
|
||||
} else {
|
||||
return 1.0;
|
||||
}
|
||||
}
|
||||
|
||||
inline static UIFont *RCTEffectiveFontFromTextAttributes(const TextAttributes &textAttributes)
|
||||
{
|
||||
NSString *fontFamily = [NSString stringWithCString:textAttributes.fontFamily.c_str() encoding:NSUTF8StringEncoding];
|
||||
@@ -71,19 +148,11 @@ inline static UIFont *RCTEffectiveFontFromTextAttributes(const TextAttributes &t
|
||||
fontProperties.weight = textAttributes.fontWeight.has_value()
|
||||
? RCTUIFontWeightFromInteger((NSInteger)textAttributes.fontWeight.value())
|
||||
: NAN;
|
||||
fontProperties.sizeMultiplier =
|
||||
textAttributes.allowFontScaling.value_or(true) ? textAttributes.fontSizeMultiplier : 1;
|
||||
fontProperties.sizeMultiplier = RCTEffectiveFontSizeMultiplierFromTextAttributes(textAttributes);
|
||||
|
||||
return RCTFontWithFontProperties(fontProperties);
|
||||
}
|
||||
|
||||
inline static CGFloat RCTEffectiveFontSizeMultiplierFromTextAttributes(const TextAttributes &textAttributes)
|
||||
{
|
||||
return textAttributes.allowFontScaling.value_or(true) && !isnan(textAttributes.fontSizeMultiplier)
|
||||
? textAttributes.fontSizeMultiplier
|
||||
: 1.0;
|
||||
}
|
||||
|
||||
inline static UIColor *RCTEffectiveForegroundColorFromTextAttributes(const TextAttributes &textAttributes)
|
||||
{
|
||||
UIColor *effectiveForegroundColor = RCTUIColorFromSharedColor(textAttributes.foregroundColor) ?: [UIColor blackColor];
|
||||
|
||||
@@ -2079,7 +2079,7 @@ static float YGDistributeFreeSpaceSecondPass(
|
||||
const float availableInnerCrossDim,
|
||||
const float availableInnerWidth,
|
||||
const float availableInnerHeight,
|
||||
const bool flexBasisOverflows,
|
||||
const bool mainAxisOverflows,
|
||||
const YGMeasureMode measureModeCrossDim,
|
||||
const bool performLayout,
|
||||
const YGConfigRef config,
|
||||
@@ -2175,7 +2175,7 @@ static float YGDistributeFreeSpaceSecondPass(
|
||||
!YGNodeIsStyleDimDefined(
|
||||
currentRelativeChild, crossAxis, availableInnerCrossDim) &&
|
||||
measureModeCrossDim == YGMeasureModeExactly &&
|
||||
!(isNodeFlexWrap && flexBasisOverflows) &&
|
||||
!(isNodeFlexWrap && mainAxisOverflows) &&
|
||||
YGNodeAlignItem(node, currentRelativeChild) == YGAlignStretch &&
|
||||
currentRelativeChild->marginLeadingValue(crossAxis).unit !=
|
||||
YGUnitAuto &&
|
||||
@@ -2383,7 +2383,7 @@ static void YGResolveFlexibleLength(
|
||||
const float availableInnerCrossDim,
|
||||
const float availableInnerWidth,
|
||||
const float availableInnerHeight,
|
||||
const bool flexBasisOverflows,
|
||||
const bool mainAxisOverflows,
|
||||
const YGMeasureMode measureModeCrossDim,
|
||||
const bool performLayout,
|
||||
const YGConfigRef config,
|
||||
@@ -2411,7 +2411,7 @@ static void YGResolveFlexibleLength(
|
||||
availableInnerCrossDim,
|
||||
availableInnerWidth,
|
||||
availableInnerHeight,
|
||||
flexBasisOverflows,
|
||||
mainAxisOverflows,
|
||||
measureModeCrossDim,
|
||||
performLayout,
|
||||
config,
|
||||
@@ -2884,7 +2884,9 @@ static void YGNodelayoutImpl(
|
||||
|
||||
// STEP 3: DETERMINE FLEX BASIS FOR EACH ITEM
|
||||
|
||||
float totalOuterFlexBasis = YGNodeComputeFlexBasisForChildren(
|
||||
// Computed basis + margins + gap
|
||||
float totalMainDim = 0;
|
||||
totalMainDim += YGNodeComputeFlexBasisForChildren(
|
||||
node,
|
||||
availableInnerWidth,
|
||||
availableInnerHeight,
|
||||
@@ -2899,10 +2901,17 @@ static void YGNodelayoutImpl(
|
||||
depth,
|
||||
generationCount);
|
||||
|
||||
const bool flexBasisOverflows = measureModeMainDim == YGMeasureModeUndefined
|
||||
? false
|
||||
: totalOuterFlexBasis > availableInnerMainDim;
|
||||
if (isNodeFlexWrap && flexBasisOverflows &&
|
||||
if (childCount > 1) {
|
||||
totalMainDim +=
|
||||
node->getGapForAxis(mainAxis, availableInnerCrossDim).unwrap() *
|
||||
(childCount - 1);
|
||||
}
|
||||
|
||||
const bool mainAxisOverflows =
|
||||
(measureModeMainDim != YGMeasureModeUndefined) &&
|
||||
totalMainDim > availableInnerMainDim;
|
||||
|
||||
if (isNodeFlexWrap && mainAxisOverflows &&
|
||||
measureModeMainDim == YGMeasureModeAtMost) {
|
||||
measureModeMainDim = YGMeasureModeExactly;
|
||||
}
|
||||
@@ -3025,7 +3034,7 @@ static void YGNodelayoutImpl(
|
||||
availableInnerCrossDim,
|
||||
availableInnerWidth,
|
||||
availableInnerHeight,
|
||||
flexBasisOverflows,
|
||||
mainAxisOverflows,
|
||||
measureModeCrossDim,
|
||||
performLayout,
|
||||
config,
|
||||
|
||||
@@ -59,7 +59,6 @@ import typeof Dimensions from './Libraries/Utilities/Dimensions';
|
||||
import typeof Easing from './Libraries/Animated/Easing';
|
||||
import typeof ReactNative from './Libraries/Renderer/shims/ReactNative';
|
||||
import typeof I18nManager from './Libraries/ReactNative/I18nManager';
|
||||
import typeof ImagePickerIOS from './Libraries/Image/ImagePickerIOS';
|
||||
import typeof InteractionManager from './Libraries/Interaction/InteractionManager';
|
||||
import typeof Keyboard from './Libraries/Components/Keyboard/Keyboard';
|
||||
import typeof LayoutAnimation from './Libraries/LayoutAnimation/LayoutAnimation';
|
||||
@@ -281,16 +280,6 @@ module.exports = {
|
||||
get I18nManager(): I18nManager {
|
||||
return require('./Libraries/ReactNative/I18nManager');
|
||||
},
|
||||
get ImagePickerIOS(): ImagePickerIOS {
|
||||
warnOnce(
|
||||
'imagePickerIOS-moved',
|
||||
'ImagePickerIOS has been extracted from react-native core and will be removed in a future release. ' +
|
||||
"Please upgrade to use either '@react-native-community/react-native-image-picker' or 'expo-image-picker'. " +
|
||||
"If you cannot upgrade to a different library, please install the deprecated '@react-native-community/image-picker-ios' package. " +
|
||||
'See https://github.com/rnc-archive/react-native-image-picker-ios',
|
||||
);
|
||||
return require('./Libraries/Image/ImagePickerIOS');
|
||||
},
|
||||
get InteractionManager(): InteractionManager {
|
||||
return require('./Libraries/Interaction/InteractionManager');
|
||||
},
|
||||
@@ -765,4 +754,20 @@ if (__DEV__) {
|
||||
);
|
||||
},
|
||||
});
|
||||
/* $FlowFixMe[prop-missing] This is intentional: Flow will error when
|
||||
* attempting to access ImagePickerIOS. */
|
||||
/* $FlowFixMe[invalid-export] This is intentional: Flow will error when
|
||||
* attempting to access ImagePickerIOS. */
|
||||
Object.defineProperty(module.exports, 'ImagePickerIOS', {
|
||||
configurable: true,
|
||||
get() {
|
||||
invariant(
|
||||
false,
|
||||
'ImagePickerIOS has been removed from React Native. ' +
|
||||
"Please upgrade to use either '@react-native-community/react-native-image-picker' or 'expo-image-picker'. " +
|
||||
"If you cannot upgrade to a different library, please install the deprecated '@react-native-community/image-picker-ios' package. " +
|
||||
'See https://github.com/rnc-archive/react-native-image-picker-ios',
|
||||
);
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
+53
-15
@@ -1,7 +1,6 @@
|
||||
{
|
||||
"name": "react-native",
|
||||
"private": true,
|
||||
"version": "1000.0.0",
|
||||
"version": "0.71.0-rc.2",
|
||||
"bin": "./cli.js",
|
||||
"description": "A framework for building native apps using React",
|
||||
"license": "MIT",
|
||||
@@ -86,7 +85,7 @@
|
||||
"prettier": "prettier --write \"./**/*.{js,md,yml,ts,tsx}\"",
|
||||
"format-check": "prettier --list-different \"./**/*.{js,md,yml,ts,tsx}\"",
|
||||
"update-lock": "npx yarn-deduplicate",
|
||||
"docker-setup-android": "docker pull reactnativecommunity/react-native-android:6.0",
|
||||
"docker-setup-android": "docker pull reactnativecommunity/react-native-android:6.1",
|
||||
"docker-build-android": "docker build -t reactnativeci/android -f .circleci/Dockerfiles/Dockerfile.android .",
|
||||
"test-android-run-instrumentation": "docker run --cap-add=SYS_ADMIN -it reactnativeci/android bash .circleci/Dockerfiles/scripts/run-android-docker-instrumentation-tests.sh",
|
||||
"test-android-run-unit": "docker run --cap-add=SYS_ADMIN -it reactnativeci/android bash .circleci/Dockerfiles/scripts/run-android-docker-unit-tests.sh",
|
||||
@@ -100,20 +99,16 @@
|
||||
"test-ios": "./scripts/objc-test.sh test",
|
||||
"test-typescript": "dtslint types"
|
||||
},
|
||||
"workspaces": [
|
||||
"packages/*",
|
||||
"repo-config"
|
||||
],
|
||||
"peerDependencies": {
|
||||
"react": "18.2.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@jest/create-cache-key-function": "^29.2.1",
|
||||
"@react-native-community/cli": "10.0.0-alpha.2",
|
||||
"@react-native-community/cli-platform-android": "10.0.0-alpha.2",
|
||||
"@react-native-community/cli-platform-ios": "10.0.0-alpha.1",
|
||||
"@react-native-community/cli": "10.0.0-alpha.5",
|
||||
"@react-native-community/cli-platform-android": "10.0.0-alpha.4",
|
||||
"@react-native-community/cli-platform-ios": "10.0.0-alpha.3",
|
||||
"@react-native/assets": "1.0.0",
|
||||
"@react-native/normalize-color": "2.0.0",
|
||||
"@react-native/normalize-color": "2.1.0",
|
||||
"@react-native/polyfills": "2.0.0",
|
||||
"abort-controller": "^3.0.0",
|
||||
"anser": "^1.4.9",
|
||||
@@ -132,7 +127,7 @@
|
||||
"pretty-format": "^26.5.2",
|
||||
"promise": "^8.3.0",
|
||||
"react-devtools-core": "^4.26.1",
|
||||
"react-native-gradle-plugin": "^0.71.8",
|
||||
"react-native-gradle-plugin": "^0.71.9",
|
||||
"react-refresh": "^0.4.0",
|
||||
"react-shallow-renderer": "^16.15.0",
|
||||
"regenerator-runtime": "^0.13.2",
|
||||
@@ -140,13 +135,56 @@
|
||||
"stacktrace-parser": "^0.1.3",
|
||||
"use-sync-external-store": "^1.0.0",
|
||||
"whatwg-fetch": "^3.0.0",
|
||||
"ws": "^6.2.2"
|
||||
"ws": "^6.2.2",
|
||||
"react-native-codegen": "^0.71.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"flow-bin": "^0.191.0",
|
||||
"hermes-eslint": "0.8.0",
|
||||
"react": "18.2.0",
|
||||
"react-test-renderer": "^18.2.0"
|
||||
"react-test-renderer": "18.2.0",
|
||||
"@babel/core": "^7.14.0",
|
||||
"@babel/eslint-parser": "^7.18.2",
|
||||
"@babel/generator": "^7.14.0",
|
||||
"@babel/plugin-transform-regenerator": "^7.0.0",
|
||||
"@definitelytyped/dtslint": "^0.0.127",
|
||||
"@react-native-community/eslint-config": "*",
|
||||
"@react-native-community/eslint-plugin": "*",
|
||||
"@react-native/eslint-plugin-specs": "^0.71.1",
|
||||
"@reactions/component": "^2.0.2",
|
||||
"@types/react": "^18.0.18",
|
||||
"@typescript-eslint/parser": "^5.30.5",
|
||||
"async": "^3.2.2",
|
||||
"clang-format": "^1.8.0",
|
||||
"connect": "^3.6.5",
|
||||
"coveralls": "^3.1.1",
|
||||
"eslint": "^8.19.0",
|
||||
"eslint-config-prettier": "^8.5.0",
|
||||
"eslint-plugin-babel": "^5.3.1",
|
||||
"eslint-plugin-eslint-comments": "^3.2.0",
|
||||
"eslint-plugin-ft-flow": "^2.0.1",
|
||||
"eslint-plugin-jest": "^26.5.3",
|
||||
"eslint-plugin-jsx-a11y": "^6.6.0",
|
||||
"eslint-plugin-lint": "^1.0.0",
|
||||
"eslint-plugin-prettier": "^4.2.1",
|
||||
"eslint-plugin-react": "^7.30.1",
|
||||
"eslint-plugin-react-hooks": "^4.6.0",
|
||||
"eslint-plugin-react-native": "^4.0.0",
|
||||
"eslint-plugin-relay": "^1.8.3",
|
||||
"inquirer": "^7.1.0",
|
||||
"jest": "^29.2.1",
|
||||
"jest-junit": "^10.0.0",
|
||||
"jscodeshift": "^0.13.1",
|
||||
"metro-babel-register": "0.73.3",
|
||||
"metro-memory-fs": "0.73.3",
|
||||
"mkdirp": "^0.5.1",
|
||||
"mock-fs": "^5.1.4",
|
||||
"prettier": "^2.4.1",
|
||||
"shelljs": "^0.8.5",
|
||||
"signedsource": "^1.0.0",
|
||||
"typescript": "4.1.3",
|
||||
"ws": "^6.2.2",
|
||||
"yargs": "^17.5.1"
|
||||
},
|
||||
"codegenConfig": {
|
||||
"libraries": [
|
||||
@@ -166,4 +204,4 @@
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"version": "0.71.0",
|
||||
"version": "0.71.1",
|
||||
"name": "@react-native/babel-plugin-codegen",
|
||||
"description": "Babel plugin to generate native module and view manager code for React Native.",
|
||||
"repository": {
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
load("@fbsource//tools/build_defs/third_party:yarn_defs.bzl", "yarn_workspace")
|
||||
|
||||
yarn_workspace(
|
||||
name = "yarn-workspace",
|
||||
srcs = glob(
|
||||
["**/*.js"],
|
||||
exclude = [
|
||||
"**/__fixtures__/**",
|
||||
"**/__flowtests__/**",
|
||||
"**/__mocks__/**",
|
||||
"**/__server_snapshot_tests__/**",
|
||||
"**/__tests__/**",
|
||||
"**/node_modules/**",
|
||||
"**/node_modules/.bin/**",
|
||||
"**/.*",
|
||||
"**/.*/**",
|
||||
"**/.*/.*",
|
||||
"**/*.xcodeproj/**",
|
||||
"**/*.xcworkspace/**",
|
||||
],
|
||||
),
|
||||
visibility = ["PUBLIC"],
|
||||
)
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@react-native-community/eslint-config",
|
||||
"version": "3.1.0",
|
||||
"version": "3.2.0",
|
||||
"description": "ESLint config for React Native",
|
||||
"main": "index.js",
|
||||
"license": "MIT",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@react-native-community/eslint-plugin",
|
||||
"version": "1.2.0",
|
||||
"version": "1.3.0",
|
||||
"description": "ESLint rules for @react-native-community/eslint-config",
|
||||
"main": "index.js",
|
||||
"repository": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@react-native/eslint-plugin-specs",
|
||||
"version": "0.71.0",
|
||||
"version": "0.71.1",
|
||||
"description": "ESLint rules to validate NativeModule and Component Specs",
|
||||
"main": "index.js",
|
||||
"repository": {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@react-native/hermes-inspector-msggen",
|
||||
"private": true,
|
||||
"version": "0.71.0",
|
||||
"version": "0.71.1",
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
"msggen": "./bin/index.js"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@react-native/normalize-color",
|
||||
"version": "2.0.0",
|
||||
"version": "2.1.0",
|
||||
"description": "Color normalization for React Native.",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "react-native-codegen",
|
||||
"version": "0.71.1",
|
||||
"version": "0.71.3",
|
||||
"description": "⚛️ Code generation tools for React Native",
|
||||
"homepage": "https://github.com/facebook/react-native/tree/HEAD/packages/react-native-codegen",
|
||||
"repository": {
|
||||
|
||||
@@ -118,9 +118,10 @@ function serializeArg(
|
||||
index: number,
|
||||
resolveAlias: AliasResolver,
|
||||
): string {
|
||||
const {typeAnnotation: nullableTypeAnnotation} = arg;
|
||||
const {typeAnnotation: nullableTypeAnnotation, optional} = arg;
|
||||
const [typeAnnotation, nullable] =
|
||||
unwrapNullable<NativeModuleParamTypeAnnotation>(nullableTypeAnnotation);
|
||||
const isRequired = !optional && !nullable;
|
||||
|
||||
let realTypeAnnotation = typeAnnotation;
|
||||
if (realTypeAnnotation.type === 'TypeAliasTypeAnnotation') {
|
||||
@@ -130,12 +131,15 @@ function serializeArg(
|
||||
function wrap(callback: (val: string) => string) {
|
||||
const val = `args[${index}]`;
|
||||
const expression = callback(val);
|
||||
|
||||
if (nullable) {
|
||||
return `${val}.isNull() || ${val}.isUndefined() ? std::nullopt : std::make_optional(${expression})`;
|
||||
if (isRequired) {
|
||||
return expression;
|
||||
} else {
|
||||
let condition = `${val}.isNull() || ${val}.isUndefined()`;
|
||||
if (optional) {
|
||||
condition = `count < ${index} || ${condition}`;
|
||||
}
|
||||
return `${condition} ? std::nullopt : std::make_optional(${expression})`;
|
||||
}
|
||||
|
||||
return expression;
|
||||
}
|
||||
|
||||
switch (realTypeAnnotation.type) {
|
||||
|
||||
@@ -16,6 +16,7 @@ import type {
|
||||
NativeModuleTypeAnnotation,
|
||||
NativeModuleFunctionTypeAnnotation,
|
||||
NativeModulePropertyShape,
|
||||
NativeModuleAliasMap,
|
||||
} from '../../CodegenSchema';
|
||||
|
||||
import type {AliasResolver} from './Utils';
|
||||
@@ -28,8 +29,13 @@ type FilesOutput = Map<string, string>;
|
||||
const ModuleClassDeclarationTemplate = ({
|
||||
hasteModuleName,
|
||||
moduleProperties,
|
||||
}: $ReadOnly<{hasteModuleName: string, moduleProperties: string[]}>) => {
|
||||
return `class JSI_EXPORT ${hasteModuleName}CxxSpecJSI : public TurboModule {
|
||||
structs,
|
||||
}: $ReadOnly<{
|
||||
hasteModuleName: string,
|
||||
moduleProperties: string[],
|
||||
structs: string,
|
||||
}>) => {
|
||||
return `${structs}class JSI_EXPORT ${hasteModuleName}CxxSpecJSI : public TurboModule {
|
||||
protected:
|
||||
${hasteModuleName}CxxSpecJSI(std::shared_ptr<CallInvoker> jsInvoker);
|
||||
|
||||
@@ -107,12 +113,14 @@ ${modules.join('\n\n')}
|
||||
|
||||
function translatePrimitiveJSTypeToCpp(
|
||||
nullableTypeAnnotation: Nullable<NativeModuleTypeAnnotation>,
|
||||
optional: boolean,
|
||||
createErrorMessage: (typeName: string) => string,
|
||||
resolveAlias: AliasResolver,
|
||||
) {
|
||||
const [typeAnnotation, nullable] = unwrapNullable<NativeModuleTypeAnnotation>(
|
||||
nullableTypeAnnotation,
|
||||
);
|
||||
const isRequired = !optional && !nullable;
|
||||
|
||||
let realTypeAnnotation = typeAnnotation;
|
||||
if (realTypeAnnotation.type === 'TypeAliasTypeAnnotation') {
|
||||
@@ -120,7 +128,7 @@ function translatePrimitiveJSTypeToCpp(
|
||||
}
|
||||
|
||||
function wrap(type: string) {
|
||||
return nullable ? `std::optional<${type}>` : type;
|
||||
return isRequired ? type : `std::optional<${type}>`;
|
||||
}
|
||||
|
||||
switch (realTypeAnnotation.type) {
|
||||
@@ -184,6 +192,76 @@ function translatePrimitiveJSTypeToCpp(
|
||||
}
|
||||
}
|
||||
|
||||
function createStructs(
|
||||
moduleName: string,
|
||||
aliasMap: NativeModuleAliasMap,
|
||||
resolveAlias: AliasResolver,
|
||||
): string {
|
||||
return Object.keys(aliasMap)
|
||||
.map(alias => {
|
||||
const value = aliasMap[alias];
|
||||
if (value.properties.length === 0) {
|
||||
return '';
|
||||
}
|
||||
const structName = `${moduleName}Base${alias}`;
|
||||
const templateParameterWithTypename = value.properties
|
||||
.map((v, i) => 'typename P' + i)
|
||||
.join(', ');
|
||||
const templateParameter = value.properties
|
||||
.map((v, i) => 'P' + i)
|
||||
.join(', ');
|
||||
return `#pragma mark - ${structName}
|
||||
|
||||
template <${templateParameterWithTypename}>
|
||||
struct ${structName} {
|
||||
${value.properties.map((v, i) => ' P' + i + ' ' + v.name).join(';\n')};
|
||||
bool operator==(const ${structName} &other) const {
|
||||
return ${value.properties
|
||||
.map(v => `${v.name} == other.${v.name}`)
|
||||
.join(' && ')};
|
||||
}
|
||||
};
|
||||
|
||||
template <${templateParameterWithTypename}>
|
||||
struct ${structName}Bridging {
|
||||
static ${structName}<${templateParameter}> fromJs(
|
||||
jsi::Runtime &rt,
|
||||
const jsi::Object &value,
|
||||
const std::shared_ptr<CallInvoker> &jsInvoker) {
|
||||
${structName}<${templateParameter}> result{
|
||||
${value.properties
|
||||
.map(
|
||||
(v, i) =>
|
||||
` bridging::fromJs<P${i}>(rt, value.getProperty(rt, "${v.name}"), jsInvoker)`,
|
||||
)
|
||||
.join(',\n')}};
|
||||
return result;
|
||||
}
|
||||
|
||||
static jsi::Object toJs(
|
||||
jsi::Runtime &rt,
|
||||
const ${structName}<${templateParameter}> &value) {
|
||||
auto result = facebook::jsi::Object(rt);
|
||||
${value.properties
|
||||
.map((v, i) => {
|
||||
if (v.optional) {
|
||||
return ` if (value.${v.name}) {
|
||||
result.setProperty(rt, "${v.name}", bridging::toJs(rt, value.${v.name}.value()));
|
||||
}`;
|
||||
} else {
|
||||
return ` result.setProperty(rt, "${v.name}", bridging::toJs(rt, value.${v.name}));`;
|
||||
}
|
||||
})
|
||||
.join('\n')}
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
`;
|
||||
})
|
||||
.join('\n');
|
||||
}
|
||||
|
||||
function translatePropertyToCpp(
|
||||
prop: NativeModulePropertyShape,
|
||||
resolveAlias: AliasResolver,
|
||||
@@ -199,6 +277,7 @@ function translatePropertyToCpp(
|
||||
const paramTypes = propTypeAnnotation.params.map(param => {
|
||||
const translatedParam = translatePrimitiveJSTypeToCpp(
|
||||
param.typeAnnotation,
|
||||
param.optional,
|
||||
typeName =>
|
||||
`Unsupported type for param "${param.name}" in ${prop.name}. Found: ${typeName}`,
|
||||
resolveAlias,
|
||||
@@ -208,6 +287,7 @@ function translatePropertyToCpp(
|
||||
|
||||
const returnType = translatePrimitiveJSTypeToCpp(
|
||||
propTypeAnnotation.returnTypeAnnotation,
|
||||
false,
|
||||
typeName => `Unsupported return type for ${prop.name}. Found: ${typeName}`,
|
||||
resolveAlias,
|
||||
);
|
||||
@@ -247,6 +327,7 @@ module.exports = {
|
||||
moduleNames: [moduleName],
|
||||
} = nativeModules[hasteModuleName];
|
||||
const resolveAlias = createAliasResolver(aliases);
|
||||
const structs = createStructs(moduleName, aliases, resolveAlias);
|
||||
|
||||
return [
|
||||
ModuleClassDeclarationTemplate({
|
||||
@@ -254,6 +335,7 @@ module.exports = {
|
||||
moduleProperties: properties.map(prop =>
|
||||
translatePropertyToCpp(prop, resolveAlias, true),
|
||||
),
|
||||
structs,
|
||||
}),
|
||||
ModuleSpecClassDeclarationTemplate({
|
||||
hasteModuleName,
|
||||
|
||||
+19
-67
@@ -275,6 +275,25 @@ const SIMPLE_NATIVE_MODULES: SchemaType = {
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'getValueWithOptionalArg',
|
||||
optional: false,
|
||||
typeAnnotation: {
|
||||
type: 'FunctionTypeAnnotation',
|
||||
returnTypeAnnotation: {
|
||||
type: 'PromiseTypeAnnotation',
|
||||
},
|
||||
params: [
|
||||
{
|
||||
optional: true,
|
||||
name: 'parameter',
|
||||
typeAnnotation: {
|
||||
type: 'GenericObjectTypeAnnotation',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'getEnums',
|
||||
optional: false,
|
||||
@@ -1205,73 +1224,6 @@ const REAL_MODULE_EXAMPLE: SchemaType = {
|
||||
},
|
||||
moduleNames: ['CameraRollManager'],
|
||||
},
|
||||
NativeImagePickerIOS: {
|
||||
type: 'NativeModule',
|
||||
aliases: {},
|
||||
spec: {
|
||||
properties: [
|
||||
{
|
||||
name: 'openCameraDialog',
|
||||
optional: false,
|
||||
typeAnnotation: {
|
||||
type: 'FunctionTypeAnnotation',
|
||||
returnTypeAnnotation: {
|
||||
type: 'VoidTypeAnnotation',
|
||||
},
|
||||
params: [
|
||||
{
|
||||
optional: false,
|
||||
name: 'config',
|
||||
typeAnnotation: {
|
||||
type: 'ObjectTypeAnnotation',
|
||||
properties: [
|
||||
{
|
||||
optional: false,
|
||||
name: 'unmirrorFrontFacingCamera',
|
||||
typeAnnotation: {
|
||||
type: 'BooleanTypeAnnotation',
|
||||
},
|
||||
},
|
||||
{
|
||||
optional: false,
|
||||
name: 'videoMode',
|
||||
typeAnnotation: {
|
||||
type: 'BooleanTypeAnnotation',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'successCallback',
|
||||
optional: false,
|
||||
typeAnnotation: {
|
||||
type: 'FunctionTypeAnnotation',
|
||||
params: [],
|
||||
returnTypeAnnotation: {
|
||||
type: 'VoidTypeAnnotation',
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'cancelCallback',
|
||||
optional: false,
|
||||
typeAnnotation: {
|
||||
type: 'FunctionTypeAnnotation',
|
||||
params: [],
|
||||
returnTypeAnnotation: {
|
||||
type: 'VoidTypeAnnotation',
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
moduleNames: ['ImagePickerIOS'],
|
||||
excludedPlatforms: ['android'],
|
||||
},
|
||||
NativeExceptionsManager: {
|
||||
type: 'NativeModule',
|
||||
aliases: {
|
||||
|
||||
+5
-10
@@ -54,7 +54,7 @@ static jsi::Value __hostFunction_NativeSampleTurboModuleCxxSpecJSI_optionals(jsi
|
||||
return jsi::Value::undefined();
|
||||
}
|
||||
static jsi::Value __hostFunction_NativeSampleTurboModuleCxxSpecJSI_optionalMethod(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) {
|
||||
static_cast<NativeSampleTurboModuleCxxSpecJSI *>(&turboModule)->optionalMethod(rt, args[0].asObject(rt), args[1].asObject(rt).asFunction(rt), args[2].asObject(rt).asArray(rt));
|
||||
static_cast<NativeSampleTurboModuleCxxSpecJSI *>(&turboModule)->optionalMethod(rt, args[0].asObject(rt), args[1].asObject(rt).asFunction(rt), count < 2 || args[2].isNull() || args[2].isUndefined() ? std::nullopt : std::make_optional(args[2].asObject(rt).asArray(rt)));
|
||||
return jsi::Value::undefined();
|
||||
}
|
||||
static jsi::Value __hostFunction_NativeSampleTurboModuleCxxSpecJSI_getArrays(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) {
|
||||
@@ -240,15 +240,6 @@ NativeCameraRollManagerCxxSpecJSI::NativeCameraRollManagerCxxSpecJSI(std::shared
|
||||
methodMap_[\\"saveToCameraRoll\\"] = MethodMetadata {2, __hostFunction_NativeCameraRollManagerCxxSpecJSI_saveToCameraRoll};
|
||||
methodMap_[\\"deletePhotos\\"] = MethodMetadata {1, __hostFunction_NativeCameraRollManagerCxxSpecJSI_deletePhotos};
|
||||
}
|
||||
static jsi::Value __hostFunction_NativeImagePickerIOSCxxSpecJSI_openCameraDialog(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) {
|
||||
static_cast<NativeImagePickerIOSCxxSpecJSI *>(&turboModule)->openCameraDialog(rt, args[0].asObject(rt), args[1].asObject(rt).asFunction(rt), args[2].asObject(rt).asFunction(rt));
|
||||
return jsi::Value::undefined();
|
||||
}
|
||||
|
||||
NativeImagePickerIOSCxxSpecJSI::NativeImagePickerIOSCxxSpecJSI(std::shared_ptr<CallInvoker> jsInvoker)
|
||||
: TurboModule(\\"ImagePickerIOS\\", jsInvoker) {
|
||||
methodMap_[\\"openCameraDialog\\"] = MethodMetadata {3, __hostFunction_NativeImagePickerIOSCxxSpecJSI_openCameraDialog};
|
||||
}
|
||||
static jsi::Value __hostFunction_NativeExceptionsManagerCxxSpecJSI_reportFatalException(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) {
|
||||
static_cast<NativeExceptionsManagerCxxSpecJSI *>(&turboModule)->reportFatalException(rt, args[0].asString(rt), args[1].asObject(rt).asArray(rt), args[2].asNumber());
|
||||
return jsi::Value::undefined();
|
||||
@@ -337,6 +328,9 @@ static jsi::Value __hostFunction_NativeSampleTurboModuleCxxSpecJSI_getValueWithC
|
||||
static jsi::Value __hostFunction_NativeSampleTurboModuleCxxSpecJSI_getValueWithPromise(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) {
|
||||
return static_cast<NativeSampleTurboModuleCxxSpecJSI *>(&turboModule)->getValueWithPromise(rt, args[0].asBool());
|
||||
}
|
||||
static jsi::Value __hostFunction_NativeSampleTurboModuleCxxSpecJSI_getValueWithOptionalArg(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) {
|
||||
return static_cast<NativeSampleTurboModuleCxxSpecJSI *>(&turboModule)->getValueWithOptionalArg(rt, count < 0 || args[0].isNull() || args[0].isUndefined() ? std::nullopt : std::make_optional(args[0].asObject(rt)));
|
||||
}
|
||||
static jsi::Value __hostFunction_NativeSampleTurboModuleCxxSpecJSI_getEnums(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) {
|
||||
return static_cast<NativeSampleTurboModuleCxxSpecJSI *>(&turboModule)->getEnums(rt, args[0].asNumber(), args[1].asNumber(), args[2].asString(rt));
|
||||
}
|
||||
@@ -354,6 +348,7 @@ NativeSampleTurboModuleCxxSpecJSI::NativeSampleTurboModuleCxxSpecJSI(std::shared
|
||||
methodMap_[\\"getValue\\"] = MethodMetadata {3, __hostFunction_NativeSampleTurboModuleCxxSpecJSI_getValue};
|
||||
methodMap_[\\"getValueWithCallback\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleCxxSpecJSI_getValueWithCallback};
|
||||
methodMap_[\\"getValueWithPromise\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleCxxSpecJSI_getValueWithPromise};
|
||||
methodMap_[\\"getValueWithOptionalArg\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleCxxSpecJSI_getValueWithOptionalArg};
|
||||
methodMap_[\\"getEnums\\"] = MethodMetadata {3, __hostFunction_NativeSampleTurboModuleCxxSpecJSI_getEnums};
|
||||
}
|
||||
|
||||
|
||||
+354
-35
@@ -87,7 +87,7 @@ protected:
|
||||
public:
|
||||
virtual jsi::Object difficult(jsi::Runtime &rt, jsi::Object A) = 0;
|
||||
virtual void optionals(jsi::Runtime &rt, jsi::Object A) = 0;
|
||||
virtual void optionalMethod(jsi::Runtime &rt, jsi::Object options, jsi::Function callback, jsi::Array extras) = 0;
|
||||
virtual void optionalMethod(jsi::Runtime &rt, jsi::Object options, jsi::Function callback, std::optional<jsi::Array> extras) = 0;
|
||||
virtual void getArrays(jsi::Runtime &rt, jsi::Object options) = 0;
|
||||
virtual std::optional<jsi::Object> getNullableObject(jsi::Runtime &rt) = 0;
|
||||
virtual std::optional<jsi::Object> getNullableGenericObject(jsi::Runtime &rt) = 0;
|
||||
@@ -129,7 +129,7 @@ private:
|
||||
return bridging::callFromJs<void>(
|
||||
rt, &T::optionals, jsInvoker_, instance_, std::move(A));
|
||||
}
|
||||
void optionalMethod(jsi::Runtime &rt, jsi::Object options, jsi::Function callback, jsi::Array extras) override {
|
||||
void optionalMethod(jsi::Runtime &rt, jsi::Object options, jsi::Function callback, std::optional<jsi::Array> extras) override {
|
||||
static_assert(
|
||||
bridging::getParameterCount(&T::optionalMethod) == 4,
|
||||
\\"Expected optionalMethod(...) to have 4 parameters\\");
|
||||
@@ -202,6 +202,36 @@ Map {
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
#pragma mark - SampleTurboModuleCxxBaseObjectAlias
|
||||
|
||||
template <typename P0>
|
||||
struct SampleTurboModuleCxxBaseObjectAlias {
|
||||
P0 x;
|
||||
bool operator==(const SampleTurboModuleCxxBaseObjectAlias &other) const {
|
||||
return x == other.x;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename P0>
|
||||
struct SampleTurboModuleCxxBaseObjectAliasBridging {
|
||||
static SampleTurboModuleCxxBaseObjectAlias<P0> fromJs(
|
||||
jsi::Runtime &rt,
|
||||
const jsi::Object &value,
|
||||
const std::shared_ptr<CallInvoker> &jsInvoker) {
|
||||
SampleTurboModuleCxxBaseObjectAlias<P0> result{
|
||||
bridging::fromJs<P0>(rt, value.getProperty(rt, \\"x\\"), jsInvoker)};
|
||||
return result;
|
||||
}
|
||||
|
||||
static jsi::Object toJs(
|
||||
jsi::Runtime &rt,
|
||||
const SampleTurboModuleCxxBaseObjectAlias<P0> &value) {
|
||||
auto result = facebook::jsi::Object(rt);
|
||||
result.setProperty(rt, \\"x\\", bridging::toJs(rt, value.x));
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
class JSI_EXPORT NativeSampleTurboModuleCxxSpecJSI : public TurboModule {
|
||||
protected:
|
||||
NativeSampleTurboModuleCxxSpecJSI(std::shared_ptr<CallInvoker> jsInvoker);
|
||||
@@ -358,6 +388,54 @@ Map {
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
#pragma mark - AliasTurboModuleBaseOptions
|
||||
|
||||
template <typename P0, typename P1, typename P2, typename P3, typename P4>
|
||||
struct AliasTurboModuleBaseOptions {
|
||||
P0 offset;
|
||||
P1 size;
|
||||
P2 displaySize;
|
||||
P3 resizeMode;
|
||||
P4 allowExternalStorage;
|
||||
bool operator==(const AliasTurboModuleBaseOptions &other) const {
|
||||
return offset == other.offset && size == other.size && displaySize == other.displaySize && resizeMode == other.resizeMode && allowExternalStorage == other.allowExternalStorage;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename P0, typename P1, typename P2, typename P3, typename P4>
|
||||
struct AliasTurboModuleBaseOptionsBridging {
|
||||
static AliasTurboModuleBaseOptions<P0, P1, P2, P3, P4> fromJs(
|
||||
jsi::Runtime &rt,
|
||||
const jsi::Object &value,
|
||||
const std::shared_ptr<CallInvoker> &jsInvoker) {
|
||||
AliasTurboModuleBaseOptions<P0, P1, P2, P3, P4> result{
|
||||
bridging::fromJs<P0>(rt, value.getProperty(rt, \\"offset\\"), jsInvoker),
|
||||
bridging::fromJs<P1>(rt, value.getProperty(rt, \\"size\\"), jsInvoker),
|
||||
bridging::fromJs<P2>(rt, value.getProperty(rt, \\"displaySize\\"), jsInvoker),
|
||||
bridging::fromJs<P3>(rt, value.getProperty(rt, \\"resizeMode\\"), jsInvoker),
|
||||
bridging::fromJs<P4>(rt, value.getProperty(rt, \\"allowExternalStorage\\"), jsInvoker)};
|
||||
return result;
|
||||
}
|
||||
|
||||
static jsi::Object toJs(
|
||||
jsi::Runtime &rt,
|
||||
const AliasTurboModuleBaseOptions<P0, P1, P2, P3, P4> &value) {
|
||||
auto result = facebook::jsi::Object(rt);
|
||||
result.setProperty(rt, \\"offset\\", bridging::toJs(rt, value.offset));
|
||||
result.setProperty(rt, \\"size\\", bridging::toJs(rt, value.size));
|
||||
if (value.displaySize) {
|
||||
result.setProperty(rt, \\"displaySize\\", bridging::toJs(rt, value.displaySize.value()));
|
||||
}
|
||||
if (value.resizeMode) {
|
||||
result.setProperty(rt, \\"resizeMode\\", bridging::toJs(rt, value.resizeMode.value()));
|
||||
}
|
||||
if (value.allowExternalStorage) {
|
||||
result.setProperty(rt, \\"allowExternalStorage\\", bridging::toJs(rt, value.allowExternalStorage.value()));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
class JSI_EXPORT AliasTurboModuleCxxSpecJSI : public TurboModule {
|
||||
protected:
|
||||
AliasTurboModuleCxxSpecJSI(std::shared_ptr<CallInvoker> jsInvoker);
|
||||
@@ -435,6 +513,179 @@ Map {
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
#pragma mark - CameraRollManagerBasePhotoIdentifierImage
|
||||
|
||||
template <typename P0, typename P1, typename P2, typename P3, typename P4, typename P5>
|
||||
struct CameraRollManagerBasePhotoIdentifierImage {
|
||||
P0 uri;
|
||||
P1 playableDuration;
|
||||
P2 width;
|
||||
P3 height;
|
||||
P4 isStored;
|
||||
P5 filename;
|
||||
bool operator==(const CameraRollManagerBasePhotoIdentifierImage &other) const {
|
||||
return uri == other.uri && playableDuration == other.playableDuration && width == other.width && height == other.height && isStored == other.isStored && filename == other.filename;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename P0, typename P1, typename P2, typename P3, typename P4, typename P5>
|
||||
struct CameraRollManagerBasePhotoIdentifierImageBridging {
|
||||
static CameraRollManagerBasePhotoIdentifierImage<P0, P1, P2, P3, P4, P5> fromJs(
|
||||
jsi::Runtime &rt,
|
||||
const jsi::Object &value,
|
||||
const std::shared_ptr<CallInvoker> &jsInvoker) {
|
||||
CameraRollManagerBasePhotoIdentifierImage<P0, P1, P2, P3, P4, P5> result{
|
||||
bridging::fromJs<P0>(rt, value.getProperty(rt, \\"uri\\"), jsInvoker),
|
||||
bridging::fromJs<P1>(rt, value.getProperty(rt, \\"playableDuration\\"), jsInvoker),
|
||||
bridging::fromJs<P2>(rt, value.getProperty(rt, \\"width\\"), jsInvoker),
|
||||
bridging::fromJs<P3>(rt, value.getProperty(rt, \\"height\\"), jsInvoker),
|
||||
bridging::fromJs<P4>(rt, value.getProperty(rt, \\"isStored\\"), jsInvoker),
|
||||
bridging::fromJs<P5>(rt, value.getProperty(rt, \\"filename\\"), jsInvoker)};
|
||||
return result;
|
||||
}
|
||||
|
||||
static jsi::Object toJs(
|
||||
jsi::Runtime &rt,
|
||||
const CameraRollManagerBasePhotoIdentifierImage<P0, P1, P2, P3, P4, P5> &value) {
|
||||
auto result = facebook::jsi::Object(rt);
|
||||
result.setProperty(rt, \\"uri\\", bridging::toJs(rt, value.uri));
|
||||
result.setProperty(rt, \\"playableDuration\\", bridging::toJs(rt, value.playableDuration));
|
||||
result.setProperty(rt, \\"width\\", bridging::toJs(rt, value.width));
|
||||
result.setProperty(rt, \\"height\\", bridging::toJs(rt, value.height));
|
||||
if (value.isStored) {
|
||||
result.setProperty(rt, \\"isStored\\", bridging::toJs(rt, value.isStored.value()));
|
||||
}
|
||||
result.setProperty(rt, \\"filename\\", bridging::toJs(rt, value.filename));
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
#pragma mark - CameraRollManagerBasePhotoIdentifier
|
||||
|
||||
template <typename P0>
|
||||
struct CameraRollManagerBasePhotoIdentifier {
|
||||
P0 node;
|
||||
bool operator==(const CameraRollManagerBasePhotoIdentifier &other) const {
|
||||
return node == other.node;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename P0>
|
||||
struct CameraRollManagerBasePhotoIdentifierBridging {
|
||||
static CameraRollManagerBasePhotoIdentifier<P0> fromJs(
|
||||
jsi::Runtime &rt,
|
||||
const jsi::Object &value,
|
||||
const std::shared_ptr<CallInvoker> &jsInvoker) {
|
||||
CameraRollManagerBasePhotoIdentifier<P0> result{
|
||||
bridging::fromJs<P0>(rt, value.getProperty(rt, \\"node\\"), jsInvoker)};
|
||||
return result;
|
||||
}
|
||||
|
||||
static jsi::Object toJs(
|
||||
jsi::Runtime &rt,
|
||||
const CameraRollManagerBasePhotoIdentifier<P0> &value) {
|
||||
auto result = facebook::jsi::Object(rt);
|
||||
result.setProperty(rt, \\"node\\", bridging::toJs(rt, value.node));
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
#pragma mark - CameraRollManagerBasePhotoIdentifiersPage
|
||||
|
||||
template <typename P0, typename P1>
|
||||
struct CameraRollManagerBasePhotoIdentifiersPage {
|
||||
P0 edges;
|
||||
P1 page_info;
|
||||
bool operator==(const CameraRollManagerBasePhotoIdentifiersPage &other) const {
|
||||
return edges == other.edges && page_info == other.page_info;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename P0, typename P1>
|
||||
struct CameraRollManagerBasePhotoIdentifiersPageBridging {
|
||||
static CameraRollManagerBasePhotoIdentifiersPage<P0, P1> fromJs(
|
||||
jsi::Runtime &rt,
|
||||
const jsi::Object &value,
|
||||
const std::shared_ptr<CallInvoker> &jsInvoker) {
|
||||
CameraRollManagerBasePhotoIdentifiersPage<P0, P1> result{
|
||||
bridging::fromJs<P0>(rt, value.getProperty(rt, \\"edges\\"), jsInvoker),
|
||||
bridging::fromJs<P1>(rt, value.getProperty(rt, \\"page_info\\"), jsInvoker)};
|
||||
return result;
|
||||
}
|
||||
|
||||
static jsi::Object toJs(
|
||||
jsi::Runtime &rt,
|
||||
const CameraRollManagerBasePhotoIdentifiersPage<P0, P1> &value) {
|
||||
auto result = facebook::jsi::Object(rt);
|
||||
result.setProperty(rt, \\"edges\\", bridging::toJs(rt, value.edges));
|
||||
result.setProperty(rt, \\"page_info\\", bridging::toJs(rt, value.page_info));
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
#pragma mark - CameraRollManagerBaseGetPhotosParams
|
||||
|
||||
template <typename P0, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6>
|
||||
struct CameraRollManagerBaseGetPhotosParams {
|
||||
P0 first;
|
||||
P1 after;
|
||||
P2 groupName;
|
||||
P3 groupTypes;
|
||||
P4 assetType;
|
||||
P5 maxSize;
|
||||
P6 mimeTypes;
|
||||
bool operator==(const CameraRollManagerBaseGetPhotosParams &other) const {
|
||||
return first == other.first && after == other.after && groupName == other.groupName && groupTypes == other.groupTypes && assetType == other.assetType && maxSize == other.maxSize && mimeTypes == other.mimeTypes;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename P0, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6>
|
||||
struct CameraRollManagerBaseGetPhotosParamsBridging {
|
||||
static CameraRollManagerBaseGetPhotosParams<P0, P1, P2, P3, P4, P5, P6> fromJs(
|
||||
jsi::Runtime &rt,
|
||||
const jsi::Object &value,
|
||||
const std::shared_ptr<CallInvoker> &jsInvoker) {
|
||||
CameraRollManagerBaseGetPhotosParams<P0, P1, P2, P3, P4, P5, P6> result{
|
||||
bridging::fromJs<P0>(rt, value.getProperty(rt, \\"first\\"), jsInvoker),
|
||||
bridging::fromJs<P1>(rt, value.getProperty(rt, \\"after\\"), jsInvoker),
|
||||
bridging::fromJs<P2>(rt, value.getProperty(rt, \\"groupName\\"), jsInvoker),
|
||||
bridging::fromJs<P3>(rt, value.getProperty(rt, \\"groupTypes\\"), jsInvoker),
|
||||
bridging::fromJs<P4>(rt, value.getProperty(rt, \\"assetType\\"), jsInvoker),
|
||||
bridging::fromJs<P5>(rt, value.getProperty(rt, \\"maxSize\\"), jsInvoker),
|
||||
bridging::fromJs<P6>(rt, value.getProperty(rt, \\"mimeTypes\\"), jsInvoker)};
|
||||
return result;
|
||||
}
|
||||
|
||||
static jsi::Object toJs(
|
||||
jsi::Runtime &rt,
|
||||
const CameraRollManagerBaseGetPhotosParams<P0, P1, P2, P3, P4, P5, P6> &value) {
|
||||
auto result = facebook::jsi::Object(rt);
|
||||
result.setProperty(rt, \\"first\\", bridging::toJs(rt, value.first));
|
||||
if (value.after) {
|
||||
result.setProperty(rt, \\"after\\", bridging::toJs(rt, value.after.value()));
|
||||
}
|
||||
if (value.groupName) {
|
||||
result.setProperty(rt, \\"groupName\\", bridging::toJs(rt, value.groupName.value()));
|
||||
}
|
||||
if (value.groupTypes) {
|
||||
result.setProperty(rt, \\"groupTypes\\", bridging::toJs(rt, value.groupTypes.value()));
|
||||
}
|
||||
if (value.assetType) {
|
||||
result.setProperty(rt, \\"assetType\\", bridging::toJs(rt, value.assetType.value()));
|
||||
}
|
||||
if (value.maxSize) {
|
||||
result.setProperty(rt, \\"maxSize\\", bridging::toJs(rt, value.maxSize.value()));
|
||||
}
|
||||
if (value.mimeTypes) {
|
||||
result.setProperty(rt, \\"mimeTypes\\", bridging::toJs(rt, value.mimeTypes.value()));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
class JSI_EXPORT NativeCameraRollManagerCxxSpecJSI : public TurboModule {
|
||||
protected:
|
||||
NativeCameraRollManagerCxxSpecJSI(std::shared_ptr<CallInvoker> jsInvoker);
|
||||
@@ -505,47 +756,106 @@ private:
|
||||
Delegate delegate_;
|
||||
};
|
||||
|
||||
class JSI_EXPORT NativeImagePickerIOSCxxSpecJSI : public TurboModule {
|
||||
protected:
|
||||
NativeImagePickerIOSCxxSpecJSI(std::shared_ptr<CallInvoker> jsInvoker);
|
||||
|
||||
public:
|
||||
virtual void openCameraDialog(jsi::Runtime &rt, jsi::Object config, jsi::Function successCallback, jsi::Function cancelCallback) = 0;
|
||||
#pragma mark - ExceptionsManagerBaseStackFrame
|
||||
|
||||
template <typename P0, typename P1, typename P2, typename P3, typename P4>
|
||||
struct ExceptionsManagerBaseStackFrame {
|
||||
P0 column;
|
||||
P1 file;
|
||||
P2 lineNumber;
|
||||
P3 methodName;
|
||||
P4 collapse;
|
||||
bool operator==(const ExceptionsManagerBaseStackFrame &other) const {
|
||||
return column == other.column && file == other.file && lineNumber == other.lineNumber && methodName == other.methodName && collapse == other.collapse;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class JSI_EXPORT NativeImagePickerIOSCxxSpec : public TurboModule {
|
||||
public:
|
||||
jsi::Value get(jsi::Runtime &rt, const jsi::PropNameID &propName) override {
|
||||
return delegate_.get(rt, propName);
|
||||
template <typename P0, typename P1, typename P2, typename P3, typename P4>
|
||||
struct ExceptionsManagerBaseStackFrameBridging {
|
||||
static ExceptionsManagerBaseStackFrame<P0, P1, P2, P3, P4> fromJs(
|
||||
jsi::Runtime &rt,
|
||||
const jsi::Object &value,
|
||||
const std::shared_ptr<CallInvoker> &jsInvoker) {
|
||||
ExceptionsManagerBaseStackFrame<P0, P1, P2, P3, P4> result{
|
||||
bridging::fromJs<P0>(rt, value.getProperty(rt, \\"column\\"), jsInvoker),
|
||||
bridging::fromJs<P1>(rt, value.getProperty(rt, \\"file\\"), jsInvoker),
|
||||
bridging::fromJs<P2>(rt, value.getProperty(rt, \\"lineNumber\\"), jsInvoker),
|
||||
bridging::fromJs<P3>(rt, value.getProperty(rt, \\"methodName\\"), jsInvoker),
|
||||
bridging::fromJs<P4>(rt, value.getProperty(rt, \\"collapse\\"), jsInvoker)};
|
||||
return result;
|
||||
}
|
||||
|
||||
protected:
|
||||
NativeImagePickerIOSCxxSpec(std::shared_ptr<CallInvoker> jsInvoker)
|
||||
: TurboModule(\\"ImagePickerIOS\\", jsInvoker),
|
||||
delegate_(static_cast<T*>(this), jsInvoker) {}
|
||||
|
||||
private:
|
||||
class Delegate : public NativeImagePickerIOSCxxSpecJSI {
|
||||
public:
|
||||
Delegate(T *instance, std::shared_ptr<CallInvoker> jsInvoker) :
|
||||
NativeImagePickerIOSCxxSpecJSI(std::move(jsInvoker)), instance_(instance) {}
|
||||
|
||||
void openCameraDialog(jsi::Runtime &rt, jsi::Object config, jsi::Function successCallback, jsi::Function cancelCallback) override {
|
||||
static_assert(
|
||||
bridging::getParameterCount(&T::openCameraDialog) == 4,
|
||||
\\"Expected openCameraDialog(...) to have 4 parameters\\");
|
||||
|
||||
return bridging::callFromJs<void>(
|
||||
rt, &T::openCameraDialog, jsInvoker_, instance_, std::move(config), std::move(successCallback), std::move(cancelCallback));
|
||||
static jsi::Object toJs(
|
||||
jsi::Runtime &rt,
|
||||
const ExceptionsManagerBaseStackFrame<P0, P1, P2, P3, P4> &value) {
|
||||
auto result = facebook::jsi::Object(rt);
|
||||
if (value.column) {
|
||||
result.setProperty(rt, \\"column\\", bridging::toJs(rt, value.column.value()));
|
||||
}
|
||||
result.setProperty(rt, \\"file\\", bridging::toJs(rt, value.file));
|
||||
if (value.lineNumber) {
|
||||
result.setProperty(rt, \\"lineNumber\\", bridging::toJs(rt, value.lineNumber.value()));
|
||||
}
|
||||
result.setProperty(rt, \\"methodName\\", bridging::toJs(rt, value.methodName));
|
||||
if (value.collapse) {
|
||||
result.setProperty(rt, \\"collapse\\", bridging::toJs(rt, value.collapse.value()));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
private:
|
||||
T *instance_;
|
||||
};
|
||||
|
||||
Delegate delegate_;
|
||||
#pragma mark - ExceptionsManagerBaseExceptionData
|
||||
|
||||
template <typename P0, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7>
|
||||
struct ExceptionsManagerBaseExceptionData {
|
||||
P0 message;
|
||||
P1 originalMessage;
|
||||
P2 name;
|
||||
P3 componentStack;
|
||||
P4 stack;
|
||||
P5 id;
|
||||
P6 isFatal;
|
||||
P7 extraData;
|
||||
bool operator==(const ExceptionsManagerBaseExceptionData &other) const {
|
||||
return message == other.message && originalMessage == other.originalMessage && name == other.name && componentStack == other.componentStack && stack == other.stack && id == other.id && isFatal == other.isFatal && extraData == other.extraData;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename P0, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7>
|
||||
struct ExceptionsManagerBaseExceptionDataBridging {
|
||||
static ExceptionsManagerBaseExceptionData<P0, P1, P2, P3, P4, P5, P6, P7> fromJs(
|
||||
jsi::Runtime &rt,
|
||||
const jsi::Object &value,
|
||||
const std::shared_ptr<CallInvoker> &jsInvoker) {
|
||||
ExceptionsManagerBaseExceptionData<P0, P1, P2, P3, P4, P5, P6, P7> result{
|
||||
bridging::fromJs<P0>(rt, value.getProperty(rt, \\"message\\"), jsInvoker),
|
||||
bridging::fromJs<P1>(rt, value.getProperty(rt, \\"originalMessage\\"), jsInvoker),
|
||||
bridging::fromJs<P2>(rt, value.getProperty(rt, \\"name\\"), jsInvoker),
|
||||
bridging::fromJs<P3>(rt, value.getProperty(rt, \\"componentStack\\"), jsInvoker),
|
||||
bridging::fromJs<P4>(rt, value.getProperty(rt, \\"stack\\"), jsInvoker),
|
||||
bridging::fromJs<P5>(rt, value.getProperty(rt, \\"id\\"), jsInvoker),
|
||||
bridging::fromJs<P6>(rt, value.getProperty(rt, \\"isFatal\\"), jsInvoker),
|
||||
bridging::fromJs<P7>(rt, value.getProperty(rt, \\"extraData\\"), jsInvoker)};
|
||||
return result;
|
||||
}
|
||||
|
||||
static jsi::Object toJs(
|
||||
jsi::Runtime &rt,
|
||||
const ExceptionsManagerBaseExceptionData<P0, P1, P2, P3, P4, P5, P6, P7> &value) {
|
||||
auto result = facebook::jsi::Object(rt);
|
||||
result.setProperty(rt, \\"message\\", bridging::toJs(rt, value.message));
|
||||
result.setProperty(rt, \\"originalMessage\\", bridging::toJs(rt, value.originalMessage));
|
||||
result.setProperty(rt, \\"name\\", bridging::toJs(rt, value.name));
|
||||
result.setProperty(rt, \\"componentStack\\", bridging::toJs(rt, value.componentStack));
|
||||
result.setProperty(rt, \\"stack\\", bridging::toJs(rt, value.stack));
|
||||
result.setProperty(rt, \\"id\\", bridging::toJs(rt, value.id));
|
||||
result.setProperty(rt, \\"isFatal\\", bridging::toJs(rt, value.isFatal));
|
||||
if (value.extraData) {
|
||||
result.setProperty(rt, \\"extraData\\", bridging::toJs(rt, value.extraData.value()));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
class JSI_EXPORT NativeExceptionsManagerCxxSpecJSI : public TurboModule {
|
||||
@@ -668,6 +978,7 @@ public:
|
||||
virtual jsi::Object getValue(jsi::Runtime &rt, double x, jsi::String y, jsi::Object z) = 0;
|
||||
virtual void getValueWithCallback(jsi::Runtime &rt, jsi::Function callback) = 0;
|
||||
virtual jsi::Value getValueWithPromise(jsi::Runtime &rt, bool error) = 0;
|
||||
virtual jsi::Value getValueWithOptionalArg(jsi::Runtime &rt, std::optional<jsi::Object> parameter) = 0;
|
||||
virtual jsi::String getEnums(jsi::Runtime &rt, double enumInt, double enumFloat, jsi::String enumString) = 0;
|
||||
|
||||
};
|
||||
@@ -778,6 +1089,14 @@ private:
|
||||
return bridging::callFromJs<jsi::Value>(
|
||||
rt, &T::getValueWithPromise, jsInvoker_, instance_, std::move(error));
|
||||
}
|
||||
jsi::Value getValueWithOptionalArg(jsi::Runtime &rt, std::optional<jsi::Object> parameter) override {
|
||||
static_assert(
|
||||
bridging::getParameterCount(&T::getValueWithOptionalArg) == 2,
|
||||
\\"Expected getValueWithOptionalArg(...) to have 2 parameters\\");
|
||||
|
||||
return bridging::callFromJs<jsi::Value>(
|
||||
rt, &T::getValueWithOptionalArg, jsInvoker_, instance_, std::move(parameter));
|
||||
}
|
||||
jsi::String getEnums(jsi::Runtime &rt, double enumInt, double enumFloat, jsi::String enumString) override {
|
||||
static_assert(
|
||||
bridging::getParameterCount(&T::getEnums) == 4,
|
||||
|
||||
+3
-44
@@ -711,40 +711,6 @@ namespace facebook {
|
||||
};
|
||||
} // namespace react
|
||||
} // namespace facebook
|
||||
namespace JS {
|
||||
namespace NativeImagePickerIOS {
|
||||
struct SpecOpenCameraDialogConfig {
|
||||
bool unmirrorFrontFacingCamera() const;
|
||||
bool videoMode() const;
|
||||
|
||||
SpecOpenCameraDialogConfig(NSDictionary *const v) : _v(v) {}
|
||||
private:
|
||||
NSDictionary *_v;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@interface RCTCxxConvert (NativeImagePickerIOS_SpecOpenCameraDialogConfig)
|
||||
+ (RCTManagedPointer *)JS_NativeImagePickerIOS_SpecOpenCameraDialogConfig:(id)json;
|
||||
@end
|
||||
@protocol NativeImagePickerIOSSpec <RCTBridgeModule, RCTTurboModule>
|
||||
|
||||
- (void)openCameraDialog:(JS::NativeImagePickerIOS::SpecOpenCameraDialogConfig &)config
|
||||
successCallback:(RCTResponseSenderBlock)successCallback
|
||||
cancelCallback:(RCTResponseSenderBlock)cancelCallback;
|
||||
|
||||
@end
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
/**
|
||||
* ObjC++ class for module 'NativeImagePickerIOS'
|
||||
*/
|
||||
class JSI_EXPORT NativeImagePickerIOSSpecJSI : public ObjCTurboModule {
|
||||
public:
|
||||
NativeImagePickerIOSSpecJSI(const ObjCTurboModule::InitParams ¶ms);
|
||||
};
|
||||
} // namespace react
|
||||
} // namespace facebook
|
||||
inline double JS::NativeCameraRollManager::GetPhotosParams::first() const
|
||||
{
|
||||
id const p = _v[@\\"first\\"];
|
||||
@@ -845,16 +811,6 @@ inline id<NSObject> _Nullable JS::NativeExceptionsManager::ExceptionData::extraD
|
||||
id const p = _v[@\\"extraData\\"];
|
||||
return p;
|
||||
}
|
||||
inline bool JS::NativeImagePickerIOS::SpecOpenCameraDialogConfig::unmirrorFrontFacingCamera() const
|
||||
{
|
||||
id const p = _v[@\\"unmirrorFrontFacingCamera\\"];
|
||||
return RCTBridgingToBool(p);
|
||||
}
|
||||
inline bool JS::NativeImagePickerIOS::SpecOpenCameraDialogConfig::videoMode() const
|
||||
{
|
||||
id const p = _v[@\\"videoMode\\"];
|
||||
return RCTBridgingToBool(p);
|
||||
}
|
||||
",
|
||||
}
|
||||
`;
|
||||
@@ -933,6 +889,9 @@ namespace JS {
|
||||
- (void)getValueWithPromise:(BOOL)error
|
||||
resolve:(RCTPromiseResolveBlock)resolve
|
||||
reject:(RCTPromiseRejectBlock)reject;
|
||||
- (void)getValueWithOptionalArg:(NSDictionary *)parameter
|
||||
resolve:(RCTPromiseResolveBlock)resolve
|
||||
reject:(RCTPromiseRejectBlock)reject;
|
||||
- (NSString *)getEnums:(double)enumInt
|
||||
enumFloat:(double)enumFloat
|
||||
enumString:(NSString *)enumString;
|
||||
|
||||
+4
@@ -377,6 +377,10 @@ public abstract class NativeSampleTurboModuleSpec extends ReactContextBaseJavaMo
|
||||
@DoNotStrip
|
||||
public abstract void getValueWithPromise(boolean error, Promise promise);
|
||||
|
||||
@ReactMethod
|
||||
@DoNotStrip
|
||||
public abstract void getValueWithOptionalArg(ReadableMap parameter, Promise promise);
|
||||
|
||||
@ReactMethod(isBlockingSynchronousMethod = true)
|
||||
@DoNotStrip
|
||||
public abstract String getEnums(double enumInt, double enumFloat, String enumString);
|
||||
|
||||
+6
@@ -384,6 +384,11 @@ static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI_getVal
|
||||
return static_cast<JavaTurboModule &>(turboModule).invokeJavaMethod(rt, PromiseKind, \\"getValueWithPromise\\", \\"(ZLcom/facebook/react/bridge/Promise;)V\\", args, count, cachedMethodId);
|
||||
}
|
||||
|
||||
static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI_getValueWithOptionalArg(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) {
|
||||
static jmethodID cachedMethodId = nullptr;
|
||||
return static_cast<JavaTurboModule &>(turboModule).invokeJavaMethod(rt, PromiseKind, \\"getValueWithOptionalArg\\", \\"(Lcom/facebook/react/bridge/ReadableMap;Lcom/facebook/react/bridge/Promise;)V\\", args, count, cachedMethodId);
|
||||
}
|
||||
|
||||
static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI_getEnums(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) {
|
||||
static jmethodID cachedMethodId = nullptr;
|
||||
return static_cast<JavaTurboModule &>(turboModule).invokeJavaMethod(rt, StringKind, \\"getEnums\\", \\"(DDLjava/lang/String;)Ljava/lang/String;\\", args, count, cachedMethodId);
|
||||
@@ -402,6 +407,7 @@ NativeSampleTurboModuleSpecJSI::NativeSampleTurboModuleSpecJSI(const JavaTurboMo
|
||||
methodMap_[\\"getValue\\"] = MethodMetadata {3, __hostFunction_NativeSampleTurboModuleSpecJSI_getValue};
|
||||
methodMap_[\\"getValueWithCallback\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleSpecJSI_getValueWithCallback};
|
||||
methodMap_[\\"getValueWithPromise\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleSpecJSI_getValueWithPromise};
|
||||
methodMap_[\\"getValueWithOptionalArg\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleSpecJSI_getValueWithOptionalArg};
|
||||
methodMap_[\\"getEnums\\"] = MethodMetadata {3, __hostFunction_NativeSampleTurboModuleSpecJSI_getEnums};
|
||||
}
|
||||
|
||||
|
||||
+7
-21
@@ -367,27 +367,6 @@ namespace facebook {
|
||||
}
|
||||
} // namespace react
|
||||
} // namespace facebook
|
||||
@implementation RCTCxxConvert (NativeImagePickerIOS_SpecOpenCameraDialogConfig)
|
||||
+ (RCTManagedPointer *)JS_NativeImagePickerIOS_SpecOpenCameraDialogConfig:(id)json
|
||||
{
|
||||
return facebook::react::managedPointer<JS::NativeImagePickerIOS::SpecOpenCameraDialogConfig>(json);
|
||||
}
|
||||
@end
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
static facebook::jsi::Value __hostFunction_NativeImagePickerIOSSpecJSI_openCameraDialog(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) {
|
||||
return static_cast<ObjCTurboModule&>(turboModule).invokeObjCMethod(rt, VoidKind, \\"openCameraDialog\\", @selector(openCameraDialog:successCallback:cancelCallback:), args, count);
|
||||
}
|
||||
|
||||
NativeImagePickerIOSSpecJSI::NativeImagePickerIOSSpecJSI(const ObjCTurboModule::InitParams ¶ms)
|
||||
: ObjCTurboModule(params) {
|
||||
|
||||
methodMap_[\\"openCameraDialog\\"] = MethodMetadata {3, __hostFunction_NativeImagePickerIOSSpecJSI_openCameraDialog};
|
||||
setMethodArgConversionSelector(@\\"openCameraDialog\\", 0, @\\"JS_NativeImagePickerIOS_SpecOpenCameraDialogConfig:\\");
|
||||
}
|
||||
} // namespace react
|
||||
} // namespace facebook
|
||||
",
|
||||
}
|
||||
`;
|
||||
@@ -453,6 +432,10 @@ namespace facebook {
|
||||
return static_cast<ObjCTurboModule&>(turboModule).invokeObjCMethod(rt, PromiseKind, \\"getValueWithPromise\\", @selector(getValueWithPromise:resolve:reject:), args, count);
|
||||
}
|
||||
|
||||
static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI_getValueWithOptionalArg(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) {
|
||||
return static_cast<ObjCTurboModule&>(turboModule).invokeObjCMethod(rt, PromiseKind, \\"getValueWithOptionalArg\\", @selector(getValueWithOptionalArg:resolve:reject:), args, count);
|
||||
}
|
||||
|
||||
static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI_getEnums(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) {
|
||||
return static_cast<ObjCTurboModule&>(turboModule).invokeObjCMethod(rt, StringKind, \\"getEnums\\", @selector(getEnums:enumFloat:enumString:), args, count);
|
||||
}
|
||||
@@ -494,6 +477,9 @@ namespace facebook {
|
||||
methodMap_[\\"getValueWithPromise\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleSpecJSI_getValueWithPromise};
|
||||
|
||||
|
||||
methodMap_[\\"getValueWithOptionalArg\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleSpecJSI_getValueWithOptionalArg};
|
||||
|
||||
|
||||
methodMap_[\\"getEnums\\"] = MethodMetadata {3, __hostFunction_NativeSampleTurboModuleSpecJSI_getEnums};
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "react-native-gradle-plugin",
|
||||
"version": "0.71.8",
|
||||
"version": "0.71.9",
|
||||
"description": "⚛️ Gradle Plugin for React Native",
|
||||
"homepage": "https://github.com/facebook/react-native/tree/HEAD/packages/react-native-gradle-plugin",
|
||||
"repository": {
|
||||
|
||||
+16
-2
@@ -35,9 +35,23 @@ internal object DependencyUtils {
|
||||
fun configureDependencies(project: Project, versionString: String) {
|
||||
if (versionString.isBlank()) return
|
||||
project.configurations.all { configuration ->
|
||||
// Here we set a dependencySubstitution for both react-native and hermes-engine as those
|
||||
// coordinates are voided due to https://github.com/facebook/react-native/issues/35210
|
||||
// This allows users to import libraries that are still using
|
||||
// implementation("com.facebook.react:react-native:+") and resolve the right dependency.
|
||||
configuration.resolutionStrategy.dependencySubstitution {
|
||||
it.substitute(it.module("com.facebook.react:react-native"))
|
||||
.using(it.module("com.facebook.react:react-android:${versionString}"))
|
||||
.because(
|
||||
"The react-native artifact was deprecated in favor of react-android due to https://github.com/facebook/react-native/issues/35210.")
|
||||
it.substitute(it.module("com.facebook.react:hermes-engine"))
|
||||
.using(it.module("com.facebook.react:hermes-android:${versionString}"))
|
||||
.because(
|
||||
"The hermes-engine artifact was deprecated in favor of hermes-android due to https://github.com/facebook/react-native/issues/35210.")
|
||||
}
|
||||
configuration.resolutionStrategy.force(
|
||||
"com.facebook.react:react-native:${versionString}",
|
||||
"com.facebook.react:hermes-engine:${versionString}",
|
||||
"com.facebook.react:react-android:${versionString}",
|
||||
"com.facebook.react:hermes-android:${versionString}",
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -177,8 +177,8 @@ class DependencyUtilsTest {
|
||||
configureDependencies(project, "1.2.3")
|
||||
|
||||
val forcedModules = project.configurations.first().resolutionStrategy.forcedModules
|
||||
assertTrue(forcedModules.any { it.toString() == "com.facebook.react:react-native:1.2.3" })
|
||||
assertTrue(forcedModules.any { it.toString() == "com.facebook.react:hermes-engine:1.2.3" })
|
||||
assertTrue(forcedModules.any { it.toString() == "com.facebook.react:react-android:1.2.3" })
|
||||
assertTrue(forcedModules.any { it.toString() == "com.facebook.react:hermes-android:1.2.3" })
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
load("@fbsource//tools/build_defs:glob_defs.bzl", "subdir_glob")
|
||||
load("@fbsource//xplat/hermes/defs:hermes.bzl", "HERMES_BYTECODE_VERSION")
|
||||
load("//tools/build_defs:fb_native_wrapper.bzl", "fb_native")
|
||||
load("//tools/build_defs:fb_xplat_platform_specific_rule.bzl", "fb_xplat_platform_specific_rule")
|
||||
@@ -10,6 +11,7 @@ load("//tools/build_defs/apple:flag_defs.bzl", "get_objc_arc_preprocessor_flags"
|
||||
load("//tools/build_defs/oss:metro_defs.bzl", "rn_library")
|
||||
load(
|
||||
"//tools/build_defs/oss:rn_defs.bzl",
|
||||
"ANDROID",
|
||||
"APPLE",
|
||||
"YOGA_APPLE_TARGET",
|
||||
"js_library_glob",
|
||||
@@ -49,6 +51,7 @@ rn_library(
|
||||
srcs = js_library_glob(
|
||||
[
|
||||
"js",
|
||||
"NativeCxxModuleExample",
|
||||
"NativeModuleExample",
|
||||
"NativeComponentExample",
|
||||
"RCTTest",
|
||||
@@ -61,10 +64,13 @@ rn_library(
|
||||
],
|
||||
),
|
||||
codegen_components = True,
|
||||
codegen_modules = True,
|
||||
labels = [
|
||||
"pfh:ReactNative_CommonInfrastructurePlaceholder",
|
||||
],
|
||||
native_component_spec_name = "AppSpecs",
|
||||
native_module_android_package_name = "com.facebook.fbreact.specs",
|
||||
native_module_spec_name = "AppSpecs",
|
||||
skip_processors = True,
|
||||
visibility = ["PUBLIC"],
|
||||
deps = [
|
||||
@@ -319,3 +325,24 @@ rn_xplat_cxx_library2(
|
||||
"//xplat/js/react-native-github:RCTFabricComponentViewsBase",
|
||||
],
|
||||
)
|
||||
|
||||
rn_xplat_cxx_library2(
|
||||
name = "NativeCxxModuleExample",
|
||||
srcs = glob(["NativeCxxModuleExample/*.cpp"]),
|
||||
header_namespace = "",
|
||||
exported_headers = subdir_glob(
|
||||
[
|
||||
("NativeCxxModuleExample", "*.h"),
|
||||
],
|
||||
prefix = "NativeCxxModuleExample",
|
||||
),
|
||||
fbandroid_compiler_flags = [
|
||||
"-fexceptions",
|
||||
"-frtti",
|
||||
],
|
||||
platforms = (ANDROID, APPLE),
|
||||
visibility = ["PUBLIC"],
|
||||
deps = [
|
||||
":AppSpecsJSI",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
# 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.
|
||||
|
||||
cmake_minimum_required(VERSION 3.13)
|
||||
set(CMAKE_VERBOSE_MAKEFILE on)
|
||||
|
||||
add_compile_options(
|
||||
-fexceptions
|
||||
-frtti
|
||||
-std=c++17
|
||||
-Wall
|
||||
-Wpedantic
|
||||
-Wno-gnu-zero-variadic-macro-arguments
|
||||
-DFOLLY_NO_CONFIG=1
|
||||
-DLOG_TAG=\"ReactNative\")
|
||||
|
||||
file(GLOB nativecxxmoduleexample_SRC CONFIGURE_DEPENDS *.cpp)
|
||||
add_library(nativecxxmoduleexample STATIC ${nativecxxmoduleexample_SRC})
|
||||
|
||||
target_include_directories(nativecxxmoduleexample PUBLIC .)
|
||||
target_include_directories(react_codegen_AppSpecs PUBLIC .)
|
||||
|
||||
target_link_libraries(nativecxxmoduleexample
|
||||
fbjni
|
||||
jsi
|
||||
react_nativemodule_core
|
||||
react_codegen_AppSpecs)
|
||||
@@ -0,0 +1,110 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "NativeCxxModuleExample.h"
|
||||
|
||||
namespace facebook::react {
|
||||
|
||||
NativeCxxModuleExample::NativeCxxModuleExample(
|
||||
std::shared_ptr<CallInvoker> jsInvoker)
|
||||
: NativeCxxModuleExampleCxxSpec(std::move(jsInvoker)) {}
|
||||
|
||||
void NativeCxxModuleExample::getValueWithCallback(
|
||||
jsi::Runtime &rt,
|
||||
AsyncCallback<std::string> callback) {
|
||||
callback({"value from callback!"});
|
||||
}
|
||||
|
||||
std::vector<std::optional<ObjectStruct>> NativeCxxModuleExample::getArray(
|
||||
jsi::Runtime &rt,
|
||||
std::vector<std::optional<ObjectStruct>> arg) {
|
||||
return arg;
|
||||
}
|
||||
|
||||
bool NativeCxxModuleExample::getBool(jsi::Runtime &rt, bool arg) {
|
||||
return arg;
|
||||
}
|
||||
|
||||
ConstantsStruct NativeCxxModuleExample::getConstants(jsi::Runtime &rt) {
|
||||
return ConstantsStruct{true, 69, "react-native"};
|
||||
}
|
||||
|
||||
int32_t NativeCxxModuleExample::getEnum(jsi::Runtime &rt, int32_t arg) {
|
||||
return arg;
|
||||
}
|
||||
|
||||
std::map<std::string, std::optional<int32_t>> NativeCxxModuleExample::getMap(
|
||||
jsi::Runtime &rt,
|
||||
std::map<std::string, std::optional<int32_t>> arg) {
|
||||
return arg;
|
||||
}
|
||||
|
||||
double NativeCxxModuleExample::getNumber(jsi::Runtime &rt, double arg) {
|
||||
return arg;
|
||||
}
|
||||
|
||||
ObjectStruct NativeCxxModuleExample::getObject(
|
||||
jsi::Runtime &rt,
|
||||
ObjectStruct arg) {
|
||||
return arg;
|
||||
}
|
||||
|
||||
std::set<float> NativeCxxModuleExample::getSet(
|
||||
jsi::Runtime &rt,
|
||||
std::set<float> arg) {
|
||||
return arg;
|
||||
}
|
||||
|
||||
std::string NativeCxxModuleExample::getString(
|
||||
jsi::Runtime &rt,
|
||||
std::string arg) {
|
||||
return arg;
|
||||
}
|
||||
|
||||
std::string NativeCxxModuleExample::getUnion(
|
||||
jsi::Runtime &rt,
|
||||
float x,
|
||||
std::string y,
|
||||
jsi::Object z) {
|
||||
std::string result = "x: " + std::to_string(x) + ", y: " + y + ", z: { ";
|
||||
if (z.hasProperty(rt, "value")) {
|
||||
result += "value: ";
|
||||
result += std::to_string(z.getProperty(rt, "value").getNumber());
|
||||
} else if (z.hasProperty(rt, "low")) {
|
||||
result += "low: ";
|
||||
result += z.getProperty(rt, "low").getString(rt).utf8(rt);
|
||||
}
|
||||
result += " }";
|
||||
return result;
|
||||
}
|
||||
|
||||
ValueStruct NativeCxxModuleExample::getValue(
|
||||
jsi::Runtime &rt,
|
||||
double x,
|
||||
std::string y,
|
||||
ObjectStruct z) {
|
||||
ValueStruct result{x, y, z};
|
||||
return result;
|
||||
}
|
||||
|
||||
AsyncPromise<std::string> NativeCxxModuleExample::getValueWithPromise(
|
||||
jsi::Runtime &rt,
|
||||
bool error) {
|
||||
auto promise = AsyncPromise<std::string>(rt, jsInvoker_);
|
||||
if (error) {
|
||||
promise.reject("intentional promise rejection");
|
||||
} else {
|
||||
promise.resolve("result!");
|
||||
}
|
||||
return promise;
|
||||
}
|
||||
|
||||
void NativeCxxModuleExample::voidFunc(jsi::Runtime &rt) {
|
||||
// Nothing to do
|
||||
}
|
||||
|
||||
} // namespace facebook::react
|
||||
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#if __has_include(<React-Codegen/AppSpecsJSI.h>) // CocoaPod headers on Apple
|
||||
#include <React-Codegen/AppSpecsJSI.h>
|
||||
#elif __has_include("AppSpecsJSI.h") // Cmake headers on Android
|
||||
#include "AppSpecsJSI.h"
|
||||
#else // BUCK headers
|
||||
#include <AppSpecs/AppSpecsJSI.h>
|
||||
#endif
|
||||
#include <memory>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace facebook::react {
|
||||
|
||||
#pragma mark - Structs
|
||||
using ConstantsStruct =
|
||||
NativeCxxModuleExampleCxxBaseConstantsStruct<bool, int32_t, std::string>;
|
||||
|
||||
template <>
|
||||
struct Bridging<ConstantsStruct>
|
||||
: NativeCxxModuleExampleCxxBaseConstantsStructBridging<
|
||||
bool,
|
||||
int32_t,
|
||||
std::string> {};
|
||||
|
||||
using ObjectStruct = NativeCxxModuleExampleCxxBaseObjectStruct<
|
||||
int32_t,
|
||||
std::string,
|
||||
std::optional<std::string>>;
|
||||
|
||||
template <>
|
||||
struct Bridging<ObjectStruct>
|
||||
: NativeCxxModuleExampleCxxBaseObjectStructBridging<
|
||||
int32_t,
|
||||
std::string,
|
||||
std::optional<std::string>> {};
|
||||
|
||||
using ValueStruct =
|
||||
NativeCxxModuleExampleCxxBaseValueStruct<double, std::string, ObjectStruct>;
|
||||
|
||||
template <>
|
||||
struct Bridging<ValueStruct> : NativeCxxModuleExampleCxxBaseValueStructBridging<
|
||||
double,
|
||||
std::string,
|
||||
ObjectStruct> {};
|
||||
|
||||
#pragma mark - implementation
|
||||
class NativeCxxModuleExample
|
||||
: public NativeCxxModuleExampleCxxSpec<NativeCxxModuleExample> {
|
||||
public:
|
||||
NativeCxxModuleExample(std::shared_ptr<CallInvoker> jsInvoker);
|
||||
|
||||
void getValueWithCallback(
|
||||
jsi::Runtime &rt,
|
||||
AsyncCallback<std::string> callback);
|
||||
|
||||
std::vector<std::optional<ObjectStruct>> getArray(
|
||||
jsi::Runtime &rt,
|
||||
std::vector<std::optional<ObjectStruct>> arg);
|
||||
|
||||
bool getBool(jsi::Runtime &rt, bool arg);
|
||||
|
||||
ConstantsStruct getConstants(jsi::Runtime &rt);
|
||||
|
||||
int32_t getEnum(jsi::Runtime &rt, int32_t arg);
|
||||
|
||||
std::map<std::string, std::optional<int32_t>> getMap(
|
||||
jsi::Runtime &rt,
|
||||
std::map<std::string, std::optional<int32_t>> arg);
|
||||
|
||||
double getNumber(jsi::Runtime &rt, double arg);
|
||||
|
||||
ObjectStruct getObject(jsi::Runtime &rt, ObjectStruct arg);
|
||||
|
||||
std::set<float> getSet(jsi::Runtime &rt, std::set<float> arg);
|
||||
|
||||
std::string getString(jsi::Runtime &rt, std::string arg);
|
||||
|
||||
std::string getUnion(jsi::Runtime &rt, float x, std::string y, jsi::Object z);
|
||||
|
||||
ValueStruct
|
||||
getValue(jsi::Runtime &rt, double x, std::string y, ObjectStruct z);
|
||||
|
||||
AsyncPromise<std::string> getValueWithPromise(jsi::Runtime &rt, bool error);
|
||||
|
||||
void voidFunc(jsi::Runtime &rt);
|
||||
};
|
||||
|
||||
} // namespace facebook::react
|
||||
@@ -0,0 +1,64 @@
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
* @flow strict-local
|
||||
* @format
|
||||
*/
|
||||
|
||||
import type {TurboModule} from 'react-native/Libraries/TurboModule/RCTExport';
|
||||
|
||||
import {TurboModuleRegistry} from 'react-native';
|
||||
|
||||
/** FIXME: Enable flow-enum support
|
||||
export enum EnumInt {
|
||||
A = 23,
|
||||
B = 42,
|
||||
}
|
||||
*/
|
||||
|
||||
export type UnionFloat = 1.44 | 2.88 | 5.76;
|
||||
export type UnionString = 'One' | 'Two' | 'Three';
|
||||
export type UnionObject = {value: number} | {low: string};
|
||||
|
||||
export type ConstantsStruct = {|
|
||||
const1: boolean,
|
||||
const2: number,
|
||||
const3: string,
|
||||
|};
|
||||
|
||||
export type ObjectStruct = {|
|
||||
a: number,
|
||||
b: string,
|
||||
c?: ?string,
|
||||
|};
|
||||
|
||||
export type ValueStruct = {|
|
||||
x: number,
|
||||
y: string,
|
||||
z: ObjectStruct,
|
||||
|};
|
||||
|
||||
export interface Spec extends TurboModule {
|
||||
+getArray: (arg: Array<ObjectStruct | null>) => Array<ObjectStruct | null>;
|
||||
+getBool: (arg: boolean) => boolean;
|
||||
+getConstants: () => ConstantsStruct;
|
||||
// FIXME: Enable flow-enum support
|
||||
+getEnum: (arg: number /*EnumInt*/) => number /*EnumInt*/;
|
||||
+getMap: (arg: {[key: string]: ?number}) => {[key: string]: ?number};
|
||||
+getNumber: (arg: number) => number;
|
||||
+getObject: (arg: ObjectStruct) => ObjectStruct;
|
||||
+getSet: (arg: Array<number>) => Array<number>;
|
||||
+getString: (arg: string) => string;
|
||||
+getUnion: (x: UnionFloat, y: UnionString, z: UnionObject) => string;
|
||||
+getValue: (x: number, y: string, z: ObjectStruct) => ValueStruct;
|
||||
+getValueWithCallback: (callback: (value: string) => void) => void;
|
||||
+getValueWithPromise: (error: boolean) => Promise<string>;
|
||||
+voidFunc: () => void;
|
||||
}
|
||||
|
||||
export default (TurboModuleRegistry.get<Spec>(
|
||||
'NativeCxxModuleExampleCxx',
|
||||
): ?Spec);
|
||||
@@ -0,0 +1,31 @@
|
||||
# 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.
|
||||
|
||||
require "json"
|
||||
|
||||
package = JSON.parse(File.read(File.join(__dir__, "../package.json")))
|
||||
|
||||
Pod::Spec.new do |s|
|
||||
s.name = "NativeCxxModuleExample"
|
||||
s.version = package["version"]
|
||||
s.summary = package["description"]
|
||||
s.description = "NativeCxxModuleExample"
|
||||
s.homepage = "https://github.com/facebook/react-native.git"
|
||||
s.license = "MIT"
|
||||
s.platforms = { :ios => "12.4" }
|
||||
s.compiler_flags = '-Wno-nullability-completeness'
|
||||
s.author = "Meta Platforms, Inc. and its affiliates"
|
||||
s.source = { :git => "https://github.com/facebook/react-native.git", :tag => "#{s.version}" }
|
||||
s.source_files = "**/*.{h,cpp}"
|
||||
s.requires_arc = true
|
||||
s.pod_target_xcconfig = {
|
||||
"USE_HEADERMAP" => "YES",
|
||||
"CLANG_CXX_LANGUAGE_STANDARD" => "c++17"
|
||||
}
|
||||
|
||||
install_modules_dependencies(s)
|
||||
|
||||
s.dependency "ReactCommon/turbomodule/core"
|
||||
end
|
||||
@@ -48,6 +48,9 @@ def pods(target_name, options = {}, use_flipper: !IN_CI && !USE_FRAMEWORKS)
|
||||
|
||||
# RNTester native modules and components
|
||||
pod 'ScreenshotManager', :path => "NativeModuleExample"
|
||||
if ENV['RCT_NEW_ARCH_ENABLED'] == '1'
|
||||
pod 'NativeCxxModuleExample', :path => "NativeCxxModuleExample"
|
||||
end
|
||||
end
|
||||
|
||||
target 'RNTester' do
|
||||
|
||||
+601
-569
File diff suppressed because it is too large
Load Diff
@@ -7,6 +7,9 @@
|
||||
|
||||
#import "RNTesterTurboModuleProvider.h"
|
||||
|
||||
#ifdef RCT_NEW_ARCH_ENABLED
|
||||
#import <NativeCxxModuleExample/NativeCxxModuleExample.h>
|
||||
#endif
|
||||
#import <React/CoreModulesPlugins.h>
|
||||
#import <ReactCommon/RCTSampleTurboModule.h>
|
||||
#import <ReactCommon/SampleTurboCxxModule.h>
|
||||
@@ -28,7 +31,11 @@ std::shared_ptr<TurboModule> RNTesterTurboModuleProvider(
|
||||
if (name == "SampleTurboCxxModule") {
|
||||
return std::make_shared<SampleTurboCxxModule>(jsInvoker);
|
||||
}
|
||||
|
||||
#ifdef RCT_NEW_ARCH_ENABLED
|
||||
if (name == "NativeCxxModuleExampleCxx") {
|
||||
return std::make_shared<NativeCxxModuleExample>(jsInvoker);
|
||||
}
|
||||
#endif
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
@@ -86,8 +86,8 @@ def reactNativeArchitectures() {
|
||||
}
|
||||
|
||||
android {
|
||||
buildToolsVersion = "31.0.0"
|
||||
compileSdkVersion 31
|
||||
buildToolsVersion = "33.0.0"
|
||||
compileSdkVersion 33
|
||||
namespace "com.facebook.react.uiapp"
|
||||
|
||||
// Used to override the NDK path/version on internal CI or by allowing
|
||||
@@ -114,7 +114,7 @@ android {
|
||||
defaultConfig {
|
||||
applicationId "com.facebook.react.uiapp"
|
||||
minSdkVersion 21
|
||||
targetSdkVersion 31
|
||||
targetSdkVersion 33
|
||||
versionCode 1
|
||||
versionName "1.0"
|
||||
testBuildType System.getProperty('testBuildType', 'debug') // This will later be used to control the test apk build type
|
||||
|
||||
@@ -11,7 +11,11 @@ project(appmodules)
|
||||
include(${REACT_ANDROID_DIR}/cmake-utils/ReactNative-application.cmake)
|
||||
|
||||
add_subdirectory(${REACT_COMMON_DIR}/react/nativemodule/samples/platform/android/ sampleturbomodule_build)
|
||||
add_subdirectory(${REACT_COMMON_DIR}/../packages/rn-tester/NativeCxxModuleExample/ nativecxxmoduleexample_build)
|
||||
|
||||
# RN Tester needs to link against the sample turbomobule
|
||||
target_link_libraries(${CMAKE_PROJECT_NAME}
|
||||
sampleturbomodule)
|
||||
# RN Tester needs to link against the NativeCxxModuleExample
|
||||
target_link_libraries(${CMAKE_PROJECT_NAME}
|
||||
nativecxxmoduleexample)
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include <AppSpecs.h>
|
||||
#include <DefaultComponentsRegistry.h>
|
||||
#include <DefaultTurboModuleManagerDelegate.h>
|
||||
#include <NativeCxxModuleExample.h>
|
||||
#include <ReactCommon/SampleTurboModuleSpec.h>
|
||||
#include <fbjni/fbjni.h>
|
||||
#include <react/renderer/componentregistry/ComponentDescriptorProviderRegistry.h>
|
||||
@@ -23,7 +24,16 @@ void registerComponents(
|
||||
RNTMyNativeViewComponentDescriptor>());
|
||||
}
|
||||
|
||||
std::shared_ptr<TurboModule> provideModules(
|
||||
std::shared_ptr<TurboModule> cxxModuleProvider(
|
||||
const std::string &name,
|
||||
const std::shared_ptr<CallInvoker> &jsInvoker) {
|
||||
if (name == "NativeCxxModuleExampleCxx") {
|
||||
return std::make_shared<NativeCxxModuleExample>(jsInvoker);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::shared_ptr<TurboModule> javaModuleProvider(
|
||||
const std::string &name,
|
||||
const JavaTurboModule::InitParams ¶ms) {
|
||||
auto module = AppSpecs_ModuleProvider(name, params);
|
||||
@@ -42,8 +52,10 @@ std::shared_ptr<TurboModule> provideModules(
|
||||
|
||||
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *) {
|
||||
return facebook::jni::initialize(vm, [] {
|
||||
facebook::react::DefaultTurboModuleManagerDelegate::
|
||||
moduleProvidersFromEntryPoint = &facebook::react::provideModules;
|
||||
facebook::react::DefaultTurboModuleManagerDelegate::cxxModuleProvider =
|
||||
&facebook::react::cxxModuleProvider;
|
||||
facebook::react::DefaultTurboModuleManagerDelegate::javaModuleProvider =
|
||||
&facebook::react::javaModuleProvider;
|
||||
facebook::react::DefaultComponentsRegistry::
|
||||
registerComponentDescriptorsFromEntryPoint =
|
||||
&facebook::react::registerComponents;
|
||||
|
||||
@@ -1283,4 +1283,49 @@ exports.examples = [
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'Dynamic Type (iOS only)',
|
||||
render: function (): React.Node {
|
||||
const boldStyle = {fontWeight: 'bold'};
|
||||
const boxStyle = {
|
||||
borderWidth: 1,
|
||||
padding: 8,
|
||||
margin: 8,
|
||||
};
|
||||
return (
|
||||
<View style={{marginTop: 10, marginBottom: 10}}>
|
||||
<Text>
|
||||
Adjust text size in Accessibility settings and watch how the font
|
||||
sizes change relative to each other.
|
||||
</Text>
|
||||
<View style={boxStyle}>
|
||||
<Text style={boldStyle}>With `dynamicTypeRamp`:</Text>
|
||||
<Text style={{fontSize: 34}} dynamicTypeRamp="largeTitle">
|
||||
Large Title
|
||||
</Text>
|
||||
<Text style={{fontSize: 28}} dynamicTypeRamp="title1">
|
||||
Title
|
||||
</Text>
|
||||
<Text style={{fontSize: 22}} dynamicTypeRamp="title2">
|
||||
Title 2
|
||||
</Text>
|
||||
<Text style={{fontSize: 20}} dynamicTypeRamp="title3">
|
||||
Title 3
|
||||
</Text>
|
||||
<Text style={{fontSize: 17}} dynamicTypeRamp="body">
|
||||
Body
|
||||
</Text>
|
||||
</View>
|
||||
<View style={boxStyle}>
|
||||
<Text style={boldStyle}>Without `dynamicTypeRamp`:</Text>
|
||||
<Text style={{fontSize: 34}}>Large Title</Text>
|
||||
<Text style={{fontSize: 28}}>Title</Text>
|
||||
<Text style={{fontSize: 22}}>Title 2</Text>
|
||||
<Text style={{fontSize: 20}}>Title 3</Text>
|
||||
<Text style={{fontSize: 17}}>Body</Text>
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
@@ -0,0 +1,222 @@
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
* @format
|
||||
* @flow strict-local
|
||||
*/
|
||||
|
||||
import type {RootTag} from 'react-native/Libraries/ReactNative/RootTag';
|
||||
|
||||
import {
|
||||
StyleSheet,
|
||||
Text,
|
||||
View,
|
||||
FlatList,
|
||||
Platform,
|
||||
TouchableOpacity,
|
||||
RootTagContext,
|
||||
} from 'react-native';
|
||||
import * as React from 'react';
|
||||
import NativeCxxModuleExample /*EnumInt,*/ from '../../../NativeCxxModuleExample/NativeCxxModuleExample';
|
||||
|
||||
type State = {|
|
||||
testResults: {
|
||||
[string]: {
|
||||
type: string,
|
||||
value: mixed,
|
||||
...
|
||||
},
|
||||
...
|
||||
},
|
||||
|};
|
||||
|
||||
type Examples =
|
||||
| 'callback'
|
||||
| 'getArray'
|
||||
| 'getBool'
|
||||
| 'getConstants'
|
||||
| 'getEnum'
|
||||
| 'getMap'
|
||||
| 'getNumber'
|
||||
| 'getObject'
|
||||
| 'getSet'
|
||||
| 'getString'
|
||||
| 'getUnion'
|
||||
| 'getValue'
|
||||
| 'promise'
|
||||
| 'rejectPromise'
|
||||
| 'voidFunc';
|
||||
|
||||
class NativeCxxModuleExampleExample extends React.Component<{||}, State> {
|
||||
static contextType: React$Context<RootTag> = RootTagContext;
|
||||
|
||||
state: State = {
|
||||
testResults: {},
|
||||
};
|
||||
|
||||
// Add calls to methods in TurboModule here
|
||||
// $FlowFixMe[missing-local-annot]
|
||||
_tests = {
|
||||
callback: () =>
|
||||
NativeCxxModuleExample?.getValueWithCallback(callbackValue =>
|
||||
this._setResult('callback', callbackValue),
|
||||
),
|
||||
getArray: () =>
|
||||
NativeCxxModuleExample?.getArray([
|
||||
{a: 1, b: 'foo'},
|
||||
{a: 2, b: 'bar'},
|
||||
null,
|
||||
]),
|
||||
getBool: () => NativeCxxModuleExample?.getBool(true),
|
||||
getConstants: () => NativeCxxModuleExample?.getConstants(),
|
||||
getEnum: () => NativeCxxModuleExample?.getEnum(/*EnumInt.A*/ 2),
|
||||
getMap: () => NativeCxxModuleExample?.getMap({a: 1, b: null, c: 3}),
|
||||
getNumber: () => NativeCxxModuleExample?.getNumber(99.95),
|
||||
getObject: () =>
|
||||
NativeCxxModuleExample?.getObject({a: 1, b: 'foo', c: null}),
|
||||
getSet: () => NativeCxxModuleExample?.getSet([1, 1.1, 1.1, 1.1, 2]),
|
||||
getString: () => NativeCxxModuleExample?.getString('Hello'),
|
||||
getUnion: () => NativeCxxModuleExample?.getUnion(1.44, 'Two', {low: '12'}),
|
||||
getValue: () =>
|
||||
NativeCxxModuleExample?.getValue(5, 'test', {a: 1, b: 'foo'}),
|
||||
promise: () =>
|
||||
NativeCxxModuleExample?.getValueWithPromise(false).then(valuePromise =>
|
||||
this._setResult('promise', valuePromise),
|
||||
),
|
||||
rejectPromise: () =>
|
||||
NativeCxxModuleExample?.getValueWithPromise(true)
|
||||
.then(() => {})
|
||||
.catch(e => this._setResult('rejectPromise', e.message)),
|
||||
voidFunc: () => NativeCxxModuleExample?.voidFunc(),
|
||||
};
|
||||
|
||||
_setResult(
|
||||
name: string | Examples,
|
||||
result:
|
||||
| $FlowFixMe
|
||||
| void
|
||||
| Array<$FlowFixMe>
|
||||
| boolean
|
||||
| {const1: boolean, const2: number, const3: string}
|
||||
| number
|
||||
| {[key: string]: ?number}
|
||||
| Promise<mixed>
|
||||
| number
|
||||
| string,
|
||||
) {
|
||||
this.setState(({testResults}) => ({
|
||||
testResults: {
|
||||
...testResults,
|
||||
/* $FlowFixMe[invalid-computed-prop] (>=0.111.0 site=react_native_fb)
|
||||
* This comment suppresses an error found when Flow v0.111 was
|
||||
* deployed. To see the error, delete this comment and run Flow. */
|
||||
[name]: {value: result, type: typeof result},
|
||||
},
|
||||
}));
|
||||
}
|
||||
|
||||
_renderResult(name: Examples): React.Node {
|
||||
const result = this.state.testResults[name] || {};
|
||||
return (
|
||||
<View style={styles.result}>
|
||||
<Text style={[styles.value]}>{JSON.stringify(result.value)}</Text>
|
||||
<Text style={[styles.type]}>{result.type}</Text>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
componentDidMount(): void {
|
||||
if (global.__turboModuleProxy == null) {
|
||||
throw new Error(
|
||||
'Cannot load this example because TurboModule is not configured.',
|
||||
);
|
||||
}
|
||||
Object.keys(this._tests).forEach(item =>
|
||||
this._setResult(item, this._tests[item]()),
|
||||
);
|
||||
}
|
||||
|
||||
render(): React.Node {
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<View style={styles.item}>
|
||||
<TouchableOpacity
|
||||
style={[styles.column, styles.button]}
|
||||
onPress={() =>
|
||||
Object.keys(this._tests).forEach(item =>
|
||||
this._setResult(item, this._tests[item]()),
|
||||
)
|
||||
}>
|
||||
<Text style={styles.buttonTextLarge}>Run all tests</Text>
|
||||
</TouchableOpacity>
|
||||
<TouchableOpacity
|
||||
onPress={() => this.setState({testResults: {}})}
|
||||
style={[styles.column, styles.button]}>
|
||||
<Text style={styles.buttonTextLarge}>Clear results</Text>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
<FlatList
|
||||
data={Object.keys(this._tests)}
|
||||
keyExtractor={item => item}
|
||||
renderItem={({item}) => (
|
||||
<View style={styles.item}>
|
||||
<TouchableOpacity
|
||||
style={[styles.column, styles.button]}
|
||||
onPress={e => this._setResult(item, this._tests[item]())}>
|
||||
<Text style={styles.buttonText}>{item}</Text>
|
||||
</TouchableOpacity>
|
||||
<View style={[styles.column]}>{this._renderResult(item)}</View>
|
||||
</View>
|
||||
)}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
},
|
||||
item: {
|
||||
flexDirection: 'row',
|
||||
margin: 6,
|
||||
},
|
||||
column: {
|
||||
flex: 2,
|
||||
justifyContent: 'center',
|
||||
padding: 3,
|
||||
},
|
||||
result: {
|
||||
alignItems: 'stretch',
|
||||
justifyContent: 'space-between',
|
||||
},
|
||||
value: {
|
||||
fontFamily: Platform.OS === 'ios' ? 'Menlo' : 'monospace',
|
||||
fontSize: 12,
|
||||
},
|
||||
type: {
|
||||
color: '#333',
|
||||
fontSize: 10,
|
||||
},
|
||||
button: {
|
||||
borderColor: '#444',
|
||||
padding: 3,
|
||||
flex: 1,
|
||||
},
|
||||
buttonTextLarge: {
|
||||
textAlign: 'center',
|
||||
color: 'rgb(0,122,255)',
|
||||
fontSize: 16,
|
||||
padding: 6,
|
||||
},
|
||||
buttonText: {
|
||||
color: 'rgb(0,122,255)',
|
||||
textAlign: 'center',
|
||||
},
|
||||
});
|
||||
|
||||
module.exports = NativeCxxModuleExampleExample;
|
||||
@@ -0,0 +1,27 @@
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
* @format
|
||||
* @flow
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
const React = require('react');
|
||||
const NativeCxxModuleExampleExample = require('./NativeCxxModuleExampleExample');
|
||||
|
||||
exports.displayName = (undefined: ?string);
|
||||
exports.title = 'Cxx TurboModule';
|
||||
exports.category = 'Basic';
|
||||
exports.description = 'Usage of Cxx TurboModule';
|
||||
exports.examples = [
|
||||
{
|
||||
title: 'TurboCxxModuleExample',
|
||||
render: function (): React.Element<any> {
|
||||
return <NativeCxxModuleExampleExample />;
|
||||
},
|
||||
},
|
||||
];
|
||||
@@ -284,6 +284,11 @@ const APIs: Array<RNTesterModuleInfo> = [
|
||||
category: 'Basic',
|
||||
module: require('../examples/TurboModule/TurboModuleExample'),
|
||||
},
|
||||
{
|
||||
key: 'TurboCxxModuleExample',
|
||||
category: 'Basic',
|
||||
module: require('../examples/TurboModule/TurboCxxModuleExample'),
|
||||
},
|
||||
];
|
||||
|
||||
if (ReactNativeFeatureFlags.shouldEmitW3CPointerEvents()) {
|
||||
|
||||
@@ -311,6 +311,10 @@ const APIs: Array<RNTesterModuleInfo> = [
|
||||
module: require('../examples/TurboModule/TurboModuleExample'),
|
||||
supportsTVOS: false,
|
||||
},
|
||||
{
|
||||
key: 'TurboCxxModuleExample',
|
||||
module: require('../examples/TurboModule/TurboCxxModuleExample'),
|
||||
},
|
||||
{
|
||||
key: 'VibrationExample',
|
||||
module: require('../examples/Vibration/VibrationExample'),
|
||||
|
||||
@@ -29,8 +29,5 @@ module.exports = {
|
||||
ios: {
|
||||
sourceDir: '.',
|
||||
},
|
||||
android: {
|
||||
sourceDir: '.',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
@@ -14,8 +14,9 @@
|
||||
"@babel/generator": "^7.14.0",
|
||||
"@babel/plugin-transform-regenerator": "^7.0.0",
|
||||
"@definitelytyped/dtslint": "^0.0.127",
|
||||
"@react-native-community/eslint-config": "*",
|
||||
"@react-native-community/eslint-plugin": "*",
|
||||
"@react-native/eslint-plugin-specs": "^0.71.0",
|
||||
"@react-native/eslint-plugin-specs": "^0.71.1",
|
||||
"@reactions/component": "^2.0.2",
|
||||
"@types/react": "^18.0.18",
|
||||
"@typescript-eslint/parser": "^5.30.5",
|
||||
@@ -46,7 +47,7 @@
|
||||
"mkdirp": "^0.5.1",
|
||||
"prettier": "^2.4.1",
|
||||
"react": "18.2.0",
|
||||
"react-native-codegen": "^0.71.1",
|
||||
"react-native-codegen": "^0.71.3",
|
||||
"react-test-renderer": "18.2.0",
|
||||
"shelljs": "^0.8.5",
|
||||
"signedsource": "^1.0.0",
|
||||
|
||||
+3
-3
@@ -4,15 +4,15 @@
|
||||
|
||||
## ANDROID ##
|
||||
# Android SDK Build Tools revision
|
||||
export ANDROID_SDK_BUILD_TOOLS_REVISION=31.0.0
|
||||
export ANDROID_SDK_BUILD_TOOLS_REVISION=33.0.0
|
||||
# Android API Level we build with
|
||||
export ANDROID_SDK_BUILD_API_LEVEL="31"
|
||||
export ANDROID_SDK_BUILD_API_LEVEL="33"
|
||||
# Google APIs for Android level
|
||||
export ANDROID_GOOGLE_API_LEVEL="23"
|
||||
# Minimum Android API SDK Level we target
|
||||
export ANDROID_SDK_MINIMUM_API_LEVEL="21"
|
||||
# Target API SDK level to build for
|
||||
export ANDROID_SDK_TARGET_API_LEVEL="31"
|
||||
export ANDROID_SDK_TARGET_API_LEVEL="33"
|
||||
# Android Image SDK level to install on the emulator
|
||||
export ANDROID_SYSTEM_IMAGE_API_LEVEL="21"
|
||||
|
||||
|
||||
@@ -7,7 +7,11 @@
|
||||
* @format
|
||||
*/
|
||||
|
||||
const {parseVersion, isReleaseBranch} = require('../version-utils');
|
||||
const {
|
||||
parseVersion,
|
||||
isReleaseBranch,
|
||||
validateBuildType,
|
||||
} = require('../version-utils');
|
||||
|
||||
let execResult = null;
|
||||
jest.mock('shelljs', () => ({
|
||||
@@ -38,18 +42,53 @@ describe('version-utils', () => {
|
||||
});
|
||||
|
||||
describe('parseVersion', () => {
|
||||
it('should throw error if invalid match', () => {
|
||||
it('should throw error if buildType is undefined', () => {
|
||||
function testInvalidVersion() {
|
||||
parseVersion('<invalid version>');
|
||||
parseVersion('v0.10.5');
|
||||
}
|
||||
expect(testInvalidVersion).toThrowErrorMatchingInlineSnapshot(
|
||||
`"Unsupported build type: undefined"`,
|
||||
);
|
||||
});
|
||||
|
||||
it('should throw error if buildType is not `release`, `dry-run` or `nightly`', () => {
|
||||
function testInvalidVersion() {
|
||||
parseVersion('v0.10.5', 'invalid_build_type');
|
||||
}
|
||||
expect(testInvalidVersion).toThrowErrorMatchingInlineSnapshot(
|
||||
`"Unsupported build type: invalid_build_type"`,
|
||||
);
|
||||
});
|
||||
it('should throw error if invalid match with release', () => {
|
||||
function testInvalidVersion() {
|
||||
parseVersion('<invalid version>', 'release');
|
||||
}
|
||||
expect(testInvalidVersion).toThrowErrorMatchingInlineSnapshot(
|
||||
`"You must pass a correctly formatted version; couldn't parse <invalid version>"`,
|
||||
);
|
||||
});
|
||||
it('should throw error if invalid match with dry-run', () => {
|
||||
function testInvalidVersion() {
|
||||
parseVersion('<invalid version>', 'dry-run');
|
||||
}
|
||||
expect(testInvalidVersion).toThrowErrorMatchingInlineSnapshot(
|
||||
`"You must pass a correctly formatted version; couldn't parse <invalid version>"`,
|
||||
);
|
||||
});
|
||||
it('should throw error if invalid match with nightly', () => {
|
||||
function testInvalidVersion() {
|
||||
parseVersion('<invalid version>', 'nightly');
|
||||
}
|
||||
expect(testInvalidVersion).toThrowErrorMatchingInlineSnapshot(
|
||||
`"You must pass a correctly formatted version; couldn't parse <invalid version>"`,
|
||||
);
|
||||
});
|
||||
|
||||
it('should parse pre-release version with .', () => {
|
||||
const {version, major, minor, patch, prerelease} =
|
||||
parseVersion('0.66.0-rc.4');
|
||||
it('should parse pre-release version with release and `.`', () => {
|
||||
const {version, major, minor, patch, prerelease} = parseVersion(
|
||||
'0.66.0-rc.4',
|
||||
'release',
|
||||
);
|
||||
expect(version).toBe('0.66.0-rc.4');
|
||||
expect(major).toBe('0');
|
||||
expect(minor).toBe('66');
|
||||
@@ -57,9 +96,11 @@ describe('version-utils', () => {
|
||||
expect(prerelease).toBe('rc.4');
|
||||
});
|
||||
|
||||
it('should parse pre-release version with -', () => {
|
||||
const {version, major, minor, patch, prerelease} =
|
||||
parseVersion('0.66.0-rc-4');
|
||||
it('should parse pre-release version with release and `-`', () => {
|
||||
const {version, major, minor, patch, prerelease} = parseVersion(
|
||||
'0.66.0-rc-4',
|
||||
'release',
|
||||
);
|
||||
expect(version).toBe('0.66.0-rc-4');
|
||||
expect(major).toBe('0');
|
||||
expect(minor).toBe('66');
|
||||
@@ -67,8 +108,20 @@ describe('version-utils', () => {
|
||||
expect(prerelease).toBe('rc-4');
|
||||
});
|
||||
|
||||
it('should reject pre-release version with random prerelease pattern', () => {
|
||||
function testInvalidVersion() {
|
||||
parseVersion('0.66.0-something_invalid', 'release');
|
||||
}
|
||||
expect(testInvalidVersion).toThrowErrorMatchingInlineSnapshot(
|
||||
`"Version 0.66.0-something_invalid is not valid for Release"`,
|
||||
);
|
||||
});
|
||||
|
||||
it('should parse stable version', () => {
|
||||
const {version, major, minor, patch, prerelease} = parseVersion('0.66.0');
|
||||
const {version, major, minor, patch, prerelease} = parseVersion(
|
||||
'0.66.0',
|
||||
'release',
|
||||
);
|
||||
expect(version).toBe('0.66.0');
|
||||
expect(major).toBe('0');
|
||||
expect(minor).toBe('66');
|
||||
@@ -77,18 +130,40 @@ describe('version-utils', () => {
|
||||
});
|
||||
|
||||
it('should parse pre-release version from tag', () => {
|
||||
const {version, major, minor, patch, prerelease} =
|
||||
parseVersion('v0.66.1-rc.4');
|
||||
expect(version).toBe('0.66.1-rc.4');
|
||||
const {version, major, minor, patch, prerelease} = parseVersion(
|
||||
'v0.66.0-rc.4',
|
||||
'release',
|
||||
);
|
||||
expect(version).toBe('0.66.0-rc.4');
|
||||
expect(major).toBe('0');
|
||||
expect(minor).toBe('66');
|
||||
expect(patch).toBe('1');
|
||||
expect(patch).toBe('0');
|
||||
expect(prerelease).toBe('rc.4');
|
||||
});
|
||||
|
||||
it('should reject pre-release version with patch != 0', () => {
|
||||
function testInvalidVersion() {
|
||||
parseVersion('0.66.3-rc.4', 'release');
|
||||
}
|
||||
expect(testInvalidVersion).toThrowErrorMatchingInlineSnapshot(
|
||||
`"Version 0.66.3-rc.4 is not valid for Release"`,
|
||||
);
|
||||
});
|
||||
|
||||
it('should reject pre-release version from tag with random prerelease pattern', () => {
|
||||
function testInvalidVersion() {
|
||||
parseVersion('v0.66.0-something_invalid', 'release');
|
||||
}
|
||||
expect(testInvalidVersion).toThrowErrorMatchingInlineSnapshot(
|
||||
`"Version 0.66.0-something_invalid is not valid for Release"`,
|
||||
);
|
||||
});
|
||||
|
||||
it('should parse stable version from tag', () => {
|
||||
const {version, major, minor, patch, prerelease} =
|
||||
parseVersion('v0.66.0');
|
||||
const {version, major, minor, patch, prerelease} = parseVersion(
|
||||
'v0.66.0',
|
||||
'release',
|
||||
);
|
||||
expect(version).toBe('0.66.0');
|
||||
expect(major).toBe('0');
|
||||
expect(minor).toBe('66');
|
||||
@@ -96,23 +171,179 @@ describe('version-utils', () => {
|
||||
expect(prerelease).toBeUndefined();
|
||||
});
|
||||
|
||||
it('should parse nightly fake version', () => {
|
||||
const {version, major, minor, patch, prerelease} = parseVersion('0.0.0');
|
||||
expect(version).toBe('0.0.0');
|
||||
it('should reject nightly with no prerelease', () => {
|
||||
// this should fail
|
||||
function testInvalidFunction() {
|
||||
parseVersion('0.0.0', 'nightly');
|
||||
}
|
||||
expect(testInvalidFunction).toThrowErrorMatchingInlineSnapshot(
|
||||
`"Version 0.0.0 is not valid for nightlies"`,
|
||||
);
|
||||
});
|
||||
|
||||
it('should reject nightly with prerelease but wrong version numbers', () => {
|
||||
// this should fail
|
||||
function testInvalidFunction() {
|
||||
parseVersion('1.2.3-pre-release', 'nightly');
|
||||
}
|
||||
expect(testInvalidFunction).toThrowErrorMatchingInlineSnapshot(
|
||||
`"Version 1.2.3-pre-release is not valid for nightlies"`,
|
||||
);
|
||||
});
|
||||
|
||||
it('should parse nightly with 0.0.0 and a prerelease part', () => {
|
||||
// this should fail
|
||||
const {version, major, minor, patch, prerelease} = parseVersion(
|
||||
'0.0.0-pre-release',
|
||||
'nightly',
|
||||
);
|
||||
|
||||
expect(version).toBe('0.0.0-pre-release');
|
||||
expect(major).toBe('0');
|
||||
expect(minor).toBe('0');
|
||||
expect(patch).toBe('0');
|
||||
expect(prerelease).toBe('pre-release');
|
||||
});
|
||||
it('should parse dryrun with release version', () => {
|
||||
const {version, major, minor, patch, prerelease} = parseVersion(
|
||||
'0.7.3',
|
||||
'dry-run',
|
||||
);
|
||||
expect(version).toBe('0.7.3');
|
||||
expect(major).toBe('0');
|
||||
expect(minor).toBe('7');
|
||||
expect(patch).toBe('3');
|
||||
expect(prerelease).toBeUndefined();
|
||||
});
|
||||
|
||||
it('should parse dryrun fake version', () => {
|
||||
const {version, major, minor, patch, prerelease} =
|
||||
parseVersion('1000.0.0');
|
||||
it('should parse dryrun with prerelease . version', () => {
|
||||
const {version, major, minor, patch, prerelease} = parseVersion(
|
||||
'0.20.0-rc.0',
|
||||
'dry-run',
|
||||
);
|
||||
expect(version).toBe('0.20.0-rc.0');
|
||||
expect(major).toBe('0');
|
||||
expect(minor).toBe('20');
|
||||
expect(patch).toBe('0');
|
||||
expect(prerelease).toBe('rc.0');
|
||||
});
|
||||
|
||||
it('should reject dryrun with prerelease . version with patch different from 0', () => {
|
||||
function testInvalidFunction() {
|
||||
parseVersion('0.20.3-rc.0', 'dry-run');
|
||||
}
|
||||
expect(testInvalidFunction).toThrowErrorMatchingInlineSnapshot(
|
||||
`"Version 0.20.3-rc.0 is not valid for dry-runs"`,
|
||||
);
|
||||
});
|
||||
|
||||
it('should parse dryrun with prerelease - version', () => {
|
||||
const {version, major, minor, patch, prerelease} = parseVersion(
|
||||
'0.20.0-rc-0',
|
||||
'dry-run',
|
||||
);
|
||||
expect(version).toBe('0.20.0-rc-0');
|
||||
expect(major).toBe('0');
|
||||
expect(minor).toBe('20');
|
||||
expect(patch).toBe('0');
|
||||
expect(prerelease).toBe('rc-0');
|
||||
});
|
||||
|
||||
it('should reject dryrun with prerelease - version with patch different from 0', () => {
|
||||
function testInvalidFunction() {
|
||||
parseVersion('0.20.3-rc-0', 'dry-run');
|
||||
}
|
||||
expect(testInvalidFunction).toThrowErrorMatchingInlineSnapshot(
|
||||
`"Version 0.20.3-rc-0 is not valid for dry-runs"`,
|
||||
);
|
||||
});
|
||||
|
||||
it('should parse dryrun with main version', () => {
|
||||
const {version, major, minor, patch, prerelease} = parseVersion(
|
||||
'1000.0.0',
|
||||
'dry-run',
|
||||
);
|
||||
expect(version).toBe('1000.0.0');
|
||||
expect(major).toBe('1000');
|
||||
expect(minor).toBe('0');
|
||||
expect(patch).toBe('0');
|
||||
expect(prerelease).toBeUndefined();
|
||||
});
|
||||
|
||||
it('should fail for dryrun with v1000.0.1 version', () => {
|
||||
function testInvalidFunction() {
|
||||
parseVersion('v1000.0.1', 'dry-run');
|
||||
}
|
||||
expect(testInvalidFunction).toThrowErrorMatchingInlineSnapshot(
|
||||
`"Version 1000.0.1 is not valid for dry-runs"`,
|
||||
);
|
||||
});
|
||||
it('should parse dryrun with nightly version', () => {
|
||||
const {version, major, minor, patch, prerelease} = parseVersion(
|
||||
'0.0.0-something-else',
|
||||
'dry-run',
|
||||
);
|
||||
expect(version).toBe('0.0.0-something-else');
|
||||
expect(major).toBe('0');
|
||||
expect(minor).toBe('0');
|
||||
expect(patch).toBe('0');
|
||||
expect(prerelease).toBe('something-else');
|
||||
});
|
||||
|
||||
it('should reject dryrun invalid values', () => {
|
||||
function testInvalidFunction() {
|
||||
parseVersion('1000.0.4', 'dry-run');
|
||||
}
|
||||
expect(testInvalidFunction).toThrowErrorMatchingInlineSnapshot(
|
||||
`"Version 1000.0.4 is not valid for dry-runs"`,
|
||||
);
|
||||
});
|
||||
|
||||
it('should reject dryrun for invalid prerelease', () => {
|
||||
function testInvalidFunction() {
|
||||
parseVersion('0.6.4-something-else', 'dry-run');
|
||||
}
|
||||
expect(testInvalidFunction).toThrowErrorMatchingInlineSnapshot(
|
||||
`"Version 0.6.4-something-else is not valid for dry-runs"`,
|
||||
);
|
||||
});
|
||||
|
||||
it('should reject dryrun for nightlies with invalid prerelease', () => {
|
||||
function testInvalidFunction() {
|
||||
parseVersion('0.0.0', 'dry-run');
|
||||
}
|
||||
expect(testInvalidFunction).toThrowErrorMatchingInlineSnapshot(
|
||||
`"Version 0.0.0 is not valid for dry-runs"`,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Validate version', () => {
|
||||
it('Throw error if the buildType is unknown', () => {
|
||||
function testInvalidFunction() {
|
||||
validateBuildType('wrong_build');
|
||||
}
|
||||
expect(testInvalidFunction).toThrowErrorMatchingInlineSnapshot(
|
||||
`"Unsupported build type: wrong_build"`,
|
||||
);
|
||||
});
|
||||
it('Does not throw if the buildType is release', () => {
|
||||
function testValidCall() {
|
||||
validateBuildType('release');
|
||||
}
|
||||
expect(testValidCall).not.toThrowError();
|
||||
});
|
||||
it('Does not throw if the buildType is nightly', () => {
|
||||
function testValidCall() {
|
||||
validateBuildType('nightly');
|
||||
}
|
||||
expect(testValidCall).not.toThrowError();
|
||||
});
|
||||
it('Does not throw if the buildType is dry-run', () => {
|
||||
function testValidCall() {
|
||||
validateBuildType('dry-run');
|
||||
}
|
||||
expect(testValidCall).not.toThrowError();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -21,6 +21,7 @@ const request = require('request');
|
||||
const {getBranchName, exitIfNotOnGit} = require('./scm-utils');
|
||||
|
||||
const {parseVersion, isReleaseBranch} = require('./version-utils');
|
||||
const {failIfTagExists} = require('./release-utils');
|
||||
|
||||
let argv = yargs
|
||||
.option('r', {
|
||||
@@ -75,6 +76,7 @@ async function main() {
|
||||
);
|
||||
const token = argv.token;
|
||||
const releaseVersion = argv.toVersion;
|
||||
failIfTagExists(releaseVersion, 'release');
|
||||
|
||||
const {pushed} = await inquirer.prompt({
|
||||
type: 'confirm',
|
||||
@@ -89,7 +91,7 @@ async function main() {
|
||||
}
|
||||
|
||||
let latest = false;
|
||||
const {version, prerelease} = parseVersion(releaseVersion);
|
||||
const {version, prerelease} = parseVersion(releaseVersion, 'release');
|
||||
if (!prerelease) {
|
||||
const {setLatest} = await inquirer.prompt({
|
||||
type: 'confirm',
|
||||
|
||||
@@ -1,123 +0,0 @@
|
||||
#!/bin/bash
|
||||
# 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.
|
||||
|
||||
# This script creates a draft GitHub Release using RELEASE_TEMPLATE.md
|
||||
# as a template and will upload the provided artifacts to the release.
|
||||
|
||||
# Install dependencies:
|
||||
# apt update && apt install -y jq jo
|
||||
|
||||
THIS_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
|
||||
REACT_NATIVE_PATH="$THIS_DIR/../.."
|
||||
|
||||
GITHUB_OWNER=${CIRCLE_PROJECT_USERNAME:-facebook}
|
||||
GITHUB_REPO=${CIRCLE_PROJECT_REPONAME:-react-native}
|
||||
|
||||
RELEASE_TYPE="$1"; shift
|
||||
GIT_TAG="$1"; shift
|
||||
RELEASE_VERSION="$1"; shift
|
||||
GITHUB_TOKEN="$1"; shift
|
||||
ARTIFACTS=("$@")
|
||||
|
||||
describe_header () {
|
||||
printf "\\n\\n>>>>> %s\\n\\n\\n" "$1"
|
||||
}
|
||||
|
||||
describe () {
|
||||
printf "\\n\\n%s\\n\\n" "$1"
|
||||
}
|
||||
|
||||
echoerr () {
|
||||
echo "$@" 1>&2
|
||||
}
|
||||
|
||||
if [[ $RELEASE_TYPE == "release" ]]; then
|
||||
describe_header "Preparing to create a GitHub release."
|
||||
elif [[ $RELEASE_TYPE == "dry-run" ]]; then
|
||||
describe_header "Preparing to create a GitHub release as a dry-run."
|
||||
elif [[ $RELEASE_TYPE == "nightly" ]]; then
|
||||
describe "GitHub Releases are not used with nightlies. Skipping."
|
||||
exit 0
|
||||
else
|
||||
echoerr "Unrecognized release type: $RELEASE_TYPE"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Derive short version string for use in the sample command used
|
||||
# to create a new RN app in RELEASE_TEMPLATE.md
|
||||
# 0.69.0-rc.4 -> 0690rc4
|
||||
RN_SHORT_VERSION=${RELEASE_VERSION//[.-]/}
|
||||
|
||||
PRERELEASE=false
|
||||
if [[ "$RELEASE_VERSION" == *"rc"* ]]; then
|
||||
PRERELEASE=true
|
||||
fi
|
||||
|
||||
RELEASE_TEMPLATE_PATH="$REACT_NATIVE_PATH/.github/RELEASE_TEMPLATE.md"
|
||||
if [[ -f $RELEASE_TEMPLATE_PATH ]]; then
|
||||
# Replace placeholders in template with actual RN version strings
|
||||
RELEASE_BODY=$(sed -e "s/__VERSION__/$RELEASE_VERSION/g" -e "s/__SHORT_VERSION__/$RN_SHORT_VERSION/g" "$RELEASE_TEMPLATE_PATH")
|
||||
else
|
||||
describe "Could not load GitHub Release template. Falling back to placeholder text."
|
||||
RELEASE_BODY="<!-- TODO: Fill this out using RELEASE_TEMPLATE.md -->"
|
||||
fi
|
||||
|
||||
# Format and encode JSON payload
|
||||
RELEASE_DATA=$(jo tag_name="$GIT_TAG" name="$RELEASE_VERSION" body="$RELEASE_BODY" draft=true prerelease="$PRERELEASE" generate_release_notes=false)
|
||||
if [[ ! $RELEASE_DATA ]]; then
|
||||
echoerr "Could not format release data."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Create GitHub Release draft
|
||||
describe_header "Creating GitHub release."
|
||||
describe "Release payload: $RELEASE_DATA"
|
||||
|
||||
if [[ $RELEASE_TYPE == "release" ]]; then
|
||||
CREATE_RELEASE_RESPONSE=$(curl -X POST \
|
||||
-H "Accept: application/vnd.github.v3+json" \
|
||||
-H "Authorization: Bearer $GITHUB_TOKEN" \
|
||||
-d "$RELEASE_DATA" \
|
||||
"https://api.github.com/repos/$GITHUB_OWNER/$GITHUB_REPO/releases"
|
||||
)
|
||||
STATUS=$?
|
||||
if [ $STATUS == 0 ]; then
|
||||
describe "Created GitHub Release successfully."
|
||||
RELEASE_ID=$(echo "$CREATE_RELEASE_RESPONSE" | jq '.id')
|
||||
else
|
||||
echoerr "Could not create GitHub release, request failed with $STATUS:\n\n$CREATE_RELEASE_RESPONSE"
|
||||
exit 1
|
||||
fi
|
||||
elif [[ $RELEASE_TYPE == "dry-run" ]]; then
|
||||
describe "Skipping creating GitHub release because dry-run."
|
||||
fi
|
||||
|
||||
# Upload artifacts
|
||||
describe_header "Uploading artifacts to GitHub release."
|
||||
for ARTIFACT_PATH in "${ARTIFACTS[@]}"
|
||||
do
|
||||
:
|
||||
# Upload Hermes artifacts to GitHub Release
|
||||
ARTIFACT_NAME=$(basename "$ARTIFACT_PATH")
|
||||
describe "Uploading $ARTIFACT_NAME..."
|
||||
|
||||
if [[ $RELEASE_TYPE == "release" ]]; then
|
||||
if curl -X POST \
|
||||
-H "Accept: application/vnd.github.v3+json" \
|
||||
-H "Authorization: Bearer $GITHUB_TOKEN" \
|
||||
-H "Content-Length: $(wc -c "$ARTIFACT_PATH" | awk '{print $1}')" \
|
||||
-H "Content-Type: application/gzip" \
|
||||
-T "$ARTIFACT_PATH" \
|
||||
--progress-bar \
|
||||
"https://uploads.github.com/repos/$GITHUB_OWNER/$GITHUB_REPO/releases/$RELEASE_ID/assets?name=$ARTIFACT_NAME"; then
|
||||
describe "Uploaded $ARTIFACT_NAME."
|
||||
else
|
||||
describe "Could not upload $ARTIFACT_NAME to GitHub release."
|
||||
fi
|
||||
elif [[ $RELEASE_TYPE == "dry-run" ]]; then
|
||||
describe "Skipping $ARTIFACT_NAME upload because dry-run."
|
||||
fi
|
||||
done
|
||||
@@ -458,15 +458,16 @@ class CodegenUtilsTests < Test::Unit::TestCase
|
||||
].join(' ')
|
||||
},
|
||||
'dependencies': {
|
||||
"FBReactNativeSpec": ["99.98.97"],
|
||||
"React-jsiexecutor": ["99.98.97"],
|
||||
"RCT-Folly": ["2021.07.22.00"],
|
||||
"RCTRequired": ["99.98.97"],
|
||||
"RCTTypeSafety": ["99.98.97"],
|
||||
"React-Core": ["99.98.97"],
|
||||
"React-jsi": ["99.98.97"],
|
||||
"hermes-engine": ["99.98.97"],
|
||||
"ReactCommon/turbomodule/core": ["99.98.97"]
|
||||
"FBReactNativeSpec": [],
|
||||
"React-jsiexecutor": [],
|
||||
"RCT-Folly": [],
|
||||
"RCTRequired": [],
|
||||
"RCTTypeSafety": [],
|
||||
"React-Core": [],
|
||||
"React-jsi": [],
|
||||
"hermes-engine": [],
|
||||
"ReactCommon/turbomodule/bridging": [],
|
||||
"ReactCommon/turbomodule/core": []
|
||||
}
|
||||
}
|
||||
end
|
||||
@@ -475,8 +476,8 @@ class CodegenUtilsTests < Test::Unit::TestCase
|
||||
specs = get_podspec_no_fabric_no_script()
|
||||
|
||||
specs[:dependencies].merge!({
|
||||
'React-graphics': ["99.98.97"],
|
||||
'React-rncore': ["99.98.97"],
|
||||
'React-graphics': [],
|
||||
'React-rncore': [],
|
||||
})
|
||||
|
||||
specs[:'script_phases'] = script_phases
|
||||
|
||||
@@ -14,16 +14,21 @@ class JSEngineTests < Test::Unit::TestCase
|
||||
:react_native_path
|
||||
|
||||
def setup
|
||||
File.enable_testing_mode!
|
||||
@react_native_path = "../.."
|
||||
podSpy_cleanUp()
|
||||
|
||||
end
|
||||
|
||||
def teardown
|
||||
ENV['HERMES_ENGINE_TARBALL_PATH'] = nil
|
||||
Open3.reset()
|
||||
Pod::Config.reset()
|
||||
Pod::UI.reset()
|
||||
podSpy_cleanUp()
|
||||
ENV['USE_HERMES'] = '1'
|
||||
ENV['CI'] = nil
|
||||
File.reset()
|
||||
end
|
||||
|
||||
# =============== #
|
||||
@@ -119,4 +124,31 @@ class JSEngineTests < Test::Unit::TestCase
|
||||
assert_equal($podInvocation["React-hermes"][:path], "../../ReactCommon/hermes")
|
||||
assert_equal($podInvocation["libevent"][:version], "~> 2.1.12")
|
||||
end
|
||||
|
||||
# ================================= #
|
||||
# TEST - isBuildingHermesFromSource #
|
||||
# ================================= #
|
||||
def test_isBuildingHermesFromSource_whenTarballIsNilAndVersionIsNotNightly_returnTrue
|
||||
assert_true(is_building_hermes_from_source("1000.0.0", '../..'))
|
||||
end
|
||||
|
||||
def test_isBuildingHermesFromSource_whenTarballIsNilAndInReleaseBranch_returnTrue
|
||||
ENV['CI'] = 'true'
|
||||
File.mocked_existing_files(['../../sdks/.hermesversion'])
|
||||
assert_true(is_building_hermes_from_source("0.999.0", '../..'))
|
||||
end
|
||||
|
||||
def test_isBuildingHermesFromSource_whenTarballIsNotNil_returnFalse
|
||||
ENV['HERMES_ENGINE_TARBALL_PATH'] = "~/Downloads/hermes-ios-debug.tar.gz"
|
||||
assert_false(is_building_hermes_from_source("1000.0.0", '../..'))
|
||||
end
|
||||
|
||||
def test_isBuildingHermesFromSource_whenIsNigthly_returnsFalse
|
||||
assert_false(is_building_hermes_from_source("0.0.0-", '../..'))
|
||||
end
|
||||
|
||||
def test_isBuildingHermesFromSource_whenIsStbleRelease_returnsFalse
|
||||
assert_false(is_building_hermes_from_source("0.71.0", '../..'))
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -134,6 +134,7 @@ class NewArchitectureTests < Test::Unit::TestCase
|
||||
{ :dependency_name => "React-Codegen" },
|
||||
{ :dependency_name => "RCTRequired" },
|
||||
{ :dependency_name => "RCTTypeSafety" },
|
||||
{ :dependency_name => "ReactCommon/turbomodule/bridging" },
|
||||
{ :dependency_name => "ReactCommon/turbomodule/core" }
|
||||
])
|
||||
end
|
||||
|
||||
@@ -328,60 +328,6 @@ class UtilsTests < Test::Unit::TestCase
|
||||
assert_equal(pods_projects_mock.save_invocation_count, 1)
|
||||
end
|
||||
|
||||
# ============================================= #
|
||||
# Test - Fix React-bridging Header Search Paths #
|
||||
# ============================================= #
|
||||
|
||||
def test_fixReactBridgingHeaderSearchPaths_correctlySetsTheHeaderSearchPathsForAllTargets
|
||||
# Arrange
|
||||
first_target = prepare_target("FirstTarget")
|
||||
second_target = prepare_target("SecondTarget")
|
||||
third_target = TargetMock.new("ThirdTarget", [
|
||||
BuildConfigurationMock.new("Debug", {
|
||||
"HEADER_SEARCH_PATHS" => '$(inherited) "${PODS_ROOT}/Headers/Public" '
|
||||
}),
|
||||
BuildConfigurationMock.new("Release", {
|
||||
"HEADER_SEARCH_PATHS" => '$(inherited) "${PODS_ROOT}/Headers/Public" '
|
||||
}),
|
||||
], nil)
|
||||
|
||||
user_project_mock = UserProjectMock.new("a/path", [
|
||||
prepare_config("Debug"),
|
||||
prepare_config("Release"),
|
||||
],
|
||||
:native_targets => [
|
||||
first_target,
|
||||
second_target
|
||||
]
|
||||
)
|
||||
pods_projects_mock = PodsProjectMock.new([], {"hermes-engine" => {}}, :native_targets => [
|
||||
third_target
|
||||
])
|
||||
installer = InstallerMock.new(pods_projects_mock, [
|
||||
AggregatedProjectMock.new(user_project_mock)
|
||||
])
|
||||
|
||||
# Act
|
||||
ReactNativePodsUtils.fix_react_bridging_header_search_paths(installer)
|
||||
|
||||
# Assert
|
||||
first_target.build_configurations.each do |config|
|
||||
assert_equal(config.build_settings["HEADER_SEARCH_PATHS"].strip,
|
||||
'$(inherited) "$(PODS_ROOT)/Headers/Private/React-bridging/react/bridging" "$(PODS_CONFIGURATION_BUILD_DIR)/React-bridging/react_bridging.framework/Headers"'
|
||||
)
|
||||
end
|
||||
second_target.build_configurations.each do |config|
|
||||
assert_equal(config.build_settings["HEADER_SEARCH_PATHS"].strip,
|
||||
'$(inherited) "$(PODS_ROOT)/Headers/Private/React-bridging/react/bridging" "$(PODS_CONFIGURATION_BUILD_DIR)/React-bridging/react_bridging.framework/Headers"'
|
||||
)
|
||||
end
|
||||
third_target.build_configurations.each do |config|
|
||||
assert_equal(config.build_settings["HEADER_SEARCH_PATHS"].strip,
|
||||
'$(inherited) "${PODS_ROOT}/Headers/Public" "$(PODS_ROOT)/Headers/Private/React-bridging/react/bridging" "$(PODS_CONFIGURATION_BUILD_DIR)/React-bridging/react_bridging.framework/Headers"'
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
# ===================================== #
|
||||
# Test - Apply Xcode14 React-Core patch #
|
||||
# ===================================== #
|
||||
|
||||
@@ -98,31 +98,32 @@ class CodegenUtils
|
||||
].join(' ')
|
||||
},
|
||||
'dependencies': {
|
||||
"FBReactNativeSpec": [version],
|
||||
"React-jsiexecutor": [version],
|
||||
"RCT-Folly": [folly_version],
|
||||
"RCTRequired": [version],
|
||||
"RCTTypeSafety": [version],
|
||||
"React-Core": [version],
|
||||
"React-jsi": [version],
|
||||
"ReactCommon/turbomodule/core": [version]
|
||||
"FBReactNativeSpec": [],
|
||||
"React-jsiexecutor": [],
|
||||
"RCT-Folly": [],
|
||||
"RCTRequired": [],
|
||||
"RCTTypeSafety": [],
|
||||
"React-Core": [],
|
||||
"React-jsi": [],
|
||||
"ReactCommon/turbomodule/bridging": [],
|
||||
"ReactCommon/turbomodule/core": []
|
||||
}
|
||||
}
|
||||
|
||||
if fabric_enabled
|
||||
spec[:'dependencies'].merge!({
|
||||
'React-graphics': [version],
|
||||
'React-rncore': [version],
|
||||
'React-graphics': [],
|
||||
'React-rncore': [],
|
||||
});
|
||||
end
|
||||
|
||||
if hermes_enabled
|
||||
spec[:'dependencies'].merge!({
|
||||
'hermes-engine': [version],
|
||||
'hermes-engine': [], # let React Native decide which version of Hermes Engine to be used. Otherwise, this can create conflicts.
|
||||
});
|
||||
else
|
||||
spec[:'dependencies'].merge!({
|
||||
'React-jsc': [version],
|
||||
'React-jsc': [],
|
||||
});
|
||||
end
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@ end
|
||||
|
||||
def add_copy_hermes_framework_script_phase(installer, react_native_path)
|
||||
utils_dir = File.join(react_native_path, "sdks", "hermes-engine", "utils")
|
||||
phase_name = "[RN]Copy Hermes framework"
|
||||
phase_name = "[RN] Copy Hermes Framework"
|
||||
project = installer.generated_aggregate_targets.first.user_project
|
||||
target = project.targets.first
|
||||
if target.shell_script_build_phases.none? { |phase| phase.name == phase_name }
|
||||
@@ -49,8 +49,33 @@ end
|
||||
|
||||
def remove_copy_hermes_framework_script_phase(installer, react_native_path)
|
||||
utils_dir = File.join(react_native_path, "sdks", "hermes-engine", "utils")
|
||||
phase_name = "[RN]Copy Hermes framework"
|
||||
phase_name = "[RN] Copy Hermes Framework"
|
||||
project = installer.generated_aggregate_targets.first.user_project
|
||||
project.targets.first.shell_script_build_phases.delete_if { |phase| phase.name == phase_name }
|
||||
target = project.native_targets.first
|
||||
target.shell_script_build_phases.each do |phase|
|
||||
if phase.name == phase_name
|
||||
target.build_phases.delete(phase)
|
||||
end
|
||||
end
|
||||
project.save()
|
||||
end
|
||||
|
||||
def remove_hermesc_build_dir(react_native_path)
|
||||
%x(rm -rf #{react_native_path}/sdks/hermes-engine/build_host_hermesc)
|
||||
end
|
||||
|
||||
def is_building_hermes_from_source(react_native_version, react_native_path)
|
||||
if ENV['HERMES_ENGINE_TARBALL_PATH'] != nil
|
||||
return false
|
||||
end
|
||||
|
||||
isInMain = react_native_version.include?('1000.0.0')
|
||||
|
||||
hermestag_file = File.join(react_native_path, "sdks", ".hermesversion")
|
||||
isInCI = ENV['CI'] === 'true'
|
||||
|
||||
isReleaseBranch = File.exist?(hermestag_file) && isInCI
|
||||
|
||||
|
||||
return isInMain || isReleaseBranch
|
||||
end
|
||||
|
||||
@@ -87,6 +87,7 @@ class NewArchitectureHelper
|
||||
|
||||
spec.dependency "RCTRequired"
|
||||
spec.dependency "RCTTypeSafety"
|
||||
spec.dependency "ReactCommon/turbomodule/bridging"
|
||||
spec.dependency "ReactCommon/turbomodule/core"
|
||||
end
|
||||
end
|
||||
|
||||
@@ -107,18 +107,6 @@ class ReactNativePodsUtils
|
||||
end
|
||||
end
|
||||
|
||||
def self.fix_react_bridging_header_search_paths(installer)
|
||||
installer.target_installation_results.pod_target_installation_results
|
||||
.each do |pod_name, target_installation_result|
|
||||
target_installation_result.native_target.build_configurations.each do |config|
|
||||
# For third party modules who have React-bridging dependency to search correct headers
|
||||
config.build_settings['HEADER_SEARCH_PATHS'] ||= '$(inherited) '
|
||||
config.build_settings['HEADER_SEARCH_PATHS'] << '"$(PODS_ROOT)/Headers/Private/React-bridging/react/bridging" '
|
||||
config.build_settings['HEADER_SEARCH_PATHS'] << '"$(PODS_CONFIGURATION_BUILD_DIR)/React-bridging/react_bridging.framework/Headers" '
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def self.apply_mac_catalyst_patches(installer)
|
||||
# Fix bundle signing issues
|
||||
installer.pods_project.targets.each do |target|
|
||||
|
||||
@@ -26,7 +26,7 @@ describe('generateSpec', () => {
|
||||
const outputDirectory = normalize('app/ios/build/generated/ios');
|
||||
const libraryName = 'library';
|
||||
const packageName = 'com.library';
|
||||
const generators = ['componentsIOS', 'modulesIOS'];
|
||||
const generators = ['componentsIOS', 'modulesIOS', 'modulesCxx'];
|
||||
|
||||
jest.mock('fs', () => ({
|
||||
readFileSync: (path, encoding) => {
|
||||
|
||||
@@ -17,16 +17,16 @@ const RNCodegen = utils.getCodegen();
|
||||
|
||||
const GENERATORS = {
|
||||
all: {
|
||||
android: ['componentsAndroid', 'modulesAndroid'],
|
||||
ios: ['componentsIOS', 'modulesIOS'],
|
||||
android: ['componentsAndroid', 'modulesAndroid', 'modulesCxx'],
|
||||
ios: ['componentsIOS', 'modulesIOS', 'modulesCxx'],
|
||||
},
|
||||
components: {
|
||||
android: ['componentsAndroid'],
|
||||
ios: ['componentsIOS'],
|
||||
},
|
||||
modules: {
|
||||
android: ['modulesAndroid'],
|
||||
ios: ['modulesIOS'],
|
||||
android: ['modulesAndroid', 'modulesCxx'],
|
||||
ios: ['modulesIOS', 'modulesCxx'],
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
@@ -387,30 +387,15 @@ describe('hermes-utils', () => {
|
||||
|
||||
describe('getHermesPrebuiltArtifactsTarballName', () => {
|
||||
it('should return Hermes prebuilts tarball name', () => {
|
||||
expect(
|
||||
getHermesPrebuiltArtifactsTarballName('Debug', '1000.0.0'),
|
||||
).toEqual('hermes-runtime-darwin-debug-v1000.0.0.tar.gz');
|
||||
expect(getHermesPrebuiltArtifactsTarballName('Debug')).toEqual(
|
||||
'hermes-ios-debug.tar.gz',
|
||||
);
|
||||
});
|
||||
it('should throw if build type is undefined', () => {
|
||||
expect(() => {
|
||||
getHermesPrebuiltArtifactsTarballName();
|
||||
}).toThrow('Did not specify build type.');
|
||||
});
|
||||
it('should throw if release version is undefined', () => {
|
||||
expect(() => {
|
||||
getHermesPrebuiltArtifactsTarballName('Release');
|
||||
}).toThrow('Did not specify release version.');
|
||||
});
|
||||
it('should return debug Hermes prebuilts tarball name for RN 0.70.0', () => {
|
||||
expect(
|
||||
getHermesPrebuiltArtifactsTarballName('Debug', '0.70.0'),
|
||||
).toEqual('hermes-runtime-darwin-debug-v0.70.0.tar.gz');
|
||||
});
|
||||
it('should return a wildcard Hermes prebuilts tarball name for any RN version', () => {
|
||||
expect(getHermesPrebuiltArtifactsTarballName('Debug', '*')).toEqual(
|
||||
'hermes-runtime-darwin-debug-v*.tar.gz',
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('createHermesPrebuiltArtifactsTarball', () => {
|
||||
@@ -426,7 +411,6 @@ describe('hermes-utils', () => {
|
||||
const tarballOutputPath = createHermesPrebuiltArtifactsTarball(
|
||||
path.join(SDKS_DIR, 'hermes'),
|
||||
'Debug',
|
||||
'1000.0.0',
|
||||
tarballOutputDir,
|
||||
excludeDebugSymbols,
|
||||
);
|
||||
@@ -448,7 +432,6 @@ describe('hermes-utils', () => {
|
||||
const tarballOutputPath = createHermesPrebuiltArtifactsTarball(
|
||||
path.join(SDKS_DIR, 'hermes'),
|
||||
'Debug',
|
||||
'1000.0.0',
|
||||
tarballOutputDir,
|
||||
excludeDebugSymbols,
|
||||
);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user