Skip to content

Commit

Permalink
feat: allow preload using activityState (#2389)
Browse files Browse the repository at this point in the history
## Description

This PR is a rewrite of
#2278 using
already existing `activityState` -> to avoid introducing redundant prop.

Connected PR to react-navigation:
react-navigation/react-navigation#12189

## Test code and steps to reproduce

You can play with the preload feature in `TestPreload.tsx`

To test assertion of activityState progress go to
`TestActivityStateProgression.tsx` - keep in mind that if the Screen has
`isNativeStack` it will just run JS validation, remove the prop to test
native checks.

## Checklist

- [ ] Included code example that can be used to test this change
- [ ] Updated TS types
- [x] Updated documentation: <!-- For adding new props to native-stack
-->
- [x]
https://github.com/software-mansion/react-native-screens/blob/main/guides/GUIDE_FOR_LIBRARY_AUTHORS.md
- [ ]
https://github.com/software-mansion/react-native-screens/blob/main/native-stack/README.md
- [ ]
https://github.com/software-mansion/react-native-screens/blob/main/src/types.tsx
- [ ]
https://github.com/software-mansion/react-native-screens/blob/main/src/native-stack/types.tsx
- [ ] Ensured that CI passes

---------

Co-authored-by: Kacper Kafara <[email protected]>
  • Loading branch information
maciekstosio and kkafar authored Oct 10, 2024
1 parent 6154c2b commit cce7d78
Show file tree
Hide file tree
Showing 11 changed files with 486 additions and 9 deletions.
3 changes: 3 additions & 0 deletions android/src/main/java/com/swmansion/rnscreens/Screen.kt
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,9 @@ class Screen(
if (activityState == this.activityState) {
return
}
if (container is ScreenStack && this.activityState != null && activityState < this.activityState!!) {
throw IllegalStateException("[RNScreens] activityState can only progress in NativeStack")
}
this.activityState = activityState
container?.notifyChildUpdate()
}
Expand Down
30 changes: 24 additions & 6 deletions android/src/main/java/com/swmansion/rnscreens/ScreenStack.kt
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ class ScreenStack(

for (i in screenWrappers.indices.reversed()) {
val screenWrapper = getScreenFragmentWrapperAt(i)
if (!dismissedWrappers.contains(screenWrapper)) {
if (!dismissedWrappers.contains(screenWrapper) && screenWrapper.screen.activityState !== Screen.ActivityState.INACTIVE) {
if (newTop == null) {
newTop = screenWrapper
} else {
Expand Down Expand Up @@ -182,8 +182,16 @@ class ScreenStack(
R.anim.rns_no_animation_medium,
)
StackAnimation.FADE_FROM_BOTTOM -> it.setCustomAnimations(R.anim.rns_fade_from_bottom, R.anim.rns_no_animation_350)
StackAnimation.IOS_FROM_RIGHT -> it.setCustomAnimations(R.anim.rns_ios_from_right_foreground_open, R.anim.rns_ios_from_right_background_open)
StackAnimation.IOS_FROM_LEFT -> it.setCustomAnimations(R.anim.rns_ios_from_left_foreground_open, R.anim.rns_ios_from_left_background_open)
StackAnimation.IOS_FROM_RIGHT ->
it.setCustomAnimations(
R.anim.rns_ios_from_right_foreground_open,
R.anim.rns_ios_from_right_background_open,
)
StackAnimation.IOS_FROM_LEFT ->
it.setCustomAnimations(
R.anim.rns_ios_from_left_foreground_open,
R.anim.rns_ios_from_left_background_open,
)
}
} else {
when (stackAnimation) {
Expand Down Expand Up @@ -221,8 +229,16 @@ class ScreenStack(
R.anim.rns_slide_out_to_bottom,
)
StackAnimation.FADE_FROM_BOTTOM -> it.setCustomAnimations(R.anim.rns_no_animation_250, R.anim.rns_fade_to_bottom)
StackAnimation.IOS_FROM_RIGHT -> it.setCustomAnimations(R.anim.rns_ios_from_right_background_close, R.anim.rns_ios_from_right_foreground_close)
StackAnimation.IOS_FROM_LEFT -> it.setCustomAnimations(R.anim.rns_ios_from_left_background_close, R.anim.rns_ios_from_left_foreground_close)
StackAnimation.IOS_FROM_RIGHT ->
it.setCustomAnimations(
R.anim.rns_ios_from_right_background_close,
R.anim.rns_ios_from_right_foreground_close,
)
StackAnimation.IOS_FROM_LEFT ->
it.setCustomAnimations(
R.anim.rns_ios_from_left_background_close,
R.anim.rns_ios_from_left_foreground_close,
)
}
}
}
Expand Down Expand Up @@ -258,7 +274,9 @@ class ScreenStack(
break
}
// detach all screens that should not be visible
if (fragmentWrapper !== newTop && !dismissedWrappers.contains(fragmentWrapper)) {
if ((fragmentWrapper !== newTop && !dismissedWrappers.contains(fragmentWrapper)) ||
fragmentWrapper.screen.activityState === Screen.ActivityState.INACTIVE
) {
it.remove(fragmentWrapper.fragment)
}
}
Expand Down
69 changes: 69 additions & 0 deletions apps/src/tests/TestActivityStateProgression.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import * as React from 'react';
import { View, Text, Button } from 'react-native';
import { Screen, ScreenStack } from '../../../src';

function HomeScreen({
setActivityState,
}: {
setActivityState: (state: 0 | 1 | 2) => void;
}) {
console.log('Render home');
return (
<View
style={{
flex: 1,
gap: 8,
alignItems: 'center',
justifyContent: 'center',
}}>
<Text>Home!</Text>
<Button
title="Set Activity State to 2"
onPress={() => setActivityState(2)}
/>
</View>
);
}

function ProfileScreen({
setActivityState,
}: {
setActivityState: (state: 0 | 1 | 2) => void;
}) {
console.log('Render profile');
return (
<View
style={{
flex: 1,
gap: 8,
alignItems: 'center',
justifyContent: 'center',
}}>
<Text>Profile!</Text>
<Button
title="Set Activity State to 0"
onPress={() => setActivityState(0)}
/>
</View>
);
}

const App = () => {
const [activityState, setActivityState] = React.useState<0 | 1 | 2>(0);
console.log('activityState', activityState);

/**
* Remove isNativeStack if you want to test native checks
*/
return (
<ScreenStack style={{ flex: 1 }}>
<Screen activityState={2} isNativeStack>
<HomeScreen setActivityState={setActivityState} />
</Screen>
<Screen activityState={activityState} isNativeStack>
<ProfileScreen setActivityState={setActivityState} />
</Screen>
</ScreenStack>
);
};
export default App;
Loading

0 comments on commit cce7d78

Please sign in to comment.