Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions FabricExample/android/settings.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,12 @@ extensions.configure(com.facebook.react.ReactSettingsExtension) { ex -> ex.autol
rootProject.name = 'FabricExample'
include ':app'
includeBuild('../node_modules/@react-native/gradle-plugin')

includeBuild('../node_modules/react-native') {
dependencySubstitution {
substitute(module("com.facebook.react:react-android")).using(project(":packages:react-native:ReactAndroid"))
substitute(module("com.facebook.react:react-native")).using(project(":packages:react-native:ReactAndroid"))
substitute(module("com.facebook.react:hermes-android")).using(project(":packages:react-native:ReactAndroid:hermes-engine"))
substitute(module("com.facebook.react:hermes-engine")).using(project(":packages:react-native:ReactAndroid:hermes-engine"))
}
}
1 change: 1 addition & 0 deletions android/src/main/jni/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ if(ReactAndroid_VERSION_MINOR GREATER_EQUAL 76)
ReactAndroid::reactnative
ReactAndroid::jsi
fbjni::fbjni
log
)
else()
target_link_libraries(
Expand Down
6 changes: 3 additions & 3 deletions apps/App.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import React from 'react';
import { enableFreeze } from 'react-native-screens';
import Example from './Example';
// import * as Test from './src/tests';
import * as Test from './src/tests';

enableFreeze(true);

export default function App() {
return <Example />;
// return <Test.TestBottomTabs />;
// return <Example />;
return <Test.Test3295 />;
}
2 changes: 1 addition & 1 deletion apps/src/tests/Test3212/ScrollViewTemplate.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export function ScrollViewTemplate() {
setConfig({ bottom: 'hidden', top: 'hidden', left: 'hidden', right: 'hidden' });
}}/>
<Text style={{ fontSize: 21 }}>
{Array.from({ length: 1000 }).map(_ => emoji[Math.floor(Math.random() * emoji.length)])}
{Array.from({ length: 50000 }).map(_ => emoji[Math.floor(Math.random() * emoji.length)])}
</Text>
</ScrollView>
);
Expand Down
190 changes: 190 additions & 0 deletions apps/src/tests/Test3295.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
import React, { useEffect } from 'react';
import { StyleSheet, View } from 'react-native';
import Animated, {
useAnimatedStyle,
useReducedMotion,
useSharedValue,
withRepeat,
withTiming,
} from 'react-native-reanimated';
import { Screen, ScreenStack } from 'react-native-screens';

const colors = [
['lime', 'green'],
['blue', 'cyan'],
];

function useLoop() {
const sv = useSharedValue(0);

useEffect(() => {
sv.value = 0;
sv.value = withRepeat(withTiming(1, { duration: 1000 }), -1, true);
}, [sv]);

return sv;
}

const N = 12;

function ChessboardExample() {
const [state, setState] = React.useState(0);

const sv = useLoop();

const shouldReduceMotion = useReducedMotion();

useEffect(() => {
if (shouldReduceMotion) {
return;
}
const id = setInterval(() => {
setState((s) => 1 - s);
}, 10);
return () => clearInterval(id);
}, [shouldReduceMotion]);

const animatedStyle = useAnimatedStyle(() => {
return {
width: 10 + sv.value * 20,
height: 10 + sv.value * 20,
};
}, []);

return (
<View style={{ flex: 1, backgroundColor: 'white' }}>
<View style={styles.workaround} collapsable={false}>
<View style={styles.chessboard}>
<View style={styles.border}>
{[...Array(N).keys()].map((i) => (
<View style={styles.row} key={i}>
{[...Array(N).keys()].map((j) => (
<Animated.View
key={j}
style={[
{ backgroundColor: colors[state % 2][(i + j) % 2] },
animatedStyle,
]}
/>
))}
</View>
))}
</View>
</View>
</View>
</View>
);
}

const styles = StyleSheet.create({
workaround: {
height: 400,
// prevents calling _state->updateState from RNScreens after each change because of view flattening
},
chessboard: {
alignItems: 'flex-start',
},
border: {
borderWidth: 10,
borderColor: 'red',
},
row: {
flexDirection: 'row',
},
});

function floodJsThread() {
setInterval(() => {
const end = Date.now() + 10;
while (Date.now() < end) {
// Intentionally do nothing; just burn CPU cycles.
Math.sqrt(Math.random());
}
}, 10);
}

/*
* create artificial pressure in the JS thread to show off thep problem.
* */
// floodJsThread();

function AppMain(): React.JSX.Element {
/*
* To keep the template simple and small we're adding padding to prevent view
* from rendering under the System UI.
* For bigger apps the reccomendation is to use `react-native-safe-area-context`:
* https://github.com/AppAndFlow/react-native-safe-area-context
*
* You can read more about it here:
* https://github.com/react-native-community/discussions-and-proposals/discussions/827
*/
const safePadding = '5%';

return (
<ChessboardExample />
// <View style={backgroundStyle}>
// <StatusBar
// barStyle={isDarkMode ? 'light-content' : 'dark-content'}
// backgroundColor={backgroundStyle.backgroundColor}
// />
// <View
// style={{
// flex: 1,
// paddingHorizontal: safePadding,
// paddingBottom: safePadding,
// justifyContent: 'center',
// alignContent: 'center',
// }}>
// <Section title="Step One">
// This test shows how the native layout update triggers a layout shift.
// </Section>
// <Section title="Step One">
// There is a view with a blue background. We don't expect to ever see
// flashes of the blue background.
// </Section>
// </View>
// </View>
);
}

// const styles = StyleSheet.create({
// sectionContainer: {
// marginTop: 32,
// paddingHorizontal: 24,
// },
// sectionTitle: {
// fontSize: 24,
// fontWeight: '600',
// },
// sectionDescription: {
// marginTop: 8,
// fontSize: 18,
// fontWeight: '400',
// },
// highlight: {
// fontWeight: '700',
// },
// });

function App() {
return (
<ScreenStack style={{ flex: 1, backgroundColor: 'red' }}>
<Screen
style={{
position: 'absolute',
top: 0,
left: 0,
bottom: 0,
right: 0,
backgroundColor: 'blue',
padding: 20,
}}
enabled
isNativeStack>
<AppMain />
</Screen>
</ScreenStack>
);
}

export default App;
1 change: 1 addition & 0 deletions apps/src/tests/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,7 @@ export { default as Test3239 } from './Test3239';
export { default as Test3265 } from './Test3265';
export { default as Test3271 } from './Test3271';
export { default as Test3282 } from './Test3282';
export { default as Test3295 } from './Test3295';
export { default as TestScreenAnimation } from './TestScreenAnimation';
export { default as TestScreenAnimationV5 } from './TestScreenAnimationV5';
export { default as TestHeader } from './TestHeader';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,16 @@

#ifdef ANDROID
#include <fbjni/fbjni.h>
#include "RNSScreenShadowNodeCommitHook.h"
#endif // ANDROID
#include <react/debug/react_native_assert.h>
#include <react/renderer/components/rnscreens/Props.h>
#include <react/renderer/components/rnscreens/utils/RectUtil.h>
#include <react/renderer/components/root/RootShadowNode.h>
#include <react/renderer/core/ConcreteComponentDescriptor.h>
#include <react/renderer/uimanager/UIManager.h>
#include <react/renderer/uimanager/UIManagerCommitHook.h>
#include <memory>
#include "RNSScreenShadowNode.h"

namespace facebook {
Expand All @@ -16,12 +21,22 @@ using namespace rnscreens;

class RNSScreenComponentDescriptor final
: public ConcreteComponentDescriptor<RNSScreenShadowNode> {
private:
#ifdef ANDROID
/*
* A commit hook that triggers on `shadowTreeWillCommit` event,
* and can read the properties of RootShadowNodes for determining screen
* orientation.
*/
mutable std::shared_ptr<RNSScreenShadowNodeCommitHook> commitHook_;
#endif // ANDROID

public:
using ConcreteComponentDescriptor::ConcreteComponentDescriptor;

void adopt(ShadowNode &shadowNode) const override {
react_native_assert(dynamic_cast<RNSScreenShadowNode *>(&shadowNode));
auto &screenShadowNode = static_cast<RNSScreenShadowNode &>(shadowNode);
auto &screenShadowNode = dynamic_cast<RNSScreenShadowNode &>(shadowNode);

react_native_assert(
dynamic_cast<YogaLayoutableShadowNode *>(&screenShadowNode));
Expand All @@ -34,6 +49,15 @@ class RNSScreenComponentDescriptor final
auto stateData = state->getData();

#ifdef ANDROID
if (!commitHook_) {
// The hook couldn't be attached in constructor because UIManager was
// missing from ContextContainer. Instead, we do it here, on the first
// call to the function. We don't anticipate any orientation changes that
// we need to respond to prior to this.
commitHook_ =
std::make_shared<RNSScreenShadowNodeCommitHook>(contextContainer_);
}

if (stateData.frameSize.width != 0 && stateData.frameSize.height != 0) {
// When we receive dimensions from JVM side we can remove padding used for
// correction, and we can stop applying height and offset corrections for
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,11 @@ class JSI_EXPORT RNSScreenShadowNode final : public ConcreteViewShadowNode<

FrameCorrectionModes &getFrameCorrectionModes();

StateData &getStateDataMutable();

private:
#ifdef ANDROID
void applyFrameCorrections();

StateData &getStateDataMutable();
#endif // ANDROID
};

Expand Down
Loading
Loading