mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Compare commits
36
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
502172e2ce | ||
|
|
559d070e8e | ||
|
|
3420eb87b0 | ||
|
|
0f1d4704df | ||
|
|
b3648be84f | ||
|
|
9d1e24cb2f | ||
|
|
2204ec94d4 | ||
|
|
e3c63cfd34 | ||
|
|
48cafc0b69 | ||
|
|
6368555ab0 | ||
|
|
ef7f714f57 | ||
|
|
51fb5ab87a | ||
|
|
a511c1bdee | ||
|
|
8b8b0ba5dc | ||
|
|
c799aa07e2 | ||
|
|
f44ff97c47 | ||
|
|
9f7bacaa6b | ||
|
|
07769d4d7e | ||
|
|
8b5e2ea683 | ||
|
|
b7eccf23de | ||
|
|
85f9939031 | ||
|
|
e4d969a4ab | ||
|
|
d95909ea15 | ||
|
|
817cb17f78 | ||
|
|
2056794d24 | ||
|
|
647ca90a30 | ||
|
|
2d320fbd76 | ||
|
|
980458c061 | ||
|
|
5a290c4cab | ||
|
|
90d2f65301 | ||
|
|
05e8007e12 | ||
|
|
1e0009407d | ||
|
|
12e321daf0 | ||
|
|
c7785e7ead | ||
|
|
fe8d102663 | ||
|
|
671520943f |
@@ -20,8 +20,6 @@ runs:
|
||||
- name: Set React Native Version
|
||||
shell: bash
|
||||
run: node ./scripts/releases/set-rn-artifacts-version.js --build-type ${{ inputs.release-type }}
|
||||
# We don't want to re-set the artifacts version if we're on the release branch.
|
||||
if: ${{ !contains(github.ref, '-stable') }}
|
||||
- name: Setup gradle
|
||||
uses: ./.github/actions/setup-gradle
|
||||
with:
|
||||
|
||||
@@ -35,7 +35,7 @@ runs:
|
||||
steps:
|
||||
- name: Installing Maestro
|
||||
shell: bash
|
||||
run: export MAESTRO_VERSION=1.39.5; curl -Ls "https://get.maestro.mobile.dev" | bash
|
||||
run: export MAESTRO_VERSION=1.39.7; curl -Ls "https://get.maestro.mobile.dev" | bash
|
||||
- name: Set up JDK 17
|
||||
if: ${{ inputs.install-java == 'true' }}
|
||||
uses: actions/setup-java@v4
|
||||
|
||||
@@ -31,7 +31,7 @@ runs:
|
||||
steps:
|
||||
- name: Installing Maestro
|
||||
shell: bash
|
||||
run: export MAESTRO_VERSION=1.39.5; curl -Ls "https://get.maestro.mobile.dev" | bash
|
||||
run: export MAESTRO_VERSION=1.39.7; curl -Ls "https://get.maestro.mobile.dev" | bash
|
||||
- name: Installing Maestro dependencies
|
||||
shell: bash
|
||||
run: |
|
||||
|
||||
@@ -157,7 +157,7 @@ jobs:
|
||||
react-native-version: ${{ needs.prepare_hermes_workspace.outputs.react-native-version }}
|
||||
|
||||
test_ios_rntester:
|
||||
runs-on: macos-13
|
||||
runs-on: macos-13-large
|
||||
needs:
|
||||
[build_apple_slices_hermes, prepare_hermes_workspace, build_hermes_macos]
|
||||
env:
|
||||
@@ -369,6 +369,11 @@ jobs:
|
||||
sed -i 's/newArchEnabled=true/newArchEnabled=false/' android/gradle.properties
|
||||
fi
|
||||
|
||||
if [[ ${{matrix.jsengine}} == "JSC" ]]; then
|
||||
echo "Using JSC instead of Hermes"
|
||||
sed -i 's/hermesEnabled=true/hermesEnabled=false/' android/gradle.properties
|
||||
fi
|
||||
|
||||
# Build
|
||||
cd android
|
||||
CAPITALIZED_FLAVOR=$(echo "${{ matrix.flavor }}" | awk '{print toupper(substr($0, 1, 1)) substr($0, 2)}')
|
||||
|
||||
-393
@@ -1,393 +0,0 @@
|
||||
Attribution 4.0 International
|
||||
|
||||
=======================================================================
|
||||
|
||||
Creative Commons Corporation ("Creative Commons") is not a law firm and
|
||||
does not provide legal services or legal advice. Distribution of
|
||||
Creative Commons public licenses does not create a lawyer-client or
|
||||
other relationship. Creative Commons makes its licenses and related
|
||||
information available on an "as-is" basis. Creative Commons gives no
|
||||
warranties regarding its licenses, any material licensed under their
|
||||
terms and conditions, or any related information. Creative Commons
|
||||
disclaims all liability for damages resulting from their use to the
|
||||
fullest extent possible.
|
||||
|
||||
Using Creative Commons Public Licenses
|
||||
|
||||
Creative Commons public licenses provide a standard set of terms and
|
||||
conditions that creators and other rights holders may use to share
|
||||
original works of authorship and other material subject to copyright
|
||||
and certain other rights specified in the public license below. The
|
||||
following considerations are for informational purposes only, are not
|
||||
exhaustive, and do not form part of our licenses.
|
||||
|
||||
Considerations for licensors: Our public licenses are
|
||||
intended for use by those authorized to give the public
|
||||
permission to use material in ways otherwise restricted by
|
||||
copyright and certain other rights. Our licenses are
|
||||
irrevocable. Licensors should read and understand the terms
|
||||
and conditions of the license they choose before applying it.
|
||||
Licensors should also secure all rights necessary before
|
||||
applying our licenses so that the public can reuse the
|
||||
material as expected. Licensors should clearly mark any
|
||||
material not subject to the license. This includes other CC-
|
||||
licensed material, or material used under an exception or
|
||||
limitation to copyright. More considerations for licensors:
|
||||
wiki.creativecommons.org/Considerations_for_licensors
|
||||
|
||||
Considerations for the public: By using one of our public
|
||||
licenses, a licensor grants the public permission to use the
|
||||
licensed material under specified terms and conditions. If
|
||||
the licensor's permission is not necessary for any reason--for
|
||||
example, because of any applicable exception or limitation to
|
||||
copyright--then that use is not regulated by the license. Our
|
||||
licenses grant only permissions under copyright and certain
|
||||
other rights that a licensor has authority to grant. Use of
|
||||
the licensed material may still be restricted for other
|
||||
reasons, including because others have copyright or other
|
||||
rights in the material. A licensor may make special requests,
|
||||
such as asking that all changes be marked or described.
|
||||
Although not required by our licenses, you are encouraged to
|
||||
respect those requests where reasonable. More_considerations
|
||||
for the public:
|
||||
wiki.creativecommons.org/Considerations_for_licensees
|
||||
|
||||
=======================================================================
|
||||
|
||||
Creative Commons Attribution 4.0 International Public License
|
||||
|
||||
By exercising the Licensed Rights (defined below), You accept and agree
|
||||
to be bound by the terms and conditions of this Creative Commons
|
||||
Attribution 4.0 International Public License ("Public License"). To the
|
||||
extent this Public License may be interpreted as a contract, You are
|
||||
granted the Licensed Rights in consideration of Your acceptance of
|
||||
these terms and conditions, and the Licensor grants You such rights in
|
||||
consideration of benefits the Licensor receives from making the
|
||||
Licensed Material available under these terms and conditions.
|
||||
|
||||
|
||||
Section 1 -- Definitions.
|
||||
|
||||
a. Adapted Material means material subject to Copyright and Similar
|
||||
Rights that is derived from or based upon the Licensed Material
|
||||
and in which the Licensed Material is translated, altered,
|
||||
arranged, transformed, or otherwise modified in a manner requiring
|
||||
permission under the Copyright and Similar Rights held by the
|
||||
Licensor. For purposes of this Public License, where the Licensed
|
||||
Material is a musical work, performance, or sound recording,
|
||||
Adapted Material is always produced where the Licensed Material is
|
||||
synched in timed relation with a moving image.
|
||||
|
||||
b. Adapter's License means the license You apply to Your Copyright
|
||||
and Similar Rights in Your contributions to Adapted Material in
|
||||
accordance with the terms and conditions of this Public License.
|
||||
|
||||
c. Copyright and Similar Rights means copyright and/or similar rights
|
||||
closely related to copyright including, without limitation,
|
||||
performance, broadcast, sound recording, and Sui Generis Database
|
||||
Rights, without regard to how the rights are labeled or
|
||||
categorized. For purposes of this Public License, the rights
|
||||
specified in Section 2(b)(1)-(2) are not Copyright and Similar
|
||||
Rights.
|
||||
|
||||
d. Effective Technological Measures means those measures that, in the
|
||||
absence of proper authority, may not be circumvented under laws
|
||||
fulfilling obligations under Article 11 of the WIPO Copyright
|
||||
Treaty adopted on December 20, 1996, and/or similar international
|
||||
agreements.
|
||||
|
||||
e. Exceptions and Limitations means fair use, fair dealing, and/or
|
||||
any other exception or limitation to Copyright and Similar Rights
|
||||
that applies to Your use of the Licensed Material.
|
||||
|
||||
f. Licensed Material means the artistic or literary work, database,
|
||||
or other material to which the Licensor applied this Public
|
||||
License.
|
||||
|
||||
g. Licensed Rights means the rights granted to You subject to the
|
||||
terms and conditions of this Public License, which are limited to
|
||||
all Copyright and Similar Rights that apply to Your use of the
|
||||
Licensed Material and that the Licensor has authority to license.
|
||||
|
||||
h. Licensor means the individual(s) or entity(ies) granting rights
|
||||
under this Public License.
|
||||
|
||||
i. Share means to provide material to the public by any means or
|
||||
process that requires permission under the Licensed Rights, such
|
||||
as reproduction, public display, public performance, distribution,
|
||||
dissemination, communication, or importation, and to make material
|
||||
available to the public including in ways that members of the
|
||||
public may access the material from a place and at a time
|
||||
individually chosen by them.
|
||||
|
||||
j. Sui Generis Database Rights means rights other than copyright
|
||||
resulting from Directive 96/9/EC of the European Parliament and of
|
||||
the Council of 11 March 1996 on the legal protection of databases,
|
||||
as amended and/or succeeded, as well as other essentially
|
||||
equivalent rights anywhere in the world.
|
||||
|
||||
k. You means the individual or entity exercising the Licensed Rights
|
||||
under this Public License. Your has a corresponding meaning.
|
||||
|
||||
|
||||
Section 2 -- Scope.
|
||||
|
||||
a. License grant.
|
||||
|
||||
1. Subject to the terms and conditions of this Public License,
|
||||
the Licensor hereby grants You a worldwide, royalty-free,
|
||||
non-sublicensable, non-exclusive, irrevocable license to
|
||||
exercise the Licensed Rights in the Licensed Material to:
|
||||
|
||||
a. reproduce and Share the Licensed Material, in whole or
|
||||
in part; and
|
||||
|
||||
b. produce, reproduce, and Share Adapted Material.
|
||||
|
||||
2. Exceptions and Limitations. For the avoidance of doubt, where
|
||||
Exceptions and Limitations apply to Your use, this Public
|
||||
License does not apply, and You do not need to comply with
|
||||
its terms and conditions.
|
||||
|
||||
3. Term. The term of this Public License is specified in Section
|
||||
6(a).
|
||||
|
||||
4. Media and formats; technical modifications allowed. The
|
||||
Licensor authorizes You to exercise the Licensed Rights in
|
||||
all media and formats whether now known or hereafter created,
|
||||
and to make technical modifications necessary to do so. The
|
||||
Licensor waives and/or agrees not to assert any right or
|
||||
authority to forbid You from making technical modifications
|
||||
necessary to exercise the Licensed Rights, including
|
||||
technical modifications necessary to circumvent Effective
|
||||
Technological Measures. For purposes of this Public License,
|
||||
simply making modifications authorized by this Section 2(a)
|
||||
(4) never produces Adapted Material.
|
||||
|
||||
5. Downstream recipients.
|
||||
|
||||
a. Offer from the Licensor -- Licensed Material. Every
|
||||
recipient of the Licensed Material automatically
|
||||
receives an offer from the Licensor to exercise the
|
||||
Licensed Rights under the terms and conditions of this
|
||||
Public License.
|
||||
|
||||
b. No downstream restrictions. You may not offer or impose
|
||||
any additional or different terms or conditions on, or
|
||||
apply any Effective Technological Measures to, the
|
||||
Licensed Material if doing so restricts exercise of the
|
||||
Licensed Rights by any recipient of the Licensed
|
||||
Material.
|
||||
|
||||
6. No endorsement. Nothing in this Public License constitutes or
|
||||
may be construed as permission to assert or imply that You
|
||||
are, or that Your use of the Licensed Material is, connected
|
||||
with, or sponsored, endorsed, or granted official status by,
|
||||
the Licensor or others designated to receive attribution as
|
||||
provided in Section 3(a)(1)(A)(i).
|
||||
|
||||
b. Other rights.
|
||||
|
||||
1. Moral rights, such as the right of integrity, are not
|
||||
licensed under this Public License, nor are publicity,
|
||||
privacy, and/or other similar personality rights; however, to
|
||||
the extent possible, the Licensor waives and/or agrees not to
|
||||
assert any such rights held by the Licensor to the limited
|
||||
extent necessary to allow You to exercise the Licensed
|
||||
Rights, but not otherwise.
|
||||
|
||||
2. Patent and trademark rights are not licensed under this
|
||||
Public License.
|
||||
|
||||
3. To the extent possible, the Licensor waives any right to
|
||||
collect royalties from You for the exercise of the Licensed
|
||||
Rights, whether directly or through a collecting society
|
||||
under any voluntary or waivable statutory or compulsory
|
||||
licensing scheme. In all other cases the Licensor expressly
|
||||
reserves any right to collect such royalties.
|
||||
|
||||
|
||||
Section 3 -- License Conditions.
|
||||
|
||||
Your exercise of the Licensed Rights is expressly made subject to the
|
||||
following conditions.
|
||||
|
||||
a. Attribution.
|
||||
|
||||
1. If You Share the Licensed Material (including in modified
|
||||
form), You must:
|
||||
|
||||
a. retain the following if it is supplied by the Licensor
|
||||
with the Licensed Material:
|
||||
|
||||
i. identification of the creator(s) of the Licensed
|
||||
Material and any others designated to receive
|
||||
attribution, in any reasonable manner requested by
|
||||
the Licensor (including by pseudonym if
|
||||
designated);
|
||||
|
||||
ii. a copyright notice;
|
||||
|
||||
iii. a notice that refers to this Public License;
|
||||
|
||||
iv. a notice that refers to the disclaimer of
|
||||
warranties;
|
||||
|
||||
v. a URI or hyperlink to the Licensed Material to the
|
||||
extent reasonably practicable;
|
||||
|
||||
b. indicate if You modified the Licensed Material and
|
||||
retain an indication of any previous modifications; and
|
||||
|
||||
c. indicate the Licensed Material is licensed under this
|
||||
Public License, and include the text of, or the URI or
|
||||
hyperlink to, this Public License.
|
||||
|
||||
2. You may satisfy the conditions in Section 3(a)(1) in any
|
||||
reasonable manner based on the medium, means, and context in
|
||||
which You Share the Licensed Material. For example, it may be
|
||||
reasonable to satisfy the conditions by providing a URI or
|
||||
hyperlink to a resource that includes the required
|
||||
information.
|
||||
|
||||
3. If requested by the Licensor, You must remove any of the
|
||||
information required by Section 3(a)(1)(A) to the extent
|
||||
reasonably practicable.
|
||||
|
||||
4. If You Share Adapted Material You produce, the Adapter's
|
||||
License You apply must not prevent recipients of the Adapted
|
||||
Material from complying with this Public License.
|
||||
|
||||
|
||||
Section 4 -- Sui Generis Database Rights.
|
||||
|
||||
Where the Licensed Rights include Sui Generis Database Rights that
|
||||
apply to Your use of the Licensed Material:
|
||||
|
||||
a. for the avoidance of doubt, Section 2(a)(1) grants You the right
|
||||
to extract, reuse, reproduce, and Share all or a substantial
|
||||
portion of the contents of the database;
|
||||
|
||||
b. if You include all or a substantial portion of the database
|
||||
contents in a database in which You have Sui Generis Database
|
||||
Rights, then the database in which You have Sui Generis Database
|
||||
Rights (but not its individual contents) is Adapted Material; and
|
||||
|
||||
c. You must comply with the conditions in Section 3(a) if You Share
|
||||
all or a substantial portion of the contents of the database.
|
||||
|
||||
For the avoidance of doubt, this Section 4 supplements and does not
|
||||
replace Your obligations under this Public License where the Licensed
|
||||
Rights include other Copyright and Similar Rights.
|
||||
|
||||
|
||||
Section 5 -- Disclaimer of Warranties and Limitation of Liability.
|
||||
|
||||
a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE
|
||||
EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS
|
||||
AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF
|
||||
ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS,
|
||||
IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION,
|
||||
WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||
PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS,
|
||||
ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT
|
||||
KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT
|
||||
ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU.
|
||||
|
||||
b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE
|
||||
TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION,
|
||||
NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT,
|
||||
INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES,
|
||||
COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR
|
||||
USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN
|
||||
ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR
|
||||
DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR
|
||||
IN PART, THIS LIMITATION MAY NOT APPLY TO YOU.
|
||||
|
||||
c. The disclaimer of warranties and limitation of liability provided
|
||||
above shall be interpreted in a manner that, to the extent
|
||||
possible, most closely approximates an absolute disclaimer and
|
||||
waiver of all liability.
|
||||
|
||||
|
||||
Section 6 -- Term and Termination.
|
||||
|
||||
a. This Public License applies for the term of the Copyright and
|
||||
Similar Rights licensed here. However, if You fail to comply with
|
||||
this Public License, then Your rights under this Public License
|
||||
terminate automatically.
|
||||
|
||||
b. Where Your right to use the Licensed Material has terminated under
|
||||
Section 6(a), it reinstates:
|
||||
|
||||
1. automatically as of the date the violation is cured, provided
|
||||
it is cured within 30 days of Your discovery of the
|
||||
violation; or
|
||||
|
||||
2. upon express reinstatement by the Licensor.
|
||||
|
||||
For the avoidance of doubt, this Section 6(b) does not affect any
|
||||
right the Licensor may have to seek remedies for Your violations
|
||||
of this Public License.
|
||||
|
||||
c. For the avoidance of doubt, the Licensor may also offer the
|
||||
Licensed Material under separate terms or conditions or stop
|
||||
distributing the Licensed Material at any time; however, doing so
|
||||
will not terminate this Public License.
|
||||
|
||||
d. Sections 1, 5, 6, 7, and 8 survive termination of this Public
|
||||
License.
|
||||
|
||||
|
||||
Section 7 -- Other Terms and Conditions.
|
||||
|
||||
a. The Licensor shall not be bound by any additional or different
|
||||
terms or conditions communicated by You unless expressly agreed.
|
||||
|
||||
b. Any arrangements, understandings, or agreements regarding the
|
||||
Licensed Material not stated herein are separate from and
|
||||
independent of the terms and conditions of this Public License.
|
||||
|
||||
|
||||
Section 8 -- Interpretation.
|
||||
|
||||
a. For the avoidance of doubt, this Public License does not, and
|
||||
shall not be interpreted to, reduce, limit, restrict, or impose
|
||||
conditions on any use of the Licensed Material that could lawfully
|
||||
be made without permission under this Public License.
|
||||
|
||||
b. To the extent possible, if any provision of this Public License is
|
||||
deemed unenforceable, it shall be automatically reformed to the
|
||||
minimum extent necessary to make it enforceable. If the provision
|
||||
cannot be reformed, it shall be severed from this Public License
|
||||
without affecting the enforceability of the remaining terms and
|
||||
conditions.
|
||||
|
||||
c. No term or condition of this Public License will be waived and no
|
||||
failure to comply consented to unless expressly agreed to by the
|
||||
Licensor.
|
||||
|
||||
d. Nothing in this Public License constitutes or may be interpreted
|
||||
as a limitation upon, or waiver of, any privileges and immunities
|
||||
that apply to the Licensor or You, including from the legal
|
||||
processes of any jurisdiction or authority.
|
||||
|
||||
|
||||
=======================================================================
|
||||
|
||||
Creative Commons is not a party to its public licenses.
|
||||
Notwithstanding, Creative Commons may elect to apply one of its public
|
||||
licenses to material it publishes and in those instances will be
|
||||
considered the "Licensor." Except for the limited purpose of indicating
|
||||
that material is shared under a Creative Commons public license or as
|
||||
otherwise permitted by the Creative Commons policies published at
|
||||
creativecommons.org/policies, Creative Commons does not authorize the
|
||||
use of the trademark "Creative Commons" or any other trademark or logo
|
||||
of Creative Commons without its prior written consent including,
|
||||
without limitation, in connection with any unauthorized modifications
|
||||
to any of its public licenses or any other arrangements,
|
||||
understandings, or agreements concerning use of licensed material. For
|
||||
the avoidance of doubt, this paragraph does not form part of the public
|
||||
licenses.
|
||||
|
||||
Creative Commons may be contacted at creativecommons.org.
|
||||
@@ -192,4 +192,4 @@ export default {
|
||||
forkEvent: AnimatedImplementation.forkEvent,
|
||||
unforkEvent: AnimatedImplementation.unforkEvent,
|
||||
Event: AnimatedEvent,
|
||||
};
|
||||
} as typeof AnimatedImplementation;
|
||||
|
||||
+27
-9
@@ -10,17 +10,35 @@
|
||||
|
||||
'use strict';
|
||||
|
||||
import type {AnimatedComponentType} from './createAnimatedComponent';
|
||||
|
||||
import AnimatedImplementation from './AnimatedImplementation';
|
||||
import React from 'react';
|
||||
|
||||
export default {
|
||||
...AnimatedImplementation,
|
||||
/* $FlowFixMe[incompatible-call] createAnimatedComponent expects to receive
|
||||
* types. Plain intrinsic components can't be typed like this */
|
||||
div: (AnimatedImplementation.createAnimatedComponent('div'): $FlowFixMe),
|
||||
/* $FlowFixMe[incompatible-call] createAnimatedComponent expects to receive
|
||||
* types. Plain intrinsic components can't be typed like this */
|
||||
span: (AnimatedImplementation.createAnimatedComponent('span'): $FlowFixMe),
|
||||
/* $FlowFixMe[incompatible-call] createAnimatedComponent expects to receive
|
||||
* types. Plain intrinsic components can't be typed like this */
|
||||
img: (AnimatedImplementation.createAnimatedComponent('img'): $FlowFixMe),
|
||||
div: AnimatedImplementation.createAnimatedComponent<
|
||||
React.PropsOf<'div'>,
|
||||
mixed,
|
||||
>(
|
||||
/* $FlowFixMe[incompatible-call] createAnimatedComponent expects to receive
|
||||
* types. Plain intrinsic components can't be typed like this */
|
||||
'div',
|
||||
) as AnimatedComponentType<React.PropsOf<'div'>>,
|
||||
span: AnimatedImplementation.createAnimatedComponent<
|
||||
React.PropsOf<'span'>,
|
||||
mixed,
|
||||
>(
|
||||
/* $FlowFixMe[incompatible-call] createAnimatedComponent expects to receive
|
||||
* types. Plain intrinsic components can't be typed like this */
|
||||
'span',
|
||||
) as AnimatedComponentType<React.PropsOf<'span'>>,
|
||||
img: AnimatedImplementation.createAnimatedComponent<
|
||||
React.PropsOf<'img'>,
|
||||
mixed,
|
||||
>(
|
||||
/* $FlowFixMe[incompatible-call] createAnimatedComponent expects to receive
|
||||
* types. Plain intrinsic components can't be typed like this */
|
||||
'img',
|
||||
) as AnimatedComponentType<React.PropsOf<'img'>>,
|
||||
};
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
*/
|
||||
|
||||
import type {EventSubscription} from '../../vendor/emitter/EventEmitter';
|
||||
import type {PlatformConfig} from '../AnimatedPlatformConfig';
|
||||
import type Animation, {EndCallback} from '../animations/Animation';
|
||||
import type {InterpolationConfigType} from './AnimatedInterpolation';
|
||||
import type AnimatedNode from './AnimatedNode';
|
||||
@@ -131,6 +132,11 @@ export default class AnimatedValue extends AnimatedWithChildren {
|
||||
return this._value + this._offset;
|
||||
}
|
||||
|
||||
__makeNative(platformConfig: ?PlatformConfig): void {
|
||||
super.__makeNative(platformConfig);
|
||||
this.#ensureUpdateSubscriptionExists();
|
||||
}
|
||||
|
||||
#ensureUpdateSubscriptionExists(): void {
|
||||
if (this.#updateSubscription != null) {
|
||||
return;
|
||||
|
||||
+2
-1
@@ -12,7 +12,8 @@
|
||||
|
||||
import type {BlobOptions} from './BlobTypes';
|
||||
|
||||
const Blob = require('./Blob');
|
||||
import Blob from './Blob';
|
||||
|
||||
const invariant = require('invariant');
|
||||
|
||||
/**
|
||||
|
||||
+1
-1
@@ -19,7 +19,7 @@ import * as React from 'react';
|
||||
import {useCallback, useEffect, useMemo, useRef, useState} from 'react';
|
||||
|
||||
export type Props = $ReadOnly<{
|
||||
children?: ExactReactElement_DEPRECATED<$FlowFixMe>,
|
||||
children?: React.Node,
|
||||
nextHeaderLayoutY: ?number,
|
||||
onLayout: (event: LayoutEvent) => void,
|
||||
scrollAnimatedValue: Animated.Value,
|
||||
|
||||
@@ -105,6 +105,24 @@ type Props = $ReadOnly<{|
|
||||
barStyle?: ?('default' | 'light-content' | 'dark-content'),
|
||||
|}>;
|
||||
|
||||
type StackProps = {
|
||||
backgroundColor: ?{
|
||||
value: Props['backgroundColor'],
|
||||
animated: boolean,
|
||||
},
|
||||
barStyle: ?{
|
||||
value: Props['barStyle'],
|
||||
animated: boolean,
|
||||
},
|
||||
translucent: Props['translucent'],
|
||||
hidden: ?{
|
||||
value: boolean,
|
||||
animated: boolean,
|
||||
transition: Props['showHideTransition'],
|
||||
},
|
||||
networkActivityIndicatorVisible: Props['networkActivityIndicatorVisible'],
|
||||
};
|
||||
|
||||
/**
|
||||
* Merges the prop stack with the default values.
|
||||
*/
|
||||
@@ -129,7 +147,7 @@ function mergePropsStack(
|
||||
* Returns an object to insert in the props stack from the props
|
||||
* and the transition/animation info.
|
||||
*/
|
||||
function createStackEntry(props: any): any {
|
||||
function createStackEntry(props: Props): StackProps {
|
||||
const animated = props.animated ?? false;
|
||||
const showHideTransition = props.showHideTransition ?? 'fade';
|
||||
return {
|
||||
@@ -203,7 +221,7 @@ function createStackEntry(props: any): any {
|
||||
* `currentHeight` (Android only) The height of the status bar.
|
||||
*/
|
||||
class StatusBar extends React.Component<Props> {
|
||||
static _propsStack: Array<any> = [];
|
||||
static _propsStack: Array<StackProps> = [];
|
||||
|
||||
static _defaultProps: any = createStackEntry({
|
||||
backgroundColor:
|
||||
@@ -218,12 +236,10 @@ class StatusBar extends React.Component<Props> {
|
||||
});
|
||||
|
||||
// Timer for updating the native module values at the end of the frame.
|
||||
// $FlowFixMe[missing-local-annot]
|
||||
static _updateImmediate = null;
|
||||
static _updateImmediate: ?number = null;
|
||||
|
||||
// The current merged values from the props stack.
|
||||
// $FlowFixMe[missing-local-annot]
|
||||
static _currentValues = null;
|
||||
static _currentValues: ?StackProps = null;
|
||||
|
||||
// TODO(janic): Provide a real API to deal with status bar height. See the
|
||||
// discussion in #6195.
|
||||
@@ -371,8 +387,7 @@ class StatusBar extends React.Component<Props> {
|
||||
return newEntry;
|
||||
}
|
||||
|
||||
// $FlowFixMe[missing-local-annot]
|
||||
_stackEntry = null;
|
||||
_stackEntry: ?StackProps = null;
|
||||
|
||||
componentDidMount() {
|
||||
// Every time a StatusBar component is mounted, we push it's prop to a stack
|
||||
@@ -412,14 +427,14 @@ class StatusBar extends React.Component<Props> {
|
||||
if (Platform.OS === 'ios') {
|
||||
if (
|
||||
!oldProps ||
|
||||
oldProps.barStyle.value !== mergedProps.barStyle.value
|
||||
oldProps.barStyle?.value !== mergedProps.barStyle.value
|
||||
) {
|
||||
NativeStatusBarManagerIOS.setStyle(
|
||||
mergedProps.barStyle.value,
|
||||
mergedProps.barStyle.animated || false,
|
||||
);
|
||||
}
|
||||
if (!oldProps || oldProps.hidden.value !== mergedProps.hidden.value) {
|
||||
if (!oldProps || oldProps.hidden?.value !== mergedProps.hidden.value) {
|
||||
NativeStatusBarManagerIOS.setHidden(
|
||||
mergedProps.hidden.value,
|
||||
mergedProps.hidden.animated
|
||||
@@ -456,7 +471,7 @@ class StatusBar extends React.Component<Props> {
|
||||
mergedProps.backgroundColor.animated,
|
||||
);
|
||||
}
|
||||
if (!oldProps || oldProps.hidden.value !== mergedProps.hidden.value) {
|
||||
if (!oldProps || oldProps.hidden?.value !== mergedProps.hidden.value) {
|
||||
NativeStatusBarManagerAndroid.setHidden(mergedProps.hidden.value);
|
||||
}
|
||||
// Activities are not translucent by default, so always set if true.
|
||||
|
||||
@@ -13,6 +13,8 @@
|
||||
import type {InspectorData} from '../Renderer/shims/ReactNativeTypes';
|
||||
import type {ViewStyleProp} from '../StyleSheet/StyleSheet';
|
||||
|
||||
import React from 'react';
|
||||
|
||||
const TouchableHighlight = require('../Components/Touchable/TouchableHighlight');
|
||||
const TouchableWithoutFeedback = require('../Components/Touchable/TouchableWithoutFeedback');
|
||||
const View = require('../Components/View/View');
|
||||
@@ -22,7 +24,6 @@ const Text = require('../Text/Text');
|
||||
const mapWithSeparator = require('../Utilities/mapWithSeparator');
|
||||
const BoxInspector = require('./BoxInspector');
|
||||
const StyleInspector = require('./StyleInspector');
|
||||
const React = require('react');
|
||||
|
||||
type Props = $ReadOnly<{|
|
||||
hierarchy: ?InspectorData['hierarchy'],
|
||||
|
||||
+1
-1
@@ -19,6 +19,7 @@ import type {ViewStyleProp} from '../StyleSheet/StyleSheet';
|
||||
import type {ReactDevToolsAgent} from '../Types/ReactDevToolsTypes';
|
||||
|
||||
import SafeAreaView from '../../src/private/components/SafeAreaView_INTERNAL_DO_NOT_USE';
|
||||
import React from 'react';
|
||||
|
||||
const View = require('../Components/View/View');
|
||||
const PressabilityDebug = require('../Pressability/PressabilityDebug');
|
||||
@@ -29,7 +30,6 @@ const Platform = require('../Utilities/Platform');
|
||||
const getInspectorDataForViewAtPoint = require('./getInspectorDataForViewAtPoint');
|
||||
const InspectorOverlay = require('./InspectorOverlay');
|
||||
const InspectorPanel = require('./InspectorPanel');
|
||||
const React = require('react');
|
||||
|
||||
const {useState} = React;
|
||||
|
||||
|
||||
@@ -13,10 +13,11 @@
|
||||
import type {PressEvent} from '../Types/CoreEventTypes';
|
||||
import type {InspectedElement} from './Inspector';
|
||||
|
||||
import React from 'react';
|
||||
|
||||
const View = require('../Components/View/View');
|
||||
const StyleSheet = require('../StyleSheet/StyleSheet');
|
||||
const ElementBox = require('./ElementBox');
|
||||
const React = require('react');
|
||||
|
||||
type Props = $ReadOnly<{|
|
||||
inspected?: ?InspectedElement,
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
import type {ElementsHierarchy, InspectedElement} from './Inspector';
|
||||
|
||||
import SafeAreaView from '../Components/SafeAreaView/SafeAreaView';
|
||||
import React from 'react';
|
||||
|
||||
const ScrollView = require('../Components/ScrollView/ScrollView');
|
||||
const TouchableHighlight = require('../Components/Touchable/TouchableHighlight');
|
||||
@@ -22,7 +23,6 @@ const Text = require('../Text/Text');
|
||||
const ElementProperties = require('./ElementProperties');
|
||||
const NetworkOverlay = require('./NetworkOverlay');
|
||||
const PerformanceOverlay = require('./PerformanceOverlay');
|
||||
const React = require('react');
|
||||
|
||||
type Props = $ReadOnly<{|
|
||||
devtoolsIsOpen: boolean,
|
||||
|
||||
@@ -10,11 +10,12 @@
|
||||
|
||||
'use strict';
|
||||
|
||||
import React from 'react';
|
||||
|
||||
const View = require('../Components/View/View');
|
||||
const StyleSheet = require('../StyleSheet/StyleSheet');
|
||||
const Text = require('../Text/Text');
|
||||
const PerformanceLogger = require('../Utilities/GlobalPerformanceLogger');
|
||||
const React = require('react');
|
||||
|
||||
class PerformanceOverlay extends React.Component<{...}> {
|
||||
render(): React.Node {
|
||||
|
||||
+1
-1
@@ -18,6 +18,7 @@ import ModalInjection from './ModalInjection';
|
||||
import NativeModalManager from './NativeModalManager';
|
||||
import RCTModalHostView from './RCTModalHostViewNativeComponent';
|
||||
import {VirtualizedListContextResetter} from '@react-native/virtualized-lists';
|
||||
import React from 'react';
|
||||
|
||||
const ScrollView = require('../Components/ScrollView/ScrollView');
|
||||
const View = require('../Components/View/View');
|
||||
@@ -26,7 +27,6 @@ const I18nManager = require('../ReactNative/I18nManager');
|
||||
const {RootTagContext} = require('../ReactNative/RootTag');
|
||||
const StyleSheet = require('../StyleSheet/StyleSheet');
|
||||
const Platform = require('../Utilities/Platform');
|
||||
const React = require('react');
|
||||
|
||||
type ModalEventDefinitions = {
|
||||
modalDismissed: [{modalID: number}],
|
||||
|
||||
@@ -12,8 +12,9 @@
|
||||
|
||||
import type {IgnorePattern} from '../LogBox/Data/LogBoxData';
|
||||
|
||||
import React from 'react';
|
||||
|
||||
const LogBox = require('../LogBox/LogBox').default;
|
||||
const React = require('react');
|
||||
|
||||
type Props = $ReadOnly<{||}>;
|
||||
|
||||
|
||||
@@ -269,68 +269,8 @@ exports[`public API should not change unintentionally Libraries/Animated/Animate
|
||||
_isUsingNativeDriver: () => boolean,
|
||||
...
|
||||
};
|
||||
declare const spring: (
|
||||
value: AnimatedValue | AnimatedValueXY | AnimatedColor,
|
||||
config: SpringAnimationConfig
|
||||
) => CompositeAnimation;
|
||||
declare const timing: (
|
||||
value: AnimatedValue | AnimatedValueXY | AnimatedColor,
|
||||
config: TimingAnimationConfig
|
||||
) => CompositeAnimation;
|
||||
declare const decay: (
|
||||
value: AnimatedValue | AnimatedValueXY | AnimatedColor,
|
||||
config: DecayAnimationConfig
|
||||
) => CompositeAnimation;
|
||||
declare const sequence: (
|
||||
animations: Array<CompositeAnimation>
|
||||
) => CompositeAnimation;
|
||||
type ParallelConfig = { stopTogether?: boolean, ... };
|
||||
declare const parallel: (
|
||||
animations: Array<CompositeAnimation>,
|
||||
config?: ?ParallelConfig
|
||||
) => CompositeAnimation;
|
||||
declare const delay: (time: number) => CompositeAnimation;
|
||||
declare const stagger: (
|
||||
time: number,
|
||||
animations: Array<CompositeAnimation>
|
||||
) => CompositeAnimation;
|
||||
type LoopAnimationConfig = {
|
||||
iterations: number,
|
||||
resetBeforeIteration?: boolean,
|
||||
...
|
||||
};
|
||||
declare const loop: (
|
||||
animation: CompositeAnimation,
|
||||
LoopAnimationConfig
|
||||
) => CompositeAnimation;
|
||||
export type { AnimatedNumeric as Numeric };
|
||||
declare export default {
|
||||
Value: AnimatedValue,
|
||||
ValueXY: AnimatedValueXY,
|
||||
Color: AnimatedColor,
|
||||
Interpolation: AnimatedInterpolation,
|
||||
Node: AnimatedNode,
|
||||
decay: decay,
|
||||
timing: timing,
|
||||
spring: spring,
|
||||
add: $FlowFixMe,
|
||||
subtract: $FlowFixMe,
|
||||
divide: $FlowFixMe,
|
||||
multiply: $FlowFixMe,
|
||||
modulo: $FlowFixMe,
|
||||
diffClamp: $FlowFixMe,
|
||||
delay: delay,
|
||||
sequence: sequence,
|
||||
parallel: parallel,
|
||||
stagger: stagger,
|
||||
loop: loop,
|
||||
event: $FlowFixMe,
|
||||
createAnimatedComponent: createAnimatedComponent,
|
||||
attachNativeEvent: attachNativeEvent,
|
||||
forkEvent: $FlowFixMe,
|
||||
unforkEvent: $FlowFixMe,
|
||||
Event: AnimatedEvent,
|
||||
};
|
||||
declare export default typeof AnimatedImplementation;
|
||||
"
|
||||
`;
|
||||
|
||||
@@ -342,9 +282,9 @@ exports[`public API should not change unintentionally Libraries/Animated/Animate
|
||||
exports[`public API should not change unintentionally Libraries/Animated/AnimatedWeb.js 1`] = `
|
||||
"declare export default {
|
||||
...AnimatedImplementation,
|
||||
div: $FlowFixMe,
|
||||
span: $FlowFixMe,
|
||||
img: $FlowFixMe,
|
||||
div: AnimatedComponentType<React.PropsOf<\\"div\\">>,
|
||||
span: AnimatedComponentType<React.PropsOf<\\"span\\">>,
|
||||
img: AnimatedComponentType<React.PropsOf<\\"img\\">>,
|
||||
};
|
||||
"
|
||||
`;
|
||||
@@ -1169,6 +1109,7 @@ declare export default class AnimatedValue extends AnimatedWithChildren {
|
||||
__attach(): void;
|
||||
__detach(): void;
|
||||
__getValue(): number;
|
||||
__makeNative(platformConfig: ?PlatformConfig): void;
|
||||
setValue(value: number): void;
|
||||
setOffset(offset: number): void;
|
||||
flattenOffset(): void;
|
||||
@@ -1476,8 +1417,7 @@ export type BlobOptions = {
|
||||
`;
|
||||
|
||||
exports[`public API should not change unintentionally Libraries/Blob/File.js 1`] = `
|
||||
"declare const Blob: $FlowFixMe;
|
||||
declare class File extends Blob {
|
||||
"declare class File extends Blob {
|
||||
constructor(
|
||||
parts: Array<Blob | string>,
|
||||
name: string,
|
||||
@@ -2450,7 +2390,7 @@ exports[`public API should not change unintentionally Libraries/Components/Scrol
|
||||
|
||||
exports[`public API should not change unintentionally Libraries/Components/ScrollView/ScrollViewStickyHeader.js 1`] = `
|
||||
"export type Props = $ReadOnly<{
|
||||
children?: ExactReactElement_DEPRECATED<$FlowFixMe>,
|
||||
children?: React.Node,
|
||||
nextHeaderLayoutY: ?number,
|
||||
onLayout: (event: LayoutEvent) => void,
|
||||
scrollAnimatedValue: Animated.Value,
|
||||
@@ -2546,11 +2486,28 @@ type Props = $ReadOnly<{|
|
||||
animated?: ?boolean,
|
||||
barStyle?: ?(\\"default\\" | \\"light-content\\" | \\"dark-content\\"),
|
||||
|}>;
|
||||
type StackProps = {
|
||||
backgroundColor: ?{
|
||||
value: Props[\\"backgroundColor\\"],
|
||||
animated: boolean,
|
||||
},
|
||||
barStyle: ?{
|
||||
value: Props[\\"barStyle\\"],
|
||||
animated: boolean,
|
||||
},
|
||||
translucent: Props[\\"translucent\\"],
|
||||
hidden: ?{
|
||||
value: boolean,
|
||||
animated: boolean,
|
||||
transition: Props[\\"showHideTransition\\"],
|
||||
},
|
||||
networkActivityIndicatorVisible: Props[\\"networkActivityIndicatorVisible\\"],
|
||||
};
|
||||
declare class StatusBar extends React.Component<Props> {
|
||||
static _propsStack: Array<any>;
|
||||
static _propsStack: Array<StackProps>;
|
||||
static _defaultProps: any;
|
||||
static _updateImmediate: $FlowFixMe;
|
||||
static _currentValues: $FlowFixMe;
|
||||
static _updateImmediate: ?number;
|
||||
static _currentValues: ?StackProps;
|
||||
static currentHeight: ?number;
|
||||
static setHidden(hidden: boolean, animation?: StatusBarAnimation): void;
|
||||
static setBarStyle(style: StatusBarStyle, animated?: boolean): void;
|
||||
@@ -2560,7 +2517,7 @@ declare class StatusBar extends React.Component<Props> {
|
||||
static pushStackEntry(props: any): any;
|
||||
static popStackEntry(entry: any): void;
|
||||
static replaceStackEntry(entry: any, props: any): any;
|
||||
_stackEntry: $FlowFixMe;
|
||||
_stackEntry: ?StackProps;
|
||||
componentDidMount(): void;
|
||||
componentWillUnmount(): void;
|
||||
componentDidUpdate(): void;
|
||||
@@ -5187,8 +5144,7 @@ declare module.exports: ElementBox;
|
||||
`;
|
||||
|
||||
exports[`public API should not change unintentionally Libraries/Inspector/ElementProperties.js 1`] = `
|
||||
"declare const React: $FlowFixMe;
|
||||
type Props = $ReadOnly<{|
|
||||
"type Props = $ReadOnly<{|
|
||||
hierarchy: ?InspectorData[\\"hierarchy\\"],
|
||||
style?: ?ViewStyleProp,
|
||||
frame?: ?Object,
|
||||
@@ -5203,8 +5159,7 @@ declare module.exports: ElementProperties;
|
||||
`;
|
||||
|
||||
exports[`public API should not change unintentionally Libraries/Inspector/Inspector.js 1`] = `
|
||||
"declare const React: $FlowFixMe;
|
||||
export type InspectedElementFrame = TouchedViewDataAtPoint[\\"frame\\"];
|
||||
"export type InspectedElementFrame = TouchedViewDataAtPoint[\\"frame\\"];
|
||||
export type InspectedElement = $ReadOnly<{
|
||||
frame: InspectedElementFrame,
|
||||
style?: ViewStyleProp,
|
||||
@@ -5221,8 +5176,7 @@ declare module.exports: Inspector;
|
||||
`;
|
||||
|
||||
exports[`public API should not change unintentionally Libraries/Inspector/InspectorOverlay.js 1`] = `
|
||||
"declare const React: $FlowFixMe;
|
||||
type Props = $ReadOnly<{|
|
||||
"type Props = $ReadOnly<{|
|
||||
inspected?: ?InspectedElement,
|
||||
onTouchPoint: (locationX: number, locationY: number) => void,
|
||||
|}>;
|
||||
@@ -5232,8 +5186,7 @@ declare module.exports: InspectorOverlay;
|
||||
`;
|
||||
|
||||
exports[`public API should not change unintentionally Libraries/Inspector/InspectorPanel.js 1`] = `
|
||||
"declare const React: $FlowFixMe;
|
||||
type Props = $ReadOnly<{|
|
||||
"type Props = $ReadOnly<{|
|
||||
devtoolsIsOpen: boolean,
|
||||
inspecting: boolean,
|
||||
setInspecting: (val: boolean) => void,
|
||||
@@ -5316,8 +5269,7 @@ declare module.exports: NetworkOverlay;
|
||||
`;
|
||||
|
||||
exports[`public API should not change unintentionally Libraries/Inspector/PerformanceOverlay.js 1`] = `
|
||||
"declare const React: $FlowFixMe;
|
||||
declare class PerformanceOverlay extends React.Component<{ ... }> {
|
||||
"declare class PerformanceOverlay extends React.Component<{ ... }> {
|
||||
render(): React.Node;
|
||||
}
|
||||
declare module.exports: PerformanceOverlay;
|
||||
@@ -6492,8 +6444,7 @@ declare export function getTextColor(opacity?: number): string;
|
||||
`;
|
||||
|
||||
exports[`public API should not change unintentionally Libraries/Modal/Modal.js 1`] = `
|
||||
"declare const React: $FlowFixMe;
|
||||
type OrientationChangeEvent = $ReadOnly<{|
|
||||
"type OrientationChangeEvent = $ReadOnly<{|
|
||||
orientation: \\"portrait\\" | \\"landscape\\",
|
||||
|}>;
|
||||
export type Props = $ReadOnly<{|
|
||||
@@ -9566,8 +9517,7 @@ declare module.exports: WebSocketInterceptor;
|
||||
`;
|
||||
|
||||
exports[`public API should not change unintentionally Libraries/YellowBox/YellowBoxDeprecated.js 1`] = `
|
||||
"declare const React: $FlowFixMe;
|
||||
type Props = $ReadOnly<{||}>;
|
||||
"type Props = $ReadOnly<{||}>;
|
||||
declare module.exports: Class<React.Component<Props>> & {
|
||||
ignoreWarnings($ReadOnlyArray<IgnorePattern>): void,
|
||||
install(): void,
|
||||
|
||||
@@ -2045,6 +2045,7 @@ public final class com/facebook/react/defaults/DefaultReactHost {
|
||||
|
||||
public abstract class com/facebook/react/defaults/DefaultReactNativeHost : com/facebook/react/ReactNativeHost {
|
||||
protected fun <init> (Landroid/app/Application;)V
|
||||
public fun clear ()V
|
||||
protected fun getJSEngineResolutionAlgorithm ()Lcom/facebook/react/JSEngineResolutionAlgorithm;
|
||||
protected fun getReactPackageTurboModuleManagerDelegateBuilder ()Lcom/facebook/react/ReactPackageTurboModuleManagerDelegate$Builder;
|
||||
protected fun getUIManagerProvider ()Lcom/facebook/react/bridge/UIManagerProvider;
|
||||
@@ -4041,6 +4042,8 @@ public abstract class com/facebook/react/uimanager/BaseViewManager : com/faceboo
|
||||
public abstract class com/facebook/react/uimanager/BaseViewManagerDelegate : com/facebook/react/uimanager/ViewManagerDelegate {
|
||||
protected final field mViewManager Lcom/facebook/react/uimanager/BaseViewManager;
|
||||
public fun <init> (Lcom/facebook/react/uimanager/BaseViewManager;)V
|
||||
public synthetic fun kotlinCompat$receiveCommand (Landroid/view/View;Ljava/lang/String;Lcom/facebook/react/bridge/ReadableArray;)V
|
||||
public synthetic fun kotlinCompat$setProperty (Landroid/view/View;Ljava/lang/String;Ljava/lang/Object;)V
|
||||
public fun receiveCommand (Landroid/view/View;Ljava/lang/String;Lcom/facebook/react/bridge/ReadableArray;)V
|
||||
public fun setProperty (Landroid/view/View;Ljava/lang/String;Ljava/lang/Object;)V
|
||||
}
|
||||
@@ -5231,8 +5234,10 @@ public abstract class com/facebook/react/uimanager/ViewManager : com/facebook/re
|
||||
}
|
||||
|
||||
public abstract interface class com/facebook/react/uimanager/ViewManagerDelegate {
|
||||
public abstract fun receiveCommand (Landroid/view/View;Ljava/lang/String;Lcom/facebook/react/bridge/ReadableArray;)V
|
||||
public abstract fun setProperty (Landroid/view/View;Ljava/lang/String;Ljava/lang/Object;)V
|
||||
public abstract synthetic fun kotlinCompat$receiveCommand (Landroid/view/View;Ljava/lang/String;Lcom/facebook/react/bridge/ReadableArray;)V
|
||||
public abstract synthetic fun kotlinCompat$setProperty (Landroid/view/View;Ljava/lang/String;Ljava/lang/Object;)V
|
||||
public fun receiveCommand (Landroid/view/View;Ljava/lang/String;Lcom/facebook/react/bridge/ReadableArray;)V
|
||||
public fun setProperty (Landroid/view/View;Ljava/lang/String;Ljava/lang/Object;)V
|
||||
}
|
||||
|
||||
public class com/facebook/react/uimanager/ViewManagerPropertyUpdater {
|
||||
|
||||
-50
@@ -1,50 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
package com.facebook.hermes.reactexecutor;
|
||||
|
||||
import com.facebook.jni.HybridData;
|
||||
import com.facebook.react.bridge.JavaScriptExecutor;
|
||||
import com.facebook.react.common.build.ReactBuildConfig;
|
||||
import com.facebook.soloader.SoLoader;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public class HermesExecutor extends JavaScriptExecutor {
|
||||
private static String mode_;
|
||||
|
||||
static {
|
||||
loadLibrary();
|
||||
}
|
||||
|
||||
public static void loadLibrary() throws UnsatisfiedLinkError {
|
||||
if (mode_ == null) {
|
||||
// libhermes must be loaded explicitly to invoke its JNI_OnLoad.
|
||||
SoLoader.loadLibrary("hermes");
|
||||
SoLoader.loadLibrary("hermes_executor");
|
||||
// libhermes_executor is built differently for Debug & Release so we load the proper mode.
|
||||
mode_ = ReactBuildConfig.DEBUG ? "Debug" : "Release";
|
||||
}
|
||||
}
|
||||
|
||||
HermesExecutor(@Nullable RuntimeConfig config, boolean enableDebugger, String debuggerName) {
|
||||
super(
|
||||
config == null
|
||||
? initHybridDefaultConfig(enableDebugger, debuggerName)
|
||||
: initHybrid(enableDebugger, debuggerName, config.getHeapSizeMB()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "HermesExecutor" + mode_;
|
||||
}
|
||||
|
||||
private static native HybridData initHybridDefaultConfig(
|
||||
boolean enableDebugger, String debuggerName);
|
||||
|
||||
private static native HybridData initHybrid(
|
||||
boolean enableDebugger, String debuggerName, long heapSizeMB);
|
||||
}
|
||||
+58
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
package com.facebook.hermes.reactexecutor
|
||||
|
||||
import com.facebook.jni.HybridData
|
||||
import com.facebook.jni.annotations.DoNotStrip
|
||||
import com.facebook.react.bridge.JavaScriptExecutor
|
||||
import com.facebook.react.common.build.ReactBuildConfig
|
||||
import com.facebook.soloader.SoLoader
|
||||
|
||||
public class HermesExecutor
|
||||
internal constructor(config: RuntimeConfig?, enableDebugger: Boolean, debuggerName: String) :
|
||||
JavaScriptExecutor(
|
||||
config?.let { initHybrid(enableDebugger, debuggerName, it.heapSizeMB) }
|
||||
?: initHybridDefaultConfig(enableDebugger, debuggerName)) {
|
||||
|
||||
override fun getName(): String = "HermesExecutor$mode"
|
||||
|
||||
public companion object {
|
||||
private var mode: String? = null
|
||||
|
||||
init {
|
||||
loadLibrary()
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
@Throws(UnsatisfiedLinkError::class)
|
||||
public fun loadLibrary() {
|
||||
if (mode == null) {
|
||||
// libhermes must be loaded explicitly to invoke its JNI_OnLoad.
|
||||
SoLoader.loadLibrary("hermes")
|
||||
SoLoader.loadLibrary("hermes_executor")
|
||||
// libhermes_executor is built differently for Debug & Release so we load the proper mode.
|
||||
mode = if (ReactBuildConfig.DEBUG) "Debug" else "Release"
|
||||
}
|
||||
}
|
||||
|
||||
@DoNotStrip
|
||||
@JvmStatic
|
||||
private external fun initHybridDefaultConfig(
|
||||
enableDebugger: Boolean,
|
||||
debuggerName: String
|
||||
): HybridData?
|
||||
|
||||
@DoNotStrip
|
||||
@JvmStatic
|
||||
private external fun initHybrid(
|
||||
enableDebugger: Boolean,
|
||||
debuggerName: String,
|
||||
heapSizeMB: Long
|
||||
): HybridData?
|
||||
}
|
||||
}
|
||||
-57
@@ -1,57 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
package com.facebook.hermes.reactexecutor;
|
||||
|
||||
import com.facebook.hermes.instrumentation.HermesSamplingProfiler;
|
||||
import com.facebook.react.bridge.JavaScriptExecutor;
|
||||
import com.facebook.react.bridge.JavaScriptExecutorFactory;
|
||||
|
||||
public class HermesExecutorFactory implements JavaScriptExecutorFactory {
|
||||
private static final String TAG = "Hermes";
|
||||
|
||||
private final RuntimeConfig mConfig;
|
||||
private boolean mEnableDebugger = true;
|
||||
private String mDebuggerName = "";
|
||||
|
||||
public HermesExecutorFactory() {
|
||||
this(null);
|
||||
}
|
||||
|
||||
public HermesExecutorFactory(RuntimeConfig config) {
|
||||
mConfig = config;
|
||||
}
|
||||
|
||||
public void setEnableDebugger(boolean enableDebugger) {
|
||||
mEnableDebugger = enableDebugger;
|
||||
}
|
||||
|
||||
public void setDebuggerName(String debuggerName) {
|
||||
mDebuggerName = debuggerName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JavaScriptExecutor create() {
|
||||
return new HermesExecutor(mConfig, mEnableDebugger, mDebuggerName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startSamplingProfiler() {
|
||||
HermesSamplingProfiler.enable();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stopSamplingProfiler(String filename) {
|
||||
HermesSamplingProfiler.dumpSampledTraceToFile(filename);
|
||||
HermesSamplingProfiler.disable();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "JSIExecutor+HermesRuntime";
|
||||
}
|
||||
}
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
package com.facebook.hermes.reactexecutor
|
||||
|
||||
import com.facebook.hermes.instrumentation.HermesSamplingProfiler.disable
|
||||
import com.facebook.hermes.instrumentation.HermesSamplingProfiler.dumpSampledTraceToFile
|
||||
import com.facebook.hermes.instrumentation.HermesSamplingProfiler.enable
|
||||
import com.facebook.react.bridge.JavaScriptExecutor
|
||||
import com.facebook.react.bridge.JavaScriptExecutorFactory
|
||||
|
||||
public class HermesExecutorFactory
|
||||
@JvmOverloads
|
||||
public constructor(private val config: RuntimeConfig? = null) : JavaScriptExecutorFactory {
|
||||
private var enableDebugger = true
|
||||
private var debuggerName = ""
|
||||
|
||||
public fun setEnableDebugger(enableDebugger: Boolean) {
|
||||
this.enableDebugger = enableDebugger
|
||||
}
|
||||
|
||||
public fun setDebuggerName(debuggerName: String) {
|
||||
this.debuggerName = debuggerName
|
||||
}
|
||||
|
||||
override fun create(): JavaScriptExecutor = HermesExecutor(config, enableDebugger, debuggerName)
|
||||
|
||||
override fun startSamplingProfiler() {
|
||||
enable()
|
||||
}
|
||||
|
||||
override fun stopSamplingProfiler(filename: String) {
|
||||
dumpSampledTraceToFile(filename)
|
||||
disable()
|
||||
}
|
||||
|
||||
override fun toString(): String = "JSIExecutor+HermesRuntime"
|
||||
}
|
||||
+8
@@ -175,4 +175,12 @@ public object DefaultReactHost {
|
||||
}
|
||||
return reactNativeHost.toReactHost(context)
|
||||
}
|
||||
|
||||
/**
|
||||
* Cleanup function for brownfield scenarios where you want to remove the references kept by
|
||||
* reactHost after destroying the RN instance.
|
||||
*/
|
||||
internal fun invalidate() {
|
||||
reactHost = null
|
||||
}
|
||||
}
|
||||
|
||||
+5
@@ -76,6 +76,11 @@ protected constructor(
|
||||
null -> null
|
||||
}
|
||||
|
||||
override fun clear() {
|
||||
super.clear()
|
||||
DefaultReactHost.invalidate()
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the user wants to use the New Architecture or not.
|
||||
*
|
||||
|
||||
+7
-1
@@ -4,7 +4,7 @@
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @generated SignedSource<<3e10f8d2f623da3b7b502d8fa78f82a4>>
|
||||
* @generated SignedSource<<2c321a7a8e811dc238a75f76180843b9>>
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -244,6 +244,12 @@ public object ReactNativeFeatureFlags {
|
||||
@JvmStatic
|
||||
public fun useAlwaysAvailableJSErrorHandling(): Boolean = accessor.useAlwaysAvailableJSErrorHandling()
|
||||
|
||||
/**
|
||||
* If true, focusing in ReactEditText will mainly use stock Android requestFocus() behavior. If false it will use legacy custom focus behavior.
|
||||
*/
|
||||
@JvmStatic
|
||||
public fun useEditTextStockAndroidFocusBehavior(): Boolean = accessor.useEditTextStockAndroidFocusBehavior()
|
||||
|
||||
/**
|
||||
* Should this application enable the Fabric Interop Layer for Android? If yes, the application will behave so that it can accept non-Fabric components and render them on Fabric. This toggle is controlling extra logic such as custom event dispatching that are needed for the Fabric Interop Layer to work correctly.
|
||||
*/
|
||||
|
||||
+11
-1
@@ -4,7 +4,7 @@
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @generated SignedSource<<497bbb23778fe0f9763e9bfa715ea3aa>>
|
||||
* @generated SignedSource<<e724939eaa9fa53c9b25c8a5a1e3196d>>
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -56,6 +56,7 @@ public class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAccesso
|
||||
private var loadVectorDrawablesOnImagesCache: Boolean? = null
|
||||
private var traceTurboModulePromiseRejectionsOnAndroidCache: Boolean? = null
|
||||
private var useAlwaysAvailableJSErrorHandlingCache: Boolean? = null
|
||||
private var useEditTextStockAndroidFocusBehaviorCache: Boolean? = null
|
||||
private var useFabricInteropCache: Boolean? = null
|
||||
private var useImmediateExecutorInAndroidBridgelessCache: Boolean? = null
|
||||
private var useNativeViewConfigsInBridgelessModeCache: Boolean? = null
|
||||
@@ -390,6 +391,15 @@ public class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAccesso
|
||||
return cached
|
||||
}
|
||||
|
||||
override fun useEditTextStockAndroidFocusBehavior(): Boolean {
|
||||
var cached = useEditTextStockAndroidFocusBehaviorCache
|
||||
if (cached == null) {
|
||||
cached = ReactNativeFeatureFlagsCxxInterop.useEditTextStockAndroidFocusBehavior()
|
||||
useEditTextStockAndroidFocusBehaviorCache = cached
|
||||
}
|
||||
return cached
|
||||
}
|
||||
|
||||
override fun useFabricInterop(): Boolean {
|
||||
var cached = useFabricInteropCache
|
||||
if (cached == null) {
|
||||
|
||||
+3
-1
@@ -4,7 +4,7 @@
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @generated SignedSource<<d801f87c988fbd921e2379f236e1711f>>
|
||||
* @generated SignedSource<<a7f3ca986725fa85a6926c9e7966669b>>
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -100,6 +100,8 @@ public object ReactNativeFeatureFlagsCxxInterop {
|
||||
|
||||
@DoNotStrip @JvmStatic public external fun useAlwaysAvailableJSErrorHandling(): Boolean
|
||||
|
||||
@DoNotStrip @JvmStatic public external fun useEditTextStockAndroidFocusBehavior(): Boolean
|
||||
|
||||
@DoNotStrip @JvmStatic public external fun useFabricInterop(): Boolean
|
||||
|
||||
@DoNotStrip @JvmStatic public external fun useImmediateExecutorInAndroidBridgeless(): Boolean
|
||||
|
||||
+3
-1
@@ -4,7 +4,7 @@
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @generated SignedSource<<5de2cfc00f486b7d07266939ce18a397>>
|
||||
* @generated SignedSource<<85d40be44d053b58a74ad76467c8e5e9>>
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -95,6 +95,8 @@ public open class ReactNativeFeatureFlagsDefaults : ReactNativeFeatureFlagsProvi
|
||||
|
||||
override fun useAlwaysAvailableJSErrorHandling(): Boolean = false
|
||||
|
||||
override fun useEditTextStockAndroidFocusBehavior(): Boolean = true
|
||||
|
||||
override fun useFabricInterop(): Boolean = false
|
||||
|
||||
override fun useImmediateExecutorInAndroidBridgeless(): Boolean = true
|
||||
|
||||
+12
-1
@@ -4,7 +4,7 @@
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @generated SignedSource<<f1ed4107e24ced5d2673bfb065573062>>
|
||||
* @generated SignedSource<<18d5c2ffa66a36e364bc358a144534ec>>
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -60,6 +60,7 @@ public class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcces
|
||||
private var loadVectorDrawablesOnImagesCache: Boolean? = null
|
||||
private var traceTurboModulePromiseRejectionsOnAndroidCache: Boolean? = null
|
||||
private var useAlwaysAvailableJSErrorHandlingCache: Boolean? = null
|
||||
private var useEditTextStockAndroidFocusBehaviorCache: Boolean? = null
|
||||
private var useFabricInteropCache: Boolean? = null
|
||||
private var useImmediateExecutorInAndroidBridgelessCache: Boolean? = null
|
||||
private var useNativeViewConfigsInBridgelessModeCache: Boolean? = null
|
||||
@@ -430,6 +431,16 @@ public class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcces
|
||||
return cached
|
||||
}
|
||||
|
||||
override fun useEditTextStockAndroidFocusBehavior(): Boolean {
|
||||
var cached = useEditTextStockAndroidFocusBehaviorCache
|
||||
if (cached == null) {
|
||||
cached = currentProvider.useEditTextStockAndroidFocusBehavior()
|
||||
accessedFeatureFlags.add("useEditTextStockAndroidFocusBehavior")
|
||||
useEditTextStockAndroidFocusBehaviorCache = cached
|
||||
}
|
||||
return cached
|
||||
}
|
||||
|
||||
override fun useFabricInterop(): Boolean {
|
||||
var cached = useFabricInteropCache
|
||||
if (cached == null) {
|
||||
|
||||
+3
-1
@@ -4,7 +4,7 @@
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @generated SignedSource<<3cd802bdd1d383ea0668e43319d53b3f>>
|
||||
* @generated SignedSource<<4f90c47ea6f23c2ebfae1f35790c4af5>>
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -95,6 +95,8 @@ public interface ReactNativeFeatureFlagsProvider {
|
||||
|
||||
@DoNotStrip public fun useAlwaysAvailableJSErrorHandling(): Boolean
|
||||
|
||||
@DoNotStrip public fun useEditTextStockAndroidFocusBehavior(): Boolean
|
||||
|
||||
@DoNotStrip public fun useFabricInterop(): Boolean
|
||||
|
||||
@DoNotStrip public fun useImmediateExecutorInAndroidBridgeless(): Boolean
|
||||
|
||||
+4
-3
@@ -23,8 +23,8 @@ public abstract class BaseViewManagerDelegate<
|
||||
T : View, U : BaseViewManager<T, out LayoutShadowNode>>(
|
||||
@Suppress("NoHungarianNotation") @JvmField protected val mViewManager: U
|
||||
) : ViewManagerDelegate<T> {
|
||||
@Suppress("DEPRECATION")
|
||||
override public fun setProperty(view: T, propName: String?, value: Any?) {
|
||||
@Suppress("ACCIDENTAL_OVERRIDE", "DEPRECATION")
|
||||
override public fun setProperty(view: T, propName: String, value: Any?) {
|
||||
when (propName) {
|
||||
ViewProps.ACCESSIBILITY_ACTIONS ->
|
||||
mViewManager.setAccessibilityActions(view, value as ReadableArray?)
|
||||
@@ -146,6 +146,7 @@ public abstract class BaseViewManagerDelegate<
|
||||
}
|
||||
}
|
||||
|
||||
override public fun receiveCommand(view: T, commandName: String?, args: ReadableArray?): Unit =
|
||||
@Suppress("ACCIDENTAL_OVERRIDE")
|
||||
override public fun receiveCommand(view: T, commandName: String, args: ReadableArray?): Unit =
|
||||
Unit
|
||||
}
|
||||
|
||||
+14
-4
@@ -41,6 +41,9 @@ public abstract class ViewManager<T extends View, C extends ReactShadowNode>
|
||||
|
||||
private static final String NAME = ViewManager.class.getSimpleName();
|
||||
|
||||
private boolean mIsDelegateLoaded = false;
|
||||
private @Nullable ViewManagerDelegate<T> mDelegate = null;
|
||||
|
||||
/**
|
||||
* For View recycling: we store a Stack of unused, dead Views. This is null by default, and when
|
||||
* null signals that View Recycling is disabled. `enableViewRecycling` must be explicitly called
|
||||
@@ -88,7 +91,7 @@ public abstract class ViewManager<T extends View, C extends ReactShadowNode>
|
||||
* @param props {@link ReactStylesDiffMap} props to update the view with
|
||||
*/
|
||||
public void updateProperties(@NonNull T viewToUpdate, ReactStylesDiffMap props) {
|
||||
final ViewManagerDelegate<T> delegate = getDelegate();
|
||||
final ViewManagerDelegate<T> delegate = getOrCreateViewManagerDelegate();
|
||||
if (delegate != null) {
|
||||
ViewManagerPropertyUpdater.updateProps(delegate, viewToUpdate, props);
|
||||
} else {
|
||||
@@ -109,11 +112,18 @@ public abstract class ViewManager<T extends View, C extends ReactShadowNode>
|
||||
* @return an instance of {@link ViewManagerDelegate} if the props of the view managed by this
|
||||
* view manager should be set via this delegate
|
||||
*/
|
||||
@Nullable
|
||||
protected ViewManagerDelegate<T> getDelegate() {
|
||||
protected @Nullable ViewManagerDelegate<T> getDelegate() {
|
||||
return null;
|
||||
}
|
||||
|
||||
private @Nullable ViewManagerDelegate<T> getOrCreateViewManagerDelegate() {
|
||||
if (!mIsDelegateLoaded) {
|
||||
mDelegate = getDelegate();
|
||||
mIsDelegateLoaded = true;
|
||||
}
|
||||
return mDelegate;
|
||||
}
|
||||
|
||||
/** Creates a view with knowledge of props and state. */
|
||||
public @NonNull T createView(
|
||||
int reactTag,
|
||||
@@ -306,7 +316,7 @@ public abstract class ViewManager<T extends View, C extends ReactShadowNode>
|
||||
* @param args optional arguments for the command
|
||||
*/
|
||||
public void receiveCommand(@NonNull T root, String commandId, @Nullable ReadableArray args) {
|
||||
final ViewManagerDelegate<T> delegate = getDelegate();
|
||||
final ViewManagerDelegate<T> delegate = getOrCreateViewManagerDelegate();
|
||||
if (delegate != null) {
|
||||
delegate.receiveCommand(root, commandId, args);
|
||||
}
|
||||
|
||||
+28
-6
@@ -22,20 +22,42 @@ public interface ViewManagerDelegate<T : View> {
|
||||
/**
|
||||
* Sets a property on a view managed by this view manager.
|
||||
*
|
||||
* We mark this method as synthetic / hide it from JVM so Java callers will call the deprecated
|
||||
* version and overrides work correctly.
|
||||
*
|
||||
* @param view the view to set the property on
|
||||
* @param propName the name of the property to set (NOTE: should be `String` but is kept as
|
||||
* `String?` to avoid breaking changes)
|
||||
* @param propName the name of the property to set
|
||||
* @param value the value to set the property to
|
||||
*/
|
||||
public fun setProperty(view: T, propName: String?, value: Any?)
|
||||
@Suppress("INAPPLICABLE_JVM_NAME")
|
||||
@JvmName("kotlinCompat\$setProperty")
|
||||
@JvmSynthetic
|
||||
public fun setProperty(view: T, propName: String, value: Any?)
|
||||
|
||||
@Suppress("INAPPLICABLE_JVM_NAME")
|
||||
@Deprecated(message = "propName is not nullable, please update your method signature")
|
||||
@JvmName("setProperty")
|
||||
public fun javaCompat_setProperty(view: T, propName: String?, value: Any?): Unit =
|
||||
setProperty(view, checkNotNull(propName), value)
|
||||
|
||||
/**
|
||||
* Executes a command from JS to the view
|
||||
*
|
||||
* We mark this method as synthetic / hide it from JVM so Java callers will call the deprecated
|
||||
* version and overrides work correctly.
|
||||
*
|
||||
* @param view the view to execute the command on
|
||||
* @param commandName the name of the command to execute (NOTE: should be `String` but is kept as
|
||||
* `String?` to avoid breaking changes)
|
||||
* @param commandName the name of the command to execute
|
||||
* @param args the arguments to pass to the command
|
||||
*/
|
||||
public fun receiveCommand(view: T, commandName: String?, args: ReadableArray?)
|
||||
@Suppress("INAPPLICABLE_JVM_NAME")
|
||||
@JvmName("kotlinCompat\$receiveCommand")
|
||||
@JvmSynthetic
|
||||
public fun receiveCommand(view: T, commandName: String, args: ReadableArray?)
|
||||
|
||||
@Suppress("INAPPLICABLE_JVM_NAME")
|
||||
@Deprecated(message = "commandName is not nullable, please update your method signature")
|
||||
@JvmName("receiveCommand")
|
||||
public fun javaCompat_receiveCommand(view: T, commandName: String?, args: ReadableArray?): Unit =
|
||||
receiveCommand(view, checkNotNull(commandName), args)
|
||||
}
|
||||
|
||||
+10
-5
@@ -11,9 +11,11 @@ import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.net.Uri;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.core.util.Preconditions;
|
||||
import com.facebook.common.logging.FLog;
|
||||
import com.facebook.common.util.UriUtil;
|
||||
import com.facebook.drawee.controller.AbstractDraweeControllerBuilder;
|
||||
import com.facebook.infer.annotation.Nullsafe;
|
||||
import com.facebook.react.bridge.Dynamic;
|
||||
import com.facebook.react.bridge.ReadableArray;
|
||||
import com.facebook.react.bridge.ReadableMap;
|
||||
@@ -27,10 +29,11 @@ import com.facebook.yoga.YogaConstants;
|
||||
import java.util.Locale;
|
||||
|
||||
/** Shadow node that represents an inline image. Loading is done using Fresco. */
|
||||
@Nullsafe(Nullsafe.Mode.LOCAL)
|
||||
class FrescoBasedReactTextInlineImageShadowNode extends ReactTextInlineImageShadowNode {
|
||||
|
||||
private @Nullable Uri mUri;
|
||||
private ReadableMap mHeaders;
|
||||
private @Nullable ReadableMap mHeaders;
|
||||
private final AbstractDraweeControllerBuilder mDraweeControllerBuilder;
|
||||
private final @Nullable Object mCallerContext;
|
||||
private float mWidth = YogaConstants.UNDEFINED;
|
||||
@@ -46,8 +49,10 @@ class FrescoBasedReactTextInlineImageShadowNode extends ReactTextInlineImageShad
|
||||
|
||||
@ReactProp(name = "src")
|
||||
public void setSource(@Nullable ReadableArray sources) {
|
||||
final String source =
|
||||
(sources == null || sources.size() == 0) ? null : sources.getMap(0).getString("uri");
|
||||
final @Nullable String source =
|
||||
(sources == null || sources.size() == 0 || sources.getType(0) != ReadableType.Map)
|
||||
? null
|
||||
: Preconditions.checkNotNull(sources.getMap(0)).getString("uri");
|
||||
Uri uri = null;
|
||||
if (source != null) {
|
||||
try {
|
||||
@@ -70,7 +75,7 @@ class FrescoBasedReactTextInlineImageShadowNode extends ReactTextInlineImageShad
|
||||
}
|
||||
|
||||
@ReactProp(name = "headers")
|
||||
public void setHeaders(ReadableMap headers) {
|
||||
public void setHeaders(@Nullable ReadableMap headers) {
|
||||
mHeaders = headers;
|
||||
}
|
||||
|
||||
@@ -109,7 +114,7 @@ class FrescoBasedReactTextInlineImageShadowNode extends ReactTextInlineImageShad
|
||||
return mUri;
|
||||
}
|
||||
|
||||
public ReadableMap getHeaders() {
|
||||
public @Nullable ReadableMap getHeaders() {
|
||||
return mHeaders;
|
||||
}
|
||||
|
||||
|
||||
+20
-19
@@ -15,14 +15,15 @@ import android.graphics.drawable.Drawable;
|
||||
import android.net.Uri;
|
||||
import android.widget.TextView;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.core.util.Preconditions;
|
||||
import com.facebook.drawee.controller.AbstractDraweeControllerBuilder;
|
||||
import com.facebook.drawee.drawable.ScalingUtils;
|
||||
import com.facebook.drawee.generic.GenericDraweeHierarchy;
|
||||
import com.facebook.drawee.generic.GenericDraweeHierarchyBuilder;
|
||||
import com.facebook.drawee.interfaces.DraweeController;
|
||||
import com.facebook.drawee.view.DraweeHolder;
|
||||
import com.facebook.imagepipeline.request.ImageRequest;
|
||||
import com.facebook.imagepipeline.request.ImageRequestBuilder;
|
||||
import com.facebook.infer.annotation.Nullsafe;
|
||||
import com.facebook.react.bridge.ReadableMap;
|
||||
import com.facebook.react.modules.fresco.ReactNetworkImageRequest;
|
||||
import com.facebook.react.uimanager.PixelUtil;
|
||||
@@ -40,6 +41,7 @@ import com.facebook.react.views.text.internal.span.TextInlineImageSpan;
|
||||
* <p>Note: It borrows code from DynamicDrawableSpan and if that code updates how it computes size
|
||||
* or draws, we need to update this as well.
|
||||
*/
|
||||
@Nullsafe(Nullsafe.Mode.LOCAL)
|
||||
class FrescoBasedReactTextInlineImageSpan extends TextInlineImageSpan {
|
||||
|
||||
private @Nullable Drawable mDrawable;
|
||||
@@ -51,8 +53,8 @@ class FrescoBasedReactTextInlineImageSpan extends TextInlineImageSpan {
|
||||
private int mTintColor;
|
||||
private Uri mUri;
|
||||
private int mWidth;
|
||||
private ReadableMap mHeaders;
|
||||
private String mResizeMode;
|
||||
private @Nullable ReadableMap mHeaders;
|
||||
private @Nullable String mResizeMode;
|
||||
|
||||
private @Nullable TextView mTextView;
|
||||
|
||||
@@ -62,10 +64,10 @@ class FrescoBasedReactTextInlineImageSpan extends TextInlineImageSpan {
|
||||
int width,
|
||||
int tintColor,
|
||||
@Nullable Uri uri,
|
||||
ReadableMap headers,
|
||||
@Nullable ReadableMap headers,
|
||||
AbstractDraweeControllerBuilder draweeControllerBuilder,
|
||||
@Nullable Object callerContext,
|
||||
String resizeMode) {
|
||||
@Nullable String resizeMode) {
|
||||
mDraweeHolder = new DraweeHolder(GenericDraweeHierarchyBuilder.newInstance(resources).build());
|
||||
mDraweeControllerBuilder = draweeControllerBuilder;
|
||||
mCallerContext = callerContext;
|
||||
@@ -116,7 +118,8 @@ class FrescoBasedReactTextInlineImageSpan extends TextInlineImageSpan {
|
||||
return mWidth;
|
||||
}
|
||||
|
||||
public void setTextView(TextView textView) {
|
||||
@Override
|
||||
public void setTextView(@Nullable TextView textView) {
|
||||
mTextView = textView;
|
||||
}
|
||||
|
||||
@@ -135,18 +138,20 @@ class FrescoBasedReactTextInlineImageSpan extends TextInlineImageSpan {
|
||||
ImageRequestBuilder imageRequestBuilder = ImageRequestBuilder.newBuilderWithSource(mUri);
|
||||
ImageRequest imageRequest =
|
||||
ReactNetworkImageRequest.fromBuilderWithHeaders(imageRequestBuilder, mHeaders);
|
||||
mDraweeHolder.getHierarchy().setActualImageScaleType(getResizeMode(mResizeMode));
|
||||
DraweeController draweeController =
|
||||
mDraweeControllerBuilder
|
||||
.reset()
|
||||
.setOldController(mDraweeHolder.getController())
|
||||
.setCallerContext(mCallerContext)
|
||||
.setImageRequest(imageRequest)
|
||||
.build();
|
||||
mDraweeHolder
|
||||
.getHierarchy()
|
||||
.setActualImageScaleType(ImageResizeMode.toScaleType(mResizeMode));
|
||||
mDraweeControllerBuilder.reset();
|
||||
mDraweeControllerBuilder.setOldController(mDraweeHolder.getController());
|
||||
if (mCallerContext != null) {
|
||||
mDraweeControllerBuilder.setCallerContext(mCallerContext);
|
||||
}
|
||||
mDraweeControllerBuilder.setImageRequest(imageRequest);
|
||||
DraweeController draweeController = mDraweeControllerBuilder.build();
|
||||
mDraweeHolder.setController(draweeController);
|
||||
mDraweeControllerBuilder.reset();
|
||||
|
||||
mDrawable = mDraweeHolder.getTopLevelDrawable();
|
||||
mDrawable = Preconditions.checkNotNull(mDraweeHolder.getTopLevelDrawable());
|
||||
mDrawable.setBounds(0, 0, mWidth, mHeight);
|
||||
if (mTintColor != 0) {
|
||||
mDrawable.setColorFilter(mTintColor, PorterDuff.Mode.SRC_IN);
|
||||
@@ -168,10 +173,6 @@ class FrescoBasedReactTextInlineImageSpan extends TextInlineImageSpan {
|
||||
canvas.restore();
|
||||
}
|
||||
|
||||
private ScalingUtils.ScaleType getResizeMode(String resizeMode) {
|
||||
return ImageResizeMode.toScaleType(resizeMode);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getWidth() {
|
||||
return mWidth;
|
||||
|
||||
-24
@@ -1,24 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
package com.facebook.react.views.text.internal;
|
||||
|
||||
import com.facebook.react.uimanager.LayoutShadowNode;
|
||||
import com.facebook.react.views.text.internal.span.TextInlineImageSpan;
|
||||
import com.facebook.yoga.YogaNode;
|
||||
|
||||
/** Base class for {@link YogaNode}s that represent inline images. */
|
||||
public abstract class ReactTextInlineImageShadowNode extends LayoutShadowNode {
|
||||
|
||||
/**
|
||||
* Build a {@link TextInlineImageSpan} from this node. This will be added to the TextView in place
|
||||
* of this node.
|
||||
*/
|
||||
public abstract TextInlineImageSpan buildInlineImageSpan();
|
||||
|
||||
public ReactTextInlineImageShadowNode() {}
|
||||
}
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
package com.facebook.react.views.text.internal
|
||||
|
||||
import com.facebook.react.uimanager.LayoutShadowNode
|
||||
import com.facebook.react.views.text.internal.span.TextInlineImageSpan
|
||||
import com.facebook.yoga.YogaNode
|
||||
|
||||
/** Base class for [YogaNode]s that represent inline images. */
|
||||
internal abstract class ReactTextInlineImageShadowNode : LayoutShadowNode() {
|
||||
/**
|
||||
* Build a [TextInlineImageSpan] from this node. This will be added to the TextView in place of
|
||||
* this node.
|
||||
*/
|
||||
public abstract fun buildInlineImageSpan(): TextInlineImageSpan
|
||||
}
|
||||
+38
-6
@@ -50,6 +50,7 @@ import com.facebook.react.bridge.ReactContext;
|
||||
import com.facebook.react.bridge.ReactSoftExceptionLogger;
|
||||
import com.facebook.react.common.ReactConstants;
|
||||
import com.facebook.react.common.build.ReactBuildConfig;
|
||||
import com.facebook.react.internal.featureflags.ReactNativeFeatureFlags;
|
||||
import com.facebook.react.uimanager.BackgroundStyleApplicator;
|
||||
import com.facebook.react.uimanager.LengthPercentage;
|
||||
import com.facebook.react.uimanager.LengthPercentageType;
|
||||
@@ -145,7 +146,9 @@ public class ReactEditText extends AppCompatEditText {
|
||||
|
||||
public ReactEditText(Context context) {
|
||||
super(context);
|
||||
setFocusableInTouchMode(false);
|
||||
if (!ReactNativeFeatureFlags.useEditTextStockAndroidFocusBehavior()) {
|
||||
setFocusableInTouchMode(false);
|
||||
}
|
||||
|
||||
mInputMethodManager =
|
||||
(InputMethodManager)
|
||||
@@ -188,7 +191,9 @@ public class ReactEditText extends AppCompatEditText {
|
||||
// selection on accessibility click to undo that.
|
||||
setSelection(length);
|
||||
}
|
||||
return requestFocusInternal();
|
||||
return ReactNativeFeatureFlags.useEditTextStockAndroidFocusBehavior()
|
||||
? requestFocusProgramatically()
|
||||
: requestFocusInternal();
|
||||
}
|
||||
return super.performAccessibilityAction(host, action, args);
|
||||
}
|
||||
@@ -338,7 +343,10 @@ public class ReactEditText extends AppCompatEditText {
|
||||
|
||||
@Override
|
||||
public void clearFocus() {
|
||||
setFocusableInTouchMode(false);
|
||||
boolean useStockFocusBehavior = ReactNativeFeatureFlags.useEditTextStockAndroidFocusBehavior();
|
||||
if (!useStockFocusBehavior) {
|
||||
setFocusableInTouchMode(false);
|
||||
}
|
||||
super.clearFocus();
|
||||
hideSoftKeyboard();
|
||||
}
|
||||
@@ -349,7 +357,9 @@ public class ReactEditText extends AppCompatEditText {
|
||||
// is a controlled component, which means its focus is controlled by JS, with two exceptions:
|
||||
// autofocus when it's attached to the window, and responding to accessibility events. In both
|
||||
// of these cases, we call requestFocusInternal() directly.
|
||||
return isFocused();
|
||||
return ReactNativeFeatureFlags.useEditTextStockAndroidFocusBehavior()
|
||||
? super.requestFocus(direction, previouslyFocusedRect)
|
||||
: isFocused();
|
||||
}
|
||||
|
||||
private boolean requestFocusInternal() {
|
||||
@@ -360,6 +370,20 @@ public class ReactEditText extends AppCompatEditText {
|
||||
if (getShowSoftInputOnFocus()) {
|
||||
showSoftKeyboard();
|
||||
}
|
||||
|
||||
return focused;
|
||||
}
|
||||
|
||||
// For cases like autoFocus, or ref.focus() where we request focus programatically and not through
|
||||
// interacting with the EditText directly (like clicking on it). We cannot use stock
|
||||
// requestFocus() because it will not pop up the soft keyboard, only clicking the input will do
|
||||
// that. This method will eventually replace requestFocusInternal()
|
||||
private boolean requestFocusProgramatically() {
|
||||
boolean focused = super.requestFocus(View.FOCUS_DOWN, null);
|
||||
if (isInTouchMode() && getShowSoftInputOnFocus()) {
|
||||
showSoftKeyboard();
|
||||
}
|
||||
|
||||
return focused;
|
||||
}
|
||||
|
||||
@@ -632,7 +656,11 @@ public class ReactEditText extends AppCompatEditText {
|
||||
|
||||
// VisibleForTesting from {@link TextInputEventsTestCase}.
|
||||
public void requestFocusFromJS() {
|
||||
requestFocusInternal();
|
||||
if (ReactNativeFeatureFlags.useEditTextStockAndroidFocusBehavior()) {
|
||||
requestFocusProgramatically();
|
||||
} else {
|
||||
requestFocusInternal();
|
||||
}
|
||||
}
|
||||
|
||||
/* package */ void clearFocusFromJS() {
|
||||
@@ -1079,7 +1107,11 @@ public class ReactEditText extends AppCompatEditText {
|
||||
}
|
||||
|
||||
if (mAutoFocus && !mDidAttachToWindow) {
|
||||
requestFocusInternal();
|
||||
if (ReactNativeFeatureFlags.useEditTextStockAndroidFocusBehavior()) {
|
||||
requestFocusProgramatically();
|
||||
} else {
|
||||
requestFocusInternal();
|
||||
}
|
||||
}
|
||||
|
||||
mDidAttachToWindow = true;
|
||||
|
||||
+15
-1
@@ -4,7 +4,7 @@
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @generated SignedSource<<7c3853858da56eb5f471abccf9dcbf55>>
|
||||
* @generated SignedSource<<63ebe186ccd5ee30fc654aa8d90f27f9>>
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -255,6 +255,12 @@ class ReactNativeFeatureFlagsProviderHolder
|
||||
return method(javaProvider_);
|
||||
}
|
||||
|
||||
bool useEditTextStockAndroidFocusBehavior() override {
|
||||
static const auto method =
|
||||
getReactNativeFeatureFlagsProviderJavaClass()->getMethod<jboolean()>("useEditTextStockAndroidFocusBehavior");
|
||||
return method(javaProvider_);
|
||||
}
|
||||
|
||||
bool useFabricInterop() override {
|
||||
static const auto method =
|
||||
getReactNativeFeatureFlagsProviderJavaClass()->getMethod<jboolean()>("useFabricInterop");
|
||||
@@ -493,6 +499,11 @@ bool JReactNativeFeatureFlagsCxxInterop::useAlwaysAvailableJSErrorHandling(
|
||||
return ReactNativeFeatureFlags::useAlwaysAvailableJSErrorHandling();
|
||||
}
|
||||
|
||||
bool JReactNativeFeatureFlagsCxxInterop::useEditTextStockAndroidFocusBehavior(
|
||||
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop> /*unused*/) {
|
||||
return ReactNativeFeatureFlags::useEditTextStockAndroidFocusBehavior();
|
||||
}
|
||||
|
||||
bool JReactNativeFeatureFlagsCxxInterop::useFabricInterop(
|
||||
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop> /*unused*/) {
|
||||
return ReactNativeFeatureFlags::useFabricInterop();
|
||||
@@ -677,6 +688,9 @@ void JReactNativeFeatureFlagsCxxInterop::registerNatives() {
|
||||
makeNativeMethod(
|
||||
"useAlwaysAvailableJSErrorHandling",
|
||||
JReactNativeFeatureFlagsCxxInterop::useAlwaysAvailableJSErrorHandling),
|
||||
makeNativeMethod(
|
||||
"useEditTextStockAndroidFocusBehavior",
|
||||
JReactNativeFeatureFlagsCxxInterop::useEditTextStockAndroidFocusBehavior),
|
||||
makeNativeMethod(
|
||||
"useFabricInterop",
|
||||
JReactNativeFeatureFlagsCxxInterop::useFabricInterop),
|
||||
|
||||
+4
-1
@@ -4,7 +4,7 @@
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @generated SignedSource<<77b4ed5aa33290ba9da1719544e974cb>>
|
||||
* @generated SignedSource<<fdb23cf034dea348c661f59718f07291>>
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -138,6 +138,9 @@ class JReactNativeFeatureFlagsCxxInterop
|
||||
static bool useAlwaysAvailableJSErrorHandling(
|
||||
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
|
||||
|
||||
static bool useEditTextStockAndroidFocusBehavior(
|
||||
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
|
||||
|
||||
static bool useFabricInterop(
|
||||
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
|
||||
|
||||
|
||||
+2
@@ -25,6 +25,7 @@ import com.facebook.react.bridge.BridgeReactContext
|
||||
import com.facebook.react.bridge.CatalystInstance
|
||||
import com.facebook.react.bridge.JavaOnlyMap
|
||||
import com.facebook.react.bridge.ReactTestHelper.createMockCatalystInstance
|
||||
import com.facebook.react.internal.featureflags.ReactNativeFeatureFlagsForTests
|
||||
import com.facebook.react.uimanager.DisplayMetricsHolder
|
||||
import com.facebook.react.uimanager.ReactStylesDiffMap
|
||||
import com.facebook.react.uimanager.ThemedReactContext
|
||||
@@ -58,6 +59,7 @@ class ReactTextInputPropertyTest {
|
||||
|
||||
@Before
|
||||
fun setup() {
|
||||
ReactNativeFeatureFlagsForTests.setUp()
|
||||
context = BridgeReactContext(RuntimeEnvironment.getApplication())
|
||||
catalystInstanceMock = createMockCatalystInstance()
|
||||
context.initializeWithInstance(catalystInstanceMock)
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @generated SignedSource<<7d301656072183649246db8fa738fc4d>>
|
||||
* @generated SignedSource<<58c69846193598ce0c3666c37b8a185f>>
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -170,6 +170,10 @@ bool ReactNativeFeatureFlags::useAlwaysAvailableJSErrorHandling() {
|
||||
return getAccessor().useAlwaysAvailableJSErrorHandling();
|
||||
}
|
||||
|
||||
bool ReactNativeFeatureFlags::useEditTextStockAndroidFocusBehavior() {
|
||||
return getAccessor().useEditTextStockAndroidFocusBehavior();
|
||||
}
|
||||
|
||||
bool ReactNativeFeatureFlags::useFabricInterop() {
|
||||
return getAccessor().useFabricInterop();
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @generated SignedSource<<eee9560521020eb75fa84c6e0cef31a3>>
|
||||
* @generated SignedSource<<1d578508c3cd69bbf9616a811508a03e>>
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -219,6 +219,11 @@ class ReactNativeFeatureFlags {
|
||||
*/
|
||||
RN_EXPORT static bool useAlwaysAvailableJSErrorHandling();
|
||||
|
||||
/**
|
||||
* If true, focusing in ReactEditText will mainly use stock Android requestFocus() behavior. If false it will use legacy custom focus behavior.
|
||||
*/
|
||||
RN_EXPORT static bool useEditTextStockAndroidFocusBehavior();
|
||||
|
||||
/**
|
||||
* Should this application enable the Fabric Interop Layer for Android? If yes, the application will behave so that it can accept non-Fabric components and render them on Fabric. This toggle is controlling extra logic such as custom event dispatching that are needed for the Fabric Interop Layer to work correctly.
|
||||
*/
|
||||
|
||||
+28
-10
@@ -4,7 +4,7 @@
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @generated SignedSource<<a360603ae99888aa172cc1b85d3893e4>>
|
||||
* @generated SignedSource<<42e2ae5cbfb15c17a7d60a771128858a>>
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -677,6 +677,24 @@ bool ReactNativeFeatureFlagsAccessor::useAlwaysAvailableJSErrorHandling() {
|
||||
return flagValue.value();
|
||||
}
|
||||
|
||||
bool ReactNativeFeatureFlagsAccessor::useEditTextStockAndroidFocusBehavior() {
|
||||
auto flagValue = useEditTextStockAndroidFocusBehavior_.load();
|
||||
|
||||
if (!flagValue.has_value()) {
|
||||
// This block is not exclusive but it is not necessary.
|
||||
// If multiple threads try to initialize the feature flag, we would only
|
||||
// be accessing the provider multiple times but the end state of this
|
||||
// instance and the returned flag value would be the same.
|
||||
|
||||
markFlagAsAccessed(36, "useEditTextStockAndroidFocusBehavior");
|
||||
|
||||
flagValue = currentProvider_->useEditTextStockAndroidFocusBehavior();
|
||||
useEditTextStockAndroidFocusBehavior_ = flagValue;
|
||||
}
|
||||
|
||||
return flagValue.value();
|
||||
}
|
||||
|
||||
bool ReactNativeFeatureFlagsAccessor::useFabricInterop() {
|
||||
auto flagValue = useFabricInterop_.load();
|
||||
|
||||
@@ -686,7 +704,7 @@ bool ReactNativeFeatureFlagsAccessor::useFabricInterop() {
|
||||
// be accessing the provider multiple times but the end state of this
|
||||
// instance and the returned flag value would be the same.
|
||||
|
||||
markFlagAsAccessed(36, "useFabricInterop");
|
||||
markFlagAsAccessed(37, "useFabricInterop");
|
||||
|
||||
flagValue = currentProvider_->useFabricInterop();
|
||||
useFabricInterop_ = flagValue;
|
||||
@@ -704,7 +722,7 @@ bool ReactNativeFeatureFlagsAccessor::useImmediateExecutorInAndroidBridgeless()
|
||||
// be accessing the provider multiple times but the end state of this
|
||||
// instance and the returned flag value would be the same.
|
||||
|
||||
markFlagAsAccessed(37, "useImmediateExecutorInAndroidBridgeless");
|
||||
markFlagAsAccessed(38, "useImmediateExecutorInAndroidBridgeless");
|
||||
|
||||
flagValue = currentProvider_->useImmediateExecutorInAndroidBridgeless();
|
||||
useImmediateExecutorInAndroidBridgeless_ = flagValue;
|
||||
@@ -722,7 +740,7 @@ bool ReactNativeFeatureFlagsAccessor::useNativeViewConfigsInBridgelessMode() {
|
||||
// be accessing the provider multiple times but the end state of this
|
||||
// instance and the returned flag value would be the same.
|
||||
|
||||
markFlagAsAccessed(38, "useNativeViewConfigsInBridgelessMode");
|
||||
markFlagAsAccessed(39, "useNativeViewConfigsInBridgelessMode");
|
||||
|
||||
flagValue = currentProvider_->useNativeViewConfigsInBridgelessMode();
|
||||
useNativeViewConfigsInBridgelessMode_ = flagValue;
|
||||
@@ -740,7 +758,7 @@ bool ReactNativeFeatureFlagsAccessor::useOptimisedViewPreallocationOnAndroid() {
|
||||
// be accessing the provider multiple times but the end state of this
|
||||
// instance and the returned flag value would be the same.
|
||||
|
||||
markFlagAsAccessed(39, "useOptimisedViewPreallocationOnAndroid");
|
||||
markFlagAsAccessed(40, "useOptimisedViewPreallocationOnAndroid");
|
||||
|
||||
flagValue = currentProvider_->useOptimisedViewPreallocationOnAndroid();
|
||||
useOptimisedViewPreallocationOnAndroid_ = flagValue;
|
||||
@@ -758,7 +776,7 @@ bool ReactNativeFeatureFlagsAccessor::useOptimizedEventBatchingOnAndroid() {
|
||||
// be accessing the provider multiple times but the end state of this
|
||||
// instance and the returned flag value would be the same.
|
||||
|
||||
markFlagAsAccessed(40, "useOptimizedEventBatchingOnAndroid");
|
||||
markFlagAsAccessed(41, "useOptimizedEventBatchingOnAndroid");
|
||||
|
||||
flagValue = currentProvider_->useOptimizedEventBatchingOnAndroid();
|
||||
useOptimizedEventBatchingOnAndroid_ = flagValue;
|
||||
@@ -776,7 +794,7 @@ bool ReactNativeFeatureFlagsAccessor::useRawPropsJsiValue() {
|
||||
// be accessing the provider multiple times but the end state of this
|
||||
// instance and the returned flag value would be the same.
|
||||
|
||||
markFlagAsAccessed(41, "useRawPropsJsiValue");
|
||||
markFlagAsAccessed(42, "useRawPropsJsiValue");
|
||||
|
||||
flagValue = currentProvider_->useRawPropsJsiValue();
|
||||
useRawPropsJsiValue_ = flagValue;
|
||||
@@ -794,7 +812,7 @@ bool ReactNativeFeatureFlagsAccessor::useRuntimeShadowNodeReferenceUpdate() {
|
||||
// be accessing the provider multiple times but the end state of this
|
||||
// instance and the returned flag value would be the same.
|
||||
|
||||
markFlagAsAccessed(42, "useRuntimeShadowNodeReferenceUpdate");
|
||||
markFlagAsAccessed(43, "useRuntimeShadowNodeReferenceUpdate");
|
||||
|
||||
flagValue = currentProvider_->useRuntimeShadowNodeReferenceUpdate();
|
||||
useRuntimeShadowNodeReferenceUpdate_ = flagValue;
|
||||
@@ -812,7 +830,7 @@ bool ReactNativeFeatureFlagsAccessor::useTurboModuleInterop() {
|
||||
// be accessing the provider multiple times but the end state of this
|
||||
// instance and the returned flag value would be the same.
|
||||
|
||||
markFlagAsAccessed(43, "useTurboModuleInterop");
|
||||
markFlagAsAccessed(44, "useTurboModuleInterop");
|
||||
|
||||
flagValue = currentProvider_->useTurboModuleInterop();
|
||||
useTurboModuleInterop_ = flagValue;
|
||||
@@ -830,7 +848,7 @@ bool ReactNativeFeatureFlagsAccessor::useTurboModules() {
|
||||
// be accessing the provider multiple times but the end state of this
|
||||
// instance and the returned flag value would be the same.
|
||||
|
||||
markFlagAsAccessed(44, "useTurboModules");
|
||||
markFlagAsAccessed(45, "useTurboModules");
|
||||
|
||||
flagValue = currentProvider_->useTurboModules();
|
||||
useTurboModules_ = flagValue;
|
||||
|
||||
+4
-2
@@ -4,7 +4,7 @@
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @generated SignedSource<<8eb2b5d6dd367826ff7bc899afbdea60>>
|
||||
* @generated SignedSource<<8423497c73f5315fdc3e8b4fa0bdc8c2>>
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -68,6 +68,7 @@ class ReactNativeFeatureFlagsAccessor {
|
||||
bool loadVectorDrawablesOnImages();
|
||||
bool traceTurboModulePromiseRejectionsOnAndroid();
|
||||
bool useAlwaysAvailableJSErrorHandling();
|
||||
bool useEditTextStockAndroidFocusBehavior();
|
||||
bool useFabricInterop();
|
||||
bool useImmediateExecutorInAndroidBridgeless();
|
||||
bool useNativeViewConfigsInBridgelessMode();
|
||||
@@ -88,7 +89,7 @@ class ReactNativeFeatureFlagsAccessor {
|
||||
std::unique_ptr<ReactNativeFeatureFlagsProvider> currentProvider_;
|
||||
bool wasOverridden_;
|
||||
|
||||
std::array<std::atomic<const char*>, 45> accessedFeatureFlags_;
|
||||
std::array<std::atomic<const char*>, 46> accessedFeatureFlags_;
|
||||
|
||||
std::atomic<std::optional<bool>> commonTestFlag_;
|
||||
std::atomic<std::optional<bool>> completeReactInstanceCreationOnBgThreadOnAndroid_;
|
||||
@@ -126,6 +127,7 @@ class ReactNativeFeatureFlagsAccessor {
|
||||
std::atomic<std::optional<bool>> loadVectorDrawablesOnImages_;
|
||||
std::atomic<std::optional<bool>> traceTurboModulePromiseRejectionsOnAndroid_;
|
||||
std::atomic<std::optional<bool>> useAlwaysAvailableJSErrorHandling_;
|
||||
std::atomic<std::optional<bool>> useEditTextStockAndroidFocusBehavior_;
|
||||
std::atomic<std::optional<bool>> useFabricInterop_;
|
||||
std::atomic<std::optional<bool>> useImmediateExecutorInAndroidBridgeless_;
|
||||
std::atomic<std::optional<bool>> useNativeViewConfigsInBridgelessMode_;
|
||||
|
||||
+5
-1
@@ -4,7 +4,7 @@
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @generated SignedSource<<e38a0e9474ac349a4b8153862470c856>>
|
||||
* @generated SignedSource<<c7b0a50bce07d6e2556b5780e0f22595>>
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -171,6 +171,10 @@ class ReactNativeFeatureFlagsDefaults : public ReactNativeFeatureFlagsProvider {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool useEditTextStockAndroidFocusBehavior() override {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool useFabricInterop() override {
|
||||
return false;
|
||||
}
|
||||
|
||||
+10
-1
@@ -4,7 +4,7 @@
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @generated SignedSource<<e5e8a3b63e42ed4b5cab143d46d20260>>
|
||||
* @generated SignedSource<<179524938d2e6148ef87835844c4135e>>
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -369,6 +369,15 @@ class ReactNativeFeatureFlagsDynamicProvider : public ReactNativeFeatureFlagsDef
|
||||
return ReactNativeFeatureFlagsDefaults::useAlwaysAvailableJSErrorHandling();
|
||||
}
|
||||
|
||||
bool useEditTextStockAndroidFocusBehavior() override {
|
||||
auto value = values_["useEditTextStockAndroidFocusBehavior"];
|
||||
if (!value.isNull()) {
|
||||
return value.getBool();
|
||||
}
|
||||
|
||||
return ReactNativeFeatureFlagsDefaults::useEditTextStockAndroidFocusBehavior();
|
||||
}
|
||||
|
||||
bool useFabricInterop() override {
|
||||
auto value = values_["useFabricInterop"];
|
||||
if (!value.isNull()) {
|
||||
|
||||
+2
-1
@@ -4,7 +4,7 @@
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @generated SignedSource<<36bfe0037e4dba3b6eb6e95075914fce>>
|
||||
* @generated SignedSource<<a36169cf43b41914533e7b5c17ec053c>>
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -61,6 +61,7 @@ class ReactNativeFeatureFlagsProvider {
|
||||
virtual bool loadVectorDrawablesOnImages() = 0;
|
||||
virtual bool traceTurboModulePromiseRejectionsOnAndroid() = 0;
|
||||
virtual bool useAlwaysAvailableJSErrorHandling() = 0;
|
||||
virtual bool useEditTextStockAndroidFocusBehavior() = 0;
|
||||
virtual bool useFabricInterop() = 0;
|
||||
virtual bool useImmediateExecutorInAndroidBridgeless() = 0;
|
||||
virtual bool useNativeViewConfigsInBridgelessMode() = 0;
|
||||
|
||||
+6
-1
@@ -4,7 +4,7 @@
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @generated SignedSource<<f5a1ea8dd3d64e435b6954c39dacb76a>>
|
||||
* @generated SignedSource<<81f3e20643ddb2612eaa9276bb75e70e>>
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -224,6 +224,11 @@ bool NativeReactNativeFeatureFlags::useAlwaysAvailableJSErrorHandling(
|
||||
return ReactNativeFeatureFlags::useAlwaysAvailableJSErrorHandling();
|
||||
}
|
||||
|
||||
bool NativeReactNativeFeatureFlags::useEditTextStockAndroidFocusBehavior(
|
||||
jsi::Runtime& /*runtime*/) {
|
||||
return ReactNativeFeatureFlags::useEditTextStockAndroidFocusBehavior();
|
||||
}
|
||||
|
||||
bool NativeReactNativeFeatureFlags::useFabricInterop(
|
||||
jsi::Runtime& /*runtime*/) {
|
||||
return ReactNativeFeatureFlags::useFabricInterop();
|
||||
|
||||
+3
-1
@@ -4,7 +4,7 @@
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @generated SignedSource<<fc3960bfa407d1fc123ee4c71eac644a>>
|
||||
* @generated SignedSource<<0852372c6b328f128319949a01aa8787>>
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -109,6 +109,8 @@ class NativeReactNativeFeatureFlags
|
||||
|
||||
bool useAlwaysAvailableJSErrorHandling(jsi::Runtime& runtime);
|
||||
|
||||
bool useEditTextStockAndroidFocusBehavior(jsi::Runtime& runtime);
|
||||
|
||||
bool useFabricInterop(jsi::Runtime& runtime);
|
||||
|
||||
bool useImmediateExecutorInAndroidBridgeless(jsi::Runtime& runtime);
|
||||
|
||||
+1
-1
@@ -45,7 +45,7 @@ using NativeIntersectionObserverEntry =
|
||||
// rootRect
|
||||
RectAsTuple,
|
||||
// intersectionRect
|
||||
std::optional<RectAsTuple>,
|
||||
RectAsTuple,
|
||||
// isIntersectingAboveThresholds
|
||||
bool,
|
||||
// time
|
||||
|
||||
@@ -5,21 +5,6 @@
|
||||
|
||||
require_relative './helpers.rb'
|
||||
|
||||
# It builds the codegen CLI if it is not present
|
||||
#
|
||||
# Parameters:
|
||||
# - react_native_path: the path to the react native installation
|
||||
# - relative_installation_root: the path to the relative installation root of the pods
|
||||
# - dir_manager: a class that implements the `Dir` interface. Defaults to `Dir`, the Dependency can be injected for testing purposes.
|
||||
# @throws an error if it could not find the codegen folder.
|
||||
def build_codegen!(react_native_path, relative_installation_root, dir_manager: Dir)
|
||||
codegen_repo_path = "#{basePath(react_native_path, relative_installation_root)}/../react-native-codegen"
|
||||
return unless dir_manager.exist?(codegen_repo_path) && !dir_manager.exist?("#{codegen_repo_path}/lib")
|
||||
|
||||
Pod::UI.puts "[Codegen] building #{codegen_repo_path}"
|
||||
system("#{codegen_repo_path}/scripts/oss/build.sh")
|
||||
end
|
||||
|
||||
# keeping the run_codegen! method for testing purposes
|
||||
def run_codegen!(
|
||||
app_path,
|
||||
|
||||
@@ -390,6 +390,15 @@ const definitions: FeatureFlagDefinitions = {
|
||||
purpose: 'release',
|
||||
},
|
||||
},
|
||||
useEditTextStockAndroidFocusBehavior: {
|
||||
defaultValue: true,
|
||||
metadata: {
|
||||
description:
|
||||
'If true, focusing in ReactEditText will mainly use stock Android requestFocus() behavior. If false it will use legacy custom focus behavior.',
|
||||
expectedReleaseValue: true,
|
||||
purpose: 'release',
|
||||
},
|
||||
},
|
||||
useFabricInterop: {
|
||||
defaultValue: false,
|
||||
metadata: {
|
||||
@@ -618,12 +627,13 @@ const definitions: FeatureFlagDefinitions = {
|
||||
},
|
||||
},
|
||||
useInsertionEffectsForAnimations: {
|
||||
defaultValue: true,
|
||||
defaultValue: false,
|
||||
metadata: {
|
||||
dateAdded: '2024-09-12',
|
||||
description:
|
||||
'Changes construction of the animation graph to `useInsertionEffect` instead of `useLayoutEffect`.',
|
||||
expectedReleaseValue: true,
|
||||
purpose: 'release',
|
||||
purpose: 'experimentation',
|
||||
},
|
||||
},
|
||||
useRefsForTextInputState: {
|
||||
|
||||
@@ -96,8 +96,6 @@ def use_react_native! (
|
||||
|
||||
ReactNativePodsUtils.warn_if_not_on_arm64()
|
||||
|
||||
build_codegen!(prefix, relative_path_from_current)
|
||||
|
||||
# The Pods which should be included in all projects
|
||||
pod 'FBLazyVector', :path => "#{prefix}/Libraries/FBLazyVector"
|
||||
pod 'RCTRequired', :path => "#{prefix}/Libraries/Required"
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @generated SignedSource<<3037cf1c938dae492b656333cec9633c>>
|
||||
* @generated SignedSource<<a88e25ee1e5bb8a324ff861c0703b9aa>>
|
||||
* @flow strict
|
||||
*/
|
||||
|
||||
@@ -87,6 +87,7 @@ export type ReactNativeFeatureFlags = $ReadOnly<{
|
||||
loadVectorDrawablesOnImages: Getter<boolean>,
|
||||
traceTurboModulePromiseRejectionsOnAndroid: Getter<boolean>,
|
||||
useAlwaysAvailableJSErrorHandling: Getter<boolean>,
|
||||
useEditTextStockAndroidFocusBehavior: Getter<boolean>,
|
||||
useFabricInterop: Getter<boolean>,
|
||||
useImmediateExecutorInAndroidBridgeless: Getter<boolean>,
|
||||
useNativeViewConfigsInBridgelessMode: Getter<boolean>,
|
||||
@@ -176,7 +177,7 @@ export const shouldUseSetNativePropsInFabric: Getter<boolean> = createJavaScript
|
||||
/**
|
||||
* Changes construction of the animation graph to `useInsertionEffect` instead of `useLayoutEffect`.
|
||||
*/
|
||||
export const useInsertionEffectsForAnimations: Getter<boolean> = createJavaScriptFlagGetter('useInsertionEffectsForAnimations', true);
|
||||
export const useInsertionEffectsForAnimations: Getter<boolean> = createJavaScriptFlagGetter('useInsertionEffectsForAnimations', false);
|
||||
|
||||
/**
|
||||
* Enable a variant of TextInput that moves some state to refs to avoid unnecessary re-renders
|
||||
@@ -331,6 +332,10 @@ export const traceTurboModulePromiseRejectionsOnAndroid: Getter<boolean> = creat
|
||||
* In Bridgeless mode, use the always available javascript error reporting pipeline.
|
||||
*/
|
||||
export const useAlwaysAvailableJSErrorHandling: Getter<boolean> = createNativeFlagGetter('useAlwaysAvailableJSErrorHandling', false);
|
||||
/**
|
||||
* If true, focusing in ReactEditText will mainly use stock Android requestFocus() behavior. If false it will use legacy custom focus behavior.
|
||||
*/
|
||||
export const useEditTextStockAndroidFocusBehavior: Getter<boolean> = createNativeFlagGetter('useEditTextStockAndroidFocusBehavior', true);
|
||||
/**
|
||||
* Should this application enable the Fabric Interop Layer for Android? If yes, the application will behave so that it can accept non-Fabric components and render them on Fabric. This toggle is controlling extra logic such as custom event dispatching that are needed for the Fabric Interop Layer to work correctly.
|
||||
*/
|
||||
|
||||
+2
-1
@@ -4,7 +4,7 @@
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @generated SignedSource<<37e95652ef5d824bb05e78ebdb051e43>>
|
||||
* @generated SignedSource<<9fd249e6c81d4aaa9793c003d986524c>>
|
||||
* @flow strict
|
||||
*/
|
||||
|
||||
@@ -60,6 +60,7 @@ export interface Spec extends TurboModule {
|
||||
+loadVectorDrawablesOnImages?: () => boolean;
|
||||
+traceTurboModulePromiseRejectionsOnAndroid?: () => boolean;
|
||||
+useAlwaysAvailableJSErrorHandling?: () => boolean;
|
||||
+useEditTextStockAndroidFocusBehavior?: () => boolean;
|
||||
+useFabricInterop?: () => boolean;
|
||||
+useImmediateExecutorInAndroidBridgeless?: () => boolean;
|
||||
+useNativeViewConfigsInBridgelessMode?: () => boolean;
|
||||
|
||||
Vendored
+1
-1
@@ -14,13 +14,13 @@ import type MutationObserverType from '../MutationObserver';
|
||||
|
||||
import View from '../../../../../Libraries/Components/View/View';
|
||||
import setUpMutationObserver from '../../../setup/setUpMutationObserver';
|
||||
import ensureInstance from '../../../utilities/ensureInstance';
|
||||
import ReactNativeElement from '../../dom/nodes/ReactNativeElement';
|
||||
import * as Fantom from '@react-native/fantom';
|
||||
import nullthrows from 'nullthrows';
|
||||
import * as React from 'react';
|
||||
|
||||
import '../../../../../Libraries/Core/InitializeCore.js';
|
||||
import ensureInstance from '../../../utilities/ensureInstance';
|
||||
|
||||
declare const MutationObserver: Class<MutationObserverType>;
|
||||
|
||||
|
||||
+71
@@ -0,0 +1,71 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @flow strict-local
|
||||
* @format
|
||||
* @oncall react_native
|
||||
* @fantom_flags enableLongTaskAPI:true
|
||||
*/
|
||||
|
||||
import setUpPerformanceObserver from '../../../setup/setUpPerformanceObserver';
|
||||
import ensureInstance from '../../../utilities/ensureInstance';
|
||||
import {PerformanceMark} from '../UserTiming';
|
||||
import {runWorkLoop} from '@react-native/fantom';
|
||||
|
||||
import '../../../../../Libraries/Core/InitializeCore.js';
|
||||
|
||||
setUpPerformanceObserver();
|
||||
|
||||
describe('User Timing API', () => {
|
||||
describe('performance.mark()', () => {
|
||||
it('reports marks to observers', () => {
|
||||
const callback = jest.fn();
|
||||
|
||||
const observer = new PerformanceObserver(callback);
|
||||
observer.observe({type: 'mark'});
|
||||
|
||||
expect(callback).not.toHaveBeenCalled();
|
||||
|
||||
const mark1Detail = Symbol('mark1Detail');
|
||||
performance.mark('mark1', {
|
||||
startTime: 100,
|
||||
detail: mark1Detail,
|
||||
});
|
||||
|
||||
const mark2Detail = Symbol('mark2Detail');
|
||||
performance.mark('mark2', {
|
||||
startTime: 200,
|
||||
detail: mark2Detail,
|
||||
});
|
||||
|
||||
expect(callback).not.toHaveBeenCalled();
|
||||
|
||||
runWorkLoop();
|
||||
|
||||
expect(callback).toHaveBeenCalledTimes(1);
|
||||
|
||||
const entries = callback.mock.lastCall[0].getEntries();
|
||||
expect(entries.length).toBe(2);
|
||||
|
||||
const mark1 = ensureInstance(entries[0], PerformanceMark);
|
||||
const mark2 = ensureInstance(entries[1], PerformanceMark);
|
||||
|
||||
expect(mark1.entryType).toBe('mark');
|
||||
expect(mark1.name).toBe('mark1');
|
||||
expect(mark1.startTime).toBe(100);
|
||||
expect(mark1.duration).toBe(0);
|
||||
// This doesn't work through PerformanceObserver yet
|
||||
// expect(mark1.detail).toBe(mark1Detail);
|
||||
|
||||
expect(mark2.entryType).toBe('mark');
|
||||
expect(mark2.name).toBe('mark2');
|
||||
expect(mark2.startTime).toBe(200);
|
||||
expect(mark2.duration).toBe(0);
|
||||
// This doesn't work through PerformanceObserver yet
|
||||
// expect(mark2.detail).toBe(mark2Detail);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -10,13 +10,14 @@
|
||||
|
||||
import invariant from 'invariant';
|
||||
import * as React from 'react';
|
||||
import {useEffect} from 'react';
|
||||
import {DeviceEventEmitter, NativeModules, View} from 'react-native';
|
||||
import NativeAccessibilityManager from 'react-native/Libraries/Components/AccessibilityInfo/NativeAccessibilityManager';
|
||||
|
||||
const {TestModule} = NativeModules;
|
||||
|
||||
class AccessibilityManagerTest extends React.Component<{...}> {
|
||||
componentDidMount(): void {
|
||||
function AccessibilityManagerTest(): React.Node {
|
||||
useEffect(() => {
|
||||
invariant(
|
||||
NativeAccessibilityManager,
|
||||
"NativeAccessibilityManager doesn't exist",
|
||||
@@ -36,16 +37,20 @@ class AccessibilityManagerTest extends React.Component<{...}> {
|
||||
accessibilityExtraExtraLarge: 11.0,
|
||||
accessibilityExtraExtraExtraLarge: 12.0,
|
||||
});
|
||||
DeviceEventEmitter.addListener('didUpdateDimensions', update => {
|
||||
TestModule.markTestPassed(update.window.fontScale === 4.0);
|
||||
});
|
||||
}
|
||||
|
||||
render(): React.Node {
|
||||
return <View />;
|
||||
}
|
||||
const subscription = DeviceEventEmitter.addListener(
|
||||
'didUpdateDimensions',
|
||||
update => {
|
||||
TestModule.markTestPassed(update.window.fontScale === 4.0);
|
||||
},
|
||||
);
|
||||
|
||||
return () => {
|
||||
subscription.remove();
|
||||
};
|
||||
}, []);
|
||||
|
||||
return <View />;
|
||||
}
|
||||
|
||||
AccessibilityManagerTest.displayName = 'AccessibilityManagerTest';
|
||||
|
||||
module.exports = AccessibilityManagerTest;
|
||||
export default AccessibilityManagerTest;
|
||||
|
||||
@@ -10,65 +10,49 @@
|
||||
|
||||
'use strict';
|
||||
|
||||
const React = require('react');
|
||||
const ReactNative = require('react-native');
|
||||
import * as React from 'react';
|
||||
import {useEffect, useState} from 'react';
|
||||
import {NativeModules, StyleSheet, Text, View} from 'react-native';
|
||||
|
||||
const {Text, View, StyleSheet} = ReactNative;
|
||||
const {TestModule} = ReactNative.NativeModules;
|
||||
const {TestModule} = NativeModules;
|
||||
|
||||
type Props = $ReadOnly<{|
|
||||
type Props = $ReadOnly<{
|
||||
shouldThrow?: boolean,
|
||||
waitOneFrame?: boolean,
|
||||
|}>;
|
||||
}>;
|
||||
|
||||
type State = {|
|
||||
done: boolean,
|
||||
|};
|
||||
function IntegrationTestHarnessTest(props: Props): React.Node {
|
||||
const [done, setDone] = useState(false);
|
||||
|
||||
class IntegrationTestHarnessTest extends React.Component<Props, State> {
|
||||
state: State = {
|
||||
done: false,
|
||||
};
|
||||
|
||||
componentDidMount() {
|
||||
if (this.props.waitOneFrame) {
|
||||
requestAnimationFrame(this.runTest);
|
||||
} else {
|
||||
this.runTest();
|
||||
}
|
||||
}
|
||||
|
||||
runTest: () => void = () => {
|
||||
if (this.props.shouldThrow) {
|
||||
throw new Error('Throwing error because shouldThrow');
|
||||
}
|
||||
if (!TestModule) {
|
||||
throw new Error('RCTTestModule is not registered.');
|
||||
} else if (!TestModule.markTestCompleted) {
|
||||
throw new Error('RCTTestModule.markTestCompleted not defined.');
|
||||
}
|
||||
this.setState({done: true}, () => {
|
||||
useEffect(() => {
|
||||
const runTest = () => {
|
||||
if (props.shouldThrow) {
|
||||
throw new Error('Throwing error because shouldThrow');
|
||||
}
|
||||
if (!TestModule) {
|
||||
throw new Error('RCTTestModule is not registered.');
|
||||
} else if (!TestModule.markTestCompleted) {
|
||||
throw new Error('RCTTestModule.markTestCompleted not defined.');
|
||||
}
|
||||
setDone(true);
|
||||
TestModule.markTestCompleted();
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
render(): React.Node {
|
||||
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.
|
||||
*/
|
||||
// $FlowFixMe[unsafe-addition]
|
||||
this.constructor.displayName + ': '
|
||||
}
|
||||
{this.state.done ? 'Done' : 'Testing...'}
|
||||
</Text>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
if (props.waitOneFrame) {
|
||||
requestAnimationFrame(runTest);
|
||||
} else {
|
||||
runTest();
|
||||
}
|
||||
}, [props.shouldThrow, props.waitOneFrame]);
|
||||
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<Text>
|
||||
{IntegrationTestHarnessTest.name + ': '}
|
||||
{done ? 'Done' : 'Testing...'}
|
||||
</Text>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
@@ -78,6 +62,4 @@ const styles = StyleSheet.create({
|
||||
},
|
||||
});
|
||||
|
||||
IntegrationTestHarnessTest.displayName = 'IntegrationTestHarnessTest';
|
||||
|
||||
module.exports = IntegrationTestHarnessTest;
|
||||
export default IntegrationTestHarnessTest;
|
||||
|
||||
@@ -32,11 +32,14 @@ const TESTS = [
|
||||
require('./GlobalEvalWithSourceUrlTest'),
|
||||
];
|
||||
|
||||
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. */
|
||||
test => AppRegistry.registerComponent(test.displayName, () => test),
|
||||
TESTS.forEach(test =>
|
||||
AppRegistry.registerComponent(
|
||||
test.displayName || test.name || '',
|
||||
/* $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. */
|
||||
() => test,
|
||||
),
|
||||
);
|
||||
|
||||
// Modules required for integration tests
|
||||
@@ -78,7 +81,9 @@ class IntegrationTestsApp extends React.Component<{...}, $FlowFixMeState> {
|
||||
* deployed. To see the error, delete this comment and run Flow.
|
||||
*/
|
||||
style={styles.row}>
|
||||
<Text style={styles.testName}>{test.displayName}</Text>
|
||||
<Text style={styles.testName}>
|
||||
{test.displayName || test.name}
|
||||
</Text>
|
||||
</TouchableOpacity>,
|
||||
<View style={styles.separator} />,
|
||||
])}
|
||||
|
||||
@@ -169,84 +169,107 @@ export default function MyNativeView(props: {}): React.Node {
|
||||
<Text style={{color: 'green', textAlign: 'center'}}>
|
||||
Opacity: {opacity.toFixed(1)}
|
||||
</Text>
|
||||
<Button
|
||||
title="Change Background"
|
||||
onPress={() => {
|
||||
let nextBGColor =
|
||||
currentBGColor + 1 >= colors.length ? 0 : currentBGColor + 1;
|
||||
let newColor = colors[nextBGColor];
|
||||
RNTMyNativeViewCommands.callNativeMethodToChangeBackgroundColor(
|
||||
// $FlowFixMe[incompatible-call]
|
||||
ref.current,
|
||||
newColor,
|
||||
);
|
||||
|
||||
callNativeMethodToChangeBackgroundColor(legacyRef.current, newColor);
|
||||
setCurrentBGColor(nextBGColor);
|
||||
}}
|
||||
/>
|
||||
<Button
|
||||
title="Add Overlays"
|
||||
onPress={() => {
|
||||
let randomColorId = Math.floor(Math.random() * 5);
|
||||
let overlayColors = [
|
||||
colors[randomColorId],
|
||||
colors[(randomColorId + 1) % 5],
|
||||
];
|
||||
RNTMyNativeViewCommands.callNativeMethodToAddOverlays(
|
||||
// $FlowFixMe[incompatible-call]
|
||||
ref.current,
|
||||
overlayColors,
|
||||
);
|
||||
callNativeMethodToAddOverlays(legacyRef.current, overlayColors);
|
||||
}}
|
||||
/>
|
||||
<Button
|
||||
title="Remove Overlays"
|
||||
onPress={() => {
|
||||
RNTMyNativeViewCommands.callNativeMethodToRemoveOverlays(
|
||||
// $FlowFixMe[incompatible-call]
|
||||
ref.current,
|
||||
);
|
||||
callNativeMethodToRemoveOverlays(legacyRef.current);
|
||||
}}
|
||||
/>
|
||||
<Button
|
||||
title="Set Opacity"
|
||||
onPress={() => {
|
||||
setOpacity(computeNextOpacity(opacity));
|
||||
setArrayValues([
|
||||
Math.floor(Math.random() * 100),
|
||||
Math.floor(Math.random() * 100),
|
||||
Math.floor(Math.random() * 100),
|
||||
]);
|
||||
}}
|
||||
/>
|
||||
<Button
|
||||
title="Console.log Measure"
|
||||
onPress={() => {
|
||||
ref.current?.measure((x, y, width, height) => {
|
||||
console.log(x, y, width, height);
|
||||
});
|
||||
|
||||
legacyRef.current?.measure((x, y, width, height) => {
|
||||
setLegacyMeasure({x, y, width, height});
|
||||
});
|
||||
legacyRef.current?.measureInWindow((x, y, width, height) => {
|
||||
setLegacyMeasureInWindow({x, y, width, height});
|
||||
});
|
||||
|
||||
if (containerRef.current) {
|
||||
legacyRef.current?.measureLayout(
|
||||
<View
|
||||
style={{
|
||||
flexDirection: 'row',
|
||||
flexWrap: 'wrap',
|
||||
justifyContent: 'space-between',
|
||||
}}>
|
||||
<Button
|
||||
title="Change Background"
|
||||
onPress={() => {
|
||||
let nextBGColor =
|
||||
currentBGColor + 1 >= colors.length ? 0 : currentBGColor + 1;
|
||||
let newColor = colors[nextBGColor];
|
||||
RNTMyNativeViewCommands.callNativeMethodToChangeBackgroundColor(
|
||||
// $FlowFixMe[incompatible-call]
|
||||
containerRef.current,
|
||||
(x, y, width, height) => {
|
||||
setLegacyMeasureLayout({x, y, width, height});
|
||||
},
|
||||
ref.current,
|
||||
newColor,
|
||||
);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
|
||||
callNativeMethodToChangeBackgroundColor(
|
||||
legacyRef.current,
|
||||
newColor,
|
||||
);
|
||||
setCurrentBGColor(nextBGColor);
|
||||
}}
|
||||
/>
|
||||
<Button
|
||||
title="Set Opacity"
|
||||
onPress={() => {
|
||||
setOpacity(computeNextOpacity(opacity));
|
||||
setArrayValues([
|
||||
Math.floor(Math.random() * 100),
|
||||
Math.floor(Math.random() * 100),
|
||||
Math.floor(Math.random() * 100),
|
||||
]);
|
||||
}}
|
||||
/>
|
||||
<Button
|
||||
title="Add Overlays"
|
||||
onPress={() => {
|
||||
let randomColorId = Math.floor(Math.random() * 5);
|
||||
let overlayColors = [
|
||||
colors[randomColorId],
|
||||
colors[(randomColorId + 1) % 5],
|
||||
];
|
||||
RNTMyNativeViewCommands.callNativeMethodToAddOverlays(
|
||||
// $FlowFixMe[incompatible-call]
|
||||
ref.current,
|
||||
overlayColors,
|
||||
);
|
||||
callNativeMethodToAddOverlays(legacyRef.current, overlayColors);
|
||||
}}
|
||||
/>
|
||||
<Button
|
||||
title="Remove Overlays"
|
||||
onPress={() => {
|
||||
RNTMyNativeViewCommands.callNativeMethodToRemoveOverlays(
|
||||
// $FlowFixMe[incompatible-call]
|
||||
ref.current,
|
||||
);
|
||||
callNativeMethodToRemoveOverlays(legacyRef.current);
|
||||
}}
|
||||
/>
|
||||
<Button
|
||||
title="Console.log Measure"
|
||||
onPress={() => {
|
||||
ref.current?.measure((x, y, width, height) => {
|
||||
console.log(x, y, width, height);
|
||||
});
|
||||
|
||||
legacyRef.current?.measure((x, y, width, height) => {
|
||||
setLegacyMeasure({x, y, width, height});
|
||||
});
|
||||
legacyRef.current?.measureInWindow((x, y, width, height) => {
|
||||
setLegacyMeasureInWindow({x, y, width, height});
|
||||
});
|
||||
|
||||
if (containerRef.current) {
|
||||
legacyRef.current?.measureLayout(
|
||||
// $FlowFixMe[incompatible-call]
|
||||
containerRef.current,
|
||||
(x, y, width, height) => {
|
||||
setLegacyMeasureLayout({x, y, width, height});
|
||||
},
|
||||
);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
<Button
|
||||
title="Test setNativeProps"
|
||||
onPress={() => {
|
||||
const newCRIndex =
|
||||
cornerRadiusIndex + 1 >= cornerRadiuses.length
|
||||
? 0
|
||||
: cornerRadiusIndex + 1;
|
||||
setCornerRadiusIndex(newCRIndex);
|
||||
legacyRef.current?.setNativeProps({
|
||||
cornerRadius: cornerRadiuses[newCRIndex],
|
||||
});
|
||||
}}
|
||||
/>
|
||||
</View>
|
||||
<Text style={{color: 'green', textAlign: 'center'}}>
|
||||
> Interop Layer Measurements <
|
||||
</Text>
|
||||
@@ -271,19 +294,6 @@ export default function MyNativeView(props: {}): React.Node {
|
||||
<Text style={{color: 'green', textAlign: 'center'}}>
|
||||
Legacy Style Event Fired {legacyStyleEventCount} times
|
||||
</Text>
|
||||
<Button
|
||||
title="Test setNativeProps"
|
||||
onPress={() => {
|
||||
const newCRIndex =
|
||||
cornerRadiusIndex + 1 >= cornerRadiuses.length
|
||||
? 0
|
||||
: cornerRadiusIndex + 1;
|
||||
setCornerRadiusIndex(newCRIndex);
|
||||
legacyRef.current?.setNativeProps({
|
||||
cornerRadius: cornerRadiuses[newCRIndex],
|
||||
});
|
||||
}}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -12,8 +12,8 @@
|
||||
|
||||
import type {PressEvent} from 'react-native/Libraries/Types/CoreEventTypes';
|
||||
|
||||
const React = require('react');
|
||||
const {Pressable, StyleSheet, Text} = require('react-native');
|
||||
import React from 'react';
|
||||
import {Pressable, StyleSheet, Text} from 'react-native';
|
||||
|
||||
type Props = $ReadOnly<{|
|
||||
testID?: string,
|
||||
@@ -22,17 +22,15 @@ type Props = $ReadOnly<{|
|
||||
onPress?: ?(event: PressEvent) => mixed,
|
||||
|}>;
|
||||
|
||||
class RNTesterButton extends React.Component<Props> {
|
||||
render(): React.Node {
|
||||
return (
|
||||
<Pressable
|
||||
testID={this.props.testID}
|
||||
onPress={this.props.onPress}
|
||||
style={({pressed}) => [styles.button, pressed && styles.pressed]}>
|
||||
<Text testID={this.props.textTestID}>{this.props.children}</Text>
|
||||
</Pressable>
|
||||
);
|
||||
}
|
||||
function RNTesterButton(props: Props): React.Node {
|
||||
return (
|
||||
<Pressable
|
||||
testID={props.testID}
|
||||
onPress={props.onPress}
|
||||
style={({pressed}) => [styles.button, pressed && styles.pressed]}>
|
||||
<Text testID={props.textTestID}>{props.children}</Text>
|
||||
</Pressable>
|
||||
);
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
@@ -51,4 +49,4 @@ const styles = StyleSheet.create({
|
||||
},
|
||||
});
|
||||
|
||||
module.exports = RNTesterButton;
|
||||
export default RNTesterButton;
|
||||
|
||||
@@ -9,9 +9,9 @@
|
||||
*/
|
||||
|
||||
import {RNTesterThemeContext} from './RNTesterTheme';
|
||||
import RNTesterTitle from './RNTesterTitle';
|
||||
import {useContext} from 'react';
|
||||
|
||||
const RNTesterTitle = require('./RNTesterTitle');
|
||||
const React = require('react');
|
||||
const {SafeAreaView, ScrollView, StyleSheet, View} = require('react-native');
|
||||
|
||||
|
||||
@@ -9,33 +9,34 @@
|
||||
*/
|
||||
|
||||
import {RNTesterThemeContext} from './RNTesterTheme';
|
||||
import React from 'react';
|
||||
import {StyleSheet, Text, View} from 'react-native';
|
||||
|
||||
const React = require('react');
|
||||
const {StyleSheet, Text, View} = require('react-native');
|
||||
type Props = $ReadOnly<{
|
||||
title: string,
|
||||
}>;
|
||||
|
||||
class RNTesterTitle extends React.Component<$FlowFixMeProps> {
|
||||
render(): React.Node {
|
||||
return (
|
||||
<RNTesterThemeContext.Consumer>
|
||||
{theme => {
|
||||
return (
|
||||
<View
|
||||
style={[
|
||||
styles.container,
|
||||
{
|
||||
borderColor: theme.SeparatorColor,
|
||||
backgroundColor: theme.TertiaryGroupedBackgroundColor,
|
||||
},
|
||||
]}>
|
||||
<Text style={[styles.text, {color: theme.LabelColor}]}>
|
||||
{this.props.title}
|
||||
</Text>
|
||||
</View>
|
||||
);
|
||||
}}
|
||||
</RNTesterThemeContext.Consumer>
|
||||
);
|
||||
}
|
||||
function RNTesterTitle({title}: Props): React.Node {
|
||||
return (
|
||||
<RNTesterThemeContext.Consumer>
|
||||
{theme => {
|
||||
return (
|
||||
<View
|
||||
style={[
|
||||
styles.container,
|
||||
{
|
||||
borderColor: theme.SeparatorColor,
|
||||
backgroundColor: theme.TertiaryGroupedBackgroundColor,
|
||||
},
|
||||
]}>
|
||||
<Text style={[styles.text, {color: theme.LabelColor}]}>
|
||||
{title}
|
||||
</Text>
|
||||
</View>
|
||||
);
|
||||
}}
|
||||
</RNTesterThemeContext.Consumer>
|
||||
);
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
@@ -53,4 +54,4 @@ const styles = StyleSheet.create({
|
||||
},
|
||||
});
|
||||
|
||||
module.exports = RNTesterTitle;
|
||||
export default RNTesterTitle;
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
|
||||
import RNTesterText from '../components/RNTesterText';
|
||||
import React from 'react';
|
||||
import {useState} from 'react';
|
||||
import {Image, TouchableHighlight, View} from 'react-native';
|
||||
|
||||
function Basic(): React.Node {
|
||||
@@ -105,116 +106,97 @@ function ClippedByText(): React.Node {
|
||||
);
|
||||
}
|
||||
|
||||
type ChangeSizeState = {|
|
||||
width: number,
|
||||
|};
|
||||
|
||||
class ChangeImageSize extends React.Component<mixed, ChangeSizeState> {
|
||||
state: ChangeSizeState = {
|
||||
width: 50,
|
||||
};
|
||||
|
||||
render(): React.Node {
|
||||
return (
|
||||
<View>
|
||||
<TouchableHighlight
|
||||
onPress={() => {
|
||||
this.setState({width: this.state.width === 50 ? 100 : 50});
|
||||
}}>
|
||||
<RNTesterText style={{fontSize: 15}}>
|
||||
Change Image Width (width={this.state.width})
|
||||
</RNTesterText>
|
||||
</TouchableHighlight>
|
||||
<RNTesterText>
|
||||
This is an
|
||||
<Image
|
||||
source={{
|
||||
uri: 'https://picsum.photos/50',
|
||||
width: this.state.width,
|
||||
height: 50,
|
||||
}}
|
||||
style={{
|
||||
width: this.state.width,
|
||||
height: 50,
|
||||
}}
|
||||
/>
|
||||
inline image
|
||||
function ChangeImageSize(): React.Node {
|
||||
const [width, setWidth] = useState(50);
|
||||
return (
|
||||
<View>
|
||||
<TouchableHighlight
|
||||
onPress={() => {
|
||||
setWidth(width === 50 ? 100 : 50);
|
||||
}}>
|
||||
<RNTesterText style={{fontSize: 15}}>
|
||||
Change Image Width (width={width})
|
||||
</RNTesterText>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
</TouchableHighlight>
|
||||
<RNTesterText>
|
||||
This is an
|
||||
<Image
|
||||
source={{
|
||||
uri: 'https://picsum.photos/50',
|
||||
width,
|
||||
height: 50,
|
||||
}}
|
||||
style={{
|
||||
width,
|
||||
height: 50,
|
||||
}}
|
||||
/>
|
||||
inline image
|
||||
</RNTesterText>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
class ChangeViewSize extends React.Component<mixed, ChangeSizeState> {
|
||||
state: ChangeSizeState = {
|
||||
width: 50,
|
||||
};
|
||||
function ChangeViewSize(): React.Node {
|
||||
const [width, setWidth] = useState(50);
|
||||
return (
|
||||
<View>
|
||||
<TouchableHighlight
|
||||
onPress={() => {
|
||||
setWidth(width === 50 ? 100 : 50);
|
||||
}}>
|
||||
<RNTesterText style={{fontSize: 15}}>
|
||||
Change View Width (width={width})
|
||||
</RNTesterText>
|
||||
</TouchableHighlight>
|
||||
<RNTesterText>
|
||||
This is an
|
||||
<View
|
||||
style={{
|
||||
width,
|
||||
height: 50,
|
||||
backgroundColor: 'steelblue',
|
||||
}}
|
||||
/>
|
||||
inline view
|
||||
</RNTesterText>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
render(): React.Node {
|
||||
return (
|
||||
<View>
|
||||
<TouchableHighlight
|
||||
onPress={() => {
|
||||
this.setState({width: this.state.width === 50 ? 100 : 50});
|
||||
}}>
|
||||
<RNTesterText style={{fontSize: 15}}>
|
||||
Change View Width (width={this.state.width})
|
||||
</RNTesterText>
|
||||
</TouchableHighlight>
|
||||
<RNTesterText>
|
||||
This is an
|
||||
function ChangeInnerViewSize(): React.Node {
|
||||
const [width, setWidth] = useState(50);
|
||||
return (
|
||||
<View>
|
||||
<TouchableHighlight
|
||||
onPress={() => {
|
||||
setWidth(width === 50 ? 100 : 50);
|
||||
}}>
|
||||
{/* When updating `width`, it's important that the only thing that
|
||||
changes is the width of the pink inline view. When we do this, we
|
||||
demonstrate a bug in RN Android where the pink view doesn't get
|
||||
rerendered and remains at its old size. If other things change
|
||||
(e.g. we display `width` as text somewhere) it could circumvent
|
||||
the bug and cause the pink view to be rerendered at its new size. */}
|
||||
<RNTesterText style={{fontSize: 15}}>
|
||||
Change Pink View Width
|
||||
</RNTesterText>
|
||||
</TouchableHighlight>
|
||||
<RNTesterText>
|
||||
This is an
|
||||
<View style={{width: 125, height: 75, backgroundColor: 'steelblue'}}>
|
||||
<View
|
||||
style={{
|
||||
width: this.state.width,
|
||||
width,
|
||||
height: 50,
|
||||
backgroundColor: 'steelblue',
|
||||
backgroundColor: 'pink',
|
||||
}}
|
||||
/>
|
||||
inline view
|
||||
</RNTesterText>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class ChangeInnerViewSize extends React.Component<mixed, ChangeSizeState> {
|
||||
state: ChangeSizeState = {
|
||||
width: 50,
|
||||
};
|
||||
|
||||
render(): React.Node {
|
||||
return (
|
||||
<View>
|
||||
<TouchableHighlight
|
||||
onPress={() => {
|
||||
this.setState({width: this.state.width === 50 ? 100 : 50});
|
||||
}}>
|
||||
{/* When updating `state.width`, it's important that the only thing that
|
||||
changes is the width of the pink inline view. When we do this, we
|
||||
demonstrate a bug in RN Android where the pink view doesn't get
|
||||
rerendered and remains at its old size. If other things change
|
||||
(e.g. we display `state.width` as text somewhere) it could circumvent
|
||||
the bug and cause the pink view to be rerendered at its new size. */}
|
||||
<RNTesterText style={{fontSize: 15}}>
|
||||
Change Pink View Width
|
||||
</RNTesterText>
|
||||
</TouchableHighlight>
|
||||
<RNTesterText>
|
||||
This is an
|
||||
<View style={{width: 125, height: 75, backgroundColor: 'steelblue'}}>
|
||||
<View
|
||||
style={{
|
||||
width: this.state.width,
|
||||
height: 50,
|
||||
backgroundColor: 'pink',
|
||||
}}
|
||||
/>
|
||||
</View>
|
||||
inline view
|
||||
</RNTesterText>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
</View>
|
||||
inline view
|
||||
</RNTesterText>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
|
||||
@@ -11,109 +11,90 @@
|
||||
'use strict';
|
||||
|
||||
import type {RNTesterModuleExample} from '../../types/RNTesterTypes';
|
||||
import type {AppStateValues} from 'react-native/Libraries/AppState/AppState';
|
||||
import type {EventSubscription} from 'react-native/Libraries/vendor/emitter/EventEmitter';
|
||||
|
||||
import RNTesterText from '../../components/RNTesterText';
|
||||
import React from 'react';
|
||||
import {useEffect, useState} from 'react';
|
||||
import {AppState, Platform, View} from 'react-native';
|
||||
|
||||
class AppStateSubscription extends React.Component<
|
||||
$FlowFixMeProps,
|
||||
$FlowFixMeState,
|
||||
> {
|
||||
state: {
|
||||
appState: ?string,
|
||||
eventsDetected: Array<string>,
|
||||
memoryWarnings: number,
|
||||
previousAppStates: Array<?(any | string)>,
|
||||
} = {
|
||||
appState: AppState.currentState,
|
||||
previousAppStates: [],
|
||||
memoryWarnings: 0,
|
||||
eventsDetected: [],
|
||||
};
|
||||
type Props = {
|
||||
detectEvents?: boolean,
|
||||
showCurrentOnly?: boolean,
|
||||
showMemoryWarnings?: boolean,
|
||||
};
|
||||
|
||||
_subscriptions: ?Array<EventSubscription>;
|
||||
function AppStateSubscription(props: Props) {
|
||||
const [currentAppState, setCurrentAppState] = useState<?string>(
|
||||
AppState.currentState,
|
||||
);
|
||||
const [previousAppStates, setPreviousAppStates] = useState<string[]>([]);
|
||||
const [memoryWarnings, setMemoryWarnings] = useState<number>(0);
|
||||
const [eventsDetected, setEventsDetected] = useState<string[]>([]);
|
||||
|
||||
componentDidMount() {
|
||||
this._subscriptions = [
|
||||
AppState.addEventListener('change', this._handleAppStateChange),
|
||||
AppState.addEventListener('memoryWarning', this._handleMemoryWarning),
|
||||
useEffect(() => {
|
||||
const subscriptions = [
|
||||
AppState.addEventListener('change', handleAppStateChange),
|
||||
AppState.addEventListener('memoryWarning', handleMemoryWarning),
|
||||
];
|
||||
|
||||
if (Platform.OS === 'android') {
|
||||
this._subscriptions.push(
|
||||
AppState.addEventListener('focus', this._handleFocus),
|
||||
AppState.addEventListener('blur', this._handleBlur),
|
||||
subscriptions.push(
|
||||
AppState.addEventListener('focus', handleFocus),
|
||||
AppState.addEventListener('blur', handleBlur),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
if (this._subscriptions != null) {
|
||||
for (const subscription of this._subscriptions) {
|
||||
subscription.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
return () => {
|
||||
subscriptions.forEach(subscription => subscription.remove());
|
||||
};
|
||||
}, []);
|
||||
|
||||
_handleMemoryWarning = () => {
|
||||
this.setState({memoryWarnings: this.state.memoryWarnings + 1});
|
||||
const handleMemoryWarning = () => {
|
||||
setMemoryWarnings(prev => prev + 1);
|
||||
};
|
||||
|
||||
_handleBlur = () => {
|
||||
const eventsDetected = this.state.eventsDetected.slice();
|
||||
eventsDetected.push('blur');
|
||||
this.setState({eventsDetected});
|
||||
const handleBlur = () => {
|
||||
setEventsDetected(prev => [...prev, 'blur']);
|
||||
};
|
||||
|
||||
_handleFocus = () => {
|
||||
const eventsDetected = this.state.eventsDetected.slice();
|
||||
eventsDetected.push('focus');
|
||||
this.setState({eventsDetected});
|
||||
const handleFocus = () => {
|
||||
setEventsDetected(prev => [...prev, 'focus']);
|
||||
};
|
||||
|
||||
_handleAppStateChange = (appState: AppStateValues) => {
|
||||
const previousAppStates = this.state.previousAppStates.slice();
|
||||
previousAppStates.push(this.state.appState);
|
||||
this.setState({
|
||||
appState,
|
||||
previousAppStates,
|
||||
});
|
||||
const handleAppStateChange = (appState: string) => {
|
||||
setPreviousAppStates(prev => [...prev, appState]);
|
||||
setCurrentAppState(appState);
|
||||
};
|
||||
|
||||
render(): React.Node {
|
||||
if (this.props.showMemoryWarnings) {
|
||||
return (
|
||||
<View>
|
||||
<RNTesterText>{this.state.memoryWarnings}</RNTesterText>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
if (this.props.showCurrentOnly) {
|
||||
return (
|
||||
<View>
|
||||
<RNTesterText>{this.state.appState}</RNTesterText>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
if (this.props.detectEvents) {
|
||||
return (
|
||||
<View>
|
||||
<RNTesterText>
|
||||
{JSON.stringify(this.state.eventsDetected)}
|
||||
</RNTesterText>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
if (props.showMemoryWarnings) {
|
||||
return (
|
||||
<View>
|
||||
<RNTesterText>
|
||||
{JSON.stringify(this.state.previousAppStates)}
|
||||
</RNTesterText>
|
||||
<RNTesterText>{memoryWarnings}</RNTesterText>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
if (props.showCurrentOnly) {
|
||||
return (
|
||||
<View>
|
||||
<RNTesterText>{currentAppState}</RNTesterText>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
if (props.detectEvents) {
|
||||
return (
|
||||
<View>
|
||||
<RNTesterText>{JSON.stringify(eventsDetected)}</RNTesterText>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<View>
|
||||
<RNTesterText>{JSON.stringify(previousAppStates)}</RNTesterText>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
exports.title = 'AppState';
|
||||
|
||||
@@ -10,179 +10,181 @@
|
||||
|
||||
'use strict';
|
||||
|
||||
import type {ViewStyleProp} from 'react-native/Libraries/StyleSheet/StyleSheet';
|
||||
|
||||
import RNTesterBlock from '../../components/RNTesterBlock';
|
||||
import RNTesterPage from '../../components/RNTesterPage';
|
||||
import RNTesterText from '../../components/RNTesterText';
|
||||
import React from 'react';
|
||||
import {StyleSheet, View} from 'react-native';
|
||||
|
||||
class Circle extends React.Component<$FlowFixMeProps> {
|
||||
render(): React.Node {
|
||||
const size = this.props.size || 20;
|
||||
const backgroundColor = this.props.bgColor || '#527fe4';
|
||||
return (
|
||||
<View
|
||||
style={{
|
||||
borderRadius: size / 2,
|
||||
backgroundColor: backgroundColor,
|
||||
width: size,
|
||||
height: size,
|
||||
margin: 1,
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
type CicleProps = $ReadOnly<{
|
||||
backgroundColor?: string,
|
||||
size?: number,
|
||||
}>;
|
||||
|
||||
function Circle({
|
||||
backgroundColor = '#527fe4',
|
||||
size = 20,
|
||||
}: CicleProps): React.Node {
|
||||
return (
|
||||
<View
|
||||
style={{
|
||||
borderRadius: size / 2,
|
||||
backgroundColor: backgroundColor,
|
||||
width: size,
|
||||
height: size,
|
||||
margin: 1,
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
class CircleBlock extends React.Component<$FlowFixMeProps> {
|
||||
render(): React.Node {
|
||||
const circleStyle = {
|
||||
flexDirection: 'row',
|
||||
backgroundColor: '#f6f7f8',
|
||||
borderWidth: 0.5,
|
||||
borderColor: '#d6d7da',
|
||||
marginBottom: 2,
|
||||
};
|
||||
return (
|
||||
<View style={[circleStyle, this.props.style]}>{this.props.children}</View>
|
||||
);
|
||||
}
|
||||
type CircleBlockProps = $ReadOnly<{
|
||||
children: React.Node,
|
||||
style: ViewStyleProp,
|
||||
}>;
|
||||
|
||||
function CircleBlock({children, style}: CircleBlockProps): React.Node {
|
||||
const circleStyle = {
|
||||
flexDirection: 'row',
|
||||
backgroundColor: '#f6f7f8',
|
||||
borderWidth: 0.5,
|
||||
borderColor: '#d6d7da',
|
||||
marginBottom: 2,
|
||||
};
|
||||
return <View style={[circleStyle, style]}>{children}</View>;
|
||||
}
|
||||
|
||||
class LayoutExample extends React.Component<$FlowFixMeProps> {
|
||||
render(): React.Node {
|
||||
const fiveColoredCircles = [
|
||||
<Circle bgColor="#527fe4" key="blue" />,
|
||||
<Circle bgColor="#D443E3" key="violet" />,
|
||||
<Circle bgColor="#FF9049" key="orange" />,
|
||||
<Circle bgColor="#FFE649" key="yellow" />,
|
||||
<Circle bgColor="#7FE040" key="green" />,
|
||||
];
|
||||
function LayoutExample(): React.Node {
|
||||
const fiveColoredCircles = [
|
||||
<Circle backgroundColor="#527fe4" key="blue" />,
|
||||
<Circle backgroundColor="#D443E3" key="violet" />,
|
||||
<Circle backgroundColor="#FF9049" key="orange" />,
|
||||
<Circle backgroundColor="#FFE649" key="yellow" />,
|
||||
<Circle backgroundColor="#7FE040" key="green" />,
|
||||
];
|
||||
|
||||
return (
|
||||
<RNTesterPage title={this.props.navigator ? null : 'Layout'}>
|
||||
<RNTesterBlock title="Flex Direction">
|
||||
<RNTesterText>row</RNTesterText>
|
||||
<CircleBlock style={{flexDirection: 'row'}}>
|
||||
{fiveColoredCircles}
|
||||
</CircleBlock>
|
||||
<RNTesterText>row-reverse</RNTesterText>
|
||||
<CircleBlock style={{flexDirection: 'row-reverse'}}>
|
||||
{fiveColoredCircles}
|
||||
</CircleBlock>
|
||||
<RNTesterText>column</RNTesterText>
|
||||
<CircleBlock style={{flexDirection: 'column'}}>
|
||||
{fiveColoredCircles}
|
||||
</CircleBlock>
|
||||
<RNTesterText>column-reverse</RNTesterText>
|
||||
<CircleBlock style={{flexDirection: 'column-reverse'}}>
|
||||
{fiveColoredCircles}
|
||||
</CircleBlock>
|
||||
<View
|
||||
style={[
|
||||
styles.overlay,
|
||||
{position: 'absolute', top: 15, left: 160},
|
||||
]}>
|
||||
<RNTesterText style={{color: 'black'}}>
|
||||
{'top: 15, left: 160'}
|
||||
</RNTesterText>
|
||||
</View>
|
||||
</RNTesterBlock>
|
||||
return (
|
||||
<RNTesterPage title={'Layout'}>
|
||||
<RNTesterBlock title="Flex Direction">
|
||||
<RNTesterText>row</RNTesterText>
|
||||
<CircleBlock style={{flexDirection: 'row'}}>
|
||||
{fiveColoredCircles}
|
||||
</CircleBlock>
|
||||
<RNTesterText>row-reverse</RNTesterText>
|
||||
<CircleBlock style={{flexDirection: 'row-reverse'}}>
|
||||
{fiveColoredCircles}
|
||||
</CircleBlock>
|
||||
<RNTesterText>column</RNTesterText>
|
||||
<CircleBlock style={{flexDirection: 'column'}}>
|
||||
{fiveColoredCircles}
|
||||
</CircleBlock>
|
||||
<RNTesterText>column-reverse</RNTesterText>
|
||||
<CircleBlock style={{flexDirection: 'column-reverse'}}>
|
||||
{fiveColoredCircles}
|
||||
</CircleBlock>
|
||||
<View
|
||||
style={[styles.overlay, {position: 'absolute', top: 15, left: 160}]}>
|
||||
<RNTesterText style={{color: 'black'}}>
|
||||
{'top: 15, left: 160'}
|
||||
</RNTesterText>
|
||||
</View>
|
||||
</RNTesterBlock>
|
||||
|
||||
<RNTesterBlock title="Justify Content - Main Direction">
|
||||
<RNTesterText>flex-start</RNTesterText>
|
||||
<CircleBlock style={{justifyContent: 'flex-start'}}>
|
||||
{fiveColoredCircles}
|
||||
</CircleBlock>
|
||||
<RNTesterText>center</RNTesterText>
|
||||
<CircleBlock style={{justifyContent: 'center'}}>
|
||||
{fiveColoredCircles}
|
||||
</CircleBlock>
|
||||
<RNTesterText>flex-end</RNTesterText>
|
||||
<CircleBlock style={{justifyContent: 'flex-end'}}>
|
||||
{fiveColoredCircles}
|
||||
</CircleBlock>
|
||||
<RNTesterText>space-between</RNTesterText>
|
||||
<CircleBlock style={{justifyContent: 'space-between'}}>
|
||||
{fiveColoredCircles}
|
||||
</CircleBlock>
|
||||
<RNTesterText>space-around</RNTesterText>
|
||||
<CircleBlock style={{justifyContent: 'space-around'}}>
|
||||
{fiveColoredCircles}
|
||||
</CircleBlock>
|
||||
</RNTesterBlock>
|
||||
<RNTesterBlock title="Align Items - Other Direction">
|
||||
<RNTesterText>flex-start</RNTesterText>
|
||||
<CircleBlock style={{alignItems: 'flex-start', height: 30}}>
|
||||
<Circle size={15} />
|
||||
<Circle size={10} />
|
||||
<Circle size={20} />
|
||||
<Circle size={17} />
|
||||
<Circle size={12} />
|
||||
<Circle size={15} />
|
||||
<Circle size={10} />
|
||||
<Circle size={20} />
|
||||
<Circle size={17} />
|
||||
<Circle size={12} />
|
||||
<Circle size={15} />
|
||||
<Circle size={10} />
|
||||
<Circle size={20} />
|
||||
<Circle size={17} />
|
||||
<Circle size={12} />
|
||||
<Circle size={15} />
|
||||
<Circle size={8} />
|
||||
</CircleBlock>
|
||||
<RNTesterText>center</RNTesterText>
|
||||
<CircleBlock style={{alignItems: 'center', height: 30}}>
|
||||
<Circle size={15} />
|
||||
<Circle size={10} />
|
||||
<Circle size={20} />
|
||||
<Circle size={17} />
|
||||
<Circle size={12} />
|
||||
<Circle size={15} />
|
||||
<Circle size={10} />
|
||||
<Circle size={20} />
|
||||
<Circle size={17} />
|
||||
<Circle size={12} />
|
||||
<Circle size={15} />
|
||||
<Circle size={10} />
|
||||
<Circle size={20} />
|
||||
<Circle size={17} />
|
||||
<Circle size={12} />
|
||||
<Circle size={15} />
|
||||
<Circle size={8} />
|
||||
</CircleBlock>
|
||||
<RNTesterText>flex-end</RNTesterText>
|
||||
<CircleBlock style={{alignItems: 'flex-end', height: 30}}>
|
||||
<Circle size={15} />
|
||||
<Circle size={10} />
|
||||
<Circle size={20} />
|
||||
<Circle size={17} />
|
||||
<Circle size={12} />
|
||||
<Circle size={15} />
|
||||
<Circle size={10} />
|
||||
<Circle size={20} />
|
||||
<Circle size={17} />
|
||||
<Circle size={12} />
|
||||
<Circle size={15} />
|
||||
<Circle size={10} />
|
||||
<Circle size={20} />
|
||||
<Circle size={17} />
|
||||
<Circle size={12} />
|
||||
<Circle size={15} />
|
||||
<Circle size={8} />
|
||||
</CircleBlock>
|
||||
</RNTesterBlock>
|
||||
<RNTesterBlock title="Flex Wrap">
|
||||
<CircleBlock style={{flexWrap: 'wrap'}}>
|
||||
{'oooooooooooooooo'.split('').map((char, i) => (
|
||||
<Circle key={i} />
|
||||
))}
|
||||
</CircleBlock>
|
||||
</RNTesterBlock>
|
||||
</RNTesterPage>
|
||||
);
|
||||
}
|
||||
<RNTesterBlock title="Justify Content - Main Direction">
|
||||
<RNTesterText>flex-start</RNTesterText>
|
||||
<CircleBlock style={{justifyContent: 'flex-start'}}>
|
||||
{fiveColoredCircles}
|
||||
</CircleBlock>
|
||||
<RNTesterText>center</RNTesterText>
|
||||
<CircleBlock style={{justifyContent: 'center'}}>
|
||||
{fiveColoredCircles}
|
||||
</CircleBlock>
|
||||
<RNTesterText>flex-end</RNTesterText>
|
||||
<CircleBlock style={{justifyContent: 'flex-end'}}>
|
||||
{fiveColoredCircles}
|
||||
</CircleBlock>
|
||||
<RNTesterText>space-between</RNTesterText>
|
||||
<CircleBlock style={{justifyContent: 'space-between'}}>
|
||||
{fiveColoredCircles}
|
||||
</CircleBlock>
|
||||
<RNTesterText>space-around</RNTesterText>
|
||||
<CircleBlock style={{justifyContent: 'space-around'}}>
|
||||
{fiveColoredCircles}
|
||||
</CircleBlock>
|
||||
</RNTesterBlock>
|
||||
<RNTesterBlock title="Align Items - Other Direction">
|
||||
<RNTesterText>flex-start</RNTesterText>
|
||||
<CircleBlock style={{alignItems: 'flex-start', height: 30}}>
|
||||
<Circle size={15} />
|
||||
<Circle size={10} />
|
||||
<Circle size={20} />
|
||||
<Circle size={17} />
|
||||
<Circle size={12} />
|
||||
<Circle size={15} />
|
||||
<Circle size={10} />
|
||||
<Circle size={20} />
|
||||
<Circle size={17} />
|
||||
<Circle size={12} />
|
||||
<Circle size={15} />
|
||||
<Circle size={10} />
|
||||
<Circle size={20} />
|
||||
<Circle size={17} />
|
||||
<Circle size={12} />
|
||||
<Circle size={15} />
|
||||
<Circle size={8} />
|
||||
</CircleBlock>
|
||||
<RNTesterText>center</RNTesterText>
|
||||
<CircleBlock style={{alignItems: 'center', height: 30}}>
|
||||
<Circle size={15} />
|
||||
<Circle size={10} />
|
||||
<Circle size={20} />
|
||||
<Circle size={17} />
|
||||
<Circle size={12} />
|
||||
<Circle size={15} />
|
||||
<Circle size={10} />
|
||||
<Circle size={20} />
|
||||
<Circle size={17} />
|
||||
<Circle size={12} />
|
||||
<Circle size={15} />
|
||||
<Circle size={10} />
|
||||
<Circle size={20} />
|
||||
<Circle size={17} />
|
||||
<Circle size={12} />
|
||||
<Circle size={15} />
|
||||
<Circle size={8} />
|
||||
</CircleBlock>
|
||||
<RNTesterText>flex-end</RNTesterText>
|
||||
<CircleBlock style={{alignItems: 'flex-end', height: 30}}>
|
||||
<Circle size={15} />
|
||||
<Circle size={10} />
|
||||
<Circle size={20} />
|
||||
<Circle size={17} />
|
||||
<Circle size={12} />
|
||||
<Circle size={15} />
|
||||
<Circle size={10} />
|
||||
<Circle size={20} />
|
||||
<Circle size={17} />
|
||||
<Circle size={12} />
|
||||
<Circle size={15} />
|
||||
<Circle size={10} />
|
||||
<Circle size={20} />
|
||||
<Circle size={17} />
|
||||
<Circle size={12} />
|
||||
<Circle size={15} />
|
||||
<Circle size={8} />
|
||||
</CircleBlock>
|
||||
</RNTesterBlock>
|
||||
<RNTesterBlock title="Flex Wrap">
|
||||
<CircleBlock style={{flexWrap: 'wrap'}}>
|
||||
{'oooooooooooooooo'.split('').map((char, i) => (
|
||||
<Circle key={i} />
|
||||
))}
|
||||
</CircleBlock>
|
||||
</RNTesterBlock>
|
||||
</RNTesterPage>
|
||||
);
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
|
||||
@@ -10,51 +10,41 @@
|
||||
|
||||
import RNTesterText from '../../components/RNTesterText';
|
||||
import React from 'react';
|
||||
import {useEffect, useState} from 'react';
|
||||
import {DeviceEventEmitter, View} from 'react-native';
|
||||
import {type EventSubscription} from 'react-native/Libraries/vendor/emitter/EventEmitter';
|
||||
|
||||
class OrientationChangeExample extends React.Component<{...}, $FlowFixMeState> {
|
||||
_orientationSubscription: EventSubscription;
|
||||
|
||||
state:
|
||||
| any
|
||||
| {
|
||||
currentOrientation: string,
|
||||
isLandscape: boolean,
|
||||
orientationDegrees: number,
|
||||
} = {
|
||||
const OrientationChangeExample = (): React.Node => {
|
||||
const [state, setState] = useState({
|
||||
currentOrientation: '',
|
||||
orientationDegrees: 0,
|
||||
isLandscape: false,
|
||||
};
|
||||
});
|
||||
|
||||
componentDidMount() {
|
||||
this._orientationSubscription = DeviceEventEmitter.addListener(
|
||||
useEffect(() => {
|
||||
const onOrientationChange = (orientation: Object) => {
|
||||
setState({
|
||||
currentOrientation: orientation.name,
|
||||
orientationDegrees: orientation.rotationDegrees,
|
||||
isLandscape: orientation.isLandscape,
|
||||
});
|
||||
};
|
||||
|
||||
const orientationSubscription = DeviceEventEmitter.addListener(
|
||||
'namedOrientationDidChange',
|
||||
this._onOrientationChange,
|
||||
onOrientationChange,
|
||||
);
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
this._orientationSubscription.remove();
|
||||
}
|
||||
return () => {
|
||||
orientationSubscription.remove();
|
||||
};
|
||||
}, []);
|
||||
|
||||
_onOrientationChange = (orientation: Object) => {
|
||||
this.setState({
|
||||
currentOrientation: orientation.name,
|
||||
orientationDegrees: orientation.rotationDegrees,
|
||||
isLandscape: orientation.isLandscape,
|
||||
});
|
||||
};
|
||||
|
||||
render(): React.Node {
|
||||
return (
|
||||
<View>
|
||||
<RNTesterText>{JSON.stringify(this.state)}</RNTesterText>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
}
|
||||
return (
|
||||
<View>
|
||||
<RNTesterText>{JSON.stringify(state)}</RNTesterText>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
exports.title = 'OrientationChangeExample';
|
||||
exports.category = 'Basic';
|
||||
|
||||
@@ -85,40 +85,66 @@ async function testRNTesterIOS(
|
||||
} version of RNTester iOS with the new Architecture enabled`,
|
||||
);
|
||||
|
||||
// if everything succeeded so far, we can launch Metro and the app
|
||||
// start the Metro server in a separate window
|
||||
launchPackagerInSeparateWindow(pwd().toString());
|
||||
|
||||
// remember that for this to be successful
|
||||
// you should have run bundle install once
|
||||
// in your local setup
|
||||
if (argv.hermes === true && ciArtifacts != null) {
|
||||
const hermesURL = await ciArtifacts.artifactURLHermesDebug();
|
||||
const hermesZipPath = path.join(ciArtifacts.baseTmpPath(), 'hermes.zip');
|
||||
// download hermes source code from manifold
|
||||
ciArtifacts.downloadArtifact(hermesURL, hermesZipPath);
|
||||
// GHA zips by default the artifacts.
|
||||
const outputFolder = path.join(ciArtifacts.baseTmpPath(), 'hermes');
|
||||
exec(`rm -rf ${outputFolder}`);
|
||||
exec(`unzip ${hermesZipPath} -d ${outputFolder}`);
|
||||
const hermesPath = path.join(outputFolder, 'hermes-ios-Debug.tar.gz');
|
||||
|
||||
console.info(`Downloaded Hermes in ${hermesPath}`);
|
||||
exec(
|
||||
`HERMES_ENGINE_TARBALL_PATH=${hermesPath} RCT_NEW_ARCH_ENABLED=1 bundle exec pod install --ansi`,
|
||||
if (ciArtifacts != null) {
|
||||
const appOutputFolder = path.join(
|
||||
ciArtifacts.baseTmpPath(),
|
||||
'RNTester.app',
|
||||
);
|
||||
exec(`rm -rf ${appOutputFolder}`);
|
||||
if (argv.hermes === true) {
|
||||
// download hermes App
|
||||
const hermesAppUrl = await ciArtifacts.artifactURLForHermesRNTesterApp();
|
||||
const hermesAppZipPath = path.join(
|
||||
ciArtifacts.baseTmpPath(),
|
||||
'RNTesterAppHermes.zip',
|
||||
);
|
||||
ciArtifacts.downloadArtifact(hermesAppUrl, hermesAppZipPath);
|
||||
exec(`unzip ${hermesAppZipPath} -d ${appOutputFolder}`);
|
||||
} else {
|
||||
// download JSC app
|
||||
const hermesAppUrl = await ciArtifacts.artifactURLForJSCRNTesterApp();
|
||||
const hermesAppZipPath = path.join(
|
||||
ciArtifacts.baseTmpPath(),
|
||||
'RNTesterAppJSC.zip',
|
||||
);
|
||||
ciArtifacts.downloadArtifact(hermesAppUrl, hermesAppZipPath);
|
||||
exec(`unzip ${hermesAppZipPath} -d ${appOutputFolder}`);
|
||||
}
|
||||
|
||||
// boot device
|
||||
const bootedDevice = String(
|
||||
exec('xcrun simctl list | grep "iPhone 16 Pro" | grep Booted', {
|
||||
silent: true,
|
||||
}),
|
||||
).trim();
|
||||
if (!bootedDevice || bootedDevice.length === 0) {
|
||||
exec('xcrun simctl boot "iPhone 16 Pro"');
|
||||
}
|
||||
|
||||
// install app on device
|
||||
exec(`xcrun simctl install booted ${appOutputFolder}`);
|
||||
|
||||
// launch the app on iOS simulator
|
||||
exec('xcrun simctl launch booted com.meta.RNTester.localDevelopment');
|
||||
} else {
|
||||
exec(
|
||||
`USE_HERMES=${
|
||||
argv.hermes === true ? 1 : 0
|
||||
} CI=${onReleaseBranch.toString()} RCT_NEW_ARCH_ENABLED=1 bundle exec pod install --ansi`,
|
||||
);
|
||||
|
||||
// launch the app on iOS simulator
|
||||
exec(
|
||||
'npx react-native run-ios --scheme RNTester --simulator "iPhone 15 Pro"',
|
||||
);
|
||||
}
|
||||
|
||||
// if everything succeeded so far, we can launch Metro and the app
|
||||
// start the Metro server in a separate window
|
||||
launchPackagerInSeparateWindow(pwd().toString());
|
||||
|
||||
// launch the app on iOS simulator
|
||||
exec(
|
||||
'npx react-native run-ios --scheme RNTester --simulator "iPhone 15 Pro"',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -201,7 +227,7 @@ async function testRNTesterAndroid(
|
||||
* - @onReleaseBranch whether we are on a release branch or not
|
||||
*/
|
||||
async function testRNTester(
|
||||
circleCIArtifacts /*:Unwrap<ReturnType<typeof setupGHAArtifacts>> */,
|
||||
ciArtifacts /*:Unwrap<ReturnType<typeof setupGHAArtifacts>> */,
|
||||
onReleaseBranch /*: boolean */,
|
||||
) {
|
||||
// FIXME: make sure that the commands retains colors
|
||||
@@ -210,9 +236,9 @@ async function testRNTester(
|
||||
pushd('packages/rn-tester');
|
||||
|
||||
if (argv.platform === 'ios') {
|
||||
await testRNTesterIOS(circleCIArtifacts, onReleaseBranch);
|
||||
await testRNTesterIOS(ciArtifacts, onReleaseBranch);
|
||||
} else {
|
||||
await testRNTesterAndroid(circleCIArtifacts);
|
||||
await testRNTesterAndroid(ciArtifacts);
|
||||
}
|
||||
popd();
|
||||
}
|
||||
|
||||
@@ -214,6 +214,14 @@ async function artifactURLForHermesRNTesterAPK(
|
||||
return getArtifactURL('rntester-hermes-debug');
|
||||
}
|
||||
|
||||
async function artifactURLForJSCRNTesterApp() /*: Promise<string> */ {
|
||||
return getArtifactURL('RNTesterApp-NewArch-JSC-Debug');
|
||||
}
|
||||
|
||||
async function artifactURLForHermesRNTesterApp() /*: Promise<string> */ {
|
||||
return getArtifactURL('RNTesterApp-NewArch-Hermes-Debug');
|
||||
}
|
||||
|
||||
async function artifactURLForMavenLocal() /*: Promise<string> */ {
|
||||
return getArtifactURL('maven-local');
|
||||
}
|
||||
@@ -247,6 +255,8 @@ module.exports = {
|
||||
downloadArtifact,
|
||||
artifactURLForJSCRNTesterAPK,
|
||||
artifactURLForHermesRNTesterAPK,
|
||||
artifactURLForJSCRNTesterApp,
|
||||
artifactURLForHermesRNTesterApp,
|
||||
artifactURLForMavenLocal,
|
||||
artifactURLHermesDebug,
|
||||
artifactURLForReactNative,
|
||||
|
||||
Reference in New Issue
Block a user