mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
27651720b4 | ||
|
|
00a942c905 | ||
|
|
ec5090adab | ||
|
|
29972f9602 | ||
|
|
f0b6eb7d9f | ||
|
|
afbd17ae41 | ||
|
|
b31a95c468 | ||
|
|
864c76b143 | ||
|
|
1875116090 | ||
|
|
c2404b4598 | ||
|
|
422260918a | ||
|
|
f2d709c3fa | ||
|
|
7c5aed7ae3 | ||
|
|
d8cf799a46 | ||
|
|
2923273bcb | ||
|
|
4846f1bf18 | ||
|
|
ccd4efac90 | ||
|
|
7100756bb8 | ||
|
|
8d8b61a695 | ||
|
|
09795971f8 | ||
|
|
e4ec71a1d9 | ||
|
|
ad6005f6bc | ||
|
|
66c8cd393c | ||
|
|
29e17754b3 | ||
|
|
e62b57e525 | ||
|
|
c72ecdb906 | ||
|
|
73747e674c | ||
|
|
2c5d4cba5c | ||
|
|
2903a291ca | ||
|
|
0042d96c1c | ||
|
|
98309fa7fc | ||
|
|
3c9e5f1470 | ||
|
|
b6ded72615 | ||
|
|
d4b6e02f2e | ||
|
|
30b4d157b2 | ||
|
|
b5fd5d0b4a | ||
|
|
1f7b0b3333 | ||
|
|
42658cf58b | ||
|
|
a642c3f264 | ||
|
|
ce0fd0a57f | ||
|
|
ab211fa7e4 | ||
|
|
49b2a6e9cd | ||
|
|
bb91f4a021 | ||
|
|
5136fcaf94 | ||
|
|
7d109659bc | ||
|
|
5394c908eb | ||
|
|
8c1718c122 | ||
|
|
cab16e4209 | ||
|
|
99fc293280 | ||
|
|
484a5ea854 | ||
|
|
4f897336b6 | ||
|
|
6ed1b39e6b | ||
|
|
0225f180f4 | ||
|
|
0b6fad6e7a | ||
|
|
fb429a5cd6 | ||
|
|
262a3f626d | ||
|
|
29639e7b95 | ||
|
|
27ccc6019e | ||
|
|
48413a4437 | ||
|
|
208bd05690 | ||
|
|
574447ae3d | ||
|
|
5e51e5492b | ||
|
|
b645f23708 | ||
|
|
18f1c69033 | ||
|
|
87f5b8b791 | ||
|
|
ff1558db3a | ||
|
|
e2dd18d8b0 | ||
|
|
787a772782 | ||
|
|
7acd6672a7 | ||
|
|
5f7b44c72d | ||
|
|
b191809d5e | ||
|
|
696fb55881 |
+3
-6
@@ -1,10 +1,6 @@
|
||||
|
||||
[android]
|
||||
target = android-31
|
||||
|
||||
[kotlin]
|
||||
compile_against_abis = True
|
||||
kotlin_version = 1.6.10
|
||||
target = android-29
|
||||
|
||||
[download]
|
||||
max_number_of_retries = 3
|
||||
@@ -12,6 +8,7 @@
|
||||
[maven_repositories]
|
||||
central = https://repo1.maven.org/maven2
|
||||
google = https://maven.google.com/
|
||||
jcenter = https://jcenter.bintray.com/
|
||||
|
||||
[alias]
|
||||
rntester = //packages/rn-tester/android/app:app
|
||||
rntester = //RNTester/android/app:app
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
BUNDLE_PATH: "vendor/bundle"
|
||||
BUNDLE_FORCE_RUBY_PLATFORM: 1
|
||||
@@ -14,31 +14,25 @@
|
||||
# and build a Android application that can be used to run the
|
||||
# tests specified in the scripts/ directory.
|
||||
#
|
||||
FROM reactnativecommunity/react-native-android:6.2
|
||||
FROM reactnativecommunity/react-native-android:2019-10-18
|
||||
|
||||
LABEL Description="React Native Android Test Image"
|
||||
LABEL maintainer="Héctor Ramos <hector@fb.com>"
|
||||
|
||||
# set default environment variables
|
||||
ENV GRADLE_OPTS="-Dorg.gradle.daemon=false -Dorg.gradle.jvmargs=\"-Xmx512m -XX:+HeapDumpOnOutOfMemoryError\""
|
||||
ENV KOTLIN_HOME="third-party/kotlin"
|
||||
ENV JAVA_TOOL_OPTIONS="-Dfile.encoding=UTF8"
|
||||
|
||||
ADD .buckconfig /app/.buckconfig
|
||||
ADD .buckjavaargs /app/.buckjavaargs
|
||||
ADD BUCK /app/BUCK
|
||||
ADD Libraries /app/Libraries
|
||||
ADD tools /app/tools
|
||||
ADD ReactAndroid /app/ReactAndroid
|
||||
ADD ReactCommon /app/ReactCommon
|
||||
ADD React /app/React
|
||||
ADD keystores /app/keystores
|
||||
ADD packages/react-native-codegen /app/packages/react-native-codegen
|
||||
ADD tools /app/tools
|
||||
add scripts /app/scripts
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
RUN scripts/download-kotlin-compiler-with-buck.sh
|
||||
|
||||
RUN buck fetch ReactAndroid/src/test/java/com/facebook/react/modules
|
||||
RUN buck fetch ReactAndroid/src/main/java/com/facebook/react
|
||||
RUN buck fetch ReactAndroid/src/main/java/com/facebook/react/shell
|
||||
@@ -52,4 +46,7 @@ ADD . /app
|
||||
|
||||
RUN yarn
|
||||
|
||||
RUN ./gradlew :ReactAndroid:assembleDebug
|
||||
RUN ./gradlew :ReactAndroid:downloadBoost :ReactAndroid:downloadDoubleConversion :ReactAndroid:downloadFolly :ReactAndroid:downloadGlog
|
||||
|
||||
RUN ./gradlew :ReactAndroid:packageReactNdkLibsForBuck -Pjobs=1
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/bin/bash
|
||||
# Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
# Copyright (c) Facebook, Inc. and its affiliates.
|
||||
#
|
||||
# This source code is licensed under the MIT license found in the
|
||||
# LICENSE file in the root directory of this source tree.
|
||||
@@ -10,7 +10,7 @@ mount -o remount,exec /dev/shm
|
||||
AVD_UUID=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 8 | head -n 1)
|
||||
|
||||
# create virtual device
|
||||
echo no | android create avd -n "$AVD_UUID" -f -t android-21 --abi default/armeabi-v7a
|
||||
echo no | android create avd -n "$AVD_UUID" -f -t android-19 --abi default/armeabi-v7a
|
||||
|
||||
# emulator setup
|
||||
emulator64-arm -avd $AVD_UUID -no-skin -no-audio -no-window -no-boot-anim &
|
||||
@@ -33,7 +33,7 @@ node cli.js bundle --platform android --dev true --entry-file ReactAndroid/src/a
|
||||
|
||||
# build test APK
|
||||
# shellcheck disable=SC1091
|
||||
source ./scripts/android-setup.sh && NO_BUCKD=1 scripts/retry3 buck install ReactAndroid/src/androidTest/buck-runner:instrumentation-tests --config build.threads=1
|
||||
source ./scripts/android-setup.sh && NO_BUCKD=1 retry3 buck install ReactAndroid/src/androidTest/buck-runner:instrumentation-tests --config build.threads=1
|
||||
|
||||
# run installed apk with tests
|
||||
node ./.circleci/Dockerfiles/scripts/run-android-ci-instrumentation-tests.js "$*"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/bin/bash
|
||||
# Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
# Copyright (c) Facebook, Inc. and its affiliates.
|
||||
#
|
||||
# This source code is licensed under the MIT license found in the
|
||||
# LICENSE file in the root directory of this source tree.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/bin/bash
|
||||
# Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
# Copyright (c) Facebook, Inc. and its affiliates.
|
||||
#
|
||||
# This source code is licensed under the MIT license found in the
|
||||
# LICENSE file in the root directory of this source tree.
|
||||
@@ -67,6 +67,11 @@ while :; do
|
||||
shift
|
||||
;;
|
||||
|
||||
--tvos)
|
||||
RUN_IOS=1
|
||||
shift
|
||||
;;
|
||||
|
||||
*)
|
||||
break
|
||||
esac
|
||||
@@ -109,7 +114,7 @@ function e2e_suite() {
|
||||
|
||||
# create virtual device
|
||||
if ! android list avd | grep "$AVD_UUID" > /dev/null; then
|
||||
echo no | android create avd -n "$AVD_UUID" -f -t android-21 --abi default/armeabi-v7a
|
||||
echo no | android create avd -n "$AVD_UUID" -f -t android-19 --abi default/armeabi-v7a
|
||||
fi
|
||||
|
||||
# newline at end of adb devices call and first line is headers
|
||||
@@ -194,7 +199,7 @@ function e2e_suite() {
|
||||
return 1
|
||||
fi
|
||||
|
||||
echo "Starting Metro"
|
||||
echo "Starting packager server"
|
||||
npm start >> /dev/null &
|
||||
SERVER_PID=$!
|
||||
sleep 15
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/bin/bash
|
||||
# Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
# Copyright (c) Facebook, Inc. and its affiliates.
|
||||
#
|
||||
# This source code is licensed under the MIT license found in the
|
||||
# LICENSE file in the root directory of this source tree.
|
||||
|
||||
+381
-1472
File diff suppressed because it is too large
Load Diff
@@ -1,44 +0,0 @@
|
||||
storage: ./storage
|
||||
auth:
|
||||
htpasswd:
|
||||
file: ./htpasswd
|
||||
uplinks:
|
||||
npmjs:
|
||||
url: https://registry.npmjs.org/
|
||||
max_fails: 40
|
||||
maxage: 30m
|
||||
timeout: 60s
|
||||
fail_timeout: 10m
|
||||
cache: false
|
||||
agent_options:
|
||||
keepAlive: true
|
||||
maxSockets: 40
|
||||
maxFreeSockets: 10
|
||||
packages:
|
||||
# Group and isolate all local packages, avoid being proxy from outside
|
||||
'@react-native/*':
|
||||
access: $all
|
||||
publish: $all
|
||||
# The below specific entries can be removed once they are renamed and have the @react-native prefix
|
||||
'@react-native-community/eslint-config':
|
||||
access: $all
|
||||
publish: $all
|
||||
'@react-native-community/eslint-plugin':
|
||||
access: $all
|
||||
publish: $all
|
||||
'react-native-codegen':
|
||||
access: $all
|
||||
publish: $all
|
||||
'react-native-gradle-plugin':
|
||||
access: $all
|
||||
publish: $all
|
||||
'@*/*':
|
||||
access: $all
|
||||
publish: $authenticated
|
||||
proxy: npmjs
|
||||
'**':
|
||||
access: $all
|
||||
publish: $all
|
||||
proxy: npmjs
|
||||
logs:
|
||||
- {type: file, path: verdaccio.log, format: json, level: warn}
|
||||
@@ -13,8 +13,5 @@ indent_size = 2
|
||||
[*.gradle]
|
||||
indent_size = 4
|
||||
|
||||
[*.kts]
|
||||
indent_size = 4
|
||||
|
||||
[BUCK]
|
||||
indent_size = 4
|
||||
|
||||
+5
-3
@@ -1,10 +1,12 @@
|
||||
# node_modules ignored by default
|
||||
|
||||
**/main.js
|
||||
**/staticBundle.js
|
||||
bots/node_modules
|
||||
docs/generatedComponentApiDocs.js
|
||||
flow/
|
||||
Libraries/Renderer/*
|
||||
Libraries/vendor/**/*
|
||||
node_modules/
|
||||
packages/*/node_modules
|
||||
packages/react-native-codegen/lib
|
||||
tools/eslint/rules/sort-imports.js
|
||||
pr-inactivity-bookmarklet.js
|
||||
question-bookmarklet.js
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
{
|
||||
"root": true,
|
||||
|
||||
"extends": [
|
||||
"./packages/eslint-config-react-native-community/index.js"
|
||||
],
|
||||
|
||||
"overrides": [
|
||||
{
|
||||
"files": [
|
||||
"Libraries/**/*.js",
|
||||
],
|
||||
rules: {
|
||||
'@react-native-community/no-haste-imports': 2,
|
||||
'@react-native-community/error-subclass-name': 2,
|
||||
'@react-native-community/platform-colors': 2,
|
||||
}
|
||||
},
|
||||
{
|
||||
"files": [
|
||||
"**/__fixtures__/**/*.js",
|
||||
"**/__mocks__/**/*.js",
|
||||
"**/__tests__/**/*.js",
|
||||
"jest/**/*.js",
|
||||
"RNTester/**/*.js",
|
||||
],
|
||||
"globals": {
|
||||
// Expose some Jest globals for test helpers
|
||||
"afterAll": true,
|
||||
"afterEach": true,
|
||||
"beforeAll": true,
|
||||
"beforeEach": true,
|
||||
"expect": true,
|
||||
"jest": true,
|
||||
},
|
||||
},
|
||||
{
|
||||
"files": [
|
||||
"**/__tests__/**/*-test.js",
|
||||
],
|
||||
"env": {
|
||||
"jasmine": true,
|
||||
"jest": true,
|
||||
},
|
||||
},
|
||||
],
|
||||
}
|
||||
@@ -1,95 +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
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
const path = require('node:path');
|
||||
|
||||
require('eslint-plugin-lint').load(path.join(__dirname, 'tools/eslint/rules'));
|
||||
|
||||
module.exports = {
|
||||
root: true,
|
||||
|
||||
extends: ['@react-native-community'],
|
||||
|
||||
plugins: ['@react-native/eslint-plugin-specs', 'lint'],
|
||||
|
||||
overrides: [
|
||||
// overriding the JS config from eslint-config-react-native-community config to ensure
|
||||
// that we use hermes-eslint for all js files
|
||||
{
|
||||
files: ['*.js'],
|
||||
parser: 'hermes-eslint',
|
||||
rules: {
|
||||
// These rules are not required with hermes-eslint
|
||||
'ft-flow/define-flow-type': 0,
|
||||
'ft-flow/use-flow-type': 0,
|
||||
// flow handles this check for us, so it's not required
|
||||
'no-undef': 0,
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
files: ['Libraries/**/*.js'],
|
||||
rules: {
|
||||
'@react-native-community/platform-colors': 2,
|
||||
'@react-native/specs/react-native-modules': 2,
|
||||
'lint/no-haste-imports': 2,
|
||||
'lint/no-react-native-imports': 2,
|
||||
'lint/require-extends-error': 2,
|
||||
'lint/sort-imports': 1,
|
||||
},
|
||||
},
|
||||
{
|
||||
files: ['flow-typed/**/*.js'],
|
||||
rules: {
|
||||
'lint/valid-flow-typed-signature': 2,
|
||||
'no-unused-vars': 0,
|
||||
quotes: 0,
|
||||
},
|
||||
},
|
||||
{
|
||||
files: [
|
||||
'**/__fixtures__/**/*.js',
|
||||
'**/__mocks__/**/*.js',
|
||||
'**/__tests__/**/*.js',
|
||||
'jest/**/*.js',
|
||||
'packages/rn-tester/**/*.js',
|
||||
],
|
||||
globals: {
|
||||
// Expose some Jest globals for test helpers
|
||||
afterAll: true,
|
||||
afterEach: true,
|
||||
beforeAll: true,
|
||||
beforeEach: true,
|
||||
expect: true,
|
||||
jest: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
files: ['**/__tests__/**/*-test.js'],
|
||||
env: {
|
||||
jasmine: true,
|
||||
jest: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
files: ['**/*.{ts,tsx}'],
|
||||
parser: '@typescript-eslint/parser',
|
||||
plugins: ['@typescript-eslint/eslint-plugin'],
|
||||
rules: {
|
||||
'@typescript-eslint/no-unused-vars': 'off',
|
||||
'react-native/no-inline-styles': 'off',
|
||||
'@typescript-eslint/no-shadow': 'off',
|
||||
'no-self-compare': 'off',
|
||||
'react/self-closing-comp': 'off',
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
+20
-8
@@ -6,16 +6,18 @@
|
||||
<PROJECT_ROOT>/template/.*
|
||||
|
||||
; Ignore the Dangerfile
|
||||
<PROJECT_ROOT>/packages/react-native-bots/dangerfile.js
|
||||
<PROJECT_ROOT>/bots/dangerfile.js
|
||||
|
||||
; Ignore "BUCK" generated dirs
|
||||
<PROJECT_ROOT>/\.buckd/
|
||||
|
||||
; These should not be required directly
|
||||
; require from fbjs/lib instead: require('fbjs/lib/warning')
|
||||
.*/node_modules/warning/.*
|
||||
|
||||
; Flow doesn't support platforms
|
||||
.*/Libraries/Utilities/LoadingView.js
|
||||
|
||||
.*/node_modules/resolve/test/resolver/malformed_package_json/package\.json$
|
||||
|
||||
[untyped]
|
||||
.*/node_modules/@react-native-community/cli/.*/.*
|
||||
|
||||
@@ -31,9 +33,10 @@ flow/
|
||||
[options]
|
||||
emoji=true
|
||||
|
||||
exact_by_default=true
|
||||
esproposal.optional_chaining=enable
|
||||
esproposal.nullish_coalescing=enable
|
||||
|
||||
format.bracket_spacing=false
|
||||
exact_by_default=true
|
||||
|
||||
module.file_ext=.js
|
||||
module.file_ext=.json
|
||||
@@ -51,7 +54,13 @@ suppress_type=$FlowFixMeProps
|
||||
suppress_type=$FlowFixMeState
|
||||
suppress_type=$FlowFixMeEmpty
|
||||
|
||||
inference_mode=constrain_writes
|
||||
suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe\\($\\|[^(]\\|(\\(<VERSION>\\)? *\\(site=[a-z,_]*react_native\\(_ios\\)?_\\(oss\\|fb\\)[a-z,_]*\\)?)\\)
|
||||
suppress_comment=\\(.\\|\n\\)*\\$FlowIssue\\((\\(<VERSION>\\)? *\\(site=[a-z,_]*react_native\\(_ios\\)?_\\(oss\\|fb\\)[a-z,_]*\\)?)\\)?:? #[0-9]+
|
||||
suppress_comment=\\(.\\|\n\\)*\\$FlowExpectedError
|
||||
|
||||
experimental.well_formed_exports=true
|
||||
experimental.types_first=true
|
||||
experimental.abstract_locations=true
|
||||
|
||||
[lints]
|
||||
sketchy-null-number=warn
|
||||
@@ -59,9 +68,12 @@ sketchy-null-mixed=warn
|
||||
sketchy-number=warn
|
||||
untyped-type-import=warn
|
||||
nonstrict-import=warn
|
||||
deprecated-type=error
|
||||
deprecated-type=warn
|
||||
unsafe-getters-setters=warn
|
||||
unnecessary-invariant=warn
|
||||
signature-verification-failure=warn
|
||||
deprecated-utility=error
|
||||
unsafe-addition=error
|
||||
|
||||
[strict]
|
||||
deprecated-type
|
||||
@@ -73,4 +85,4 @@ untyped-import
|
||||
untyped-type-import
|
||||
|
||||
[version]
|
||||
^0.191.0
|
||||
^0.122.0
|
||||
|
||||
+20
-8
@@ -6,16 +6,18 @@
|
||||
<PROJECT_ROOT>/template/.*
|
||||
|
||||
; Ignore the Dangerfile
|
||||
<PROJECT_ROOT>/packages/react-native-bots/dangerfile.js
|
||||
<PROJECT_ROOT>/bots/dangerfile.js
|
||||
|
||||
; Ignore "BUCK" generated dirs
|
||||
<PROJECT_ROOT>/\.buckd/
|
||||
|
||||
; These should not be required directly
|
||||
; require from fbjs/lib instead: require('fbjs/lib/warning')
|
||||
.*/node_modules/warning/.*
|
||||
|
||||
; Flow doesn't support platforms
|
||||
.*/Libraries/Utilities/LoadingView.js
|
||||
|
||||
.*/node_modules/resolve/test/resolver/malformed_package_json/package\.json$
|
||||
|
||||
[untyped]
|
||||
.*/node_modules/@react-native-community/cli/.*/.*
|
||||
|
||||
@@ -31,9 +33,10 @@ flow/
|
||||
[options]
|
||||
emoji=true
|
||||
|
||||
exact_by_default=true
|
||||
esproposal.optional_chaining=enable
|
||||
esproposal.nullish_coalescing=enable
|
||||
|
||||
format.bracket_spacing=false
|
||||
exact_by_default=true
|
||||
|
||||
module.file_ext=.js
|
||||
module.file_ext=.json
|
||||
@@ -51,7 +54,13 @@ suppress_type=$FlowFixMeProps
|
||||
suppress_type=$FlowFixMeState
|
||||
suppress_type=$FlowFixMeEmpty
|
||||
|
||||
inference_mode=constrain_writes
|
||||
suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe\\($\\|[^(]\\|(\\(<VERSION>\\)? *\\(site=[a-z,_]*react_native\\(_android\\)?_\\(oss\\|fb\\)[a-z,_]*\\)?)\\)
|
||||
suppress_comment=\\(.\\|\n\\)*\\$FlowIssue\\((\\(<VERSION>\\)? *\\(site=[a-z,_]*react_native\\(_android\\)?_\\(oss\\|fb\\)[a-z,_]*\\)?)\\)?:? #[0-9]+
|
||||
suppress_comment=\\(.\\|\n\\)*\\$FlowExpectedError
|
||||
|
||||
experimental.well_formed_exports=true
|
||||
experimental.types_first=true
|
||||
experimental.abstract_locations=true
|
||||
|
||||
[lints]
|
||||
sketchy-null-number=warn
|
||||
@@ -59,9 +68,12 @@ sketchy-null-mixed=warn
|
||||
sketchy-number=warn
|
||||
untyped-type-import=warn
|
||||
nonstrict-import=warn
|
||||
deprecated-type=error
|
||||
deprecated-type=warn
|
||||
unsafe-getters-setters=warn
|
||||
unnecessary-invariant=warn
|
||||
signature-verification-failure=warn
|
||||
deprecated-utility=error
|
||||
unsafe-addition=error
|
||||
|
||||
[strict]
|
||||
deprecated-type
|
||||
@@ -73,4 +85,4 @@ untyped-import
|
||||
untyped-type-import
|
||||
|
||||
[version]
|
||||
^0.191.0
|
||||
^0.122.0
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
# Force LF line endings for Bash scripts. On Windows the rest of the source
|
||||
# files will typically have CR+LF endings (Git default on Windows), but Bash
|
||||
# scripts need to have LF endings to work (under Cygwin), thus override to force
|
||||
# that.
|
||||
gradlew text eol=lf
|
||||
*.sh text eol=lf
|
||||
+1
-1
@@ -9,7 +9,7 @@
|
||||
|
||||
# GitHub Settings, Bots
|
||||
/.github/ @hramos
|
||||
/packages/react-native-bots @hramos
|
||||
/bots @hramos
|
||||
|
||||
# Continuous Integration
|
||||
/.circleci/ @hramos
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
---
|
||||
name: "🐛 Bug Report"
|
||||
about: Report a reproducible bug or regression in React Native.
|
||||
title: ''
|
||||
labels: 'Needs: Triage :mag:'
|
||||
|
||||
---
|
||||
|
||||
Please provide all the information requested. Issues that do not follow this format are likely to stall.
|
||||
|
||||
## Description
|
||||
Please provide a clear and concise description of what the bug is. Include screenshots if needed.
|
||||
Please test using the latest React Native release to make sure your issue has not already been fixed: https://reactnative.dev/docs/upgrading.html
|
||||
|
||||
## React Native version:
|
||||
Run `react-native info` in your terminal and copy the results here.
|
||||
|
||||
## Steps To Reproduce
|
||||
Provide a detailed list of steps that reproduce the issue.
|
||||
|
||||
1.
|
||||
2.
|
||||
|
||||
## Expected Results
|
||||
Describe what you expected to happen.
|
||||
|
||||
## Snack, code example, screenshot, or link to a repository:
|
||||
Please provide a Snack (https://snack.expo.io/), a link to a repository on GitHub, or provide a minimal code example that reproduces the problem.
|
||||
You may provide a screenshot of the application if you think it is relevant to your bug report.
|
||||
Here are some tips for providing a minimal example: https://stackoverflow.com/help/mcve
|
||||
@@ -1,48 +0,0 @@
|
||||
name: 🐛 Bug Report
|
||||
description: Report a reproducible bug or regression in React Native.
|
||||
labels: ["Needs: Triage :mag:"]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Please provide all the information requested. Issues that do not follow this format are likely to stall.
|
||||
- type: textarea
|
||||
id: description
|
||||
attributes:
|
||||
label: Description
|
||||
description: Please provide a clear and concise description of what the bug is. Include screenshots if needed. Please test using the latest React Native release to make sure your issue has not already been fixed - https://reactnative.dev/docs/upgrading.html
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: version
|
||||
attributes:
|
||||
label: Version
|
||||
description: What react-native version does this appear on?
|
||||
placeholder: ex. 0.66.0
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: react-native-info
|
||||
attributes:
|
||||
label: Output of `npx react-native info`
|
||||
description: Run `npx react-native info` in your terminal, copy and paste the results here.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: reproduction
|
||||
attributes:
|
||||
label: Steps to reproduce
|
||||
description: Provide a detailed list of steps that reproduce the issue.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: extra
|
||||
attributes:
|
||||
label: Snack, code example, screenshot, or link to a repository
|
||||
description: |
|
||||
Please provide a Snack (https://snack.expo.dev/), a link to a repository on GitHub, or provide a minimal code example that reproduces the problem.
|
||||
You may provide a screenshot of the application if you think it is relevant to your bug report.
|
||||
Here are some tips for providing a minimal example: https://stackoverflow.com/help/mcve
|
||||
Please note that a reproducer is mandatory. Issues without reproducer are more likely to stall and will be closed.
|
||||
validations:
|
||||
required: true
|
||||
@@ -3,12 +3,12 @@ contact_links:
|
||||
- name: 📃 Documentation Issue
|
||||
url: https://github.com/facebook/react-native-website/issues
|
||||
about: Please report documentation issues in the React Native website repository.
|
||||
- name: ⤴️ Upgrade Issue
|
||||
url: https://github.com/react-native-community/upgrade-support
|
||||
about: Need help upgrading to a newer React Native version? Visit the Upgrade Support repository.
|
||||
- name: 🤔 Questions and Help
|
||||
url: https://reactnative.dev/help
|
||||
about: Looking for help with your app? Please refer to the React Native community's support resources.
|
||||
- name: 💫 New Architecture - Questions & Technical Deep dive insights
|
||||
url: https://github.com/reactwg/react-native-new-architecture
|
||||
about: Questions and doubts related to technical questions for the New Architecture should be directed to the Working Group. Instructions on how to join are available in the README.
|
||||
- name: 🚀 Discussions and Proposals
|
||||
url: https://github.com/react-native-community/discussions-and-proposals
|
||||
about: Discuss the future of React Native in the React Native community's discussions and proposals repository.
|
||||
|
||||
@@ -1,53 +0,0 @@
|
||||
name: 💫 New Architecture - Bug Report
|
||||
description: Report a reproducible bug or a build issue when using the New Architecture (Fabric & TurboModules) in React Native.
|
||||
labels: ["Needs: Triage :mag:", "Type: New Architecture"]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Please provide all the information requested. Issues that do not follow this format are going to be closed.
|
||||
This issue report is reserved to bug & build issues for users on the New Architecture. If you're not using
|
||||
the New Architecture, please don't open issues on this category.
|
||||
- type: textarea
|
||||
id: description
|
||||
attributes:
|
||||
label: Description
|
||||
description: |
|
||||
Please provide a clear and concise description of what the bug or issue is. Include screenshots if needed.
|
||||
Please make sure you check the New Architecture documentation first, as your issue might
|
||||
already be answered there - https://reactnative.dev/docs/next/new-architecture-intro
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: version
|
||||
attributes:
|
||||
label: Version
|
||||
description: What react-native version does this appear on? Please test against the latest stable version. Bug reports against older versions are more likely to stall.
|
||||
placeholder: ex. 0.68.0
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: react-native-info
|
||||
attributes:
|
||||
label: Output of `npx react-native info`
|
||||
description: Run `npx react-native info` in your terminal, copy and paste the results here.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: reproduction
|
||||
attributes:
|
||||
label: Steps to reproduce
|
||||
description: Provide a detailed list of steps that reproduce the issue.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: extra
|
||||
attributes:
|
||||
label: Snack, code example, screenshot, or link to a repository
|
||||
description: |
|
||||
Please provide a Snack (https://snack.expo.dev/), a link to a repository on GitHub, or provide a minimal code example that reproduces the problem.
|
||||
You may provide a screenshot of the application if you think it is relevant to your bug report.
|
||||
Here are some tips for providing a minimal example: https://stackoverflow.com/help/mcve
|
||||
Please note that a reproducer is mandatory. Issues without reproducer are more likely to stall and will be closed.
|
||||
validations:
|
||||
required: true
|
||||
@@ -1,46 +0,0 @@
|
||||
name: ⬆️ Upgrade - Build Regression
|
||||
description: If you are upgrading to a new React Native version (stable or pre-release) and encounter a build regression.
|
||||
labels: ["Needs: Triage :mag:", "Type: Upgrade Issue"]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Please use this form to file an issue if you have upgarded or are upgrading to [latest stable release](https://github.com/facebook/react-native/releases/latest) and have experienced a regression (something that used to work in previous version).
|
||||
- type: input
|
||||
id: new-version
|
||||
attributes:
|
||||
label: New Version
|
||||
description: This is the version you are attempting to upgrade to.
|
||||
placeholder: ex. 0.66.1
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: old-version
|
||||
attributes:
|
||||
label: Old Version
|
||||
description: This is the version you were on where the behavior was working.
|
||||
placeholder: ex. 0.65.1
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: target
|
||||
attributes:
|
||||
label: Build Target(s)
|
||||
description: What target(s) are encountering this issue?
|
||||
placeholder: iOS simulator in release flavor
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: react-native-info
|
||||
attributes:
|
||||
label: Output of `react-native info`
|
||||
description: Run `react-native info` in your terminal, copy and paste the results here.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: reproduction
|
||||
attributes:
|
||||
label: Issue and Reproduction Steps
|
||||
description: Please describe the issue and list out commands run to reproduce.
|
||||
validations:
|
||||
required: true
|
||||
@@ -7,7 +7,7 @@
|
||||
## Changelog
|
||||
|
||||
<!-- Help reviewers and the release process by writing your own changelog entry. For an example, see:
|
||||
https://reactnative.dev/contributing/changelogs-in-pull-requests
|
||||
https://github.com/facebook/react-native/wiki/Changelog
|
||||
-->
|
||||
|
||||
[CATEGORY] [TYPE] - Message
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
<!-- Template for pre-release GitHub release -->
|
||||
|
||||
<!-- TODO Post about this release to https://github.com/reactwg/react-native-releases/discussions) -->
|
||||
|
||||
- <!-- TODO List out notable picks for this patch -->
|
||||
|
||||
---
|
||||
|
||||
To test it, run:
|
||||
|
||||
npx react-native init RN__SHORT_VERSION__ --version __VERSION__
|
||||
|
||||
---
|
||||
|
||||
You can participate in the conversation on the status of this release in the [working group](https://github.com/reactwg/react-native-releases/discussions).
|
||||
|
||||
---
|
||||
|
||||
To help you upgrade to this version, you can use the [upgrade helper](https://react-native-community.github.io/upgrade-helper/) ⚛️
|
||||
|
||||
---
|
||||
|
||||
See changes from this release in the [changelog PR](https://github.com/facebook/react-native/labels/%F0%9F%93%9D%20Changelog)
|
||||
+1
-1
@@ -27,7 +27,7 @@ If you'd like to discuss topics related to the future of React Native, please ch
|
||||
|
||||
If you want to participate in casual discussions about the use of React Native, consider participating in one of the following forums:
|
||||
|
||||
- [Reactiflux Discord Server](https://www.reactiflux.com)
|
||||
- [Reactiflux Discord Server](https://www.reactiflux)
|
||||
- [Spectrum Chat](https://spectrum.chat/react-native)
|
||||
- [React Native Community Facebook Group](https://www.facebook.com/groups/react.native.community)
|
||||
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
# Configuration for Label Actions - https://github.com/marketplace/actions/label-actions
|
||||
|
||||
"Type: Invalid":
|
||||
close: true
|
||||
"Type: Question":
|
||||
comment: >
|
||||
We are using GitHub issues exclusively to track bugs in React Native. GitHub may not be the ideal place to ask a question, but you can try asking over on [Stack Overflow](http://stackoverflow.com/questions/tagged/react-native), or on [Reactiflux](https://www.reactiflux.com/).
|
||||
close: true
|
||||
"Type: Docs":
|
||||
comment: >
|
||||
Please report documentation issues in the [`react-native-website`](https://github.com/facebook/react-native-website/issues) repository.
|
||||
close: true
|
||||
"Resolution: For Stack Overflow":
|
||||
comment: >
|
||||
We are using GitHub issues exclusively to track bugs in the core React Native library. Please try asking over on [Stack Overflow](http://stackoverflow.com/questions/tagged/react-native) as it is better suited for this type of question.
|
||||
close: true
|
||||
"Needs: Issue Template":
|
||||
comment: >
|
||||
<table><tbody><tr><th width="50">:warning:</th><th width="100%">
|
||||
Missing Required Fields
|
||||
</th></tr><tr><td>:information_source:</td><td>
|
||||
It looks like your issue may be missing some necessary information. GitHub provides an example template whenever a <a href="https://github.com/facebook/react-native/issues/new?template=bug_report.md">new issue is created</a>. Could you go back and make sure to fill out the template? You may edit this issue, or close it and open a new one.
|
||||
</td></tr></tbody></table>
|
||||
labels:
|
||||
- "Needs: Author Feedback"
|
||||
"Needs: Environment Info":
|
||||
comment: >
|
||||
<table><tbody><tr><th width="50">:warning:</th><th width="100%">
|
||||
Missing Environment Information
|
||||
</th></tr><tr><td>:information_source:</td><td>
|
||||
Your issue may be missing information about your development environment. You can obtain the missing information by running <code>react-native info</code> in a console.
|
||||
</td></tr></tbody></table>
|
||||
labels:
|
||||
- "Needs: Author Feedback"
|
||||
"Needs: Verify on Latest Version":
|
||||
comment: >
|
||||
<table><tbody><tr><th width="50">:warning:</th><th width="100%">
|
||||
Using Old Version
|
||||
</th></tr><tr><td>:information_source:</td><td>
|
||||
It looks like you are using an older version of React Native. Please <a href="https://reactnative.dev/docs/upgrading">upgrade</a> to the latest version, and verify if the issue persists. If it does not, please let us know so we can close out this issue. This helps us ensure we are looking at issues that still exist in the current release.
|
||||
</td></tr></tbody></table>
|
||||
labels:
|
||||
- "Needs: Author Feedback"
|
||||
"Needs: Repro":
|
||||
comment: >
|
||||
<table><tbody><tr><th width="50">:warning:</th><th width="100%">
|
||||
Missing Reproducible Example
|
||||
</th></tr><tr><td>:information_source:</td><td>
|
||||
It looks like your issue is missing a reproducible example. Please provide a <a href="https://snack.expo.io">Snack</a> or a repository that demonstrates the issue you are reporting in a <a href="https://stackoverflow.com/help/minimal-reproducible-example">minimal, complete, and reproducible</a> manner.
|
||||
</td></tr></tbody></table>
|
||||
labels:
|
||||
- "Needs: Author Feedback"
|
||||
@@ -1,52 +0,0 @@
|
||||
# Configuration for Respond To Issue Based on Label https://github.com/marketplace/actions/respond-to-issue-based-on-label
|
||||
|
||||
"Type: Invalid":
|
||||
close: true
|
||||
"Type: Question":
|
||||
comment: >
|
||||
We are using GitHub issues exclusively to track bugs in React Native. GitHub may not be the ideal place to ask a question, but you can try asking over on [Stack Overflow](http://stackoverflow.com/questions/tagged/react-native), or on [Reactiflux](https://www.reactiflux.com/).
|
||||
close: true
|
||||
"Type: Docs":
|
||||
comment: >
|
||||
Please report documentation issues in the [`react-native-website`](https://github.com/facebook/react-native-website/issues) repository.
|
||||
close: true
|
||||
"Resolution: For Stack Overflow":
|
||||
comment: >
|
||||
We are using GitHub issues exclusively to track bugs in the core React Native library. Please try asking over on [Stack Overflow](http://stackoverflow.com/questions/tagged/react-native) as it is better suited for this type of question.
|
||||
close: true
|
||||
"Needs: Issue Template":
|
||||
comment: >
|
||||
<table><tbody><tr><th width="50">:warning:</th><th width="100%">
|
||||
Missing Required Fields
|
||||
</th></tr><tr><td>:information_source:</td><td>
|
||||
It looks like your issue may be missing some necessary information. GitHub provides an example template whenever a <a href="https://github.com/facebook/react-native/issues/new?template=bug_report.md">new issue is created</a>. Could you go back and make sure to fill out the template? You may edit this issue, or close it and open a new one.
|
||||
</td></tr></tbody></table>
|
||||
labels:
|
||||
- "Needs: Author Feedback"
|
||||
"Needs: Environment Info":
|
||||
comment: >
|
||||
<table><tbody><tr><th width="50">:warning:</th><th width="100%">
|
||||
Missing Environment Information
|
||||
</th></tr><tr><td>:information_source:</td><td>
|
||||
Your issue may be missing information about your development environment. You can obtain the missing information by running <code>react-native info</code> in a console.
|
||||
</td></tr></tbody></table>
|
||||
labels:
|
||||
- "Needs: Author Feedback"
|
||||
"Needs: Verify on Latest Version":
|
||||
comment: >
|
||||
<table><tbody><tr><th width="50">:warning:</th><th width="100%">
|
||||
Using Old Version
|
||||
</th></tr><tr><td>:information_source:</td><td>
|
||||
It looks like you are using an older version of React Native. Please <a href="https://reactnative.dev/docs/upgrading">upgrade</a> to the latest version, and verify if the issue persists. If it does not, please let us know so we can close out this issue. This helps us ensure we are looking at issues that still exist in the current release.
|
||||
</td></tr></tbody></table>
|
||||
labels:
|
||||
- "Needs: Author Feedback"
|
||||
"Needs: Repro":
|
||||
comment: >
|
||||
<table><tbody><tr><th width="50">:warning:</th><th width="100%">
|
||||
Missing Reproducible Example
|
||||
</th></tr><tr><td>:information_source:</td><td>
|
||||
It looks like your issue is missing a reproducible example. Please provide a <a href="https://snack.expo.dev">Snack</a> or a repository that demonstrates the issue you are reporting in a <a href="https://stackoverflow.com/help/minimal-reproducible-example">minimal, complete, and reproducible</a> manner.
|
||||
</td></tr></tbody></table>
|
||||
labels:
|
||||
- "Needs: Author Feedback"
|
||||
@@ -0,0 +1,26 @@
|
||||
# Configuration for probot-stale - https://github.com/probot/stale
|
||||
# Number of days of inactivity before an issue becomes stale
|
||||
daysUntilStale: 90
|
||||
# Number of days of inactivity before a stale issue is closed
|
||||
daysUntilClose: 7
|
||||
# Issues with these labels will never be considered stale
|
||||
exemptLabels:
|
||||
- Good first issue
|
||||
- "Type: Discussion"
|
||||
- Partner
|
||||
- Core Team
|
||||
- "Help Wanted :octocat:"
|
||||
- "Impact: Regression"
|
||||
- "Resolution: PR Submitted"
|
||||
- "Resolution: Backlog"
|
||||
# Label to use when marking an issue as stale
|
||||
staleLabel: Stale
|
||||
# Comment to post when marking an issue as stale. Set to `false` to disable
|
||||
markComment: >
|
||||
Hey there, it looks like there has been no activity on this issue recently. Has the issue been fixed, or does it still require the community's attention? This issue may be closed if no further activity occurs.
|
||||
You may also label this issue as a "Discussion" or add it to the "Backlog" and I will leave it open.
|
||||
Thank you for your contributions.
|
||||
# Comment to post when closing a stale issue. Set to `false` to disable
|
||||
closeComment: >
|
||||
Closing this issue after a prolonged period of inactivity. If this issue is still present in the latest release, please feel free to create a new issue with up-to-date information.
|
||||
only: issues
|
||||
@@ -1,21 +0,0 @@
|
||||
name: Apply version label to issue
|
||||
|
||||
on:
|
||||
issues:
|
||||
types: [opened, edited]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
add-version-label-issue:
|
||||
permissions:
|
||||
issues: write # for react-native-community/actions-apply-version-label to label issues
|
||||
runs-on: ubuntu-latest
|
||||
continue-on-error: true
|
||||
|
||||
steps:
|
||||
- uses: react-native-community/actions-apply-version-label@v0.0.3
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
required-label: "Type: Upgrade Issue"
|
||||
@@ -1,24 +0,0 @@
|
||||
name: Automatic Rebase
|
||||
on:
|
||||
issue_comment:
|
||||
types: [created]
|
||||
permissions:
|
||||
contents: read
|
||||
jobs:
|
||||
rebase:
|
||||
permissions:
|
||||
contents: write # for cirrus-actions/rebase to push code to rebase
|
||||
pull-requests: read # for cirrus-actions/rebase to get info about PR
|
||||
name: Rebase
|
||||
if: github.event.issue.pull_request != '' && contains(github.event.comment.body, '/rebase')
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout the latest code
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
fetch-depth: 0 # otherwise, you will fail to push refs to dest repo
|
||||
- name: Automatic Rebase
|
||||
uses: cirrus-actions/rebase@1.7
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
@@ -1,27 +0,0 @@
|
||||
name: Run Danger on PR
|
||||
|
||||
on:
|
||||
pull_request_target:
|
||||
types: [opened, edited, reopened, synchronize]
|
||||
|
||||
permissions:
|
||||
actions: write
|
||||
checks: write
|
||||
contents: write
|
||||
issues: write
|
||||
pull-requests: write
|
||||
statuses: write
|
||||
|
||||
jobs:
|
||||
danger:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Run Yarn Install on Root
|
||||
run: yarn install
|
||||
working-directory: .
|
||||
- name: Danger
|
||||
run: yarn danger ci --use-github-checks --failOnErrors
|
||||
working-directory: packages/react-native-bots
|
||||
env:
|
||||
DANGER_GITHUB_API_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
@@ -4,18 +4,12 @@ on:
|
||||
issue_comment:
|
||||
types: created
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
applyNeedsAttentionLabel:
|
||||
permissions:
|
||||
contents: read # for actions/checkout to fetch code
|
||||
issues: write # for hramos/needs-attention to label issues
|
||||
name: Apply Needs Attention Label
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v2
|
||||
- name: Apply Needs Attention Label
|
||||
uses: hramos/needs-attention@v1
|
||||
with:
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
name: On Issue Labeled
|
||||
# This workflow is triggered when a label is added to an issue.
|
||||
on:
|
||||
issues:
|
||||
types: labeled
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
respondToIssueBasedOnLabel:
|
||||
permissions:
|
||||
contents: read # for hramos/respond-to-issue-based-on-label to fetch config file
|
||||
issues: write # for hramos/respond-to-issue-based-on-label to update issues
|
||||
name: Respond to Issue Based on Label
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Respond to Issue Based on Label
|
||||
uses: hramos/respond-to-issue-based-on-label@v2
|
||||
with:
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
@@ -0,0 +1,16 @@
|
||||
name: Label Actions
|
||||
# This workflow is triggered when a label is added to an issue.
|
||||
on:
|
||||
issues:
|
||||
types: labeled
|
||||
|
||||
jobs:
|
||||
processLabelAction:
|
||||
name: Process Label Action
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Process Label Action
|
||||
uses: hramos/label-actions@v1
|
||||
with:
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
@@ -1,19 +0,0 @@
|
||||
name: Mark stale issues and pull requests
|
||||
on:
|
||||
schedule:
|
||||
- cron: "30 1 * * *"
|
||||
jobs:
|
||||
stale:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
issues: write
|
||||
pull-requests: write
|
||||
steps:
|
||||
- uses: actions/stale@v5
|
||||
with:
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
days-before-stale: 180
|
||||
stale-issue-message: 'This issue is stale because it has been open 180 days with no activity. Remove stale label or comment or this will be closed in 7 days.'
|
||||
stale-pr-message: 'This PR is stale because it has been open 180 days with no activity. Remove stale label or comment or this will be closed in 7 days.'
|
||||
close-issue-message: 'This issue was closed because it has been stalled for 7 days with no activity.'
|
||||
close-pr-message: 'This PR was closed because it has been stalled for 7 days with no activity.'
|
||||
@@ -1,26 +0,0 @@
|
||||
name: Test Docker Android Image
|
||||
# This workflow is triggered on commits to main and pull requests.
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
pull_request:
|
||||
branches:
|
||||
- main
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
test-docker-android:
|
||||
name: Test Docker
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Free up space by removing unnecessary folders
|
||||
run: |
|
||||
sudo rm -rf /usr/share/dotnet
|
||||
sudo rm -rf /opt/ghc
|
||||
sudo rm -rf "$AGENT_TOOLSDIRECTORY"
|
||||
- name: Build Docker image with Android test app
|
||||
run: npm run docker-build-android
|
||||
+14
-53
@@ -20,34 +20,21 @@ DerivedData
|
||||
*.ipa
|
||||
*.xcuserstate
|
||||
project.xcworkspace
|
||||
**/.xcode.env.local
|
||||
|
||||
# Gradle
|
||||
/build/
|
||||
/packages/react-native-gradle-plugin/build/
|
||||
/packages/rn-tester/build
|
||||
/packages/rn-tester/android/app/.cxx/
|
||||
/packages/rn-tester/android/app/build/
|
||||
/packages/rn-tester/android/app/gradle/
|
||||
/packages/rn-tester/android/app/gradlew
|
||||
/packages/rn-tester/android/app/gradlew.bat
|
||||
/RNTester/android/app/build/
|
||||
/RNTester/android/app/gradle/
|
||||
/RNTester/android/app/gradlew
|
||||
/RNTester/android/app/gradlew.bat
|
||||
/ReactAndroid/build/
|
||||
/ReactAndroid/.cxx/
|
||||
/ReactAndroid/gradle/
|
||||
/ReactAndroid/gradlew
|
||||
/ReactAndroid/gradlew.bat
|
||||
/ReactAndroid/external-artifacts/build/
|
||||
/ReactAndroid/external-artifacts/artifacts/
|
||||
/ReactAndroid/hermes-engine/build/
|
||||
/ReactAndroid/hermes-engine/.cxx/
|
||||
/template/android/app/build/
|
||||
/template/android/build/
|
||||
|
||||
# Buck
|
||||
.buckd
|
||||
buck-out
|
||||
/.lsp.buckd
|
||||
/.lsp-buck-out
|
||||
/ReactAndroid/src/main/jni/prebuilt/lib/
|
||||
/ReactAndroid/src/main/gen
|
||||
|
||||
@@ -64,13 +51,13 @@ buck-out
|
||||
.gradle
|
||||
local.properties
|
||||
*.iml
|
||||
/android/*
|
||||
!/android/README.md
|
||||
/android/
|
||||
|
||||
# Node
|
||||
node_modules
|
||||
*.log
|
||||
.nvm
|
||||
/bots/node_modules/
|
||||
package-lock.json
|
||||
|
||||
# OS X
|
||||
@@ -88,54 +75,28 @@ package-lock.json
|
||||
|
||||
# ReactCommon subdir shouldn't have Xcode project
|
||||
/ReactCommon/**/*.xcodeproj
|
||||
RNTester/build
|
||||
|
||||
# Libs that shouldn't have Xcode project
|
||||
/Libraries/FBLazyVector/**/*.xcodeproj
|
||||
/Libraries/FBReactNativeSpec/**/*.xcodeproj
|
||||
/Libraries/RCTRequired/**/*.xcodeproj
|
||||
/React/CoreModules/**/*.xcodeproj
|
||||
/React/FBReactNativeSpec/**/*.xcodeproj
|
||||
/packages/react-native-codegen/**/*.xcodeproj
|
||||
|
||||
# Ruby Gems (Bundler)
|
||||
/vendor
|
||||
/template/vendor
|
||||
.ruby-version
|
||||
/**/.ruby-version
|
||||
|
||||
# iOS / CocoaPods
|
||||
/template/ios/build/
|
||||
# CocoaPods
|
||||
/template/ios/Pods/
|
||||
/template/ios/Podfile.lock
|
||||
/packages/rn-tester/Gemfile.lock
|
||||
/RNTester/Gemfile.lock
|
||||
|
||||
# Ignore RNTester specific Pods, but keep the __offline_mirrors__ here.
|
||||
/packages/rn-tester/Pods/*
|
||||
!/packages/rn-tester/Pods/__offline_mirrors_hermes__
|
||||
!/packages/rn-tester/Pods/__offline_mirrors_jsc__
|
||||
RNTester/Pods/*
|
||||
!RNTester/Pods/__offline_mirrors
|
||||
|
||||
# react-native-codegen
|
||||
/React/FBReactNativeSpec/FBReactNativeSpec
|
||||
/packages/react-native-codegen/lib
|
||||
/packages/react-native-codegen/tmp/
|
||||
/ReactCommon/react/renderer/components/rncore/
|
||||
/packages/rn-tester/NativeModuleExample/ScreenshotManagerSpec*
|
||||
|
||||
|
||||
# Additional SDKs
|
||||
/sdks/download
|
||||
/sdks/hermes
|
||||
/sdks/hermesc
|
||||
/sdks/hermes-engine/build_host_hermesc
|
||||
/ReactCommon/fabric/components/rncore/
|
||||
/schema-rncore.json
|
||||
|
||||
# Visual studio
|
||||
.vscode
|
||||
.vs
|
||||
|
||||
# Android memory profiler files
|
||||
*.hprof
|
||||
|
||||
# Temporary files created by Metro to check the health of the file watcher
|
||||
.metro-health-check*
|
||||
|
||||
# monorepo (main)
|
||||
packages/react-native/
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
18
|
||||
+3
-4
@@ -1,8 +1,7 @@
|
||||
{
|
||||
"arrowParens": "avoid",
|
||||
"bracketSameLine": true,
|
||||
"bracketSpacing": false,
|
||||
"requirePragma": true,
|
||||
"singleQuote": true,
|
||||
"trailingComma": "all"
|
||||
"trailingComma": "all",
|
||||
"bracketSpacing": false,
|
||||
"jsxBracketSameLine": true
|
||||
}
|
||||
|
||||
-4860
File diff suppressed because it is too large
Load Diff
+2
-2
@@ -67,8 +67,8 @@ members of the project's leadership.
|
||||
|
||||
## Attribution
|
||||
|
||||
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 2.1,
|
||||
available at https://www.contributor-covenant.org/version/2/1/code_of_conduct/
|
||||
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
|
||||
available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
|
||||
|
||||
[homepage]: https://www.contributor-covenant.org
|
||||
|
||||
|
||||
+108
-4
@@ -1,7 +1,111 @@
|
||||
# Contributing to React Native
|
||||
|
||||
Thank you for your interest in contributing to React Native! From commenting on and triaging issues, to reviewing and sending Pull Requests, all contributions are welcome.
|
||||
We aim to build a vibrant and inclusive [ecosystem of partners, core contributors, and community](ECOSYSTEM.md) that goes beyond the main React Native GitHub repository.
|
||||
Thank you for your interest in contributing to React Native! From commenting on and triaging issues, to reviewing and sending Pull Requests, all contributions are welcome. We aim to build a vibrant and inclusive [ecosystem of partners, core contributors, and community](ECOSYSTEM.md) that goes beyond the main React Native GitHub repository.
|
||||
|
||||
To learn more about how to contribute check out the Contributing section on the React Native website:
|
||||
* https://reactnative.dev/contributing/overview
|
||||
The [Open Source Guides](https://opensource.guide/) website has a collection of resources for individuals, communities, and companies who want to learn how to run and contribute to an open source project. Contributors and people new to open source alike will find the following guides especially useful:
|
||||
|
||||
* [How to Contribute to Open Source](https://opensource.guide/how-to-contribute/)
|
||||
* [Building Welcoming Communities](https://opensource.guide/building-community/)
|
||||
|
||||
|
||||
### [Code of Conduct](https://github.com/facebook/react/blob/master/CODE_OF_CONDUCT.md)
|
||||
|
||||
As a reminder, all contributors are expected to adhere to the [Code of Conduct](https://github.com/facebook/react/blob/master/CODE_OF_CONDUCT.md).
|
||||
|
||||
## Ways to Contribute
|
||||
|
||||
If you are eager to start contributing code right away, we have a list of [good first issues](https://github.com/facebook/react-native/labels/good%20first%20issue) that contain bugs which have a relatively limited scope. As you gain more experience and demonstrate a commitment to evolving React Native, you may be granted issue management permissions in the repository.
|
||||
|
||||
There are other ways you can contribute without writing a single line of code. Here are a few things you can do to help out:
|
||||
|
||||
1. **Replying and handling open issues.** We get a lot of issues every day, and some of them may lack necessary information. You can help out by guiding people through the process of filling out the issue template, asking for clarifying information, or pointing them to existing issues that match their description of the problem. We cover more about this process in the [Issue Triage wiki](https://github.com/facebook/react-native/wiki/Issues#triage).
|
||||
2. **Reviewing pull requests for the docs.** Reviewing [documentation updates](https://github.com/facebook/react-native-website/pulls) can be as simple as checking for spelling and grammar. If you encounter situations that can be explained better in the docs, click **Edit** at the top of most docs pages to get started with your own contribution.
|
||||
3. **Help people write test plans.** Some pull requests sent to the main repository may lack a proper test plan. These help reviewers understand how the change was tested, and can speed up the time it takes for a contribution to be accepted.
|
||||
|
||||
Each of these tasks is highly impactful, and maintainers will greatly appreciate your help.
|
||||
|
||||
### Our Development Process
|
||||
|
||||
We use GitHub issues and pull requests to keep track of bug reports and contributions from the community. All changes from engineers at Facebook will sync to [GitHub](https://github.com/facebook/react-native) through a bridge with Facebook's internal source control. Changes from the community are handled through GitHub pull requests. Once a change made on GitHub is approved, it will first be imported into Facebook's internal source control and tested against Facebook's codebase. Once merged at Facebook, the change will eventually sync back to GitHub as a single commit once it has passed Facebook's internal tests.
|
||||
|
||||
You can learn more about the contribution process in the following documents:
|
||||
|
||||
* [Issues](https://github.com/facebook/react-native/wiki/Issues)
|
||||
* [Pull Requests](https://github.com/facebook/react-native/wiki/Pull-Requests)
|
||||
|
||||
We also have a thriving community of contributors who would be happy to help you get set up. You can reach out to us through [@ReactNative](http://twitter.com/reactnative) (the React Native team) and [@ReactNativeComm](http://twitter.com/reactnativecomm) (the React Native Community organization).
|
||||
|
||||
### Repositories
|
||||
|
||||
The main repository, <https://github.com/facebook/react-native>, contains the React Native framework itself and it is here where we keep track of bug reports and manage pull requests.
|
||||
|
||||
There are a few other repositories you might want to familiarize yourself with:
|
||||
|
||||
* **React Native website** which contains the source code for the website, including the documentation, located at <https://github.com/facebook/react-native-website>
|
||||
* **Releases** are coordinated through the <https://github.com/react-native-community/react-native-releases> repository. This includes important documents such as the Changelog.
|
||||
* **Discussions** about the future of React Native take place in the <https://github.com/react-native-community/discussions-and-proposals> repository.
|
||||
* **High-quality plugins** for React Native can be found throughout the [React Native Community GitHub Organization](http://github.com/react-native-community/).
|
||||
|
||||
Browsing through these repositories should provide some insight into how the React Native open source project is managed.
|
||||
|
||||
## GitHub Issues
|
||||
|
||||
We use GitHub issues to track bugs exclusively. We have documented our issue handling processes in the [Issues wiki](https://github.com/facebook/react-native/wiki/Issues).
|
||||
|
||||
### Security Bugs
|
||||
|
||||
Facebook has a [bounty program](https://www.facebook.com/whitehat/) for the safe disclosure of security bugs. In those cases, please go through the process outlined on that page and do not file a public issue.
|
||||
|
||||
## Helping with Documentation
|
||||
|
||||
The React Native documentation is hosted as part of the React Native website repository at https://github.com/facebook/react-native-website. The website itself is located at <https://reactnative.dev/> and it is built using [Docusaurus](https://docusaurus.io/). If there's anything you'd like to change in the docs, you can get started by clicking on the "Edit" button located on the upper right of most pages in the website.
|
||||
|
||||
If you are adding new functionality or introducing a change in behavior, we will ask you to update the documentation to reflect your changes.
|
||||
|
||||
### Contributing to the Blog
|
||||
|
||||
The React Native blog is generated [from the Markdown sources for the blog](https://github.com/facebook/react-native-website/tree/master/website/blog).
|
||||
|
||||
Please open an issue in the https://github.com/facebook/react-native-website repository or tag us on [@ReactNative on Twitter](http://twitter.com/reactnative) and get the go-ahead from a maintainer before writing an article intended for the React Native blog. In most cases, you might want to share your article on your own blog or writing medium instead. It's worth asking, though, in case we find your article is a good fit for the blog.
|
||||
|
||||
We recommend referring to the [CONTRIBUTING](https://github.com/facebook/react-native-website/blob/master/CONTRIBUTING.md) document for the `react-native-website` repository to learn more about contributing to the website in general.
|
||||
|
||||
## Contributing Code
|
||||
|
||||
Code-level contributions to React Native generally come in the form of [pull requests](https://help.github.com/en/articles/about-pull-requests). These are done by forking the repo and making changes locally. Directly in the repo, there is the [`RNTester` app](/RNTester) that you can install on your device (or simulators) and use to test the changes you're making to React Native sources.
|
||||
|
||||
The process of proposing a change to React Native can be summarized as follows:
|
||||
|
||||
1. Fork the React Native repository and create your branch from `master`.
|
||||
2. Make the desired changes to React Native sources. Use the `RNTester` app to test them out.
|
||||
3. If you've added code that should be tested, add tests.
|
||||
4. If you've changed APIs, update the documentation, which lives in [another repo](https://github.com/facebook/react-native-website/).
|
||||
5. Ensure the test suite passes, either locally or on CI once you opened a pull request.
|
||||
6. Make sure your code lints (for example via `yarn lint --fix`).
|
||||
7. Push the changes to your fork.
|
||||
8. Create a pull request to the React Native repository.
|
||||
9. Review and address comments on your pull request.
|
||||
1. A bot may comment with suggestions. Generally we ask you to resolve these first before a maintainer will review your code.
|
||||
10. If you haven't already, please complete the [Contributor License Agreement](https://github.com/facebook/react-native/wiki/Contributor-License-Agreement) ("CLA"). **[Complete your CLA here.](https://code.facebook.com/cla)**
|
||||
|
||||
If all goes well, your pull request will be merged. If it is not merged, maintainers will do their best to explain the reason why.
|
||||
|
||||
### Step-by-step Guide
|
||||
|
||||
Whenever you are ready to contribute code, check out our [step-by-step guide to sending your first pull request](https://github.com/facebook/react-native/wiki/Pull-Requests#getting-ready-to-submit-your-first-pull-request), or read the [How to Contribute Code](https://github.com/facebook/react-native/wiki/How-to-Contribute) wiki for more details.
|
||||
|
||||
### Tests
|
||||
|
||||
Tests help us prevent regressions from being introduced to the codebase. The GitHub repository is continuously tested using Circle and Appveyor, the results of which are available through the Checks functionality on [commits](https://github.com/facebook/react-native/commits/master) and pull requests. You can learn more about running and writing tests in the [Tests wiki](http://github.com/facebook/react-native/wiki/Tests).
|
||||
|
||||
## Community Contributions
|
||||
|
||||
Contributions to React Native are not limited to GitHub. You can help others by sharing your experience using React Native, whether that is through blog posts, presenting talks at conferences, or simply sharing your thoughts on Twitter and tagging @ReactNative.
|
||||
|
||||
## Where to Get Help
|
||||
|
||||
As you work on React Native, it is natural that sooner or later you may require help. In addition to the resources listed in [SUPPORT](.github/SUPPORT.md), people interested in contributing may take advantage of the following:
|
||||
|
||||
* **Twitter**. The React Native team at Facebook has its own account at [@reactnative](https://twitter.com/reactnative), and the React Native Community uses [@reactnativecomm](https://twitter.com/reactnativecomm). If you feel stuck, or need help contributing, please do not hesitate to reach out.
|
||||
* **Proposals Repository**. If you are considering working on a feature large in scope, consider [creating a proposal first](https://github.com/react-native-community/discussions-and-proposals). The community can help you figure out the right approach, and we'd be happy to help.
|
||||
* **React Native Community Discord**. While we try to hold most discussions in public, sometimes it can be beneficial to have conversations in real time with other contributors. People who have demonstrated a commitment to moving React Native forward through sustained contributions to the project may eventually be invited to join the React Native Community Discord.
|
||||
|
||||
+13
-29
@@ -1,36 +1,26 @@
|
||||
# The React Native Ecosystem
|
||||
|
||||
We aim to build a vibrant and inclusive ecosystem of partners, core contributors, and community that goes beyond the main React Native GitHub repository. This document explains the roles and responsibilities of various stakeholders and provides guidelines for the community organization. The structure outlined in this document has been in place for a while but had not been written down before.
|
||||
We aim to build a vibrant and inclusive ecosystem of partners, core contributors, and community that goes beyond the main React Native GitHub repository. This document explains the roles and responsibilities of various stakeholders and provides guidelines for the community organization. The structure outlined in this document has been in place for a while but hadn't been written down before.
|
||||
|
||||
There are three types of stakeholders:
|
||||
|
||||
* **Partners:** Companies significantly invested in React Native and take responsibility for the React Native vision and community.
|
||||
* **Partners:** Companies that are significantly invested in React Native and have been for years.
|
||||
* **Core Contributors:** Individual people who contribute to the React Native project.
|
||||
* **Community Contributors:** Individuals who support projects in the [react-native-community](https://github.com/react-native-community) organization.
|
||||
|
||||
## Partners
|
||||
|
||||
Partners are companies that are significantly invested in React Native and demonstrate ownership. Informed by their use of React Native, they push for improvements of the core and/or the ecosystem around it. Examples of this may include large scale contributions to `react-native` or owning essential tools or libraries.
|
||||
Partners are companies that are significantly invested in React Native and have been for years. Informed by their use of React Native, they push for improvements of the core and/or the ecosystem around it. Facebook's partners think of React Native as a product: they understand the trade offs that the project makes as well as future plans and goals. Together we shape the vision for React Native to make it the best way to build applications.
|
||||
|
||||
Partners think of React Native as a product; they understand the trade offs that the project makes as well as future plans and goals. Together we shape the vision for React Native to make it the best way to build applications.
|
||||
Our current set of partners include Callstack, Expo, Infinite Red, Microsoft and Software Mansion. Many engineers from these companies are core contributors, and their partner responsibilities also include:
|
||||
|
||||
Baseline responsibilities of partners include:
|
||||
* Attending monthly meeting
|
||||
* Contributing to the release process. Examples include being a [community releaser](https://reactnative.dev/contributing/release-roles-responsibilities#release-role-2-community-releaser), testing new releases, technical support for release issues.
|
||||
* Engage on the core contributor Discord
|
||||
* **[Callstack](https://callstack.com/):** Manages releases, maintains the [React Native CLI](https://github.com/react-native-community/react-native-cli) and organizes [React Native EU](https://react-native.eu/)
|
||||
* **[Expo](https://expo.io/):** Builds [expo](https://github.com/expo/expo) on top of React Native to simplify app development
|
||||
* **[Infinite Red](https://infinite.red/):** Maintains the [ignite cli/boilerplate](https://github.com/infinitered/ignite), organizes [Chain React Conf](https://infinite.red/ChainReactConf)
|
||||
* **[Microsoft](https://www.microsoft.com/en-gb/):** Develops [React Native Windows](https://github.com/Microsoft/react-native-windows) for the Universal Windows Platform (UWP)
|
||||
* **[Software Mansion](https://swmansion.com/):** Maintain core infrastructure including JSC, Animated, and other popular third-party plugins.
|
||||
|
||||
Our current partners and other areas of ownership:
|
||||
* **[Coinbase](https://www.coinbase.com/):** Publishes [posts](https://blog.coinbase.com/tagged/react-native) advocating React Native usage. Supports `@react-native-community/datetimepicker` and other community modules to migrate to the new architecture. Supports releases in testing and feedback.
|
||||
* **[Callstack](https://callstack.com/):** Maintains the [React Native CLI](https://github.com/react-native-community/react-native-cli) and [other community libraries](https://github.com/callstack), organizes [React Native EU](https://react-native.eu/) and hosts [The React Native Show podcast](https://www.callstack.com/podcast-react-native-show)
|
||||
* **[Expo](https://expo.dev/):** Builds [Expo Go and SDK](https://github.com/expo/expo), [Snack](https://snack.expo.dev/), and [Expo Application Services](https://expo.dev/eas). Maintains [React Native Directory](https://reactnative.directory/), stewards [React Navigation](https://reactnavigation.org/) along with other partners.
|
||||
* **[Infinite Red](https://infinite.red/):** Maintains the [ignite cli/boilerplate](https://github.com/infinitered/ignite), organizes [Chain React Conf](https://cr.infinite.red/), hosts the [React Native Radio podcast](https://reactnativeradio.com), publishes the [React Native Newsletter](https://reactnativenewsletter.com)
|
||||
* **[Meta](https://opensource.fb.com/):** Oversees the React Native product and maintains the [React Native core repo](https://reactnative.dev/)
|
||||
* **[Microsoft](https://twitter.com/ReactNativeMSFT):** Develops [React Native Windows](https://github.com/Microsoft/react-native-windows) and [React Native macOS](https://github.com/microsoft/react-native-macos) for building apps that target Windows and macOS; maintains [rnx-kit](https://github.com/microsoft/rnx-kit), [react-native-test-app](https://github.com/microsoft/react-native-test-app) and coordinates cross-companies efforts such as the [bundle working group](https://github.com/microsoft/rnx-kit/discussions/categories/bundle-working-group).
|
||||
* **[Shopify](https://www.shopify.com/):** Maintains React Native open source libraries such as [flash-list](https://github.com/Shopify/flash-list) or [@shopify/react-native-skia](https://github.com/Shopify/react-native-skia) and sponsors Software Mansion.
|
||||
* **[Software Mansion](https://swmansion.com/):** Maintain core infrastructure including JSC, Animated, and other popular third-party plugins and organizes [App.js Conf](https://appjs.co/)
|
||||
* **[Wix.com](https://wix.engineering/open-source):** Maintains a variety of React Native open source projects ([see all](https://github.com/orgs/wix/repositories?q=react-native)), including: [Detox](https://wix.github.io/Detox/) end-to-end testing library for React Native apps, [RN UILib](https://wix.github.io/react-native-ui-lib/), [RN Navigation](https://wix.github.io/react-native-navigation/), [RN Calendars](https://wix.github.io/react-native-calendars/) and [RN Notifications](https://github.com/wix/react-native-notifications).
|
||||
|
||||
This list may fluctuate in response to newcomers who meet our partner definition. In terms of open source work, pull requests from partners are commonly prioritized. When you are contributing to React Native, you'll most likely meet somebody who works at one of the partner companies and who is a core contributor:
|
||||
In terms of open source work, pull requests from partners are commonly prioritized. When you are contributing to React Native, you'll most likely meet somebody who works at one of the partner companies and who is a core contributor:
|
||||
|
||||
## Core Contributors
|
||||
|
||||
@@ -47,19 +37,13 @@ Core contributors are individuals who contribute to the React Native project. A
|
||||
|
||||
These are behaviors we have observed in our existing core contributors. They aren't strict rules but rather outline their usual responsibilities. We do not expect every core contributor to do all of the above things all the time. Most importantly, we want to create a supportive and friendly environment that fosters collaboration. Above all else, **we are always polite and friendly.**
|
||||
|
||||
Core contributor status is attained after consistently contributing and taking on the responsibilities outlined above and granted by other core contributors. Similarly, after a long period of inactivity (~6 months or more), a core contributor may be contacted to understand if they’re still interested in being part of the program.
|
||||
Core contributor status is attained after consistently contributing and taking on the responsibilities outlined above and granted by other core contributors. Similarly, after a long period of inactivity, a core contributor may be removed.
|
||||
|
||||
You can use this [form](https://forms.gle/4jpA4QeNUvAUDnNe8) to either:
|
||||
* Apply yourself to become a Core Contributor. Make sure to include a list of valuable contributions you did to the React Native repository and ecosystem.
|
||||
* Nominate someone to become a Core Contributor.
|
||||
|
||||
As a core contributor, you will have access to the core contributor Discord which is used for light-weight coordination and discussion.
|
||||
|
||||
**We aim to make contributing to React Native as easy and transparent as possible.** We have discussion groups dedicated to the [new architecture rollout](https://github.com/reactwg/react-native-new-architecture), [releases](https://github.com/reactwg/react-native-releases), and [general questions and proposals](https://github.com/react-native-community/discussions-and-proposals). We are always looking for active, enthusiastic members of the React Native community to become core contributors.
|
||||
We aim to make contributing to React Native as easy and transparent as possible. All important topics are handled through a [discussion or RFC process on GitHub](https://github.com/react-native-community/discussions-and-proposals). We are always looking for active, enthusiastic members of the React Native community to become core contributors.
|
||||
|
||||
## Community Contributors
|
||||
|
||||
Community contributors are individuals who support projects in the [react-native-community](https://github.com/react-native-community) organization. This organization exists as an incubator for high quality components that extend the capabilities of React Native with functionality that many but not all applications require. Meta engineers will provide guidance to help build a vibrant community of people and components that make React Native better.
|
||||
Community contributors are individuals who support projects in the [react-native-community](https://github.com/react-native-community) organization. This organization exists as an incubator for high quality components that extend the capabilities of React Native with functionality that many but not all applications require. Facebook engineers will provide guidance to help build a vibrant community of people and components that make React Native better.
|
||||
|
||||
This structure has multiple benefits:
|
||||
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
source 'https://rubygems.org'
|
||||
|
||||
# You may use http://rbenv.org/ or https://rvm.io/ to install and use this version
|
||||
ruby '>= 2.6.10'
|
||||
|
||||
gem 'cocoapods', '>= 1.11.3'
|
||||
gem 'activesupport', '>= 6.1.7.3', '< 7.1.0'
|
||||
@@ -1,99 +0,0 @@
|
||||
GEM
|
||||
remote: https://rubygems.org/
|
||||
specs:
|
||||
CFPropertyList (3.0.6)
|
||||
rexml
|
||||
activesupport (7.0.8)
|
||||
concurrent-ruby (~> 1.0, >= 1.0.2)
|
||||
i18n (>= 1.6, < 2)
|
||||
minitest (>= 5.1)
|
||||
tzinfo (~> 2.0)
|
||||
addressable (2.8.6)
|
||||
public_suffix (>= 2.0.2, < 6.0)
|
||||
algoliasearch (1.27.5)
|
||||
httpclient (~> 2.8, >= 2.8.3)
|
||||
json (>= 1.5.1)
|
||||
atomos (0.1.3)
|
||||
claide (1.1.0)
|
||||
cocoapods (1.14.3)
|
||||
addressable (~> 2.8)
|
||||
claide (>= 1.0.2, < 2.0)
|
||||
cocoapods-core (= 1.14.3)
|
||||
cocoapods-deintegrate (>= 1.0.3, < 2.0)
|
||||
cocoapods-downloader (>= 2.1, < 3.0)
|
||||
cocoapods-plugins (>= 1.0.0, < 2.0)
|
||||
cocoapods-search (>= 1.0.0, < 2.0)
|
||||
cocoapods-trunk (>= 1.6.0, < 2.0)
|
||||
cocoapods-try (>= 1.1.0, < 2.0)
|
||||
colored2 (~> 3.1)
|
||||
escape (~> 0.0.4)
|
||||
fourflusher (>= 2.3.0, < 3.0)
|
||||
gh_inspector (~> 1.0)
|
||||
molinillo (~> 0.8.0)
|
||||
nap (~> 1.0)
|
||||
ruby-macho (>= 2.3.0, < 3.0)
|
||||
xcodeproj (>= 1.23.0, < 2.0)
|
||||
cocoapods-core (1.14.3)
|
||||
activesupport (>= 5.0, < 8)
|
||||
addressable (~> 2.8)
|
||||
algoliasearch (~> 1.0)
|
||||
concurrent-ruby (~> 1.1)
|
||||
fuzzy_match (~> 2.0.4)
|
||||
nap (~> 1.0)
|
||||
netrc (~> 0.11)
|
||||
public_suffix (~> 4.0)
|
||||
typhoeus (~> 1.0)
|
||||
cocoapods-deintegrate (1.0.5)
|
||||
cocoapods-downloader (2.1)
|
||||
cocoapods-plugins (1.0.0)
|
||||
nap
|
||||
cocoapods-search (1.0.1)
|
||||
cocoapods-trunk (1.6.0)
|
||||
nap (>= 0.8, < 2.0)
|
||||
netrc (~> 0.11)
|
||||
cocoapods-try (1.2.0)
|
||||
colored2 (3.1.2)
|
||||
concurrent-ruby (1.2.2)
|
||||
escape (0.0.4)
|
||||
ethon (0.16.0)
|
||||
ffi (>= 1.15.0)
|
||||
ffi (1.16.3)
|
||||
fourflusher (2.3.1)
|
||||
fuzzy_match (2.0.4)
|
||||
gh_inspector (1.1.3)
|
||||
httpclient (2.8.3)
|
||||
i18n (1.14.1)
|
||||
concurrent-ruby (~> 1.0)
|
||||
json (2.7.1)
|
||||
minitest (5.20.0)
|
||||
molinillo (0.8.0)
|
||||
nanaimo (0.3.0)
|
||||
nap (1.1.0)
|
||||
netrc (0.11.0)
|
||||
public_suffix (4.0.7)
|
||||
rexml (3.2.6)
|
||||
ruby-macho (2.5.1)
|
||||
typhoeus (1.4.1)
|
||||
ethon (>= 0.9.0)
|
||||
tzinfo (2.0.6)
|
||||
concurrent-ruby (~> 1.0)
|
||||
xcodeproj (1.23.0)
|
||||
CFPropertyList (>= 2.3.3, < 4.0)
|
||||
atomos (~> 0.1.3)
|
||||
claide (>= 1.0.2, < 2.0)
|
||||
colored2 (~> 3.1)
|
||||
nanaimo (~> 0.3.0)
|
||||
rexml (~> 3.2.4)
|
||||
|
||||
PLATFORMS
|
||||
ruby
|
||||
|
||||
DEPENDENCIES
|
||||
activesupport (>= 6.1.7.3, < 7.1.0)
|
||||
cocoapods (>= 1.11.3)
|
||||
|
||||
RUBY VERSION
|
||||
ruby 2.7.6p219
|
||||
|
||||
BUNDLED WITH
|
||||
2.3.22
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
@@ -8,15 +8,18 @@
|
||||
* @flow strict-local
|
||||
*/
|
||||
|
||||
import invariant from 'invariant';
|
||||
import NativeAccessibilityManager from 'react-native/Libraries/Components/AccessibilityInfo/NativeAccessibilityManager';
|
||||
import {DeviceEventEmitter, NativeModules, View} from 'react-native';
|
||||
import * as React from 'react';
|
||||
'use strict';
|
||||
|
||||
const {TestModule} = NativeModules;
|
||||
const React = require('react');
|
||||
const ReactNative = require('react-native');
|
||||
const {View} = ReactNative;
|
||||
const RCTDeviceEventEmitter = require('react-native/Libraries/EventEmitter/RCTDeviceEventEmitter');
|
||||
const {TestModule} = ReactNative.NativeModules;
|
||||
import NativeAccessibilityManager from 'react-native/Libraries/Components/AccessibilityInfo/NativeAccessibilityManager';
|
||||
import invariant from 'invariant';
|
||||
|
||||
class AccessibilityManagerTest extends React.Component<{...}> {
|
||||
componentDidMount(): void {
|
||||
componentDidMount() {
|
||||
invariant(
|
||||
NativeAccessibilityManager,
|
||||
"NativeAccessibilityManager doesn't exist",
|
||||
@@ -36,7 +39,7 @@ class AccessibilityManagerTest extends React.Component<{...}> {
|
||||
accessibilityExtraExtraLarge: 11.0,
|
||||
accessibilityExtraExtraExtraLarge: 12.0,
|
||||
});
|
||||
DeviceEventEmitter.addListener('didUpdateDimensions', update => {
|
||||
RCTDeviceEventEmitter.addListener('didUpdateDimensions', update => {
|
||||
TestModule.markTestPassed(update.window.fontScale === 4.0);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
|
||||
@@ -0,0 +1,217 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its 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 ReactNative = require('react-native');
|
||||
const {AsyncStorage, Text, View, StyleSheet} = ReactNative;
|
||||
const {TestModule} = ReactNative.NativeModules;
|
||||
|
||||
const deepDiffer = require('react-native/Libraries/Utilities/differ/deepDiffer');
|
||||
|
||||
const DEBUG = false;
|
||||
|
||||
const KEY_1 = 'key_1';
|
||||
const VAL_1 = 'val_1';
|
||||
const KEY_2 = 'key_2';
|
||||
const VAL_2 = 'val_2';
|
||||
const KEY_MERGE = 'key_merge';
|
||||
const VAL_MERGE_1 = {foo: 1, bar: {hoo: 1, boo: 1}, moo: {a: 3}};
|
||||
const VAL_MERGE_2 = {bar: {hoo: 2}, baz: 2, moo: {a: 3}};
|
||||
const VAL_MERGE_EXPECT = {foo: 1, bar: {hoo: 2, boo: 1}, baz: 2, moo: {a: 3}};
|
||||
|
||||
// setup in componentDidMount
|
||||
let done = (result: ?boolean) => {};
|
||||
let updateMessage = (message: string) => {};
|
||||
|
||||
function runTestCase(description: string, fn) {
|
||||
updateMessage(description);
|
||||
fn();
|
||||
}
|
||||
|
||||
function expectTrue(condition: boolean, message: string) {
|
||||
if (!condition) {
|
||||
throw new Error(message);
|
||||
}
|
||||
}
|
||||
|
||||
function expectEqual(lhs, rhs, testname: string) {
|
||||
expectTrue(
|
||||
!deepDiffer(lhs, rhs),
|
||||
'Error in test ' +
|
||||
testname +
|
||||
': expected\n' +
|
||||
JSON.stringify(rhs) +
|
||||
'\ngot\n' +
|
||||
JSON.stringify(lhs),
|
||||
);
|
||||
}
|
||||
|
||||
function expectAsyncNoError(place, err) {
|
||||
if (err instanceof Error) {
|
||||
err = err.message;
|
||||
}
|
||||
expectTrue(
|
||||
err === null,
|
||||
'Unexpected error in ' + place + ': ' + JSON.stringify(err),
|
||||
);
|
||||
}
|
||||
|
||||
function testSetAndGet() {
|
||||
AsyncStorage.setItem(KEY_1, VAL_1, err1 => {
|
||||
expectAsyncNoError('testSetAndGet/setItem', err1);
|
||||
AsyncStorage.getItem(KEY_1, (err2, result) => {
|
||||
expectAsyncNoError('testSetAndGet/getItem', err2);
|
||||
expectEqual(result, VAL_1, 'testSetAndGet setItem');
|
||||
updateMessage('get(key_1) correctly returned ' + result);
|
||||
runTestCase('should get null for missing key', testMissingGet);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function testMissingGet() {
|
||||
AsyncStorage.getItem(KEY_2, (err, result) => {
|
||||
expectAsyncNoError('testMissingGet/setItem', err);
|
||||
expectEqual(result, null, 'testMissingGet');
|
||||
updateMessage('missing get(key_2) correctly returned ' + result);
|
||||
runTestCase('check set twice results in a single key', testSetTwice);
|
||||
});
|
||||
}
|
||||
|
||||
function testSetTwice() {
|
||||
AsyncStorage.setItem(KEY_1, VAL_1, () => {
|
||||
AsyncStorage.setItem(KEY_1, VAL_1, () => {
|
||||
AsyncStorage.getItem(KEY_1, (err, result) => {
|
||||
expectAsyncNoError('testSetTwice/setItem', err);
|
||||
expectEqual(result, VAL_1, 'testSetTwice');
|
||||
updateMessage('setTwice worked as expected');
|
||||
runTestCase('test removeItem', testRemoveItem);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function testRemoveItem() {
|
||||
AsyncStorage.setItem(KEY_1, VAL_1, () => {
|
||||
AsyncStorage.setItem(KEY_2, VAL_2, () => {
|
||||
AsyncStorage.getAllKeys((err, result) => {
|
||||
expectAsyncNoError('testRemoveItem/getAllKeys', err);
|
||||
expectTrue(
|
||||
result.indexOf(KEY_1) >= 0 && result.indexOf(KEY_2) >= 0,
|
||||
'Missing KEY_1 or KEY_2 in ' + '(' + result + ')',
|
||||
);
|
||||
updateMessage('testRemoveItem - add two items');
|
||||
AsyncStorage.removeItem(KEY_1, err2 => {
|
||||
expectAsyncNoError('testRemoveItem/removeItem', err2);
|
||||
updateMessage('delete successful ');
|
||||
AsyncStorage.getItem(KEY_1, (err3, result2) => {
|
||||
expectAsyncNoError('testRemoveItem/getItem', err3);
|
||||
expectEqual(
|
||||
result2,
|
||||
null,
|
||||
'testRemoveItem: key_1 present after delete',
|
||||
);
|
||||
updateMessage('key properly removed ');
|
||||
AsyncStorage.getAllKeys((err4, result3) => {
|
||||
expectAsyncNoError('testRemoveItem/getAllKeys', err4);
|
||||
expectTrue(
|
||||
result3.indexOf(KEY_1) === -1,
|
||||
'Unexpected: KEY_1 present in ' + result3,
|
||||
);
|
||||
updateMessage('proper length returned.');
|
||||
runTestCase('should merge values', testMerge);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function testMerge() {
|
||||
AsyncStorage.setItem(KEY_MERGE, JSON.stringify(VAL_MERGE_1), err1 => {
|
||||
expectAsyncNoError('testMerge/setItem', err1);
|
||||
AsyncStorage.mergeItem(KEY_MERGE, JSON.stringify(VAL_MERGE_2), err2 => {
|
||||
expectAsyncNoError('testMerge/mergeItem', err2);
|
||||
AsyncStorage.getItem(KEY_MERGE, (err3, result) => {
|
||||
expectAsyncNoError('testMerge/setItem', err3);
|
||||
expectEqual(JSON.parse(result), VAL_MERGE_EXPECT, 'testMerge');
|
||||
updateMessage('objects deeply merged\nDone!');
|
||||
runTestCase('multi set and get', testOptimizedMultiGet);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function testOptimizedMultiGet() {
|
||||
let batch = [[KEY_1, VAL_1], [KEY_2, VAL_2]];
|
||||
let keys = batch.map(([key, value]) => key);
|
||||
AsyncStorage.multiSet(batch, err1 => {
|
||||
// yes, twice on purpose
|
||||
[1, 2].forEach(i => {
|
||||
expectAsyncNoError(`${i} testOptimizedMultiGet/multiSet`, err1);
|
||||
AsyncStorage.multiGet(keys, (err2, result) => {
|
||||
expectAsyncNoError(`${i} testOptimizedMultiGet/multiGet`, err2);
|
||||
expectEqual(result, batch, `${i} testOptimizedMultiGet multiGet`);
|
||||
updateMessage(
|
||||
'multiGet([key_1, key_2]) correctly returned ' +
|
||||
JSON.stringify(result),
|
||||
);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
class AsyncStorageTest extends React.Component<{...}, $FlowFixMeState> {
|
||||
state: any | {|done: boolean, messages: string|} = {
|
||||
messages: 'Initializing...',
|
||||
done: false,
|
||||
};
|
||||
|
||||
componentDidMount() {
|
||||
done = () =>
|
||||
this.setState({done: true}, () => {
|
||||
TestModule.markTestCompleted();
|
||||
});
|
||||
updateMessage = msg => {
|
||||
this.setState({messages: this.state.messages.concat('\n' + msg)});
|
||||
DEBUG && console.log(msg);
|
||||
};
|
||||
AsyncStorage.clear(testSetAndGet);
|
||||
}
|
||||
|
||||
render(): React.Node {
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<Text>
|
||||
{/* $FlowFixMe(>=0.54.0 site=react_native_fb,react_native_oss) This
|
||||
* comment suppresses an error found when Flow v0.54 was deployed.
|
||||
* To see the error delete this comment and run Flow. */
|
||||
this.constructor.displayName + ': '}
|
||||
{this.state.done ? 'Done' : 'Testing...'}
|
||||
{'\n\n' + this.state.messages}
|
||||
</Text>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
backgroundColor: 'white',
|
||||
padding: 40,
|
||||
},
|
||||
});
|
||||
|
||||
AsyncStorageTest.displayName = 'AsyncStorageTest';
|
||||
|
||||
module.exports = AsyncStorageTest;
|
||||
@@ -1,32 +0,0 @@
|
||||
load("@fbsource//tools/build_defs:js_library_glob.bzl", "js_library_glob")
|
||||
load("@fbsource//tools/build_defs/oss:metro_defs.bzl", "rn_library")
|
||||
|
||||
# This file was generated by running
|
||||
# js1 build buckfiles
|
||||
|
||||
rn_library(
|
||||
name = "IntegrationTests",
|
||||
srcs = js_library_glob(
|
||||
[
|
||||
"**/*",
|
||||
],
|
||||
excludes = [
|
||||
"**/__*__/**",
|
||||
"**/*.command",
|
||||
"**/*.md",
|
||||
"websocket_integration_test_server.js",
|
||||
],
|
||||
),
|
||||
labels = [
|
||||
"pfh:ReactNative_CommonInfrastructurePlaceholder",
|
||||
],
|
||||
skip_processors = True,
|
||||
visibility = ["PUBLIC"],
|
||||
deps = [
|
||||
"//xplat/js:node_modules__invariant",
|
||||
"//xplat/js:node_modules__nullthrows",
|
||||
"//xplat/js/RKJSModules/vendor/react:react",
|
||||
"//xplat/js/react-native-github:react-native",
|
||||
"//xplat/js/react-native-github/packages/assets:assets",
|
||||
],
|
||||
)
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
@@ -10,8 +10,6 @@
|
||||
|
||||
'use strict';
|
||||
|
||||
import type {ExtendedError} from 'react-native/Libraries/Core/ExtendedError';
|
||||
|
||||
const React = require('react');
|
||||
const ReactNative = require('react-native');
|
||||
const parseErrorStack = require('react-native/Libraries/Core/Devtools/parseErrorStack');
|
||||
@@ -20,7 +18,7 @@ const {View} = ReactNative;
|
||||
const {TestModule} = ReactNative.NativeModules;
|
||||
|
||||
class GlobalEvalWithSourceUrlTest extends React.Component<{...}> {
|
||||
componentDidMount(): void {
|
||||
componentDidMount() {
|
||||
if (typeof global.globalEvalWithSourceUrl !== 'function') {
|
||||
throw new Error(
|
||||
'Expected to find globalEvalWithSourceUrl function on global object but found ' +
|
||||
@@ -33,7 +31,7 @@ class GlobalEvalWithSourceUrlTest extends React.Component<{...}> {
|
||||
'Expected globalEvalWithSourceUrl(expression) to return a value',
|
||||
);
|
||||
}
|
||||
let syntaxError: ?ExtendedError;
|
||||
let syntaxError;
|
||||
try {
|
||||
global.globalEvalWithSourceUrl('{');
|
||||
} catch (e) {
|
||||
@@ -44,12 +42,7 @@ class GlobalEvalWithSourceUrlTest extends React.Component<{...}> {
|
||||
'Expected globalEvalWithSourceUrl to throw on a syntax error',
|
||||
);
|
||||
}
|
||||
// Hermes throws an Error instead of a SyntaxError
|
||||
// https://github.com/facebook/hermes/issues/400
|
||||
if (
|
||||
syntaxError.jsEngine !== 'hermes' &&
|
||||
!(syntaxError instanceof SyntaxError)
|
||||
) {
|
||||
if (!(syntaxError instanceof SyntaxError)) {
|
||||
throw new Error(
|
||||
'Expected globalEvalWithSourceUrl to throw SyntaxError on a syntax error',
|
||||
);
|
||||
@@ -66,7 +59,7 @@ class GlobalEvalWithSourceUrlTest extends React.Component<{...}> {
|
||||
'Expected globalEvalWithSourceUrl to throw an Error object',
|
||||
);
|
||||
}
|
||||
const parsedStack = parseErrorStack(error?.stack);
|
||||
const parsedStack = parseErrorStack(error);
|
||||
if (parsedStack[0].file !== url) {
|
||||
throw new Error(
|
||||
`Expected first eval stack frame to be in ${url} but found ${String(
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
@@ -64,7 +64,7 @@ class ImageCachePolicyTest extends React.Component<Props, $FlowFixMeState> {
|
||||
<Image
|
||||
source={{
|
||||
uri:
|
||||
'https://raw.githubusercontent.com/facebook/react-native/HEAD/Libraries/NewAppScreen/components/logo.png?cacheBust=notinCache' +
|
||||
'https://raw.githubusercontent.com/facebook/react-native/master/Libraries/NewAppScreen/components/logo.png?cacheBust=notinCache' +
|
||||
Date.now(),
|
||||
cache: 'only-if-cached',
|
||||
}}
|
||||
@@ -75,7 +75,7 @@ class ImageCachePolicyTest extends React.Component<Props, $FlowFixMeState> {
|
||||
<Image
|
||||
source={{
|
||||
uri:
|
||||
'https://raw.githubusercontent.com/facebook/react-native/HEAD/Libraries/NewAppScreen/components/logo.png?cacheBust=notinCache' +
|
||||
'https://raw.githubusercontent.com/facebook/react-native/master/Libraries/NewAppScreen/components/logo.png?cacheBust=notinCache' +
|
||||
Date.now(),
|
||||
cache: 'default',
|
||||
}}
|
||||
@@ -86,7 +86,7 @@ class ImageCachePolicyTest extends React.Component<Props, $FlowFixMeState> {
|
||||
<Image
|
||||
source={{
|
||||
uri:
|
||||
'https://raw.githubusercontent.com/facebook/react-native/HEAD/Libraries/NewAppScreen/components/logo.png?cacheBust=notinCache' +
|
||||
'https://raw.githubusercontent.com/facebook/react-native/master/Libraries/NewAppScreen/components/logo.png?cacheBust=notinCache' +
|
||||
Date.now(),
|
||||
cache: 'reload',
|
||||
}}
|
||||
@@ -97,7 +97,7 @@ class ImageCachePolicyTest extends React.Component<Props, $FlowFixMeState> {
|
||||
<Image
|
||||
source={{
|
||||
uri:
|
||||
'https://raw.githubusercontent.com/facebook/react-native/HEAD/Libraries/NewAppScreen/components/logo.png?cacheBust=notinCache' +
|
||||
'https://raw.githubusercontent.com/facebook/react-native/master/Libraries/NewAppScreen/components/logo.png?cacheBust=notinCache' +
|
||||
Date.now(),
|
||||
cache: 'force-cache',
|
||||
}}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
@@ -16,7 +16,7 @@ const {Image} = ReactNative;
|
||||
const {TestModule} = ReactNative.NativeModules;
|
||||
|
||||
class ImageSnapshotTest extends React.Component<{...}> {
|
||||
componentDidMount(): void {
|
||||
componentDidMount() {
|
||||
if (!TestModule.verifySnapshot) {
|
||||
throw new Error('TestModule.verifySnapshot not defined.');
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
@@ -13,6 +13,7 @@
|
||||
const React = require('react');
|
||||
const ReactNative = require('react-native');
|
||||
|
||||
const requestAnimationFrame = require('fbjs/lib/requestAnimationFrame');
|
||||
const {Text, View, StyleSheet} = ReactNative;
|
||||
const {TestModule} = ReactNative.NativeModules;
|
||||
|
||||
@@ -56,13 +57,10 @@ class IntegrationTestHarnessTest extends React.Component<Props, State> {
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<Text>
|
||||
{
|
||||
/* $FlowFixMe[incompatible-type] (>=0.54.0 site=react_native_fb,react_
|
||||
* native_oss) This comment suppresses an error found when Flow v0.54
|
||||
* was deployed. To see the error delete this comment and run Flow.
|
||||
*/
|
||||
this.constructor.displayName + ': '
|
||||
}
|
||||
{/* $FlowFixMe(>=0.54.0 site=react_native_fb,react_native_oss) This
|
||||
* comment suppresses an error found when Flow v0.54 was deployed.
|
||||
* To see the error delete this comment and run Flow. */
|
||||
this.constructor.displayName + ': '}
|
||||
{this.state.done ? 'Done' : 'Testing...'}
|
||||
</Text>
|
||||
</View>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
@@ -13,13 +13,20 @@
|
||||
require('react-native/Libraries/Core/InitializeCore');
|
||||
const React = require('react');
|
||||
const ReactNative = require('react-native');
|
||||
const {AppRegistry, ScrollView, StyleSheet, Text, TouchableOpacity, View} =
|
||||
ReactNative;
|
||||
const {
|
||||
AppRegistry,
|
||||
ScrollView,
|
||||
StyleSheet,
|
||||
Text,
|
||||
TouchableOpacity,
|
||||
View,
|
||||
} = ReactNative;
|
||||
|
||||
// Keep this list in sync with RNTesterIntegrationTests.m
|
||||
const TESTS = [
|
||||
require('./IntegrationTestHarnessTest'),
|
||||
require('./TimersTest'),
|
||||
require('./AsyncStorageTest'),
|
||||
require('./LayoutEventsTest'),
|
||||
require('./AppEventsTest'),
|
||||
require('./SimpleSnapshotTest'),
|
||||
@@ -33,9 +40,9 @@ const TESTS = [
|
||||
];
|
||||
|
||||
TESTS.forEach(
|
||||
/* $FlowFixMe[incompatible-call] (>=0.54.0 site=react_native_fb,react_native_
|
||||
* oss) This comment suppresses an error found when Flow v0.54 was deployed.
|
||||
* To see the error delete this comment and run Flow. */
|
||||
/* $FlowFixMe(>=0.54.0 site=react_native_fb,react_native_oss) This comment
|
||||
* suppresses an error found when Flow v0.54 was deployed. To see the error
|
||||
* delete this comment and run Flow. */
|
||||
test => AppRegistry.registerComponent(test.displayName, () => test),
|
||||
);
|
||||
|
||||
@@ -45,18 +52,17 @@ require('./LoggingTestModule');
|
||||
type Test = any;
|
||||
|
||||
class IntegrationTestsApp extends React.Component<{...}, $FlowFixMeState> {
|
||||
state: {test: ?Test} = {
|
||||
state = {
|
||||
test: (null: ?Test),
|
||||
};
|
||||
|
||||
render(): React.Node {
|
||||
render() {
|
||||
if (this.state.test) {
|
||||
return (
|
||||
<ScrollView>
|
||||
{/* $FlowFixMe[type-as-value] (>=0.53.0 site=react_native_fb,react_
|
||||
* native_oss) This comment suppresses an error when upgrading
|
||||
* Flow's support for React. To see the error delete this comment
|
||||
* and run Flow. */}
|
||||
{/* $FlowFixMe(>=0.53.0 site=react_native_fb,react_native_oss) This
|
||||
* comment suppresses an error when upgrading Flow's support for
|
||||
* React. To see the error delete this comment and run Flow. */}
|
||||
<this.state.test />
|
||||
</ScrollView>
|
||||
);
|
||||
@@ -73,10 +79,9 @@ class IntegrationTestsApp extends React.Component<{...}, $FlowFixMeState> {
|
||||
{TESTS.map(test => [
|
||||
<TouchableOpacity
|
||||
onPress={() => this.setState({test})}
|
||||
/* $FlowFixMe[incompatible-type] (>=0.115.0 site=react_native_fb)
|
||||
* This comment suppresses an error found when Flow v0.115 was
|
||||
* deployed. To see the error, delete this comment and run Flow.
|
||||
*/
|
||||
/* $FlowFixMe(>=0.115.0 site=react_native_fb) This comment
|
||||
* suppresses an error found when Flow v0.115 was deployed. To
|
||||
* see the error, delete this comment and run Flow. */
|
||||
style={styles.row}>
|
||||
<Text style={styles.testName}>{test.displayName}</Text>
|
||||
</TouchableOpacity>,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
@@ -19,7 +19,7 @@ import type {ViewStyleProp} from 'react-native/Libraries/StyleSheet/StyleSheet';
|
||||
|
||||
const deepDiffer = require('react-native/Libraries/Utilities/differ/deepDiffer');
|
||||
|
||||
function debug(...args: Array<void | Layout | string>) {
|
||||
function debug(...args) {
|
||||
// console.log.apply(null, arguments);
|
||||
}
|
||||
|
||||
@@ -119,19 +119,16 @@ class LayoutEventsTest extends React.Component<Props, State> {
|
||||
}
|
||||
|
||||
onViewLayout: (e: LayoutEvent) => void = (e: LayoutEvent) => {
|
||||
// $FlowFixMe[incompatible-call]
|
||||
debug('received view layout event\n', e.nativeEvent);
|
||||
this.setState({viewLayout: e.nativeEvent.layout}, this.checkLayout);
|
||||
};
|
||||
|
||||
onTextLayout: (e: LayoutEvent) => void = (e: LayoutEvent) => {
|
||||
// $FlowFixMe[incompatible-call]
|
||||
debug('received text layout event\n', e.nativeEvent);
|
||||
this.setState({textLayout: e.nativeEvent.layout}, this.checkLayout);
|
||||
};
|
||||
|
||||
onImageLayout: (e: LayoutEvent) => void = (e: LayoutEvent) => {
|
||||
// $FlowFixMe[incompatible-call]
|
||||
debug('received image layout event\n', e.nativeEvent);
|
||||
this.setState({imageLayout: e.nativeEvent.layout}, this.checkLayout);
|
||||
};
|
||||
@@ -200,5 +197,4 @@ const styles = StyleSheet.create({
|
||||
},
|
||||
});
|
||||
|
||||
LayoutEventsTest.displayName = 'LayoutEventsTest';
|
||||
module.exports = LayoutEventsTest;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
@@ -11,27 +11,28 @@
|
||||
|
||||
const BatchedBridge = require('react-native/Libraries/BatchedBridge/BatchedBridge');
|
||||
|
||||
const warning = require('fbjs/lib/warning');
|
||||
const invariant = require('invariant');
|
||||
|
||||
const LoggingTestModule = {
|
||||
logToConsole: function (str) {
|
||||
logToConsole: function(str) {
|
||||
console.log(str);
|
||||
},
|
||||
logToConsoleAfterWait: function (str, timeout_ms) {
|
||||
setTimeout(function () {
|
||||
logToConsoleAfterWait: function(str, timeout_ms) {
|
||||
setTimeout(function() {
|
||||
console.log(str);
|
||||
}, timeout_ms);
|
||||
},
|
||||
warning: function (str) {
|
||||
console.warn(str);
|
||||
warning: function(str) {
|
||||
warning(false, str);
|
||||
},
|
||||
invariant: function (str) {
|
||||
invariant: function(str) {
|
||||
invariant(false, str);
|
||||
},
|
||||
logErrorToConsole: function (str) {
|
||||
logErrorToConsole: function(str) {
|
||||
console.error(str);
|
||||
},
|
||||
throwError: function (str) {
|
||||
throwError: function(str) {
|
||||
throw new Error(str);
|
||||
},
|
||||
};
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
@@ -12,8 +12,14 @@
|
||||
const React = require('react');
|
||||
const ReactNative = require('react-native');
|
||||
|
||||
const {AppRegistry, ScrollView, StyleSheet, Text, TouchableOpacity, View} =
|
||||
ReactNative;
|
||||
const {
|
||||
AppRegistry,
|
||||
ScrollView,
|
||||
StyleSheet,
|
||||
Text,
|
||||
TouchableOpacity,
|
||||
View,
|
||||
} = ReactNative;
|
||||
|
||||
/* Keep this list in sync with RCTRootViewIntegrationTests.m */
|
||||
const TESTS = [
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
@@ -8,6 +8,8 @@
|
||||
* @flow strict-local
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
const RCTNativeAppEventEmitter = require('react-native/Libraries/EventEmitter/RCTNativeAppEventEmitter');
|
||||
const React = require('react');
|
||||
const ReactNative = require('react-native');
|
||||
@@ -15,7 +17,7 @@ const ReactNative = require('react-native');
|
||||
const {View} = ReactNative;
|
||||
|
||||
const {TestModule} = ReactNative.NativeModules;
|
||||
import {type EventSubscription} from 'react-native/Libraries/vendor/emitter/EventEmitter';
|
||||
import type EmitterSubscription from 'react-native/Libraries/vendor/emitter/EmitterSubscription';
|
||||
|
||||
const reactViewWidth = 101;
|
||||
const reactViewHeight = 102;
|
||||
@@ -31,7 +33,7 @@ type State = {|
|
||||
|
||||
class ReactContentSizeUpdateTest extends React.Component<Props, State> {
|
||||
_timeoutID: ?TimeoutID = null;
|
||||
_subscription: ?EventSubscription = null;
|
||||
_subscription: ?EmitterSubscription = null;
|
||||
|
||||
state: State = {
|
||||
height: reactViewHeight,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
@@ -13,11 +13,13 @@
|
||||
const React = require('react');
|
||||
const ReactNative = require('react-native');
|
||||
|
||||
const requestAnimationFrame = require('fbjs/lib/requestAnimationFrame');
|
||||
|
||||
const {StyleSheet, View} = ReactNative;
|
||||
const {TestModule} = ReactNative.NativeModules;
|
||||
|
||||
class SimpleSnapshotTest extends React.Component<{...}> {
|
||||
componentDidMount(): void {
|
||||
componentDidMount() {
|
||||
if (!TestModule.verifySnapshot) {
|
||||
throw new Error('TestModule.verifySnapshot not defined.');
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
@@ -8,13 +8,15 @@
|
||||
* @flow strict-local
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
const RCTNativeAppEventEmitter = require('react-native/Libraries/EventEmitter/RCTNativeAppEventEmitter');
|
||||
const React = require('react');
|
||||
const ReactNative = require('react-native');
|
||||
const {View} = ReactNative;
|
||||
|
||||
const {TestModule} = ReactNative.NativeModules;
|
||||
import {type EventSubscription} from 'react-native/Libraries/vendor/emitter/EventEmitter';
|
||||
import type EmitterSubscription from 'react-native/Libraries/vendor/emitter/EmitterSubscription';
|
||||
|
||||
const reactViewWidth = 111;
|
||||
const reactViewHeight = 222;
|
||||
@@ -29,7 +31,7 @@ type Props = $ReadOnly<{|
|
||||
|}>;
|
||||
|
||||
class SizeFlexibilityUpdateTest extends React.Component<Props> {
|
||||
_subscription: ?EventSubscription = null;
|
||||
_subscription: ?EmitterSubscription = null;
|
||||
|
||||
UNSAFE_componentWillMount() {
|
||||
this._subscription = RCTNativeAppEventEmitter.addListener(
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
@@ -17,7 +17,7 @@ const {View} = ReactNative;
|
||||
const {TestModule, RNTesterTestModule} = ReactNative.NativeModules;
|
||||
|
||||
class SyncMethodTest extends React.Component<{...}> {
|
||||
componentDidMount(): void {
|
||||
componentDidMount() {
|
||||
if (
|
||||
RNTesterTestModule.echoString('test string value') !== 'test string value'
|
||||
) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
@@ -39,7 +39,7 @@ class TimersTest extends React.Component<Props, State> {
|
||||
};
|
||||
|
||||
setTimeout(fn: () => void, time: number): TimeoutID {
|
||||
const id: TimeoutID = setTimeout(() => {
|
||||
const id = setTimeout(() => {
|
||||
this._timeoutIDs.delete(id);
|
||||
fn();
|
||||
}, time);
|
||||
@@ -70,7 +70,7 @@ class TimersTest extends React.Component<Props, State> {
|
||||
}
|
||||
|
||||
setImmediate(fn: () => void): ImmediateID {
|
||||
const id: any = setImmediate(() => {
|
||||
const id = setImmediate(() => {
|
||||
this._immediateIDs.delete(id);
|
||||
fn();
|
||||
});
|
||||
@@ -81,7 +81,7 @@ class TimersTest extends React.Component<Props, State> {
|
||||
}
|
||||
|
||||
requestAnimationFrame(fn: () => void): AnimationFrameID {
|
||||
const id: AnimationFrameID = requestAnimationFrame(() => {
|
||||
const id = requestAnimationFrame(() => {
|
||||
this._animationFrameIDs.delete(id);
|
||||
fn();
|
||||
});
|
||||
@@ -97,46 +97,36 @@ class TimersTest extends React.Component<Props, State> {
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
// $FlowFixMe[method-unbinding] added when improving typing for this parameters
|
||||
this.setTimeout(this.testSetTimeout0, 1000);
|
||||
}
|
||||
|
||||
testSetTimeout0() {
|
||||
// $FlowFixMe[method-unbinding] added when improving typing for this parameters
|
||||
this.setTimeout(this.testSetTimeout1, 0);
|
||||
}
|
||||
|
||||
testSetTimeout1() {
|
||||
// $FlowFixMe[method-unbinding] added when improving typing for this parameters
|
||||
this.setTimeout(this.testSetTimeout50, 1);
|
||||
}
|
||||
|
||||
testSetTimeout50() {
|
||||
// $FlowFixMe[method-unbinding] added when improving typing for this parameters
|
||||
this.setTimeout(this.testRequestAnimationFrame, 50);
|
||||
}
|
||||
|
||||
testRequestAnimationFrame() {
|
||||
// $FlowFixMe[method-unbinding] added when improving typing for this parameters
|
||||
this.requestAnimationFrame(this.testSetInterval0);
|
||||
}
|
||||
|
||||
testSetInterval0() {
|
||||
// $FlowFixMe[method-unbinding] added when improving typing for this parameters
|
||||
this._nextTest = this.testSetInterval20;
|
||||
// $FlowFixMe[method-unbinding] added when improving typing for this parameters
|
||||
this._interval = this.setInterval(this._incrementInterval, 0);
|
||||
}
|
||||
|
||||
testSetInterval20() {
|
||||
// $FlowFixMe[method-unbinding] added when improving typing for this parameters
|
||||
this._nextTest = this.testSetImmediate;
|
||||
// $FlowFixMe[method-unbinding] added when improving typing for this parameters
|
||||
this._interval = this.setInterval(this._incrementInterval, 20);
|
||||
}
|
||||
|
||||
testSetImmediate() {
|
||||
// $FlowFixMe[method-unbinding] added when improving typing for this parameters
|
||||
this.setImmediate(this.testClearTimeout0);
|
||||
}
|
||||
|
||||
@@ -149,7 +139,6 @@ class TimersTest extends React.Component<Props, State> {
|
||||
testClearTimeout30() {
|
||||
const timeout = this.setTimeout(() => this._fail('testClearTimeout30'), 30);
|
||||
this.clearTimeout(timeout);
|
||||
// $FlowFixMe[method-unbinding] added when improving typing for this parameters
|
||||
this.setTimeout(this.testClearMulti, 50);
|
||||
}
|
||||
|
||||
@@ -167,7 +156,6 @@ class TimersTest extends React.Component<Props, State> {
|
||||
fails.forEach(timeout => this.clearTimeout(timeout));
|
||||
this.setTimeout(() => this.clearTimeout(delayClear), 20);
|
||||
|
||||
// $FlowFixMe[method-unbinding] added when improving typing for this parameters
|
||||
this.setTimeout(this.testOrdering, 50);
|
||||
}
|
||||
|
||||
@@ -203,7 +191,6 @@ class TimersTest extends React.Component<Props, State> {
|
||||
),
|
||||
25,
|
||||
);
|
||||
// $FlowFixMe[method-unbinding] added when improving typing for this parameters
|
||||
this.setTimeout(this.done, 50);
|
||||
}
|
||||
|
||||
@@ -253,7 +240,7 @@ class TimersTest extends React.Component<Props, State> {
|
||||
);
|
||||
}
|
||||
|
||||
_incrementInterval(): void {
|
||||
_incrementInterval() {
|
||||
if (this.state.count > 3) {
|
||||
throw new Error('interval incremented past end.');
|
||||
}
|
||||
@@ -262,7 +249,6 @@ class TimersTest extends React.Component<Props, State> {
|
||||
this.clearInterval(this._interval);
|
||||
this._interval = null;
|
||||
}
|
||||
// $FlowFixMe[method-unbinding]
|
||||
this.setState({count: 0}, this._nextTest);
|
||||
return;
|
||||
}
|
||||
@@ -281,5 +267,4 @@ const styles = StyleSheet.create({
|
||||
},
|
||||
});
|
||||
|
||||
TimersTest.displayName = 'TimersTest';
|
||||
module.exports = TimersTest;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
@@ -45,7 +45,7 @@ class WebSocketTest extends React.Component<{...}, State> {
|
||||
|
||||
_waitFor = (condition: any, timeout: any, callback: any) => {
|
||||
let remaining = timeout;
|
||||
const timeoutFunction = function () {
|
||||
const timeoutFunction = function() {
|
||||
if (condition()) {
|
||||
callback(true);
|
||||
return;
|
||||
@@ -69,11 +69,11 @@ class WebSocketTest extends React.Component<{...}, State> {
|
||||
});
|
||||
};
|
||||
|
||||
_socketIsConnected = (): boolean => {
|
||||
_socketIsConnected = () => {
|
||||
return this.state.socketState === 1; //'OPEN'
|
||||
};
|
||||
|
||||
_socketIsDisconnected = (): boolean => {
|
||||
_socketIsDisconnected = () => {
|
||||
return this.state.socketState === 3; //'CLOSED'
|
||||
};
|
||||
|
||||
@@ -106,7 +106,7 @@ class WebSocketTest extends React.Component<{...}, State> {
|
||||
this._sendText(this.state.testMessage);
|
||||
};
|
||||
|
||||
_receivedTestExpectedResponse = (): boolean => {
|
||||
_receivedTestExpectedResponse = () => {
|
||||
return this.state.lastMessage === this.state.testExpectedResponse;
|
||||
};
|
||||
|
||||
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Copyright (c) Facebook, Inc. and its affiliates.
|
||||
#
|
||||
# This source code is licensed under the MIT license found in the
|
||||
# LICENSE file in the root directory of this source tree.
|
||||
|
||||
# Set terminal title
|
||||
echo -en "\033]0;Web Socket Test Server\a"
|
||||
clear
|
||||
|
||||
THIS_DIR=$(cd -P "$(dirname "$(readlink "${BASH_SOURCE[0]}" || echo "${BASH_SOURCE[0]}")")" && pwd)
|
||||
pushd "$THIS_DIR"
|
||||
./websocket_integration_test_server.js
|
||||
popd
|
||||
|
||||
echo "Process terminated. Press <enter> to close the window"
|
||||
read
|
||||
@@ -1,12 +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_DIR=$(cd -P "$(dirname "$(readlink "${BASH_SOURCE[0]}" || echo "${BASH_SOURCE[0]}")")" && pwd)
|
||||
pushd "$THIS_DIR" || exit
|
||||
./websocket_integration_test_server.js
|
||||
popd || exit
|
||||
|
||||
echo "Process terminated."
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/usr/bin/env node
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
Copyright (c) Facebook, Inc. and its affiliates.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
// A little helper to make sure we have the right memory allocation ready for use.
|
||||
// We assume that we will only this in one place so no reference counting is necessary.
|
||||
// Needs to be freed when deallocated.
|
||||
|
||||
// This is fragile since this relies on these values not getting reused. Consider
|
||||
// wrapping these in an Obj-C class or some ARC hackery to get refcounting.
|
||||
|
||||
typedef struct {
|
||||
size_t count;
|
||||
CGFloat *array;
|
||||
} ARTCGFloatArray;
|
||||
@@ -0,0 +1,16 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its 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>
|
||||
|
||||
@protocol ARTContainer <NSObject>
|
||||
|
||||
// This is used as a hook for child to mark it's parent as dirty.
|
||||
// This bubbles up to the root which gets marked as dirty.
|
||||
- (void)invalidate;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its 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 "ARTContainer.h"
|
||||
#import "ARTNode.h"
|
||||
|
||||
@interface ARTGroup : ARTNode <ARTContainer>
|
||||
|
||||
@property (nonatomic, assign) CGRect clipping;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its 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/ARTGroup.h>
|
||||
|
||||
@implementation ARTGroup
|
||||
|
||||
- (void)renderLayerTo:(CGContextRef)context
|
||||
{
|
||||
|
||||
if (!CGRectIsEmpty(self.clipping)) {
|
||||
CGContextClipToRect(context, self.clipping);
|
||||
}
|
||||
|
||||
for (ARTNode *node in self.subviews) {
|
||||
[node renderTo:context];
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its 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/UIView+React.h>
|
||||
|
||||
/**
|
||||
* ART nodes are implemented as empty UIViews but this is just an implementation detail to fit
|
||||
* into the existing view management. They should also be shadow views and painted on a background
|
||||
* thread.
|
||||
*/
|
||||
|
||||
@interface ARTNode : UIView
|
||||
|
||||
@property (nonatomic, assign) CGFloat opacity;
|
||||
|
||||
- (void)invalidate;
|
||||
- (void)renderTo:(CGContextRef)context;
|
||||
|
||||
/**
|
||||
* renderTo will take opacity into account and draw renderLayerTo off-screen if there is opacity
|
||||
* specified, then composite that onto the context. renderLayerTo always draws at opacity=1.
|
||||
* @abstract
|
||||
*/
|
||||
- (void)renderLayerTo:(CGContextRef)context;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its 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/ARTNode.h>
|
||||
|
||||
#import <React/ARTContainer.h>
|
||||
|
||||
@implementation ARTNode
|
||||
|
||||
- (void)insertReactSubview:(UIView *)subview atIndex:(NSInteger)atIndex
|
||||
{
|
||||
[super insertReactSubview:subview atIndex:atIndex];
|
||||
[self insertSubview:subview atIndex:atIndex];
|
||||
[self invalidate];
|
||||
}
|
||||
|
||||
- (void)removeReactSubview:(UIView *)subview
|
||||
{
|
||||
[super removeReactSubview:subview];
|
||||
[self invalidate];
|
||||
}
|
||||
|
||||
- (void)didUpdateReactSubviews
|
||||
{
|
||||
// Do nothing, as subviews are inserted by insertReactSubview:
|
||||
}
|
||||
|
||||
- (void)setOpacity:(CGFloat)opacity
|
||||
{
|
||||
[self invalidate];
|
||||
_opacity = opacity;
|
||||
}
|
||||
|
||||
- (void)setTransform:(CGAffineTransform)transform
|
||||
{
|
||||
[self invalidate];
|
||||
super.transform = transform;
|
||||
}
|
||||
|
||||
- (void)invalidate
|
||||
{
|
||||
id<ARTContainer> container = (id<ARTContainer>)self.superview;
|
||||
[container invalidate];
|
||||
}
|
||||
|
||||
- (void)renderTo:(CGContextRef)context
|
||||
{
|
||||
if (self.opacity <= 0) {
|
||||
// Nothing to paint
|
||||
return;
|
||||
}
|
||||
if (self.opacity >= 1) {
|
||||
// Just paint at full opacity
|
||||
CGContextSaveGState(context);
|
||||
CGContextConcatCTM(context, self.transform);
|
||||
CGContextSetAlpha(context, 1);
|
||||
[self renderLayerTo:context];
|
||||
CGContextRestoreGState(context);
|
||||
return;
|
||||
}
|
||||
// This needs to be painted on a layer before being composited.
|
||||
CGContextSaveGState(context);
|
||||
CGContextConcatCTM(context, self.transform);
|
||||
CGContextSetAlpha(context, self.opacity);
|
||||
CGContextBeginTransparencyLayer(context, NULL);
|
||||
[self renderLayerTo:context];
|
||||
CGContextEndTransparencyLayer(context);
|
||||
CGContextRestoreGState(context);
|
||||
}
|
||||
|
||||
- (void)renderLayerTo:(CGContextRef)context
|
||||
{
|
||||
// abstract
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its 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 "ARTBrush.h"
|
||||
#import "ARTCGFloatArray.h"
|
||||
#import "ARTNode.h"
|
||||
|
||||
@interface ARTRenderable : ARTNode
|
||||
|
||||
@property (nonatomic, strong) ARTBrush *fill;
|
||||
@property (nonatomic, assign) CGColorRef stroke;
|
||||
@property (nonatomic, assign) CGFloat strokeWidth;
|
||||
@property (nonatomic, assign) CGLineCap strokeCap;
|
||||
@property (nonatomic, assign) CGLineJoin strokeJoin;
|
||||
@property (nonatomic, assign) ARTCGFloatArray strokeDash;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its 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/ARTRenderable.h>
|
||||
|
||||
@implementation ARTRenderable
|
||||
|
||||
- (void)setFill:(ARTBrush *)fill
|
||||
{
|
||||
[self invalidate];
|
||||
_fill = fill;
|
||||
}
|
||||
|
||||
- (void)setStroke:(CGColorRef)stroke
|
||||
{
|
||||
if (stroke == _stroke) {
|
||||
return;
|
||||
}
|
||||
[self invalidate];
|
||||
CGColorRelease(_stroke);
|
||||
_stroke = CGColorRetain(stroke);
|
||||
}
|
||||
|
||||
- (void)setStrokeWidth:(CGFloat)strokeWidth
|
||||
{
|
||||
[self invalidate];
|
||||
_strokeWidth = strokeWidth;
|
||||
}
|
||||
|
||||
- (void)setStrokeCap:(CGLineCap)strokeCap
|
||||
{
|
||||
[self invalidate];
|
||||
_strokeCap = strokeCap;
|
||||
}
|
||||
|
||||
- (void)setStrokeJoin:(CGLineJoin)strokeJoin
|
||||
{
|
||||
[self invalidate];
|
||||
_strokeJoin = strokeJoin;
|
||||
}
|
||||
|
||||
- (void)setStrokeDash:(ARTCGFloatArray)strokeDash
|
||||
{
|
||||
if (strokeDash.array == _strokeDash.array) {
|
||||
return;
|
||||
}
|
||||
if (_strokeDash.array) {
|
||||
free(_strokeDash.array);
|
||||
}
|
||||
[self invalidate];
|
||||
_strokeDash = strokeDash;
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
CGColorRelease(_stroke);
|
||||
if (_strokeDash.array) {
|
||||
free(_strokeDash.array);
|
||||
}
|
||||
}
|
||||
|
||||
- (void)renderTo:(CGContextRef)context
|
||||
{
|
||||
if (self.opacity <= 0 || self.opacity >= 1 || (self.fill && self.stroke)) {
|
||||
// If we have both fill and stroke, we will need to paint this using normal compositing
|
||||
[super renderTo: context];
|
||||
return;
|
||||
}
|
||||
// This is a terminal with only one painting. Therefore we don't need to paint this
|
||||
// off-screen. We can just composite it straight onto the buffer.
|
||||
CGContextSaveGState(context);
|
||||
CGContextConcatCTM(context, self.transform);
|
||||
CGContextSetAlpha(context, self.opacity);
|
||||
[self renderLayerTo:context];
|
||||
CGContextRestoreGState(context);
|
||||
}
|
||||
|
||||
- (void)renderLayerTo:(CGContextRef)context
|
||||
{
|
||||
// abstract
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,16 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its 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 "ARTRenderable.h"
|
||||
|
||||
@interface ARTShape : ARTRenderable
|
||||
|
||||
@property (nonatomic, assign) CGPathRef d;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its 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/ARTShape.h>
|
||||
|
||||
@implementation ARTShape
|
||||
|
||||
- (void)setD:(CGPathRef)d
|
||||
{
|
||||
if (d == _d) {
|
||||
return;
|
||||
}
|
||||
[self invalidate];
|
||||
CGPathRelease(_d);
|
||||
_d = CGPathRetain(d);
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
CGPathRelease(_d);
|
||||
}
|
||||
|
||||
- (void)renderLayerTo:(CGContextRef)context
|
||||
{
|
||||
if ((!self.fill && !self.stroke) || !self.d) {
|
||||
return;
|
||||
}
|
||||
|
||||
CGPathDrawingMode mode = kCGPathStroke;
|
||||
if (self.fill) {
|
||||
if ([self.fill applyFillColor:context]) {
|
||||
mode = kCGPathFill;
|
||||
} else {
|
||||
CGContextSaveGState(context);
|
||||
CGContextAddPath(context, self.d);
|
||||
CGContextClip(context);
|
||||
[self.fill paint:context];
|
||||
CGContextRestoreGState(context);
|
||||
if (!self.stroke) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (self.stroke) {
|
||||
CGContextSetStrokeColorWithColor(context, self.stroke);
|
||||
CGContextSetLineWidth(context, self.strokeWidth);
|
||||
CGContextSetLineCap(context, self.strokeCap);
|
||||
CGContextSetLineJoin(context, self.strokeJoin);
|
||||
ARTCGFloatArray dash = self.strokeDash;
|
||||
if (dash.count) {
|
||||
CGContextSetLineDash(context, 0, dash.array, dash.count);
|
||||
}
|
||||
if (mode == kCGPathFill) {
|
||||
mode = kCGPathFillStroke;
|
||||
}
|
||||
}
|
||||
|
||||
CGContextAddPath(context, self.d);
|
||||
CGContextDrawPath(context, mode);
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,14 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
#import "ARTContainer.h"
|
||||
|
||||
@interface ARTSurfaceView : UIView <ARTContainer>
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its 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/ARTSurfaceView.h>
|
||||
|
||||
#import <React/RCTLog.h>
|
||||
|
||||
#import <React/ARTNode.h>
|
||||
|
||||
@implementation ARTSurfaceView
|
||||
|
||||
- (instancetype)initWithFrame:(CGRect)frame
|
||||
{
|
||||
if (self = [super initWithFrame:frame]) {
|
||||
self.opaque = NO;
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)insertReactSubview:(UIView *)subview atIndex:(NSInteger)atIndex
|
||||
{
|
||||
[super insertReactSubview:subview atIndex:atIndex];
|
||||
[self insertSubview:subview atIndex:atIndex];
|
||||
[self invalidate];
|
||||
}
|
||||
|
||||
- (void)removeReactSubview:(UIView *)subview
|
||||
{
|
||||
[super removeReactSubview:subview];
|
||||
[self invalidate];
|
||||
}
|
||||
|
||||
- (void)didUpdateReactSubviews
|
||||
{
|
||||
// Do nothing, as subviews are inserted by insertReactSubview:
|
||||
}
|
||||
|
||||
- (void)invalidate
|
||||
{
|
||||
[self setNeedsDisplay];
|
||||
}
|
||||
|
||||
- (void)drawRect:(CGRect)rect
|
||||
{
|
||||
[super drawRect:rect];
|
||||
CGContextRef context = UIGraphicsGetCurrentContext();
|
||||
for (ARTNode *node in self.subviews) {
|
||||
[node renderTo:context];
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,18 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its 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 "ARTRenderable.h"
|
||||
#import "ARTTextFrame.h"
|
||||
|
||||
@interface ARTText : ARTRenderable
|
||||
|
||||
@property (nonatomic, assign) CTTextAlignment alignment;
|
||||
@property (nonatomic, assign) ARTTextFrame textFrame;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,125 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its 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/ARTText.h>
|
||||
|
||||
#import <CoreText/CoreText.h>
|
||||
|
||||
@implementation ARTText
|
||||
|
||||
- (void)setAlignment:(CTTextAlignment)alignment
|
||||
{
|
||||
[self invalidate];
|
||||
_alignment = alignment;
|
||||
}
|
||||
|
||||
static void ARTFreeTextFrame(ARTTextFrame frame)
|
||||
{
|
||||
if (frame.count) {
|
||||
// We must release each line before freeing up this struct
|
||||
for (int i = 0; i < frame.count; i++) {
|
||||
CFRelease(frame.lines[i]);
|
||||
}
|
||||
free(frame.lines);
|
||||
free(frame.widths);
|
||||
}
|
||||
}
|
||||
|
||||
- (void)setTextFrame:(ARTTextFrame)frame
|
||||
{
|
||||
if (frame.lines != _textFrame.lines) {
|
||||
ARTFreeTextFrame(_textFrame);
|
||||
}
|
||||
[self invalidate];
|
||||
_textFrame = frame;
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
ARTFreeTextFrame(_textFrame);
|
||||
}
|
||||
|
||||
- (void)renderLayerTo:(CGContextRef)context
|
||||
{
|
||||
ARTTextFrame frame = self.textFrame;
|
||||
|
||||
if ((!self.fill && !self.stroke) || !frame.count) {
|
||||
return;
|
||||
}
|
||||
|
||||
// to-do: draw along a path
|
||||
|
||||
CGTextDrawingMode mode = kCGTextStroke;
|
||||
if (self.fill) {
|
||||
if ([self.fill applyFillColor:context]) {
|
||||
mode = kCGTextFill;
|
||||
} else {
|
||||
|
||||
for (int i = 0; i < frame.count; i++) {
|
||||
CGContextSaveGState(context);
|
||||
// Inverse the coordinate space since CoreText assumes a bottom-up coordinate space
|
||||
CGContextScaleCTM(context, 1.0, -1.0);
|
||||
CGContextSetTextDrawingMode(context, kCGTextClip);
|
||||
[self renderLineTo:context atIndex:i];
|
||||
// Inverse the coordinate space back to the original before filling
|
||||
CGContextScaleCTM(context, 1.0, -1.0);
|
||||
[self.fill paint:context];
|
||||
// Restore the state so that the next line can be clipped separately
|
||||
CGContextRestoreGState(context);
|
||||
}
|
||||
|
||||
if (!self.stroke) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (self.stroke) {
|
||||
CGContextSetStrokeColorWithColor(context, self.stroke);
|
||||
CGContextSetLineWidth(context, self.strokeWidth);
|
||||
CGContextSetLineCap(context, self.strokeCap);
|
||||
CGContextSetLineJoin(context, self.strokeJoin);
|
||||
ARTCGFloatArray dash = self.strokeDash;
|
||||
if (dash.count) {
|
||||
CGContextSetLineDash(context, 0, dash.array, dash.count);
|
||||
}
|
||||
if (mode == kCGTextFill) {
|
||||
mode = kCGTextFillStroke;
|
||||
}
|
||||
}
|
||||
|
||||
CGContextSetTextDrawingMode(context, mode);
|
||||
|
||||
// Inverse the coordinate space since CoreText assumes a bottom-up coordinate space
|
||||
CGContextScaleCTM(context, 1.0, -1.0);
|
||||
for (int i = 0; i < frame.count; i++) {
|
||||
[self renderLineTo:context atIndex:i];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)renderLineTo:(CGContextRef)context atIndex:(int)index
|
||||
{
|
||||
ARTTextFrame frame = self.textFrame;
|
||||
CGFloat shift;
|
||||
switch (self.alignment) {
|
||||
case kCTTextAlignmentRight:
|
||||
shift = frame.widths[index];
|
||||
break;
|
||||
case kCTTextAlignmentCenter:
|
||||
shift = (frame.widths[index] / 2);
|
||||
break;
|
||||
default:
|
||||
shift = 0;
|
||||
break;
|
||||
}
|
||||
// We should consider snapping this shift to device pixels to improve rendering quality
|
||||
// when a line has subpixel width.
|
||||
CGContextSetTextPosition(context, -shift, -frame.baseLine - frame.lineHeight * index);
|
||||
CTLineRef line = frame.lines[index];
|
||||
CTLineDraw(line, context);
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <CoreText/CoreText.h>
|
||||
|
||||
// A little helper to make sure we have a set of lines including width ready for use.
|
||||
// We assume that we will only this in one place so no reference counting is necessary.
|
||||
// Needs to be freed when deallocated.
|
||||
|
||||
// This is fragile since this relies on these values not getting reused. Consider
|
||||
// wrapping these in an Obj-C class or some ARC hackery to get refcounting.
|
||||
|
||||
typedef struct {
|
||||
size_t count;
|
||||
CGFloat baseLine; // Distance from the origin to the base line of the first line
|
||||
CGFloat lineHeight; // Distance between lines
|
||||
CTLineRef *lines;
|
||||
CGFloat *widths; // Width of each line
|
||||
} ARTTextFrame;
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <CoreGraphics/CoreGraphics.h>
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@interface ARTBrush : NSObject
|
||||
|
||||
/* @abstract */
|
||||
- (instancetype)initWithArray:(NSArray *)data NS_DESIGNATED_INITIALIZER;
|
||||
|
||||
/**
|
||||
* For certain brushes we can fast path a combined fill and stroke.
|
||||
* For those brushes we override applyFillColor which sets the fill
|
||||
* color to be used by those batch paints. Those return YES.
|
||||
* We can't batch gradient painting in CoreGraphics, so those will
|
||||
* return NO and paint gets called instead.
|
||||
* @abstract
|
||||
*/
|
||||
- (BOOL)applyFillColor:(CGContextRef)context;
|
||||
|
||||
/**
|
||||
* paint fills the context with a brush. The context is assumed to
|
||||
* be clipped.
|
||||
* @abstract
|
||||
*/
|
||||
- (void)paint:(CGContextRef)context;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its 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/ARTBrush.h>
|
||||
|
||||
#import <React/RCTDefines.h>
|
||||
|
||||
@implementation ARTBrush
|
||||
|
||||
- (instancetype)initWithArray:(NSArray *)data
|
||||
{
|
||||
return [super init];
|
||||
}
|
||||
|
||||
RCT_NOT_IMPLEMENTED(- (instancetype)init)
|
||||
|
||||
- (BOOL)applyFillColor:(CGContextRef)context
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (void)paint:(CGContextRef)context
|
||||
{
|
||||
// abstract
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,12 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import "ARTBrush.h"
|
||||
|
||||
@interface ARTLinearGradient : ARTBrush
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its 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/ARTLinearGradient.h>
|
||||
|
||||
#import <React/RCTLog.h>
|
||||
|
||||
#import "RCTConvert+ART.h"
|
||||
|
||||
@implementation ARTLinearGradient
|
||||
{
|
||||
CGGradientRef _gradient;
|
||||
CGPoint _startPoint;
|
||||
CGPoint _endPoint;
|
||||
}
|
||||
|
||||
- (instancetype)initWithArray:(NSArray<NSNumber *> *)array
|
||||
{
|
||||
if ((self = [super initWithArray:array])) {
|
||||
if (array.count < 5) {
|
||||
RCTLogError(@"-[%@ %@] expects 5 elements, received %@",
|
||||
self.class, NSStringFromSelector(_cmd), array);
|
||||
return nil;
|
||||
}
|
||||
_startPoint = [RCTConvert CGPoint:array offset:1];
|
||||
_endPoint = [RCTConvert CGPoint:array offset:3];
|
||||
_gradient = CGGradientRetain([RCTConvert CGGradient:array offset:5]);
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
CGGradientRelease(_gradient);
|
||||
}
|
||||
|
||||
- (void)paint:(CGContextRef)context
|
||||
{
|
||||
CGGradientDrawingOptions extendOptions =
|
||||
kCGGradientDrawsBeforeStartLocation | kCGGradientDrawsAfterEndLocation;
|
||||
CGContextDrawLinearGradient(context, _gradient, _startPoint, _endPoint, extendOptions);
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,12 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import "ARTBrush.h"
|
||||
|
||||
@interface ARTPattern : ARTBrush
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its 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/ARTPattern.h>
|
||||
|
||||
#import <React/RCTLog.h>
|
||||
|
||||
#import "RCTConvert+ART.h"
|
||||
|
||||
@implementation ARTPattern
|
||||
{
|
||||
CGImageRef _image;
|
||||
CGRect _rect;
|
||||
}
|
||||
|
||||
- (instancetype)initWithArray:(NSArray<id /* imagesource + numbers */> *)array
|
||||
{
|
||||
if ((self = [super initWithArray:array])) {
|
||||
if (array.count < 6) {
|
||||
RCTLogError(@"-[%@ %@] expects 6 elements, received %@",
|
||||
self.class, NSStringFromSelector(_cmd), array);
|
||||
return nil;
|
||||
}
|
||||
_image = CGImageRetain([RCTConvert CGImage:array[1]]);
|
||||
_rect = [RCTConvert CGRect:array offset:2];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
CGImageRelease(_image);
|
||||
}
|
||||
|
||||
// Note: This could use applyFillColor with a pattern. This could be more efficient but
|
||||
// to do that, we need to calculate our own user space CTM.
|
||||
|
||||
- (void)paint:(CGContextRef)context
|
||||
{
|
||||
CGContextDrawTiledImage(context, _rect, _image);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,12 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import "ARTBrush.h"
|
||||
|
||||
@interface ARTRadialGradient : ARTBrush
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its 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/ARTRadialGradient.h>
|
||||
|
||||
#import <React/RCTLog.h>
|
||||
|
||||
#import "RCTConvert+ART.h"
|
||||
|
||||
@implementation ARTRadialGradient
|
||||
{
|
||||
CGGradientRef _gradient;
|
||||
CGPoint _focusPoint;
|
||||
CGPoint _centerPoint;
|
||||
CGFloat _radius;
|
||||
CGFloat _radiusRatio;
|
||||
}
|
||||
|
||||
- (instancetype)initWithArray:(NSArray<NSNumber *> *)array
|
||||
{
|
||||
if ((self = [super initWithArray:array])) {
|
||||
if (array.count < 7) {
|
||||
RCTLogError(@"-[%@ %@] expects 7 elements, received %@",
|
||||
self.class, NSStringFromSelector(_cmd), array);
|
||||
return nil;
|
||||
}
|
||||
_radius = [RCTConvert CGFloat:array[3]];
|
||||
_radiusRatio = [RCTConvert CGFloat:array[4]] / _radius;
|
||||
_focusPoint.x = [RCTConvert CGFloat:array[1]];
|
||||
_focusPoint.y = [RCTConvert CGFloat:array[2]] / _radiusRatio;
|
||||
_centerPoint.x = [RCTConvert CGFloat:array[5]];
|
||||
_centerPoint.y = [RCTConvert CGFloat:array[6]] / _radiusRatio;
|
||||
_gradient = CGGradientRetain([RCTConvert CGGradient:array offset:7]);
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
CGGradientRelease(_gradient);
|
||||
}
|
||||
|
||||
- (void)paint:(CGContextRef)context
|
||||
{
|
||||
CGAffineTransform transform = CGAffineTransformMakeScale(1, _radiusRatio);
|
||||
CGContextConcatCTM(context, transform);
|
||||
CGGradientDrawingOptions extendOptions = kCGGradientDrawsBeforeStartLocation | kCGGradientDrawsAfterEndLocation;
|
||||
CGContextDrawRadialGradient(context, _gradient, _focusPoint, 0, _centerPoint, _radius, extendOptions);
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,12 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import "ARTBrush.h"
|
||||
|
||||
@interface ARTSolidColor : ARTBrush
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its 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/ARTSolidColor.h>
|
||||
|
||||
#import <React/RCTLog.h>
|
||||
|
||||
#import "RCTConvert+ART.h"
|
||||
|
||||
@implementation ARTSolidColor
|
||||
{
|
||||
CGColorRef _color;
|
||||
}
|
||||
|
||||
- (instancetype)initWithArray:(NSArray<NSNumber *> *)array
|
||||
{
|
||||
if ((self = [super initWithArray:array])) {
|
||||
_color = CGColorRetain([RCTConvert CGColor:array offset:1]);
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
CGColorRelease(_color);
|
||||
}
|
||||
|
||||
- (BOOL)applyFillColor:(CGContextRef)context
|
||||
{
|
||||
CGContextSetFillColorWithColor(context, _color);
|
||||
return YES;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <QuartzCore/QuartzCore.h>
|
||||
|
||||
#import <React/RCTConvert.h>
|
||||
|
||||
#import "ARTBrush.h"
|
||||
#import "ARTCGFloatArray.h"
|
||||
#import "ARTTextFrame.h"
|
||||
|
||||
@interface RCTConvert (ART)
|
||||
|
||||
+ (CGPathRef)CGPath:(id)json CF_RETURNS_NOT_RETAINED;
|
||||
+ (CTTextAlignment)CTTextAlignment:(id)json;
|
||||
+ (ARTTextFrame)ARTTextFrame:(id)json;
|
||||
+ (ARTCGFloatArray)ARTCGFloatArray:(id)json;
|
||||
+ (ARTBrush *)ARTBrush:(id)json;
|
||||
|
||||
+ (CGPoint)CGPoint:(id)json offset:(NSUInteger)offset;
|
||||
+ (CGRect)CGRect:(id)json offset:(NSUInteger)offset;
|
||||
+ (CGColorRef)CGColor:(id)json offset:(NSUInteger)offset CF_RETURNS_NOT_RETAINED;
|
||||
+ (CGGradientRef)CGGradient:(id)json offset:(NSUInteger)offset CF_RETURNS_NOT_RETAINED;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,222 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import "RCTConvert+ART.h"
|
||||
|
||||
#import <React/RCTFont.h>
|
||||
#import <React/RCTLog.h>
|
||||
|
||||
#import <React/ARTLinearGradient.h>
|
||||
#import <React/ARTPattern.h>
|
||||
#import <React/ARTRadialGradient.h>
|
||||
#import <React/ARTSolidColor.h>
|
||||
|
||||
@implementation RCTConvert (ART)
|
||||
|
||||
+ (CGPathRef)CGPath:(id)json
|
||||
{
|
||||
NSArray *arr = [self NSNumberArray:json];
|
||||
|
||||
NSUInteger count = [arr count];
|
||||
|
||||
#define NEXT_VALUE [self double:arr[i++]]
|
||||
|
||||
CGMutablePathRef path = CGPathCreateMutable();
|
||||
CGPathMoveToPoint(path, NULL, 0, 0);
|
||||
|
||||
@try {
|
||||
NSUInteger i = 0;
|
||||
while (i < count) {
|
||||
NSUInteger type = [arr[i++] unsignedIntegerValue];
|
||||
switch (type) {
|
||||
case 0:
|
||||
CGPathMoveToPoint(path, NULL, NEXT_VALUE, NEXT_VALUE);
|
||||
break;
|
||||
case 1:
|
||||
CGPathCloseSubpath(path);
|
||||
break;
|
||||
case 2:
|
||||
CGPathAddLineToPoint(path, NULL, NEXT_VALUE, NEXT_VALUE);
|
||||
break;
|
||||
case 3:
|
||||
CGPathAddCurveToPoint(path, NULL, NEXT_VALUE, NEXT_VALUE, NEXT_VALUE, NEXT_VALUE, NEXT_VALUE, NEXT_VALUE);
|
||||
break;
|
||||
case 4:
|
||||
CGPathAddArc(path, NULL, NEXT_VALUE, NEXT_VALUE, NEXT_VALUE, NEXT_VALUE, NEXT_VALUE, NEXT_VALUE == 0);
|
||||
break;
|
||||
default:
|
||||
RCTLogError(@"Invalid CGPath type %llu at element %llu of %@", (unsigned long long)type, (unsigned long long)i, arr);
|
||||
CGPathRelease(path);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
@catch (NSException *exception) {
|
||||
RCTLogError(@"Invalid CGPath format: %@", arr);
|
||||
CGPathRelease(path);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return (CGPathRef)CFAutorelease(path);
|
||||
}
|
||||
|
||||
RCT_ENUM_CONVERTER(CTTextAlignment, (@{
|
||||
@"auto": @(kCTTextAlignmentNatural),
|
||||
@"left": @(kCTTextAlignmentLeft),
|
||||
@"center": @(kCTTextAlignmentCenter),
|
||||
@"right": @(kCTTextAlignmentRight),
|
||||
@"justify": @(kCTTextAlignmentJustified),
|
||||
}), kCTTextAlignmentNatural, integerValue)
|
||||
|
||||
// This takes a tuple of text lines and a font to generate a CTLine for each text line.
|
||||
// This prepares everything for rendering a frame of text in ARTText.
|
||||
+ (ARTTextFrame)ARTTextFrame:(id)json
|
||||
{
|
||||
NSDictionary *dict = [self NSDictionary:json];
|
||||
ARTTextFrame frame;
|
||||
frame.count = 0;
|
||||
|
||||
NSArray *lines = [self NSArray:dict[@"lines"]];
|
||||
NSUInteger lineCount = [lines count];
|
||||
if (lineCount == 0) {
|
||||
return frame;
|
||||
}
|
||||
|
||||
CTFontRef font = (__bridge CTFontRef)[self UIFont:dict[@"font"]];
|
||||
if (!font) {
|
||||
return frame;
|
||||
}
|
||||
|
||||
// Create a dictionary for this font
|
||||
CFDictionaryRef attributes = (__bridge CFDictionaryRef)@{
|
||||
(NSString *)kCTFontAttributeName:(__bridge id)font,
|
||||
(NSString *)kCTForegroundColorFromContextAttributeName: @YES
|
||||
};
|
||||
|
||||
// Set up text frame with font metrics
|
||||
CGFloat size = CTFontGetSize(font);
|
||||
frame.count = lineCount;
|
||||
frame.baseLine = size; // estimate base line
|
||||
frame.lineHeight = size * 1.1; // Base on ART canvas line height estimate
|
||||
frame.lines = malloc(sizeof(CTLineRef) * lineCount);
|
||||
frame.widths = malloc(sizeof(CGFloat) * lineCount);
|
||||
|
||||
[lines enumerateObjectsUsingBlock:^(NSString *text, NSUInteger i, BOOL *stop) {
|
||||
|
||||
CFStringRef string = (__bridge CFStringRef)text;
|
||||
CFAttributedStringRef attrString = CFAttributedStringCreate(kCFAllocatorDefault, string, attributes);
|
||||
CTLineRef line = CTLineCreateWithAttributedString(attrString);
|
||||
CFRelease(attrString);
|
||||
|
||||
frame.lines[i] = line;
|
||||
frame.widths[i] = CTLineGetTypographicBounds(line, NULL, NULL, NULL);
|
||||
}];
|
||||
|
||||
return frame;
|
||||
}
|
||||
|
||||
+ (ARTCGFloatArray)ARTCGFloatArray:(id)json
|
||||
{
|
||||
NSArray *arr = [self NSNumberArray:json];
|
||||
NSUInteger count = arr.count;
|
||||
|
||||
ARTCGFloatArray array;
|
||||
array.count = count;
|
||||
array.array = NULL;
|
||||
|
||||
if (count) {
|
||||
// Ideally, these arrays should already use the same memory layout.
|
||||
// In that case we shouldn't need this new malloc.
|
||||
array.array = malloc(sizeof(CGFloat) * count);
|
||||
for (NSUInteger i = 0; i < count; i++) {
|
||||
array.array[i] = [arr[i] doubleValue];
|
||||
}
|
||||
}
|
||||
|
||||
return array;
|
||||
}
|
||||
|
||||
+ (ARTBrush *)ARTBrush:(id)json
|
||||
{
|
||||
NSArray *arr = [self NSArray:json];
|
||||
NSUInteger type = [self NSUInteger:arr.firstObject];
|
||||
switch (type) {
|
||||
case 0: // solid color
|
||||
// These are probably expensive allocations since it's often the same value.
|
||||
// We should memoize colors but look ups may be just as expensive.
|
||||
return [[ARTSolidColor alloc] initWithArray:arr];
|
||||
case 1: // linear gradient
|
||||
return [[ARTLinearGradient alloc] initWithArray:arr];
|
||||
case 2: // radial gradient
|
||||
return [[ARTRadialGradient alloc] initWithArray:arr];
|
||||
case 3: // pattern
|
||||
return [[ARTPattern alloc] initWithArray:arr];
|
||||
default:
|
||||
RCTLogError(@"Unknown brush type: %llu", (unsigned long long)type);
|
||||
return nil;
|
||||
}
|
||||
}
|
||||
|
||||
+ (CGPoint)CGPoint:(id)json offset:(NSUInteger)offset
|
||||
{
|
||||
NSArray *arr = [self NSArray:json];
|
||||
if (arr.count < offset + 2) {
|
||||
RCTLogError(@"Too few elements in array (expected at least %llu): %@", (unsigned long long)(2 + offset), arr);
|
||||
return CGPointZero;
|
||||
}
|
||||
return (CGPoint){
|
||||
[self CGFloat:arr[offset]],
|
||||
[self CGFloat:arr[offset + 1]],
|
||||
};
|
||||
}
|
||||
|
||||
+ (CGRect)CGRect:(id)json offset:(NSUInteger)offset
|
||||
{
|
||||
NSArray *arr = [self NSArray:json];
|
||||
if (arr.count < offset + 4) {
|
||||
RCTLogError(@"Too few elements in array (expected at least %llu): %@", (unsigned long long)(4 + offset), arr);
|
||||
return CGRectZero;
|
||||
}
|
||||
return (CGRect){
|
||||
{[self CGFloat:arr[offset]], [self CGFloat:arr[offset + 1]]},
|
||||
{[self CGFloat:arr[offset + 2]], [self CGFloat:arr[offset + 3]]},
|
||||
};
|
||||
}
|
||||
|
||||
+ (CGColorRef)CGColor:(id)json offset:(NSUInteger)offset
|
||||
{
|
||||
NSArray *arr = [self NSArray:json];
|
||||
if (arr.count < offset + 4) {
|
||||
RCTLogError(@"Too few elements in array (expected at least %llu): %@", (unsigned long long)(4 + offset), arr);
|
||||
return NULL;
|
||||
}
|
||||
return [self CGColor:[arr subarrayWithRange:(NSRange){offset, 4}]];
|
||||
}
|
||||
|
||||
+ (CGGradientRef)CGGradient:(id)json offset:(NSUInteger)offset
|
||||
{
|
||||
NSArray *arr = [self NSArray:json];
|
||||
if (arr.count < offset) {
|
||||
RCTLogError(@"Too few elements in array (expected at least %llu): %@", (unsigned long long)offset, arr);
|
||||
return NULL;
|
||||
}
|
||||
arr = [arr subarrayWithRange:(NSRange){offset, arr.count - offset}];
|
||||
ARTCGFloatArray colorsAndOffsets = [self ARTCGFloatArray:arr];
|
||||
size_t stops = colorsAndOffsets.count / 5;
|
||||
CGColorSpaceRef rgb = CGColorSpaceCreateDeviceRGB();
|
||||
CGGradientRef gradient = CGGradientCreateWithColorComponents(
|
||||
rgb,
|
||||
colorsAndOffsets.array,
|
||||
colorsAndOffsets.array + stops * 4,
|
||||
stops
|
||||
);
|
||||
CGColorSpaceRelease(rgb);
|
||||
free(colorsAndOffsets.array);
|
||||
return (CGGradientRef)CFAutorelease(gradient);
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,33 @@
|
||||
# Copyright (c) Facebook, Inc. and its 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
|
||||
else
|
||||
source[:tag] = "v#{version}"
|
||||
end
|
||||
|
||||
Pod::Spec.new do |s|
|
||||
s.name = "React-ART"
|
||||
s.version = version
|
||||
s.summary = "A library for drawing vector graphics."
|
||||
s.homepage = "https://reactnative.dev/"
|
||||
s.license = package["license"]
|
||||
s.author = "Facebook, Inc. and its affiliates"
|
||||
s.platforms = { :ios => "10.0", :tvos => "10.0" }
|
||||
s.source = source
|
||||
s.source_files = "**/*.{m}"
|
||||
s.preserve_paths = "package.json", "LICENSE", "LICENSE-docs"
|
||||
s.header_dir = "ART"
|
||||
|
||||
s.dependency "React-Core/ARTHeaders", version
|
||||
end
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user