react-native-navigation icon indicating copy to clipboard operation
react-native-navigation copied to clipboard

Shared Element transition breaks when using ScreenWrapper with SafeAreaContext

Open Pietro-Putelli opened this issue 2 years ago • 1 comments

🐛 Bug Report

In the app I need to use Redux and SafeAreaContext, therefore I created a ScreenWrapper component and wrap all screens into it, to provide the right contexts to all of them. Then when I try to create a sharedElement transition, using showModal, and not push because I need a transparent background, the showModal animation don't work, it works only when dismissing.

Expected behavior

The sharedElement transition should perform exactly as it does using push.

Actual Behavior

Using showModal, for the reason I've explained before, the sharedElement animation for opening (for dismissing it actually works) it doesn't work, I mean it's replaced by a cross fade transition.

Here's the code:

const ScreenWrapper = (Component, params) => {
  return function inject(props) {
    return (
      <Provider store={store}>
        <PersistGate loading={<></>} persistor={persistor}>
          <NavigationProvider value={{ componentId: props.componentId }}>
            <SafeAreaProvider>
              <Component {...params} {...props} />
            </SafeAreaProvider>
          </NavigationProvider>
        </PersistGate>
      </Provider>
    );
  };
};


Navigation.registerComponent("Screen1", () => ScreenWrapper(component));
Navigation.registerComponent("Screen2", () => ScreenWrapper(component));

Navigation.events().registerAppLaunchedListener(() => {
  Navigation.setRoot({
    root: {
      stack: {
        children: [
          {
            component: {
              name: 'Screen1',
            },
          },
        ],
      },
    },
  });
});

Navigation.showModal({
            component: {
              name: 'Detail',
              options: {
                modalPresentationStyle: 'fullScreen',
                animations: {
                  showModal: {
                    alpha: {
                      from: 0,
                      to: 1,
                      duration: 500,
                    },
                    sharedElementTransitions: [
                      {
                        fromId: `image.from`,
                        toId: `image.to`,
                        duration: 500,
                        interpolation: {type: 'spring', ...SPRING_CONFIG},
                      },
                    ],
                  },
                  dismissModal: {
                    alpha: {
                      from: 1,
                      to: 0,
                      duration: 500,
                    },
                    sharedElementTransitions: [
                      {
                        toId: `image.from`,
                        fromId: `image.to`,
                        duration: 500,
                        interpolation: {type: 'spring', ...SPRING_CONFIG},
                      },
                    ],
                  },
                },
              },
            },
          });

Maybe I've made mistakes with the wrapper logic. Thank you

Pietro-Putelli avatar Apr 02 '22 13:04 Pietro-Putelli

@Pietro-Putelli I had the same problem, I discovered that by passing initialWindowMetrics to SafeAreaProvider the problem disappear, I guess that if you don't the component will renderer nothing during the initial calculation

fdecampredon avatar May 17 '22 15:05 fdecampredon