Files
react-native/Libraries/Linking/Linking.js
T
Pieter De Baets 3921f05f59 Do not use InteractionManager to wait for Activity (#35289)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/35289

This was originally added in D15258046 (https://github.com/facebook/react-native/commit/c802d0b757912358d703d4d8a114073377a905b9) but seems to be the wrong solution to the problem from my perspective. InteractionManager does not provide timing information on the activity being available, but ReactContext's LifecycleEventListener does.

This should also address some of the issues raised in https://github.com/facebook/react-native/issues/25675

Changelog: [Android][Fixed] Linking.getInitialUrl should not wait for InteractionManager

Reviewed By: mdvacca

Differential Revision: D41157646

fbshipit-source-id: 6e23969212570204a7e076b6d4d9db004412da09
2022-11-14 03:38:52 -08:00

134 lines
3.6 KiB
JavaScript

/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @format
* @flow strict-local
*/
import type {EventSubscription} from '../vendor/emitter/EventEmitter';
import NativeEventEmitter from '../EventEmitter/NativeEventEmitter';
import Platform from '../Utilities/Platform';
import NativeIntentAndroid from './NativeIntentAndroid';
import NativeLinkingManager from './NativeLinkingManager';
import invariant from 'invariant';
import nullthrows from 'nullthrows';
type LinkingEventDefinitions = {
url: [{url: string}],
};
/**
* `Linking` gives you a general interface to interact with both incoming
* and outgoing app links.
*
* See https://reactnative.dev/docs/linking
*/
class Linking extends NativeEventEmitter<LinkingEventDefinitions> {
constructor() {
super(Platform.OS === 'ios' ? nullthrows(NativeLinkingManager) : undefined);
}
/**
* Add a handler to Linking changes by listening to the `url` event type
* and providing the handler
*
* See https://reactnative.dev/docs/linking#addeventlistener
*/
addEventListener<K: $Keys<LinkingEventDefinitions>>(
eventType: K,
listener: (...$ElementType<LinkingEventDefinitions, K>) => mixed,
context: $FlowFixMe,
): EventSubscription {
return this.addListener(eventType, listener);
}
/**
* Try to open the given `url` with any of the installed apps.
*
* See https://reactnative.dev/docs/linking#openurl
*/
openURL(url: string): Promise<void> {
this._validateURL(url);
if (Platform.OS === 'android') {
return nullthrows(NativeIntentAndroid).openURL(url);
} else {
return nullthrows(NativeLinkingManager).openURL(url);
}
}
/**
* Determine whether or not an installed app can handle a given URL.
*
* See https://reactnative.dev/docs/linking#canopenurl
*/
canOpenURL(url: string): Promise<boolean> {
this._validateURL(url);
if (Platform.OS === 'android') {
return nullthrows(NativeIntentAndroid).canOpenURL(url);
} else {
return nullthrows(NativeLinkingManager).canOpenURL(url);
}
}
/**
* Open app settings.
*
* See https://reactnative.dev/docs/linking#opensettings
*/
openSettings(): Promise<void> {
if (Platform.OS === 'android') {
return nullthrows(NativeIntentAndroid).openSettings();
} else {
return nullthrows(NativeLinkingManager).openSettings();
}
}
/**
* If the app launch was triggered by an app link,
* it will give the link url, otherwise it will give `null`
*
* See https://reactnative.dev/docs/linking#getinitialurl
*/
getInitialURL(): Promise<?string> {
return Platform.OS === 'android'
? nullthrows(NativeIntentAndroid).getInitialURL()
: nullthrows(NativeLinkingManager).getInitialURL();
}
/*
* Launch an Android intent with extras (optional)
*
* @platform android
*
* See https://reactnative.dev/docs/linking#sendintent
*/
sendIntent(
action: string,
extras?: Array<{
key: string,
value: string | number | boolean,
...
}>,
): Promise<void> {
if (Platform.OS === 'android') {
return nullthrows(NativeIntentAndroid).sendIntent(action, extras);
} else {
return new Promise((resolve, reject) => reject(new Error('Unsupported')));
}
}
_validateURL(url: string): void {
invariant(
typeof url === 'string',
'Invalid URL: should be a string. Was: ' + url,
);
invariant(url, 'Invalid URL: cannot be empty');
}
}
module.exports = (new Linking(): Linking);