For apps with push notifications linking to screens inside the app, currently we need to handle them separately (e.g. [instructions for firebase](https://rnfirebase.io/messaging/notifications#handling-interaction), [instructions for expo notifications](https://docs.expo.io/push-notifications/receiving-notifications/)). But if we add a link in the notification to use for deep linking, we can instead reuse the same deep linking logic instead.
This commit adds the `getInitialURL` and `subscribe` options which internally used `Linking` API to allow more advanced implementations by combining it with other sources such as push notifications.
Example usage with Firebase notifications could look like this:
```js
const linking = {
prefixes: ['myapp://', 'https://myapp.com'],
async getInitialURL() {
// Check if app was opened from a deep link
const url = await Linking.getInitialURL();
if (url != null) {
return url;
}
// Check if there is an initial firebase notification
const message = await messaging().getInitialNotification();
// Get the `url` property from the notification which corresponds to a screen
// This property needs to be set on the notification payload when sending it
return message?.notification.url;
},
subscribe(listener) {
const onReceiveURL = ({ url }: { url: string }) => listener(url);
// Listen to incoming links from deep linking
Linking.addEventListener('url', onReceiveURL);
// Listen to firebase push notifications
const unsubscribeNotification = messaging().onNotificationOpenedApp(
(message) => {
const url = message.notification.url;
if (url) {
// If the notification has a `url` property, use it for linking
listener(url);
}
}
);
return () => {
// Clean up the event listeners
Linking.removeEventListener('url', onReceiveURL);
unsubscribeNotification();
};
},
config,
};
```
Currently when we receive a deep link after the app is rendered, it always results in a `navigate` action. While it's ok with the default configuration, it may result in incorrect behaviour when a custom `getStateForPath` function is provided and it returns a routes array different than the initial route and new route pair.
The commit changes 2 things:
1. Add ability to reset state via params of `navigate` by specifying a `state` property instead of `screen`
2. Update `getStateForAction` to return an action for reset when necessary according to the deep linking configuration
Closes#8952
Changes done here will work properly with https://github.com/software-mansion/react-native-screens/pull/624 merged and released. The documentation of `screensEnabled` and `activeLimit` props should also be added. It also enabled `Screens` in iOS stack-navigator by default.
New things:
- `detachInactiveScreens` - prop for navigators with `react-native-screens` integration that can be set by user. It controls if the `react-native-screens` are used by the navigator.
- `detachPreviousScreen` - option that tells to keep the previous screen active. It can be set by user, defaults to `true` for normal mode and `false` for the last screen for mode = “modal”.
Co-authored-by: Satyajit Sahoo <satyajit.happy@gmail.com>
The commit improves the navigation state object to have more specific types.
e.g. The `routeNames` array will now have proper type instead of `string[]`
This feature adds the sceneContainerStyle prop to the bottom-tabs navigator, to allow setting styles on the container's view. It's already implemented in the material-top-tabs and drawer navigators, I've simply ported it into the bottom-tabs navigator.
It also fixes this issue:
https://github.com/react-navigation/react-navigation/issues/8076
Co-authored-by: Satyajit Sahoo <satyajit.happy@gmail.com>
Motivation
--
Previously when using `headerMode="float"` with headerTransparent set to true, we cant press header buttons in Android. This PR fixes this. (resolves#8731 )
Been doing some debugging and found out that this is caused by `HeaderContainer` being set as `absolute`. Initially it didn't have width & height in Android when it's set to default, that's why we can't access the children.
So, the solution in this PR is to define the height by using headerHeight. But, since we can't access headerHeight from header, Im using local state for keeping up with the headerHeight. Or should I move the HeaderHeight provider out of StackContainer? I'm not sure, since I think it was intended to be kept inside the StackContainer
Test Plan
--
With this config, now the header button can be clicked. Tested in both platform
```typescript
<Stack.Navigator
headerMode="float"
screenOptions={{
headerTransparent: true
}}
>
<Stack.Screen
name="Home Screen"
component={Home}
/>
<Stack.Screen
name="Details Screen"
component={Details}
/>
</Stack.Navigator>
```
Android:
-

iOS:
--
<img width="300" src="https://user-images.githubusercontent.com/24470609/94682743-9a3e3580-034f-11eb-8e90-2d31748bde5c.gif" />
Prefixes should be more flexible for situations like wild card subdomain. On android and IOS we can define wild cards by * but react-navigation does not work, In this PR I added support for RegExp Prefixes.
For Example
```js
{
prefixes: [
/^[^.s]+.example.com/g
],
}
```
I tested this work well.
Closes#8941
Co-authored-by: Satyajit Sahoo <satyajit.happy@gmail.com>
Referenced from 4b26429c49/src/components/MaterialCommunityIcon.tsx (L14)https://callstack.github.io/react-native-paper/getting-started.html
> To get smaller bundle size by excluding modules you don't use, you can use our optional babel plugin. The plugin automatically rewrites the import statements so that only the modules you use are imported instead of the whole library. Add react-native-paper/babel to the plugins section in your babel.config.js for production environment. It should look like this:
> ```
> module.exports = {
> presets: ['module:metro-react-native-babel-preset'],
> env: {
> production: {
> plugins: ['react-native-paper/babel'],
> },
> },
> };
> ```
> If you created your project using Expo, it'll look something like this:
> ```
> module.exports = function(api) {
> api.cache(true);
> return {
> presets: ['babel-preset-expo'],
> env: {
> production: {
> plugins: ['react-native-paper/babel'],
> },
> },
> };
> };
> ```
Closes#8821
Currently, stack router adds a duplicate route when pushing a new route with a key that already exists. This is a buggy behaviour since keys need to be unique in the stack.
This commit fixes the behaviour to bring the existing route with the same key to focus (and merge new params if any) instead of adding a duplicate route.
This adds a compact height mode for iOS devices that are in a compact vertical class (phones in landscape). This is similar to the size change that happens to the header when in landscape mode. Finding a size reference was challenging since most apps lock phones to portrait, but [this answer](https://stackoverflow.com/a/25550871) on Stack Overflow states that it should be 32 pts.
I asked yesterday in the Discord chat if there would be interest in this and some other enhancements here, but no on replied, so I thought I would go ahead and open this to at least start a discussion.
What just randomly reading, but I think there's a typo
```
['ab', 'aba'].sort((a, b) => {
if (a.startsWith(b)) {
return -1;
}
if (b.startsWith(a)) {
return 1;
}
});
(2) ["aba", "ab"]
['ab', 'a'].sort((a, b) => {
if (a.startsWith(b)) {
return -1;
}
if (b.startsWith(a)) {
return 1;
}
});
(2) ["ab", "a"]
```