RNTester: add the ability to open a specific example from incoming URL (#41642)

Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/41642

This allows opening an example within RNTester without tapping the module card. If the app receives an openURL request with the format `rntester://example/<key>`, open that example (if exists) directly. Such URL request may come from various sources (e.g. custom test run, etc).

Changelog: [Internal]

Reviewed By: christophpurrer

Differential Revision: D51543385

fbshipit-source-id: f9a01963cefb4602b629da0b01be6e334c28a912
This commit is contained in:
Kevin Gozali
2023-11-24 11:37:37 -08:00
committed by Facebook GitHub Bot
parent 67c852e82f
commit 0363485069
2 changed files with 55 additions and 1 deletions
+46 -1
View File
@@ -26,7 +26,13 @@ import {
initialNavigationState,
} from './utils/testerStateUtils';
import * as React from 'react';
import {BackHandler, StyleSheet, View, useColorScheme} from 'react-native';
import {
BackHandler,
Linking,
StyleSheet,
View,
useColorScheme,
} from 'react-native';
// RNTester App currently uses in memory storage for storing navigation state
@@ -113,6 +119,45 @@ const RNTesterApp = ({
[dispatch],
);
// Setup Linking event subscription
const handleOpenUrlRequest = React.useCallback(
({url}: {url: string, ...}) => {
// Supported URL pattern(s):
// * rntester://example/<key>
const match = /^rntester:\/\/example\/(.+)$/.exec(url);
if (!match) {
console.warn(
`handleOpenUrlRequest: Received unsupported URL: '${url}'`,
);
return;
}
const key = match[1];
const exampleModule = RNTesterList.Modules[key];
if (exampleModule == null) {
console.warn(
`handleOpenUrlRequest: Unable to find requested module with key: '${key}'`,
);
return;
}
console.log(`handleOpenUrlRequest: Opening example '${key}'`);
dispatch({
type: RNTesterNavigationActionsType.EXAMPLE_OPEN_URL_REQUEST,
data: {
key,
title: exampleModule.title || key,
},
});
},
[dispatch],
);
React.useEffect(() => {
const subscription = Linking.addEventListener('url', handleOpenUrlRequest);
return () => subscription.remove();
}, [handleOpenUrlRequest]);
const theme = colorScheme === 'dark' ? themes.dark : themes.light;
if (examplesList === null) {
@@ -18,6 +18,7 @@ export const RNTesterNavigationActionsType = {
BACK_BUTTON_PRESS: 'BACK_BUTTON_PRESS',
MODULE_CARD_PRESS: 'MODULE_CARD_PRESS',
EXAMPLE_CARD_PRESS: 'EXAMPLE_CARD_PRESS',
EXAMPLE_OPEN_URL_REQUEST: 'EXAMPLE_OPEN_URL_REQUEST',
};
const getUpdatedRecentlyUsed = ({
@@ -100,6 +101,14 @@ export const RNTesterNavigationReducer = (
state.activeModuleExampleKey != null ? state.activeModuleTitle : null,
};
case RNTesterNavigationActionsType.EXAMPLE_OPEN_URL_REQUEST:
return {
...state,
activeModuleKey: key,
activeModuleTitle: title,
activeModuleExampleKey: null,
};
default:
throw new Error(`Invalid action type ${action.type}`);
}