Skip to content

Commit

Permalink
Fix issue when emptying nav stack on Windows (software-mansion#1890)
Browse files Browse the repository at this point in the history
## Description

When using a `StackNavigator` on an app on Windows, when you popped the
stack you would end up with no displayed content instead of the first
page.

## Changes

The Windows stack implementation wasn't updating `Content` to the top of
the stack (after the removal and motification of the vector).
Also the Windows project had an aggressive assertion of SDK version,
causing apps to unnecessarily either download an older SDK or patch
their app. See
react-native-async-storage/async-storage#810 for
a similar fix.

## Test code and steps to reproduce

```jsx
import { NavigationContainer } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';

// ,,,

const Stack = createNativeStackNavigator();

export default function App() : JSX.Element {
  return (
    <NavigationContainer>
      <Stack.Navigator initialRouteName='Home'>
        <Stack.Screen name='Home' component={HomeScreen} />
        <Stack.Screen name='Details' component={DetailsScreen} />
      </Stack.Navigator>
    </NavigationContainer>
  );
}
```

Somewhere else
```jsx
navigation.navigate('Details');
```

And then later
```jsx
navigation.goBack();
```

Result: rendering nothing instead of the 'Home' page.

Yep, that's all it took. As far as I can tell this was broken since
implementation, but the usage I know of on Windows was using Drawer and
that part's all fine.

## Checklist

- [x] Included code example that can be used to test this change
- [x] Updated TS types **N/A**
- [x] Updated documentation: **N/A**
- [x] Ensured that CI passes **No tests on Windows :'(**
- [x] _Tested via patch-packing in an app_
  • Loading branch information
chrisglein authored and ja1ns committed Oct 9, 2024
1 parent 9fbc6c3 commit b4b6b9d
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 3 deletions.
9 changes: 6 additions & 3 deletions windows/RNScreens/RNScreens.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,16 @@
<AppContainerApplication>true</AppContainerApplication>
<ApplicationType>Windows Store</ApplicationType>
<ApplicationTypeRevision>10.0</ApplicationTypeRevision>
<WindowsTargetPlatformVersion Condition=" '$(WindowsTargetPlatformVersion)' == '' ">10.0.18362.0</WindowsTargetPlatformVersion>
<WindowsTargetPlatformMinVersion>10.0.16299.0</WindowsTargetPlatformMinVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Label="ReactNativeWindowsProps">
<ReactNativeWindowsDir Condition="'$(ReactNativeWindowsDir)' == ''">$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), 'node_modules\react-native-windows\package.json'))\node_modules\react-native-windows\</ReactNativeWindowsDir>
</PropertyGroup>
<Import Project="$(ReactNativeWindowsDir)\PropertySheets\External\Microsoft.ReactNative.WindowsSdk.Default.props" Condition="Exists('$(ReactNativeWindowsDir)\PropertySheets\External\Microsoft.ReactNative.WindowsSdk.Default.props')" />
<PropertyGroup Label="Fallback Windows SDK Versions">
<WindowsTargetPlatformVersion Condition=" '$(WindowsTargetPlatformVersion)' == '' ">10.0.18362.0</WindowsTargetPlatformVersion>
<WindowsTargetPlatformMinVersion Condition=" '$(WindowsTargetPlatformMinVersion)' == '' ">10.0.16299.0</WindowsTargetPlatformMinVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|ARM">
<Configuration>Debug</Configuration>
Expand Down
16 changes: 16 additions & 0 deletions windows/RNScreens/ScreenStack.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ void ScreenStack::removeAllChildren() {

void ScreenStack::removeChildAt(int64_t index) {
m_children.RemoveAt(static_cast<uint32_t>(index));
onChildModified(index);
}

void ScreenStack::replaceChild(
Expand All @@ -45,5 +46,20 @@ void ScreenStack::replaceChild(
return;

m_children.SetAt(index, newChild);
onChildModified(index);
}

void ScreenStack::onChildModified(int64_t index) {
// Was it the topmost item in the stack?
if (index >= m_children.Size() - 1) {
if (m_children.Size() == 0) {
// Nobody left
Content(nullptr);
} else {
// Focus on the top item
auto uiElement = m_children.GetAt(m_children.Size() - 1);
Content(uiElement);
}
}
}
} // namespace winrt::RNScreens::implementation
1 change: 1 addition & 0 deletions windows/RNScreens/ScreenStack.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ class ScreenStack
m_children;

private:
void onChildModified(int64_t index);
winrt::Microsoft::ReactNative::IReactContext m_reactContext{nullptr};
};
} // namespace winrt::RNScreens::implementation

0 comments on commit b4b6b9d

Please sign in to comment.