mirror of
https://github.com/expo/config-plugins.git
synced 2026-11-13 20:28:07 -10:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e57c2a75a2 | ||
|
|
92776140fe |
No files matched your search
@@ -42,7 +42,6 @@ body:
|
||||
- '@config-plugins/react-native-google-cast'
|
||||
- '@config-plugins/react-native-pdf'
|
||||
- '@config-plugins/react-native-quick-actions'
|
||||
- '@config-plugins/react-native-siri-shortcut'
|
||||
- '@config-plugins/react-native-webrtc'
|
||||
validations:
|
||||
required: true
|
||||
|
||||
@@ -39,9 +39,6 @@ contact_links:
|
||||
- about: A react-native interface for Touch 3D home screen quick actions
|
||||
name: 📦 react-native-quick-actions issues
|
||||
url: https://github.com/jordanbyron/react-native-quick-actions/issues
|
||||
- about: A React Native library that enables you to use iOS 12+ Siri Shortcuts.
|
||||
name: 📦 react-native-siri-shortcut issues
|
||||
url: https://github.com/Gustash/react-native-siri-shortcut/issues
|
||||
- about: WebRTC for React Native
|
||||
name: 📦 react-native-webrtc issues
|
||||
url: https://github.com/react-native-webrtc/react-native-webrtc/issues
|
||||
@@ -83,12 +83,6 @@ updates:
|
||||
interval: daily
|
||||
time: '09:00'
|
||||
timezone: America/Los_Angeles
|
||||
- package-ecosystem: npm
|
||||
directory: packages/react-native-siri-shortcut
|
||||
schedule:
|
||||
interval: daily
|
||||
time: '09:00'
|
||||
timezone: America/Los_Angeles
|
||||
- package-ecosystem: npm
|
||||
directory: packages/react-native-webrtc
|
||||
schedule:
|
||||
|
||||
@@ -41,7 +41,6 @@ jobs:
|
||||
react-native-ble-plx,
|
||||
react-native-blob-util,
|
||||
react-native-branch,
|
||||
react-native-siri-shortcut,
|
||||
react-native-google-cast,
|
||||
react-native-pdf,
|
||||
# react-native-quick-actions,
|
||||
|
||||
@@ -6,57 +6,6 @@
|
||||
- All packages here are community maintained. Feel free to improve docs, packages, tests, etc.
|
||||
- We maintain a 1-1 mapping of **native packages** ⇔ `@config-plugins/*`. This means there should be no general utility packages here -- those are better suited for a different repo / NPM namespace.
|
||||
|
||||
## Awesome
|
||||
|
||||
Here is a list of known packages that have a built-in Config Plugin.
|
||||
|
||||
> Not all packages need a config plugin, packages that don't appear here might still work with managed EAS.
|
||||
|
||||
- [React Native Firebase](https://rnfirebase.io/) (`@react-native-firebase/perf`, `@react-native-firebase/app`)
|
||||
- [react-native-nfc-manager](https://github.com/revtel/react-native-nfc-manager)
|
||||
- [react-native-health](https://github.com/agencyenterprise/react-native-health)
|
||||
- [@react-native-mapbox-gl/maps](https://github.com/rnmapbox/maps)
|
||||
- [@logrocket/react-native](https://www.npmjs.com/package/@logrocket/react-native)
|
||||
- [sentry-expo](https://www.npmjs.com/package/sentry-expo)
|
||||
- [@leanplum/react-native-sdk](https://github.com/Leanplum/Leanplum-ReactNative-SDK#readme)
|
||||
- [react-native-fbsdk-next](https://www.npmjs.com/package/react-native-fbsdk-next)
|
||||
- [@stripe/stripe-react-native](https://www.npmjs.com/package/@stripe/stripe-react-native)
|
||||
- [@react-native-voice/voice](https://www.npmjs.com/package/@react-native-voice/voice)
|
||||
- [react-native-imglysdk](https://www.npmjs.com/package/react-native-imglysdk)
|
||||
- [@viro-community/react-viro](https://github.com/virocommunity/viro) -- [Guide](https://viro-community.readme.io/docs/integrating-with-expo)
|
||||
- [react-native-msal](https://www.npmjs.com/package/react-native-msal)
|
||||
- [react-native-spotlight-search](https://www.npmjs.com/package/react-native-spotlight-search)
|
||||
- [newrelic-react-native-agent](https://www.npmjs.com/package/newrelic-react-native-agent)
|
||||
- [react-native-videoeditorsdk](https://www.npmjs.com/package/react-native-videoeditorsdk)
|
||||
- [notifee](https://notifee.app/)
|
||||
- [App Clips](https://github.com/bndkt/react-native-app-clip/)
|
||||
- [iOS Safari Extensions](https://github.com/andrew-levy/react-native-safari-extension/)
|
||||
|
||||
### Complementary
|
||||
|
||||
More out-of-tree plugins which can be used to configure more packages.
|
||||
|
||||
- [onesignal-expo-plugin](https://github.com/OneSignal/onesignal-expo-plugin) (for use with `react-native-onesignal`)
|
||||
- [@lyrahealth-inc/react-native-orientation-plugin](@lyrahealth-inc/react-native-orientation-plugin) (for use with `react-native-orientation-plugin`)
|
||||
- [airship-expo-plugin](https://www.npmjs.com/package/airship-expo-plugin) (for use with `urbanairship-react-native`)
|
||||
- [config-plugin-react-native-intercom](https://www.npmjs.com/package/config-plugin-react-native-intercom) (for use with `intercom-react-native`)
|
||||
- [@allboatsrise/expo-marketingcloudsdk](https://www.npmjs.com/package/@allboatsrise/expo-marketingcloudsdk) (for use with `react-native-marketingcloudsdk`)
|
||||
- [@ouvio/react-native-background-location-plugin](https://www.npmjs.com/package/@ouvio/react-native-background-location-plugin) (for use with `react-native-background-location-plugin`)
|
||||
- [expo-community-flipper](https://www.npmjs.com/package/expo-community-flipper) (for use with Flipper)
|
||||
|
||||
### No Plugin Required
|
||||
|
||||
Just install and rebuild! If a package doesn't require any futher setup then it most likely doesn't need an Expo config plugin. Most packages work without a config plugin (including packages not listed below):
|
||||
|
||||
- [react-native-share](https://github.com/react-native-share/react-native-share)
|
||||
- [@react-native-menu/menu](https://github.com/react-native-menu/menu)
|
||||
- [react-native-blurhash](https://github.com/mrousavy/react-native-blurhash)
|
||||
- [react-native-app-shortcuts](https://github.com/lokyoung/react-native-app-shortcuts)
|
||||
- [react-native-multiple-image-picker](https://github.com/baronha/react-native-multiple-image-picker)
|
||||
- [`@shopify/flash-list`](https://github.com/Shopify/flash-list)
|
||||
|
||||
> Feel free to [open a PR](https://github.com/expo/config-plugins/edit/main/README.md) with missing packages.
|
||||
|
||||
## Contributing!
|
||||
|
||||
See the [contributing guide](/CONTRIBUTING.md).
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"expo": {
|
||||
"icon": "https://icogen.vercel.app/api/icon?icon=1f334",
|
||||
"plugins": [
|
||||
"@config-plugins/airbridge-react-native-sdk"
|
||||
]
|
||||
}
|
||||
}
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
+3
-3
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"name": "@config-plugins-app/react-native-siri-shortcut",
|
||||
"name": "@config-plugins-app/airbridge-react-native-sdk",
|
||||
"main": "./index.js",
|
||||
"version": "1.0.0",
|
||||
"scripts": {
|
||||
@@ -8,12 +8,12 @@
|
||||
"android": "expo run:android"
|
||||
},
|
||||
"dependencies": {
|
||||
"@config-plugins/react-native-siri-shortcut": "*",
|
||||
"@config-plugins/airbridge-react-native-sdk": "*",
|
||||
"expo": "^45.0.0",
|
||||
"expo-splash-screen": "~0.15.1",
|
||||
"react": "17.0.2",
|
||||
"react-native": "0.68.2",
|
||||
"react-native-siri-shortcut": "^3.1.0",
|
||||
"airbridge-react-native-sdk": "^1.4.5",
|
||||
"expo-status-bar": "~1.3.0",
|
||||
"react-dom": "17.0.2",
|
||||
"react-native-web": "0.17.7"
|
||||
@@ -0,0 +1,10 @@
|
||||
import React from "react";
|
||||
import { Text, View } from "react-native";
|
||||
|
||||
export default function App() {
|
||||
return (
|
||||
<View style={{ flex: 1, justifyContent: "center", alignItems: "center" }}>
|
||||
<Text>airbridge-react-native-sdk</Text>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
{
|
||||
"expo": {
|
||||
"icon": "https://icogen.vercel.app/api/icon",
|
||||
"plugins": [
|
||||
[
|
||||
"@config-plugins/react-native-siri-shortcut",
|
||||
[
|
||||
"com.example.InitiateWorkout",
|
||||
"com.example.FinishWorkout"
|
||||
]
|
||||
]
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -1,264 +0,0 @@
|
||||
|
||||
import React, { Component } from 'react';
|
||||
import {
|
||||
StyleSheet,
|
||||
Text,
|
||||
ScrollView,
|
||||
Button,
|
||||
SafeAreaView,
|
||||
View,
|
||||
EmitterSubscription,
|
||||
} from 'react-native';
|
||||
import {
|
||||
ShortcutOptions,
|
||||
ShortcutData,
|
||||
ShortcutInfo,
|
||||
donateShortcut,
|
||||
suggestShortcuts,
|
||||
clearAllShortcuts,
|
||||
clearShortcutsWithIdentifiers,
|
||||
presentShortcut,
|
||||
getShortcuts,
|
||||
addShortcutListener,
|
||||
getInitialShortcut,
|
||||
AddToSiriButton,
|
||||
SiriButtonStyles,
|
||||
} from 'react-native-siri-shortcut';
|
||||
|
||||
const opts1: ShortcutOptions = {
|
||||
activityType: 'com.github.gustash.SiriShortcutsModuleExample.sayHello',
|
||||
title: 'Say Hi',
|
||||
userInfo: {
|
||||
foo: 1,
|
||||
bar: 'baz',
|
||||
baz: 34.5,
|
||||
},
|
||||
requiredUserInfoKeys: ['foo', 'bar', 'baz'],
|
||||
keywords: ['kek', 'foo', 'bar'],
|
||||
persistentIdentifier:
|
||||
'com.github.gustash.SiriShortcutsModuleExample.sayHello',
|
||||
isEligibleForSearch: true,
|
||||
isEligibleForPrediction: true,
|
||||
suggestedInvocationPhrase: 'Say something',
|
||||
needsSave: true,
|
||||
};
|
||||
|
||||
const opts2: ShortcutOptions = {
|
||||
activityType: 'com.github.gustash.SiriShortcutsModuleExample.somethingElse',
|
||||
title: 'Something Else',
|
||||
persistentIdentifier: 'some.persistent.identifier',
|
||||
isEligibleForSearch: true,
|
||||
isEligibleForPrediction: true,
|
||||
suggestedInvocationPhrase: "What's up?",
|
||||
description: 'Just a random description',
|
||||
};
|
||||
type State = {
|
||||
shortcutInfo: any | null,
|
||||
shortcutActivityType: string | null,
|
||||
addToSiriStyle: 0 | 1 | 2 | 3 | 4 | 5,
|
||||
shortcuts: Array<ShortcutData>,
|
||||
};
|
||||
|
||||
|
||||
|
||||
export default class App extends Component<void, State> {
|
||||
listener: EmitterSubscription | null = null;
|
||||
|
||||
state: State = {
|
||||
shortcutInfo: null,
|
||||
shortcutActivityType: null,
|
||||
addToSiriStyle: SiriButtonStyles.blackOutline,
|
||||
shortcuts: [],
|
||||
};
|
||||
|
||||
componentDidMount() {
|
||||
this.handleInitialShortcut();
|
||||
this.listener = addShortcutListener(this.handleSiriShortcut.bind(this));
|
||||
|
||||
// This will suggest these two shortcuts so that they appear
|
||||
// in Settings > Siri & Search, even if they are not yet
|
||||
// donated. Suitable for shortcuts that you expect the user
|
||||
// may want to use. (https://developer.apple.com/documentation/sirikit/shortcut_management/suggesting_shortcuts_to_users)
|
||||
suggestShortcuts([opts1, opts2]);
|
||||
|
||||
this.updateShortcutList();
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
if (this.listener) {
|
||||
this.listener.remove();
|
||||
}
|
||||
}
|
||||
|
||||
async handleInitialShortcut() {
|
||||
const initialShortcut = await getInitialShortcut();
|
||||
|
||||
if (!initialShortcut) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.handleSiriShortcut(initialShortcut);
|
||||
}
|
||||
|
||||
handleSiriShortcut({ userInfo, activityType }: ShortcutInfo) {
|
||||
this.setState({
|
||||
shortcutInfo: userInfo,
|
||||
shortcutActivityType: activityType,
|
||||
});
|
||||
}
|
||||
|
||||
setupShortcut1() {
|
||||
donateShortcut(opts1);
|
||||
}
|
||||
|
||||
setupShortcut2() {
|
||||
donateShortcut(opts2);
|
||||
}
|
||||
|
||||
async clearShortcut1() {
|
||||
try {
|
||||
await clearShortcutsWithIdentifiers([
|
||||
'com.github.gustash.SiriShortcutsModuleExample.sayHello',
|
||||
]);
|
||||
alert('Cleared Shortcut 1');
|
||||
} catch (e) {
|
||||
alert("You're not running iOS 12!");
|
||||
}
|
||||
}
|
||||
|
||||
async clearShortcut2() {
|
||||
try {
|
||||
await clearShortcutsWithIdentifiers(['some.persistent.identifier']);
|
||||
alert('Cleared Shortcut 2');
|
||||
} catch (e) {
|
||||
alert("You're not running iOS 12!");
|
||||
}
|
||||
}
|
||||
|
||||
async updateShortcutList() {
|
||||
try {
|
||||
const shortcuts = await getShortcuts();
|
||||
|
||||
this.setState({
|
||||
shortcuts,
|
||||
});
|
||||
} catch (e) {
|
||||
alert("You're not running iOS 12!");
|
||||
}
|
||||
}
|
||||
|
||||
async clearBothShortcuts() {
|
||||
try {
|
||||
await clearShortcutsWithIdentifiers([
|
||||
'com.github.gustash.SiriShortcutsModuleExample.sayHello',
|
||||
'some.persistent.identifier',
|
||||
]);
|
||||
alert('Cleared Both Shortcuts');
|
||||
} catch (e) {
|
||||
alert("You're not running iOS 12!");
|
||||
}
|
||||
}
|
||||
|
||||
async clearShortcuts() {
|
||||
try {
|
||||
await clearAllShortcuts();
|
||||
alert('Deleted all the shortcuts');
|
||||
} catch (e) {
|
||||
alert("You're not running iOS 12!");
|
||||
}
|
||||
}
|
||||
|
||||
swapSiriButtonTheme() {
|
||||
const { addToSiriStyle } = this.state;
|
||||
|
||||
const styles = Object.keys(SiriButtonStyles).map(
|
||||
key => SiriButtonStyles[key],
|
||||
);
|
||||
const index = styles.findIndex(style => style === addToSiriStyle);
|
||||
if (index === styles.length - 1) this.setState({ addToSiriStyle: styles[0] });
|
||||
else this.setState({ addToSiriStyle: styles[index + 1] });
|
||||
}
|
||||
|
||||
render() {
|
||||
const { shortcutInfo, shortcutActivityType, addToSiriStyle, shortcuts } =
|
||||
this.state;
|
||||
|
||||
return (
|
||||
<SafeAreaView style={styles.container}>
|
||||
<ScrollView
|
||||
style={styles.container}
|
||||
contentContainerStyle={styles.contentContainer}>
|
||||
<Text>Shortcut Activity Type: {shortcutActivityType || 'None'}</Text>
|
||||
<Text>
|
||||
Shortcut Info:{' '}
|
||||
{shortcutInfo ? JSON.stringify(shortcutInfo) : 'No shortcut data.'}
|
||||
</Text>
|
||||
<Button
|
||||
title="Create Shortcut 1"
|
||||
onPress={this.setupShortcut1.bind(this)}
|
||||
/>
|
||||
<Button
|
||||
title="Create Shortcut 2"
|
||||
onPress={this.setupShortcut2.bind(this)}
|
||||
/>
|
||||
<Button
|
||||
title="Clear Shortcut 1"
|
||||
onPress={this.clearShortcut1.bind(this)}
|
||||
/>
|
||||
<Button
|
||||
title="Clear Shortcut 2"
|
||||
onPress={this.clearShortcut2.bind(this)}
|
||||
/>
|
||||
<Button
|
||||
title="Clear Both Shortcuts"
|
||||
onPress={this.clearBothShortcuts.bind(this)}
|
||||
/>
|
||||
<Button
|
||||
title="Delete All Shortcuts"
|
||||
onPress={this.clearShortcuts.bind(this)}
|
||||
/>
|
||||
<Button
|
||||
title="Update list of shortcuts"
|
||||
onPress={this.updateShortcutList.bind(this)}
|
||||
/>
|
||||
<AddToSiriButton
|
||||
buttonStyle={addToSiriStyle}
|
||||
onPress={() => {
|
||||
presentShortcut(opts1, ({ status }) => {
|
||||
console.log(`I was ${status}`);
|
||||
});
|
||||
}}
|
||||
shortcut={opts1}
|
||||
/>
|
||||
<Button
|
||||
title="Swap Siri Button Theme"
|
||||
onPress={this.swapSiriButtonTheme.bind(this)}
|
||||
/>
|
||||
{shortcuts.length ? (
|
||||
shortcuts.map(({ identifier, phrase, options }, i) => (
|
||||
<View key={identifier}>
|
||||
<Text>Shortcut {i + 1}:</Text>
|
||||
<Text>Identifier - {identifier}</Text>
|
||||
<Text>Phrase - {phrase}</Text>
|
||||
<Text>Options - {JSON.stringify(options)}</Text>
|
||||
</View>
|
||||
))
|
||||
) : (
|
||||
<Text>No Shortcuts yet</Text>
|
||||
)}
|
||||
</ScrollView>
|
||||
</SafeAreaView>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
backgroundColor: '#F5FCFF',
|
||||
},
|
||||
contentContainer: {
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
},
|
||||
});
|
||||
@@ -1,6 +0,0 @@
|
||||
import React from 'react';
|
||||
import { View, Text } from 'react-native';
|
||||
|
||||
export default function App() {
|
||||
return (<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}><Text>No-op on this platform</Text></View>)
|
||||
}
|
||||
File renamed without changes.
+11
-10
@@ -1,6 +1,6 @@
|
||||
# @config-plugins/react-native-siri-shortcut
|
||||
# @config-plugins/airbridge-react-native-sdk
|
||||
|
||||
Expo Config Plugin to auto configure [`react-native-siri-shortcut`](https://www.npmjs.com/package/react-native-siri-shortcut) when the native code is generated (`expo prebuild`).
|
||||
Expo Config Plugin to auto configure [`airbridge-react-native-sdk`](https://www.npmjs.com/package/airbridge-react-native-sdk) when the native code is generated (`expo prebuild`).
|
||||
|
||||
## Expo installation
|
||||
|
||||
@@ -11,7 +11,7 @@ This package cannot be used in the "Expo Go" app because [it requires custom nat
|
||||
- First install the package with yarn, npm, or [`expo install`](https://docs.expo.io/workflow/expo-cli/#expo-install).
|
||||
|
||||
```sh
|
||||
expo install react-native-siri-shortcut @config-plugins/react-native-siri-shortcut
|
||||
expo install airbridge-react-native-sdk @config-plugins/airbridge-react-native-sdk
|
||||
```
|
||||
|
||||
After installing this npm package, add the [config plugin](https://docs.expo.io/guides/config-plugins/) to the [`plugins`](https://docs.expo.io/versions/latest/config/app/#plugins) array of your `app.json` or `app.config.js`:
|
||||
@@ -19,7 +19,7 @@ After installing this npm package, add the [config plugin](https://docs.expo.io/
|
||||
```json
|
||||
{
|
||||
"expo": {
|
||||
"plugins": ["@config-plugins/react-native-siri-shortcut"]
|
||||
"plugins": ["@config-plugins/airbridge-react-native-sdk"]
|
||||
}
|
||||
}
|
||||
```
|
||||
@@ -28,7 +28,9 @@ Next, rebuild your app as described in the ["Adding custom native code"](https:/
|
||||
|
||||
## API
|
||||
|
||||
When working with Siri Shorcuts, you need to defined their identifiers on the Xcode project. To achieve the same result using this plugin, just pass an array of strings with the identifiers of your shortcuts, and they will be added automatically during the build cycle:
|
||||
The plugin provides props for extra customization. Every time you change the props or plugins, you'll need to rebuild (and `prebuild`) the native app. If no extra properties are added, defaults will be used.
|
||||
|
||||
- `foobar` (_boolean_): Does XYZ. Default `false`.
|
||||
|
||||
#### Example
|
||||
|
||||
@@ -37,11 +39,10 @@ When working with Siri Shorcuts, you need to defined their identifiers on the Xc
|
||||
"expo": {
|
||||
"plugins": [
|
||||
[
|
||||
"@config-plugins/react-native-siri-shortcut",
|
||||
[
|
||||
"com.example.InitiateWorkout",
|
||||
"com.example.FinishWorkout",
|
||||
],
|
||||
"@config-plugins/airbridge-react-native-sdk",
|
||||
{
|
||||
// props ...
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
# Gradle files
|
||||
.gradle/
|
||||
build/
|
||||
@@ -0,0 +1,67 @@
|
||||
apply plugin: 'com.android.library'
|
||||
apply plugin: 'kotlin-android'
|
||||
|
||||
group = 'host.exp.exponent'
|
||||
version = '2.0.0'
|
||||
|
||||
buildscript {
|
||||
def expoModulesCorePlugin = new File(project(":expo-modules-core").projectDir.absolutePath, "ExpoModulesCorePlugin.gradle")
|
||||
if (expoModulesCorePlugin.exists()) {
|
||||
apply from: expoModulesCorePlugin
|
||||
applyKotlinExpoModulesCorePlugin()
|
||||
}
|
||||
|
||||
// Simple helper that allows the root project to override versions declared by this library.
|
||||
ext.safeExtGet = { prop, fallback ->
|
||||
rootProject.ext.has(prop) ? rootProject.ext.get(prop) : fallback
|
||||
}
|
||||
|
||||
// Ensures backward compatibility
|
||||
ext.getKotlinVersion = {
|
||||
if (ext.has("kotlinVersion")) {
|
||||
ext.kotlinVersion()
|
||||
} else {
|
||||
ext.safeExtGet("kotlinVersion", "1.6.10")
|
||||
}
|
||||
}
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:${getKotlinVersion()}")
|
||||
}
|
||||
}
|
||||
|
||||
android {
|
||||
compileSdkVersion safeExtGet("compileSdkVersion", 31)
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_11
|
||||
targetCompatibility JavaVersion.VERSION_11
|
||||
}
|
||||
|
||||
kotlinOptions {
|
||||
jvmTarget = JavaVersion.VERSION_11.majorVersion
|
||||
}
|
||||
|
||||
defaultConfig {
|
||||
minSdkVersion safeExtGet("minSdkVersion", 21)
|
||||
targetSdkVersion safeExtGet("targetSdkVersion", 31)
|
||||
versionCode 2
|
||||
versionName '2.0.0'
|
||||
}
|
||||
lintOptions {
|
||||
abortOnError false
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation project(':expo-modules-core')
|
||||
// implementation project(':react-native-branch')
|
||||
|
||||
//noinspection GradleDynamicVersion
|
||||
implementation 'com.facebook.react:react-native:+'
|
||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:${getKotlinVersion()}"
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
<manifest package="expo.modules.adapters.airbridge">
|
||||
</manifest>
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
package expo.modules.adapters.airbridge
|
||||
|
||||
import android.app.Application
|
||||
import android.content.Context
|
||||
import expo.modules.core.interfaces.ApplicationLifecycleListener
|
||||
// import io.branch.rnbranch.RNBranchModule
|
||||
|
||||
class AirbridgeApplicationLifecycleListener(context: Context?) : ApplicationLifecycleListener {
|
||||
var context = context
|
||||
|
||||
override fun onCreate(application: Application) {
|
||||
super.onCreate(application)
|
||||
// RNBranchModule.getAutoInstance(this.context)
|
||||
}
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
package expo.modules.adapters.airbridge
|
||||
|
||||
import android.content.Context
|
||||
import expo.modules.core.interfaces.ApplicationLifecycleListener
|
||||
import expo.modules.core.interfaces.Package
|
||||
import expo.modules.core.interfaces.ReactActivityLifecycleListener
|
||||
|
||||
class AirbridgePackage : Package {
|
||||
override fun createApplicationLifecycleListeners(context: Context?): List<ApplicationLifecycleListener> {
|
||||
return listOf(AirbridgeApplicationLifecycleListener(context))
|
||||
}
|
||||
override fun createReactActivityLifecycleListeners(activityContext: Context): List<ReactActivityLifecycleListener> {
|
||||
return listOf(AirbridgeReactActivityLifecycleListener(activityContext))
|
||||
}
|
||||
}
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
package expo.modules.adapters.airbridge
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import expo.modules.core.interfaces.ReactActivityLifecycleListener
|
||||
// import io.airbridge.rnbranch.RNBranchModule
|
||||
|
||||
|
||||
class AirbridgeReactActivityLifecycleListener(activityContext: Context) : ReactActivityLifecycleListener {
|
||||
override fun onCreate(activity: Activity, savedInstanceState: Bundle?) {
|
||||
// RNBranchModule.initSession(activity.getIntent().getData(), activity);
|
||||
}
|
||||
|
||||
override fun onNewIntent(intent: Intent?): Boolean {
|
||||
if (intent != null) {
|
||||
// RNBranchModule.onNewIntent(intent);
|
||||
}
|
||||
return super.onNewIntent(intent)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
module.exports = require("./build/withAirbridgeReactNativeSdk");
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"platforms": [
|
||||
"android",
|
||||
"ios"
|
||||
],
|
||||
"ios": {
|
||||
"appDelegateSubscribers": ["AirbridgeAppDelegate"]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
require 'json'
|
||||
|
||||
package = JSON.parse(File.read(File.join(__dir__, '..', 'package.json')))
|
||||
|
||||
Pod::Spec.new do |s|
|
||||
s.name = 'ExpoAdapterAirbridge'
|
||||
s.version = package['version']
|
||||
s.summary = package['description']
|
||||
s.description = package['description']
|
||||
s.license = package['license']
|
||||
s.author = package['author']
|
||||
s.homepage = package['homepage']
|
||||
s.platform = :ios, '12.0'
|
||||
s.swift_version = '5.4'
|
||||
s.source = { git: 'https://github.com/expo/config-plugins.git' }
|
||||
s.static_framework = true
|
||||
|
||||
# s.compiler_flags = %(-DRNBRANCH_VERSION=@\\"#{package['dependencies']['react-native-branch']}\\")
|
||||
|
||||
s.dependency 'ExpoModulesCore'
|
||||
s.dependency 'React-Core'
|
||||
# s.dependency 'react-native-branch'
|
||||
|
||||
# Swift/Objective-C compatibility
|
||||
s.pod_target_xcconfig = {
|
||||
'DEFINES_MODULE' => 'YES'
|
||||
}
|
||||
|
||||
if !$ExpoUseSources&.include?(package['name']) && ENV['EXPO_USE_SOURCE'].to_i == 0 && File.exist?("#{s.name}.xcframework") && Gem::Version.new(Pod::VERSION) >= Gem::Version.new('1.10.0')
|
||||
s.source_files = "#{s.name}/**/*.h"
|
||||
s.vendored_frameworks = "#{s.name}.xcframework"
|
||||
else
|
||||
s.source_files = "#{s.name}/**/*.{h,m,swift}"
|
||||
end
|
||||
end
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
import ExpoModulesCore
|
||||
import AirbridgeRN
|
||||
|
||||
public class AirbridgeAppDelegate: ExpoAppDelegateSubscriber {
|
||||
public func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
|
||||
AirbridgeRN.getInstance("YOUR_APP_TOKEN", appName:"YOUR_APP_NAME", withLaunchOptions:launchOptions)
|
||||
// RNBranch.initSession(launchOptions: launchOptions, isReferrable: true)
|
||||
return true
|
||||
}
|
||||
|
||||
// public func application(_ application: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
|
||||
// return RNBranch.application(application, open:url, options:options)
|
||||
// }
|
||||
|
||||
// public func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {
|
||||
// return RNBranch.continue(userActivity)
|
||||
// }
|
||||
}
|
||||
+19
-10
@@ -1,15 +1,25 @@
|
||||
{
|
||||
"name": "@config-plugins/react-native-siri-shortcut",
|
||||
"version": "1.0.0",
|
||||
"description": "Config plugin for react-native-siri-shortcut package",
|
||||
"main": "build/withReactNativeSiriShortcut.js",
|
||||
"types": "build/withReactNativeSiriShortcut.d.ts",
|
||||
"name": "@config-plugins/airbridge-react-native-sdk",
|
||||
"version": "0.0.0",
|
||||
"description": "Config plugin for airbridge-react-native-sdk package",
|
||||
"author": "650 Industries, Inc.",
|
||||
"license": "MIT",
|
||||
"homepage": "https://github.com/expo/config-plugins/tree/main/packages/airbridge-react-native-sdk",
|
||||
"main": "build/withAirbridgeReactNativeSdk.js",
|
||||
"types": "build/withAirbridgeReactNativeSdk.d.ts",
|
||||
"sideEffects": false,
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/expo/config-plugins.git",
|
||||
"directory": "packages/react-native-siri-shortcut"
|
||||
"directory": "packages/airbridge-react-native-sdk"
|
||||
},
|
||||
"files": [
|
||||
"android",
|
||||
"app.plugin.js",
|
||||
"build",
|
||||
"expo-module.config.json",
|
||||
"ios"
|
||||
],
|
||||
"scripts": {
|
||||
"build": "expo-module build",
|
||||
"clean": "expo-module clean",
|
||||
@@ -24,7 +34,7 @@
|
||||
"expo",
|
||||
"config-plugins",
|
||||
"prebuild",
|
||||
"react-native-siri-shortcut",
|
||||
"airbridge-react-native-sdk",
|
||||
"expo-42"
|
||||
],
|
||||
"jest": {
|
||||
@@ -35,6 +45,5 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"expo-module-scripts": "^2.0.0"
|
||||
},
|
||||
"upstreamPackage": "react-native-siri-shortcut"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
import { ConfigPlugin, createRunOncePlugin } from "@expo/config-plugins";
|
||||
|
||||
/**
|
||||
* Apply airbridge-react-native-sdk configuration for Expo SDK 42 projects.
|
||||
*/
|
||||
const withAirbridgeReactNativeSdk: ConfigPlugin<{} | void> = (config, _props = {}) => {
|
||||
// Support passing no props to the plugin.
|
||||
const props = _props || {};
|
||||
|
||||
// Return the modified config.
|
||||
return config;
|
||||
};
|
||||
|
||||
const pkg = {
|
||||
// Prevent this plugin from being run more than once.
|
||||
// This pattern enables users to safely migrate off of this
|
||||
// out-of-tree `@config-plugins/airbridge-react-native-sdk` to a future
|
||||
// upstream plugin in `airbridge-react-native-sdk`
|
||||
name: "airbridge-react-native-sdk",
|
||||
// Indicates that this plugin is dangerously linked to a module,
|
||||
// and might not work with the latest version of that module.
|
||||
version: "UNVERSIONED",
|
||||
};
|
||||
|
||||
export default createRunOncePlugin(withAirbridgeReactNativeSdk, pkg.name, pkg.version);
|
||||
File renamed without changes.
@@ -1,19 +1,3 @@
|
||||
## @config-plugins/ffmpeg-kit-react-native [2.0.0](https://github.com/expo/config-plugins/compare/@config-plugins/[email protected]...@config-plugins/[email protected]) (2022-05-30)
|
||||
|
||||
|
||||
### ⚠ BREAKING CHANGES
|
||||
|
||||
* add SDK 45 support (#79)
|
||||
|
||||
### Features
|
||||
|
||||
* add SDK 45 support ([#79](https://github.com/expo/config-plugins/issues/79)) ([96c72dd](https://github.com/expo/config-plugins/commit/96c72dda469ace2b9eafd38ba4d21f1bcd2e3cdf))
|
||||
|
||||
|
||||
### Other chores
|
||||
|
||||
* publish packages [no-ci] ([0c7b413](https://github.com/expo/config-plugins/commit/0c7b413a765e4b1ff92b9e3edc2b62077c41ce46))
|
||||
|
||||
### @config-plugins/ffmpeg-kit-react-native [1.0.3](https://github.com/expo/config-plugins/compare/@config-plugins/[email protected]...@config-plugins/[email protected]) (2022-03-22)
|
||||
|
||||
|
||||
|
||||
@@ -1,17 +1,3 @@
|
||||
### @config-plugins/ios-stickers [2.0.2](https://github.com/expo/config-plugins/compare/@config-plugins/[email protected]...@config-plugins/[email protected]) (2022-06-30)
|
||||
|
||||
|
||||
### Other chores
|
||||
|
||||
* **deps-dev:** bump memfs in /packages/ios-stickers ([#83](https://github.com/expo/config-plugins/issues/83)) ([764a047](https://github.com/expo/config-plugins/commit/764a04710bea6e66dbc6d0065812acb1591435fb))
|
||||
|
||||
### @config-plugins/ios-stickers [2.0.1](https://github.com/expo/config-plugins/compare/@config-plugins/[email protected]...@config-plugins/[email protected]) (2022-05-30)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **ios-stickers:** fix app icon generation ([#82](https://github.com/expo/config-plugins/issues/82)) ([190c489](https://github.com/expo/config-plugins/commit/190c489b764f285dbbecfa42fd7ee953fc849dcb))
|
||||
|
||||
## @config-plugins/ios-stickers [2.0.0](https://github.com/expo/config-plugins/compare/@config-plugins/[email protected]...@config-plugins/[email protected]) (2022-05-12)
|
||||
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ In your app.json `plugins` array:
|
||||
]
|
||||
```
|
||||
|
||||
- `name`: defaults to the iOS app name
|
||||
- `icon`: defaults to the iOS app icon
|
||||
- `columns`: number of stickers to render, defaults to `3`. Can be one of `2`, `3`, `4`.
|
||||
- `stickers`: local file paths or remote URLs, or `{ image: "...", name: "...", accessibilityLabel: "..." }`. Order is preserved.
|
||||
- name: defaults to the iOS app name
|
||||
- icon: defaults to the iOS app icon
|
||||
- columns: number of stickers to render, defaults to `3` iirc.
|
||||
- stickers: local file paths or remote URLs, or `{ image: "...", name: "...", accessibilityLabel: "..." }`. Order is preserved.
|
||||
@@ -1,8 +0,0 @@
|
||||
export const generateImageAsync = jest.fn(async (input: any, { src }) => {
|
||||
const fs = require("fs");
|
||||
return { source: fs.readFileSync(src) };
|
||||
});
|
||||
|
||||
export const compositeImagesAsync = jest.fn(async ({ foreground }) => {
|
||||
return foreground;
|
||||
});
|
||||
@@ -1,2 +0,0 @@
|
||||
import { fs } from 'memfs';
|
||||
module.exports = fs;
|
||||
+3
-3
@@ -8,7 +8,7 @@ const config_plugins_1 = require("@expo/config-plugins");
|
||||
const image_utils_1 = require("@expo/image-utils");
|
||||
const fs_1 = __importDefault(require("fs"));
|
||||
const path_1 = __importDefault(require("path"));
|
||||
const generateImessageIconsAsync_1 = require("./generateImessageIconsAsync");
|
||||
const withStickerIcon_1 = require("./withStickerIcon");
|
||||
const withStickerXcodeTarget_1 = require("./withStickerXcodeTarget");
|
||||
const STICKERS_ROOT_PATH = "Stickers.xcassets";
|
||||
const IMESSAGE_APP_ICON_PATH = "Stickers.xcassets/iMessage App Icon.stickersiconset";
|
||||
@@ -70,13 +70,13 @@ const withStickerAssets = (config, { stickers, icon, size }) => {
|
||||
const iMessageAppIconsPath = path_1.default.join(stickerRootPath, IMESSAGE_APP_ICON_PATH);
|
||||
// Only generate icons if an icon is defined
|
||||
const imessageIconContents = icon
|
||||
? await generateImessageIconsAsync_1.generateImessageIconsAsync(config.modRequest.projectRoot, icon, iMessageAppIconsPath)
|
||||
? await withStickerIcon_1.generateImessageIconsAsync(config.modRequest.projectRoot, icon, iMessageAppIconsPath)
|
||||
: [];
|
||||
const iMessageAppIconContentsJsonPath = path_1.default.join(iMessageAppIconsPath, "Contents.json");
|
||||
fs_1.default.mkdirSync(iMessageAppIconsPath, {
|
||||
recursive: true,
|
||||
});
|
||||
fs_1.default.writeFileSync(iMessageAppIconContentsJsonPath, JSON.stringify({ images: imessageIconContents, info: defaultInfo }, null, 2));
|
||||
fs_1.default.writeFileSync(iMessageAppIconContentsJsonPath, JSON.stringify({ info: defaultInfo, images: imessageIconContents }, null, 2));
|
||||
const stickerPackContentsPath = path_1.default.join(stickerRootPath, STICKER_PACK_PATH);
|
||||
const stickersContents = {
|
||||
info: defaultInfo,
|
||||
|
||||
Generated
Vendored
File renamed without changes.
+7
-8
@@ -59,11 +59,11 @@ const ICON_CONTENTS = [
|
||||
idiom: "ios-marketing",
|
||||
sizes: [
|
||||
{
|
||||
platform: "ios",
|
||||
size: 1024,
|
||||
scales: [1],
|
||||
},
|
||||
{
|
||||
platform: "ios",
|
||||
size: [1024, 768],
|
||||
scales: [1],
|
||||
},
|
||||
@@ -108,16 +108,15 @@ async function generateImessageIconsAsync(projectRoot, icon, iconsPath) {
|
||||
// Save a reference to the generated image so we don't create a duplicate.
|
||||
generatedIcons[filename] = true;
|
||||
}
|
||||
const imgJson = {
|
||||
filename,
|
||||
imagesJson.push({
|
||||
idiom: platform.idiom,
|
||||
scale: `${scale}x`,
|
||||
size: `${width}x${height}`,
|
||||
};
|
||||
// This order closely matches Xcode formatting.
|
||||
imagesJson.push(imgJson);
|
||||
// @ts-ignore: template types not supported in TS yet
|
||||
scale: `${scale}x`,
|
||||
filename,
|
||||
});
|
||||
if (rest.platform) {
|
||||
imgJson.platform = rest.platform;
|
||||
imagesJson[imagesJson.length - 1].platform = rest.platform;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,12 +1 @@
|
||||
const path = require("path");
|
||||
|
||||
const roots = ["__mocks__", "src"];
|
||||
|
||||
module.exports = {
|
||||
...require("expo-module-scripts/jest-preset-plugin"),
|
||||
rootDir: path.resolve(__dirname),
|
||||
displayName: require("./package").name,
|
||||
roots,
|
||||
setupFiles: ["<rootDir>/jest/setup.js"],
|
||||
clearMocks: true,
|
||||
};
|
||||
module.exports = require('expo-module-scripts/jest-preset-plugin');
|
||||
@@ -1,2 +0,0 @@
|
||||
jest.mock("@expo/image-utils");
|
||||
jest.mock("fs");
|
||||
@@ -1,13 +1,10 @@
|
||||
{
|
||||
"name": "@config-plugins/ios-stickers",
|
||||
"version": "2.0.2",
|
||||
"version": "2.0.0",
|
||||
"description": "Config plugin to auto configure iOS iMessage stickers",
|
||||
"main": "build/withStickerPack.js",
|
||||
"types": "build/withStickerPack.d.ts",
|
||||
"sideEffects": false,
|
||||
"files": [
|
||||
"build"
|
||||
],
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/expo/config-plugins.git",
|
||||
@@ -33,7 +30,6 @@
|
||||
"xcode": "^3.0.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"expo-module-scripts": "^2.0.0",
|
||||
"memfs": "^3.4.4"
|
||||
"expo-module-scripts": "^2.0.0"
|
||||
}
|
||||
}
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 80 B |
@@ -1,111 +0,0 @@
|
||||
import { generateImageAsync } from "@expo/image-utils";
|
||||
import fs from "fs";
|
||||
import { vol } from "memfs";
|
||||
import path from "path";
|
||||
|
||||
import { generateImessageIconsAsync } from "../generateImessageIconsAsync";
|
||||
|
||||
const fsReal = jest.requireActual("fs") as typeof fs;
|
||||
|
||||
describe(generateImessageIconsAsync, () => {
|
||||
it(`should generate imessage icons`, async () => {
|
||||
vol.fromJSON({}, "/");
|
||||
await fs.promises.writeFile(
|
||||
"/icon.png",
|
||||
await fsReal.promises.readFile(path.join(__dirname, "fixtures/icon.png"))
|
||||
);
|
||||
const contents = await generateImessageIconsAsync(
|
||||
"/",
|
||||
"/icon.png",
|
||||
"/output"
|
||||
);
|
||||
|
||||
expect(generateImageAsync).toHaveBeenCalledTimes(13);
|
||||
|
||||
expect(contents).toEqual([
|
||||
{
|
||||
filename: "[email protected]",
|
||||
idiom: "iphone",
|
||||
scale: "2x",
|
||||
size: "29x29",
|
||||
},
|
||||
{
|
||||
filename: "[email protected]",
|
||||
idiom: "iphone",
|
||||
scale: "3x",
|
||||
size: "29x29",
|
||||
},
|
||||
{
|
||||
filename: "[email protected]",
|
||||
idiom: "iphone",
|
||||
scale: "2x",
|
||||
size: "60x45",
|
||||
},
|
||||
{
|
||||
filename: "[email protected]",
|
||||
idiom: "iphone",
|
||||
scale: "3x",
|
||||
size: "60x45",
|
||||
},
|
||||
{
|
||||
filename: "[email protected]",
|
||||
idiom: "ipad",
|
||||
scale: "2x",
|
||||
size: "29x29",
|
||||
},
|
||||
{
|
||||
filename: "[email protected]",
|
||||
idiom: "ipad",
|
||||
scale: "2x",
|
||||
size: "67x50",
|
||||
},
|
||||
{
|
||||
filename: "[email protected]",
|
||||
idiom: "ipad",
|
||||
scale: "2x",
|
||||
size: "74x55",
|
||||
},
|
||||
{
|
||||
filename: "[email protected]",
|
||||
idiom: "universal",
|
||||
platform: "ios",
|
||||
scale: "2x",
|
||||
size: "27x20",
|
||||
},
|
||||
{
|
||||
filename: "[email protected]",
|
||||
idiom: "universal",
|
||||
platform: "ios",
|
||||
scale: "3x",
|
||||
size: "27x20",
|
||||
},
|
||||
{
|
||||
filename: "[email protected]",
|
||||
idiom: "universal",
|
||||
platform: "ios",
|
||||
scale: "2x",
|
||||
size: "32x24",
|
||||
},
|
||||
{
|
||||
filename: "[email protected]",
|
||||
idiom: "universal",
|
||||
platform: "ios",
|
||||
scale: "3x",
|
||||
size: "32x24",
|
||||
},
|
||||
{
|
||||
filename: "[email protected]",
|
||||
idiom: "ios-marketing",
|
||||
scale: "1x",
|
||||
size: "1024x1024",
|
||||
},
|
||||
{
|
||||
filename: "[email protected]",
|
||||
idiom: "ios-marketing",
|
||||
platform: "ios",
|
||||
scale: "1x",
|
||||
size: "1024x768",
|
||||
},
|
||||
]);
|
||||
});
|
||||
});
|
||||
@@ -3,7 +3,7 @@ import { generateImageAsync } from "@expo/image-utils";
|
||||
import fs from "fs";
|
||||
import path from "path";
|
||||
|
||||
import { generateImessageIconsAsync } from "./generateImessageIconsAsync";
|
||||
import { generateImessageIconsAsync } from "./withStickerIcon";
|
||||
import { getProjectStickersName } from "./withStickerXcodeTarget";
|
||||
|
||||
const STICKERS_ROOT_PATH = "Stickers.xcassets";
|
||||
@@ -136,7 +136,7 @@ export const withStickerAssets: ConfigPlugin<{
|
||||
fs.writeFileSync(
|
||||
iMessageAppIconContentsJsonPath,
|
||||
JSON.stringify(
|
||||
{ images: imessageIconContents, info: defaultInfo },
|
||||
{ info: defaultInfo, images: imessageIconContents },
|
||||
null,
|
||||
2
|
||||
)
|
||||
|
||||
+8
-8
@@ -86,11 +86,12 @@ const ICON_CONTENTS: {
|
||||
idiom: "ios-marketing",
|
||||
sizes: [
|
||||
{
|
||||
platform: "ios",
|
||||
|
||||
size: 1024,
|
||||
scales: [1],
|
||||
},
|
||||
{
|
||||
platform: "ios",
|
||||
size: [1024, 768],
|
||||
scales: [1],
|
||||
},
|
||||
@@ -147,16 +148,15 @@ export async function generateImessageIconsAsync(
|
||||
// Save a reference to the generated image so we don't create a duplicate.
|
||||
generatedIcons[filename] = true;
|
||||
}
|
||||
const imgJson: ContentsJsonImage = {
|
||||
filename,
|
||||
imagesJson.push({
|
||||
idiom: platform.idiom as ContentsJsonImageIdiom,
|
||||
scale: `${scale}x`,
|
||||
size: `${width}x${height}`,
|
||||
};
|
||||
// This order closely matches Xcode formatting.
|
||||
imagesJson.push(imgJson);
|
||||
// @ts-ignore: template types not supported in TS yet
|
||||
scale: `${scale}x`,
|
||||
filename,
|
||||
});
|
||||
if (rest.platform) {
|
||||
imgJson.platform = rest.platform;
|
||||
imagesJson[imagesJson.length - 1].platform = rest.platform;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,26 +1,3 @@
|
||||
### @config-plugins/react-native-ble-plx [2.0.1](https://github.com/expo/config-plugins/compare/@config-plugins/[email protected]...@config-plugins/[email protected]) (2022-07-25)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **react-native-ble-plx:** Added new Bluetooth specific permission for Android 12 (SDK 31). ([#91](https://github.com/expo/config-plugins/issues/91)) ([d3df63f](https://github.com/expo/config-plugins/commit/d3df63fbb2344251b9b371959de3ce6e4b9ab0cd))
|
||||
|
||||
## @config-plugins/react-native-ble-plx [2.0.0](https://github.com/expo/config-plugins/compare/@config-plugins/[email protected]...@config-plugins/[email protected]) (2022-05-27)
|
||||
|
||||
|
||||
### ⚠ BREAKING CHANGES
|
||||
|
||||
* add SDK 45 support (#79)
|
||||
|
||||
### Features
|
||||
|
||||
* add SDK 45 support ([#79](https://github.com/expo/config-plugins/issues/79)) ([96c72dd](https://github.com/expo/config-plugins/commit/96c72dda469ace2b9eafd38ba4d21f1bcd2e3cdf))
|
||||
|
||||
|
||||
### Other chores
|
||||
|
||||
* publish packages [no-ci] ([0c7b413](https://github.com/expo/config-plugins/commit/0c7b413a765e4b1ff92b9e3edc2b62077c41ce46))
|
||||
|
||||
### @config-plugins/react-native-ble-plx [1.0.3](https://github.com/expo/config-plugins/compare/@config-plugins/[email protected]...@config-plugins/[email protected]) (2022-05-09)
|
||||
|
||||
|
||||
|
||||
@@ -30,7 +30,6 @@ Next, rebuild your app as described in the ["Adding custom native code"](https:/
|
||||
The plugin provides props for extra customization. Every time you change the props or plugins, you'll need to rebuild (and `prebuild`) the native app. If no extra properties are added, defaults will be used.
|
||||
|
||||
- `isBackgroundEnabled` (_boolean_): Enable background BLE support on Android. Adds `<uses-feature android:name="android.hardware.bluetooth_le" android:required="true"/>` to the `AndroidManifest.xml`. Default `false`.
|
||||
- `neverForLocation` (_boolean_): Set to true only if you can strongly assert that your app never derives physical location from Bluetooth scan results. The location permission will be still required on older Android devices. Note, that some BLE beacons are filtered from the scan results. Android SDK 31+. Default `false`. *WARNING: This parameter is experimental and BLE might not work. Make sure to test before releasing to production.*
|
||||
- `modes` (_string[]_): Adds iOS `UIBackgroundModes` to the `Info.plist`. Options are: `peripheral`, and `central`. Defaults to undefined.
|
||||
- `bluetoothAlwaysPermission` (_string | false_): Sets the iOS `NSBluetoothAlwaysUsageDescription` permission message to the `Info.plist`. Setting `false` will skip adding the permission. Defaults to `Allow $(PRODUCT_NAME) to connect to bluetooth devices`.
|
||||
- `bluetoothPeripheralPermission` (_string | false_): Sets the iOS `NSBluetoothPeripheralUsageDescription` permission message to the `Info.plist`. Setting `false` will skip adding the permission. Defaults to `Allow $(PRODUCT_NAME) to connect to bluetooth devices`.
|
||||
|
||||
-1
@@ -3,7 +3,6 @@ import { BackgroundMode } from "./withBLEBackgroundModes";
|
||||
export { BackgroundMode };
|
||||
declare const _default: ConfigPlugin<void | {
|
||||
isBackgroundEnabled?: boolean | undefined;
|
||||
neverForLocation?: boolean | undefined;
|
||||
modes?: BackgroundMode[] | undefined;
|
||||
bluetoothAlwaysPermission?: string | false | undefined;
|
||||
bluetoothPeripheralPermission?: string | false | undefined;
|
||||
|
||||
+2
-7
@@ -11,10 +11,9 @@ const pkg = { name: "react-native-ble-plx", version: "UNVERSIONED" }; //require(
|
||||
* Apply BLE configuration for Expo SDK 42 projects.
|
||||
*/
|
||||
const withBLE = (config, props = {}) => {
|
||||
var _a, _b;
|
||||
var _a;
|
||||
const _props = props || {};
|
||||
const isBackgroundEnabled = (_a = _props.isBackgroundEnabled) !== null && _a !== void 0 ? _a : false;
|
||||
const neverForLocation = (_b = _props.neverForLocation) !== null && _b !== void 0 ? _b : false;
|
||||
// iOS
|
||||
config = withBluetoothPermissions_1.withBluetoothPermissions(config, _props);
|
||||
config = withBLEBackgroundModes_1.withBLEBackgroundModes(config, _props.modes || []);
|
||||
@@ -22,12 +21,8 @@ const withBLE = (config, props = {}) => {
|
||||
config = config_plugins_1.AndroidConfig.Permissions.withPermissions(config, [
|
||||
"android.permission.BLUETOOTH",
|
||||
"android.permission.BLUETOOTH_ADMIN",
|
||||
"android.permission.BLUETOOTH_CONNECT", // since Android SDK 31
|
||||
]);
|
||||
config = withBLEAndroidManifest_1.withBLEAndroidManifest(config, {
|
||||
isBackgroundEnabled,
|
||||
neverForLocation,
|
||||
});
|
||||
config = withBLEAndroidManifest_1.withBLEAndroidManifest(config, { isBackgroundEnabled });
|
||||
return config;
|
||||
};
|
||||
exports.default = config_plugins_1.createRunOncePlugin(withBLE, pkg.name, pkg.version);
|
||||
+3
-21
@@ -1,35 +1,17 @@
|
||||
import { ConfigPlugin, AndroidConfig } from "@expo/config-plugins";
|
||||
declare type InnerManifest = AndroidConfig.Manifest.AndroidManifest["manifest"];
|
||||
declare type ManifestPermission = InnerManifest["permission"];
|
||||
declare type ExtraTools = {
|
||||
"tools:targetApi"?: string;
|
||||
};
|
||||
declare type ManifestUsesPermissionWithExtraTools = {
|
||||
$: AndroidConfig.Manifest.ManifestUsesPermission["$"] & ExtraTools;
|
||||
};
|
||||
declare type AndroidManifest = {
|
||||
manifest: InnerManifest & {
|
||||
permission?: ManifestPermission;
|
||||
"uses-permission"?: ManifestUsesPermissionWithExtraTools[];
|
||||
"uses-permission-sdk-23"?: ManifestUsesPermissionWithExtraTools[];
|
||||
"uses-permission"?: InnerManifest["uses-permission"];
|
||||
"uses-permission-sdk-23"?: InnerManifest["uses-permission"];
|
||||
"uses-feature"?: InnerManifest["uses-feature"];
|
||||
};
|
||||
};
|
||||
export declare const withBLEAndroidManifest: ConfigPlugin<{
|
||||
isBackgroundEnabled: boolean;
|
||||
neverForLocation: boolean;
|
||||
}>;
|
||||
/**
|
||||
* Add location permissions
|
||||
* - 'android.permission.ACCESS_COARSE_LOCATION' for Android SDK 28 (Android 9) and lower
|
||||
* - 'android.permission.ACCESS_FINE_LOCATION' for Android SDK 29 (Android 10) and higher.
|
||||
* From Android SDK 31 (Android 12) it might not be required if BLE is not used for location.
|
||||
*/
|
||||
export declare function addLocationPermissionToManifest(androidManifest: AndroidManifest, neverForLocationSinceSdk31: boolean): AndroidManifest;
|
||||
/**
|
||||
* Add 'android.permission.BLUETOOTH_SCAN'.
|
||||
* Required since Android SDK 31 (Android 12).
|
||||
*/
|
||||
export declare function addScanPermissionToManifest(androidManifest: AndroidManifest, neverForLocation: boolean): AndroidManifest;
|
||||
export declare function addFineControlPermissionToManifest(androidManifest: AndroidManifest): AndroidManifest;
|
||||
export declare function addBLEHardwareFeatureToManifest(androidManifest: AndroidConfig.Manifest.AndroidManifest): AndroidConfig.Manifest.AndroidManifest;
|
||||
export {};
|
||||
+8
-53
@@ -1,11 +1,10 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.addBLEHardwareFeatureToManifest = exports.addScanPermissionToManifest = exports.addLocationPermissionToManifest = exports.withBLEAndroidManifest = void 0;
|
||||
exports.addBLEHardwareFeatureToManifest = exports.addFineControlPermissionToManifest = exports.withBLEAndroidManifest = void 0;
|
||||
const config_plugins_1 = require("@expo/config-plugins");
|
||||
const withBLEAndroidManifest = (config, { isBackgroundEnabled, neverForLocation }) => {
|
||||
const withBLEAndroidManifest = (config, { isBackgroundEnabled }) => {
|
||||
return config_plugins_1.withAndroidManifest(config, (config) => {
|
||||
config.modResults = addLocationPermissionToManifest(config.modResults, neverForLocation);
|
||||
config.modResults = addScanPermissionToManifest(config.modResults, neverForLocation);
|
||||
config.modResults = addFineControlPermissionToManifest(config.modResults);
|
||||
if (isBackgroundEnabled) {
|
||||
config.modResults = addBLEHardwareFeatureToManifest(config.modResults);
|
||||
}
|
||||
@@ -13,66 +12,22 @@ const withBLEAndroidManifest = (config, { isBackgroundEnabled, neverForLocation
|
||||
});
|
||||
};
|
||||
exports.withBLEAndroidManifest = withBLEAndroidManifest;
|
||||
/**
|
||||
* Add location permissions
|
||||
* - 'android.permission.ACCESS_COARSE_LOCATION' for Android SDK 28 (Android 9) and lower
|
||||
* - 'android.permission.ACCESS_FINE_LOCATION' for Android SDK 29 (Android 10) and higher.
|
||||
* From Android SDK 31 (Android 12) it might not be required if BLE is not used for location.
|
||||
*/
|
||||
function addLocationPermissionToManifest(androidManifest, neverForLocationSinceSdk31) {
|
||||
function addFineControlPermissionToManifest(androidManifest) {
|
||||
var _a;
|
||||
// Add `<uses-permission-sdk-23 android:name="android.permission.ACCESS_FINE_LOCATION"/>` to the AndroidManifest.xml
|
||||
if (!Array.isArray(androidManifest.manifest["uses-permission-sdk-23"])) {
|
||||
androidManifest.manifest["uses-permission-sdk-23"] = [];
|
||||
}
|
||||
const optMaxSdkVersion = neverForLocationSinceSdk31
|
||||
? {
|
||||
"android:maxSdkVersion": "30",
|
||||
}
|
||||
: {};
|
||||
if (!androidManifest.manifest["uses-permission-sdk-23"].find((item) => item.$["android:name"] === "android.permission.ACCESS_COARSE_LOCATION")) {
|
||||
androidManifest.manifest["uses-permission-sdk-23"].push({
|
||||
$: {
|
||||
"android:name": "android.permission.ACCESS_COARSE_LOCATION",
|
||||
...optMaxSdkVersion,
|
||||
},
|
||||
});
|
||||
}
|
||||
if (!androidManifest.manifest["uses-permission-sdk-23"].find((item) => item.$["android:name"] === "android.permission.ACCESS_FINE_LOCATION")) {
|
||||
androidManifest.manifest["uses-permission-sdk-23"].push({
|
||||
(_a = androidManifest.manifest["uses-permission-sdk-23"]) === null || _a === void 0 ? void 0 : _a.push({
|
||||
$: {
|
||||
"android:name": "android.permission.ACCESS_FINE_LOCATION",
|
||||
...optMaxSdkVersion,
|
||||
},
|
||||
});
|
||||
}
|
||||
return androidManifest;
|
||||
}
|
||||
exports.addLocationPermissionToManifest = addLocationPermissionToManifest;
|
||||
/**
|
||||
* Add 'android.permission.BLUETOOTH_SCAN'.
|
||||
* Required since Android SDK 31 (Android 12).
|
||||
*/
|
||||
function addScanPermissionToManifest(androidManifest, neverForLocation) {
|
||||
var _a;
|
||||
if (!Array.isArray(androidManifest.manifest["uses-permission"])) {
|
||||
androidManifest.manifest["uses-permission"] = [];
|
||||
}
|
||||
if (!androidManifest.manifest["uses-permission"].find((item) => item.$["android:name"] === "android.permission.BLUETOOTH_SCAN")) {
|
||||
config_plugins_1.AndroidConfig.Manifest.ensureToolsAvailable(androidManifest);
|
||||
(_a = androidManifest.manifest["uses-permission"]) === null || _a === void 0 ? void 0 : _a.push({
|
||||
$: {
|
||||
"android:name": "android.permission.BLUETOOTH_SCAN",
|
||||
...(neverForLocation
|
||||
? {
|
||||
"android:usesPermissionFlags": "neverForLocation",
|
||||
}
|
||||
: {}),
|
||||
"tools:targetApi": "31",
|
||||
},
|
||||
});
|
||||
}
|
||||
return androidManifest;
|
||||
}
|
||||
exports.addScanPermissionToManifest = addScanPermissionToManifest;
|
||||
exports.addFineControlPermissionToManifest = addFineControlPermissionToManifest;
|
||||
// Add this line if your application always requires BLE. More info can be found on: https://developer.android.com/guide/topics/connectivity/bluetooth-le.html#permissions
|
||||
function addBLEHardwareFeatureToManifest(androidManifest) {
|
||||
var _a;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@config-plugins/react-native-ble-plx",
|
||||
"version": "2.0.1",
|
||||
"version": "2.0.0",
|
||||
"description": "Config plugin to auto configure react-native-ble-plx on prebuild",
|
||||
"main": "build/withBLE.js",
|
||||
"types": "build/withBLE.d.ts",
|
||||
|
||||
@@ -2,98 +2,31 @@ import { AndroidConfig, XML } from "@expo/config-plugins";
|
||||
import { resolve } from "path";
|
||||
|
||||
import {
|
||||
addLocationPermissionToManifest,
|
||||
addScanPermissionToManifest,
|
||||
addBLEHardwareFeatureToManifest,
|
||||
addFineControlPermissionToManifest,
|
||||
} from "../withBLEAndroidManifest";
|
||||
|
||||
const { readAndroidManifestAsync } = AndroidConfig.Manifest;
|
||||
|
||||
const sampleManifestPath = resolve(__dirname, "fixtures/AndroidManifest.xml");
|
||||
|
||||
describe("addLocationPermissionToManifest", () => {
|
||||
it(`adds elements`, async () => {
|
||||
describe("addFineControlPermissionToManifest", () => {
|
||||
it(`adds element`, async () => {
|
||||
let androidManifest = await readAndroidManifestAsync(sampleManifestPath);
|
||||
androidManifest = addLocationPermissionToManifest(androidManifest, false);
|
||||
expect(androidManifest.manifest["uses-permission-sdk-23"]).toContainEqual({
|
||||
$: {
|
||||
"android:name": "android.permission.ACCESS_COARSE_LOCATION",
|
||||
},
|
||||
});
|
||||
expect(androidManifest.manifest["uses-permission-sdk-23"]).toContainEqual({
|
||||
$: {
|
||||
"android:name": "android.permission.ACCESS_FINE_LOCATION",
|
||||
},
|
||||
});
|
||||
androidManifest = await addFineControlPermissionToManifest(androidManifest);
|
||||
expect(androidManifest.manifest["uses-permission-sdk-23"]).toStrictEqual([
|
||||
{ $: { "android:name": "android.permission.ACCESS_FINE_LOCATION" } },
|
||||
]);
|
||||
// Sanity
|
||||
expect(XML.format(androidManifest)).toMatch(
|
||||
/<uses-permission-sdk-23 android:name="android\.permission\.ACCESS_COARSE_LOCATION"\/>/
|
||||
);
|
||||
expect(XML.format(androidManifest)).toMatch(
|
||||
/<uses-permission-sdk-23 android:name="android\.permission\.ACCESS_FINE_LOCATION"\/>/
|
||||
);
|
||||
});
|
||||
it(`adds elements with SDK limit`, async () => {
|
||||
let androidManifest = await readAndroidManifestAsync(sampleManifestPath);
|
||||
androidManifest = addLocationPermissionToManifest(androidManifest, true);
|
||||
expect(androidManifest.manifest["uses-permission-sdk-23"]).toContainEqual({
|
||||
$: {
|
||||
"android:name": "android.permission.ACCESS_COARSE_LOCATION",
|
||||
"android:maxSdkVersion": "30",
|
||||
},
|
||||
});
|
||||
expect(androidManifest.manifest["uses-permission-sdk-23"]).toContainEqual({
|
||||
$: {
|
||||
"android:name": "android.permission.ACCESS_FINE_LOCATION",
|
||||
"android:maxSdkVersion": "30",
|
||||
},
|
||||
});
|
||||
// Sanity
|
||||
expect(XML.format(androidManifest)).toMatch(
|
||||
/<uses-permission-sdk-23 android:name="android\.permission\.ACCESS_COARSE_LOCATION" android:maxSdkVersion="30"\/>/
|
||||
);
|
||||
expect(XML.format(androidManifest)).toMatch(
|
||||
/<uses-permission-sdk-23 android:name="android\.permission\.ACCESS_FINE_LOCATION" android:maxSdkVersion="30"\/>/
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe("addScanPermissionToManifest", () => {
|
||||
it(`adds element`, async () => {
|
||||
let androidManifest = await readAndroidManifestAsync(sampleManifestPath);
|
||||
androidManifest = addScanPermissionToManifest(androidManifest, false);
|
||||
expect(androidManifest.manifest["uses-permission"]).toContainEqual({
|
||||
$: {
|
||||
"android:name": "android.permission.BLUETOOTH_SCAN",
|
||||
"tools:targetApi": "31",
|
||||
},
|
||||
});
|
||||
// Sanity
|
||||
expect(XML.format(androidManifest)).toMatch(
|
||||
/<uses-permission android:name="android\.permission\.BLUETOOTH_SCAN" tools:targetApi="31"\/>/
|
||||
);
|
||||
});
|
||||
it(`adds element with 'neverForLocation' attribute`, async () => {
|
||||
let androidManifest = await readAndroidManifestAsync(sampleManifestPath);
|
||||
androidManifest = addScanPermissionToManifest(androidManifest, true);
|
||||
expect(androidManifest.manifest["uses-permission"]).toContainEqual({
|
||||
$: {
|
||||
"android:name": "android.permission.BLUETOOTH_SCAN",
|
||||
"android:usesPermissionFlags": "neverForLocation",
|
||||
"tools:targetApi": "31",
|
||||
},
|
||||
});
|
||||
// Sanity
|
||||
expect(XML.format(androidManifest)).toMatch(
|
||||
/<uses-permission android:name="android\.permission\.BLUETOOTH_SCAN" android:usesPermissionFlags="neverForLocation" tools:targetApi="31"\/>/
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe("addBLEHardwareFeatureToManifest", () => {
|
||||
it(`adds element`, async () => {
|
||||
let androidManifest = await readAndroidManifestAsync(sampleManifestPath);
|
||||
androidManifest = addBLEHardwareFeatureToManifest(androidManifest);
|
||||
androidManifest = await addBLEHardwareFeatureToManifest(androidManifest);
|
||||
|
||||
expect(androidManifest.manifest["uses-feature"]).toStrictEqual([
|
||||
{
|
||||
|
||||
@@ -18,14 +18,12 @@ const pkg = { name: "react-native-ble-plx", version: "UNVERSIONED" }; //require(
|
||||
*/
|
||||
const withBLE: ConfigPlugin<{
|
||||
isBackgroundEnabled?: boolean;
|
||||
neverForLocation?: boolean;
|
||||
modes?: BackgroundMode[];
|
||||
bluetoothAlwaysPermission?: string | false;
|
||||
bluetoothPeripheralPermission?: string | false;
|
||||
} | void> = (config, props = {}) => {
|
||||
const _props = props || {};
|
||||
const isBackgroundEnabled = _props.isBackgroundEnabled ?? false;
|
||||
const neverForLocation = _props.neverForLocation ?? false;
|
||||
|
||||
// iOS
|
||||
config = withBluetoothPermissions(config, _props);
|
||||
@@ -35,12 +33,8 @@ const withBLE: ConfigPlugin<{
|
||||
config = AndroidConfig.Permissions.withPermissions(config, [
|
||||
"android.permission.BLUETOOTH",
|
||||
"android.permission.BLUETOOTH_ADMIN",
|
||||
"android.permission.BLUETOOTH_CONNECT", // since Android SDK 31
|
||||
]);
|
||||
config = withBLEAndroidManifest(config, {
|
||||
isBackgroundEnabled,
|
||||
neverForLocation,
|
||||
});
|
||||
config = withBLEAndroidManifest(config, { isBackgroundEnabled });
|
||||
|
||||
return config;
|
||||
};
|
||||
|
||||
@@ -8,38 +8,20 @@ type InnerManifest = AndroidConfig.Manifest.AndroidManifest["manifest"];
|
||||
|
||||
type ManifestPermission = InnerManifest["permission"];
|
||||
|
||||
// TODO: add to `AndroidManifestAttributes` in @expo/config-plugins
|
||||
type ExtraTools = {
|
||||
// https://developer.android.com/studio/write/tool-attributes#toolstargetapi
|
||||
"tools:targetApi"?: string;
|
||||
};
|
||||
|
||||
type ManifestUsesPermissionWithExtraTools = {
|
||||
$: AndroidConfig.Manifest.ManifestUsesPermission["$"] & ExtraTools;
|
||||
};
|
||||
|
||||
type AndroidManifest = {
|
||||
manifest: InnerManifest & {
|
||||
permission?: ManifestPermission;
|
||||
"uses-permission"?: ManifestUsesPermissionWithExtraTools[];
|
||||
"uses-permission-sdk-23"?: ManifestUsesPermissionWithExtraTools[];
|
||||
"uses-permission"?: InnerManifest["uses-permission"];
|
||||
"uses-permission-sdk-23"?: InnerManifest["uses-permission"];
|
||||
"uses-feature"?: InnerManifest["uses-feature"];
|
||||
};
|
||||
};
|
||||
|
||||
export const withBLEAndroidManifest: ConfigPlugin<{
|
||||
isBackgroundEnabled: boolean;
|
||||
neverForLocation: boolean;
|
||||
}> = (config, { isBackgroundEnabled, neverForLocation }) => {
|
||||
}> = (config, { isBackgroundEnabled }) => {
|
||||
return withAndroidManifest(config, (config) => {
|
||||
config.modResults = addLocationPermissionToManifest(
|
||||
config.modResults,
|
||||
neverForLocation
|
||||
);
|
||||
config.modResults = addScanPermissionToManifest(
|
||||
config.modResults,
|
||||
neverForLocation
|
||||
);
|
||||
config.modResults = addFineControlPermissionToManifest(config.modResults);
|
||||
if (isBackgroundEnabled) {
|
||||
config.modResults = addBLEHardwareFeatureToManifest(config.modResults);
|
||||
}
|
||||
@@ -47,84 +29,23 @@ export const withBLEAndroidManifest: ConfigPlugin<{
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Add location permissions
|
||||
* - 'android.permission.ACCESS_COARSE_LOCATION' for Android SDK 28 (Android 9) and lower
|
||||
* - 'android.permission.ACCESS_FINE_LOCATION' for Android SDK 29 (Android 10) and higher.
|
||||
* From Android SDK 31 (Android 12) it might not be required if BLE is not used for location.
|
||||
*/
|
||||
export function addLocationPermissionToManifest(
|
||||
androidManifest: AndroidManifest,
|
||||
neverForLocationSinceSdk31: boolean
|
||||
export function addFineControlPermissionToManifest(
|
||||
androidManifest: AndroidManifest
|
||||
) {
|
||||
// Add `<uses-permission-sdk-23 android:name="android.permission.ACCESS_FINE_LOCATION"/>` to the AndroidManifest.xml
|
||||
if (!Array.isArray(androidManifest.manifest["uses-permission-sdk-23"])) {
|
||||
androidManifest.manifest["uses-permission-sdk-23"] = [];
|
||||
}
|
||||
|
||||
const optMaxSdkVersion = neverForLocationSinceSdk31
|
||||
? {
|
||||
"android:maxSdkVersion": "30",
|
||||
}
|
||||
: {};
|
||||
|
||||
if (
|
||||
!androidManifest.manifest["uses-permission-sdk-23"].find(
|
||||
(item) =>
|
||||
item.$["android:name"] === "android.permission.ACCESS_COARSE_LOCATION"
|
||||
)
|
||||
) {
|
||||
androidManifest.manifest["uses-permission-sdk-23"].push({
|
||||
$: {
|
||||
"android:name": "android.permission.ACCESS_COARSE_LOCATION",
|
||||
...optMaxSdkVersion,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
if (
|
||||
!androidManifest.manifest["uses-permission-sdk-23"].find(
|
||||
(item) =>
|
||||
item.$["android:name"] === "android.permission.ACCESS_FINE_LOCATION"
|
||||
)
|
||||
) {
|
||||
androidManifest.manifest["uses-permission-sdk-23"].push({
|
||||
androidManifest.manifest["uses-permission-sdk-23"]?.push({
|
||||
$: {
|
||||
"android:name": "android.permission.ACCESS_FINE_LOCATION",
|
||||
...optMaxSdkVersion,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
return androidManifest;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add 'android.permission.BLUETOOTH_SCAN'.
|
||||
* Required since Android SDK 31 (Android 12).
|
||||
*/
|
||||
export function addScanPermissionToManifest(
|
||||
androidManifest: AndroidManifest,
|
||||
neverForLocation: boolean
|
||||
) {
|
||||
if (!Array.isArray(androidManifest.manifest["uses-permission"])) {
|
||||
androidManifest.manifest["uses-permission"] = [];
|
||||
}
|
||||
|
||||
if (
|
||||
!androidManifest.manifest["uses-permission"].find(
|
||||
(item) => item.$["android:name"] === "android.permission.BLUETOOTH_SCAN"
|
||||
)
|
||||
) {
|
||||
AndroidConfig.Manifest.ensureToolsAvailable(androidManifest);
|
||||
androidManifest.manifest["uses-permission"]?.push({
|
||||
$: {
|
||||
"android:name": "android.permission.BLUETOOTH_SCAN",
|
||||
...(neverForLocation
|
||||
? {
|
||||
"android:usesPermissionFlags": "neverForLocation",
|
||||
}
|
||||
: {}),
|
||||
"tools:targetApi": "31",
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,19 +1,3 @@
|
||||
## @config-plugins/react-native-callkeep [2.0.0](https://github.com/expo/config-plugins/compare/@config-plugins/[email protected]...@config-plugins/[email protected]) (2022-07-25)
|
||||
|
||||
|
||||
### ⚠ BREAKING CHANGES
|
||||
|
||||
* add SDK 45 support (#79)
|
||||
|
||||
### Features
|
||||
|
||||
* add SDK 45 support ([#79](https://github.com/expo/config-plugins/issues/79)) ([96c72dd](https://github.com/expo/config-plugins/commit/96c72dda469ace2b9eafd38ba4d21f1bcd2e3cdf))
|
||||
|
||||
|
||||
### Other chores
|
||||
|
||||
* publish packages [no-ci] ([0c7b413](https://github.com/expo/config-plugins/commit/0c7b413a765e4b1ff92b9e3edc2b62077c41ce46))
|
||||
|
||||
### @config-plugins/react-native-callkeep [1.0.3](https://github.com/expo/config-plugins/compare/@config-plugins/[email protected]...@config-plugins/[email protected]) (2022-03-22)
|
||||
|
||||
|
||||
|
||||
@@ -1,19 +1,3 @@
|
||||
## @config-plugins/react-native-dynamic-app-icon [2.0.0](https://github.com/expo/config-plugins/compare/@config-plugins/[email protected]...@config-plugins/[email protected]) (2022-06-14)
|
||||
|
||||
|
||||
### ⚠ BREAKING CHANGES
|
||||
|
||||
* add SDK 45 support (#79)
|
||||
|
||||
### Features
|
||||
|
||||
* add SDK 45 support ([#79](https://github.com/expo/config-plugins/issues/79)) ([96c72dd](https://github.com/expo/config-plugins/commit/96c72dda469ace2b9eafd38ba4d21f1bcd2e3cdf))
|
||||
|
||||
|
||||
### Other chores
|
||||
|
||||
* publish packages [no-ci] ([0c7b413](https://github.com/expo/config-plugins/commit/0c7b413a765e4b1ff92b9e3edc2b62077c41ce46))
|
||||
|
||||
### @config-plugins/react-native-dynamic-app-icon [1.0.3](https://github.com/expo/config-plugins/compare/@config-plugins/[email protected]...@config-plugins/[email protected]) (2022-05-12)
|
||||
|
||||
|
||||
|
||||
@@ -1,19 +1,3 @@
|
||||
## @config-plugins/react-native-google-cast [2.0.0](https://github.com/expo/config-plugins/compare/@config-plugins/[email protected]...@config-plugins/[email protected]) (2022-05-30)
|
||||
|
||||
|
||||
### ⚠ BREAKING CHANGES
|
||||
|
||||
* add SDK 45 support (#79)
|
||||
|
||||
### Features
|
||||
|
||||
* add SDK 45 support ([#79](https://github.com/expo/config-plugins/issues/79)) ([96c72dd](https://github.com/expo/config-plugins/commit/96c72dda469ace2b9eafd38ba4d21f1bcd2e3cdf))
|
||||
|
||||
|
||||
### Other chores
|
||||
|
||||
* publish packages [no-ci] ([0c7b413](https://github.com/expo/config-plugins/commit/0c7b413a765e4b1ff92b9e3edc2b62077c41ce46))
|
||||
|
||||
### @config-plugins/react-native-google-cast [1.0.3](https://github.com/expo/config-plugins/compare/@config-plugins/[email protected]...@config-plugins/[email protected]) (2022-03-23)
|
||||
|
||||
|
||||
|
||||
@@ -1,19 +1,3 @@
|
||||
## @config-plugins/react-native-quick-actions [2.0.0](https://github.com/expo/config-plugins/compare/@config-plugins/[email protected]...@config-plugins/[email protected]) (2022-06-13)
|
||||
|
||||
|
||||
### ⚠ BREAKING CHANGES
|
||||
|
||||
* add SDK 45 support (#79)
|
||||
|
||||
### Features
|
||||
|
||||
* add SDK 45 support ([#79](https://github.com/expo/config-plugins/issues/79)) ([96c72dd](https://github.com/expo/config-plugins/commit/96c72dda469ace2b9eafd38ba4d21f1bcd2e3cdf))
|
||||
|
||||
|
||||
### Other chores
|
||||
|
||||
* publish packages [no-ci] ([0c7b413](https://github.com/expo/config-plugins/commit/0c7b413a765e4b1ff92b9e3edc2b62077c41ce46))
|
||||
|
||||
### @config-plugins/react-native-quick-actions [1.0.2](https://github.com/expo/config-plugins/compare/@config-plugins/[email protected]...@config-plugins/[email protected]) (2022-03-22)
|
||||
|
||||
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
## @config-plugins/react-native-siri-shortcut 1.0.0 (2022-07-12)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **siri-shortcut:** Add config plugin ([#86](https://github.com/expo/config-plugins/issues/86)) ([226b2a6](https://github.com/expo/config-plugins/commit/226b2a6412ad3fe75c98952831fab5a63254d19f))
|
||||
|
||||
|
||||
### Other chores
|
||||
|
||||
* **react-native-siri-shortcut:** add tests ([#88](https://github.com/expo/config-plugins/issues/88)) ([994fadc](https://github.com/expo/config-plugins/commit/994fadc8ddf9ee858f2ccb7d544674f107f7f9ad))
|
||||
@@ -1 +0,0 @@
|
||||
module.exports = require("./build/withReactNativeSiriShortcut");
|
||||
-6
@@ -1,6 +0,0 @@
|
||||
import { ConfigPlugin } from "@expo/config-plugins";
|
||||
import { MergeResults } from "@expo/config-plugins/build/utils/generateCode";
|
||||
export declare function addSiriShortcutAppDelegateImport(src: string): MergeResults;
|
||||
export declare function addSiriShortcutAppDelegateInit(src: string): MergeResults;
|
||||
declare const _default: ConfigPlugin<void | string[]>;
|
||||
export default _default;
|
||||
-88
@@ -1,88 +0,0 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.addSiriShortcutAppDelegateInit = exports.addSiriShortcutAppDelegateImport = void 0;
|
||||
const config_plugins_1 = require("@expo/config-plugins");
|
||||
const generateCode_1 = require("@expo/config-plugins/build/utils/generateCode");
|
||||
/**
|
||||
* Apply react-native-siri-shortcut configuration for Expo SDK 44 projects.
|
||||
*/
|
||||
const withReactNativeSiriShortcut = (config, activityTypes) => {
|
||||
withSiriShortcutAppDelegate(config);
|
||||
withSiriEntitlements(config);
|
||||
const items = activityTypes || [];
|
||||
if (!Array.isArray(items) || !items.length) {
|
||||
return config;
|
||||
}
|
||||
return withReactNativeSiriShortcutInfoPlist(config, items);
|
||||
};
|
||||
const withReactNativeSiriShortcutInfoPlist = (config, activityTypes) => {
|
||||
return config_plugins_1.withInfoPlist(config, (config) => {
|
||||
config.modResults.NSUserActivityTypes = activityTypes;
|
||||
return config;
|
||||
});
|
||||
};
|
||||
function addSiriShortcutAppDelegateImport(src) {
|
||||
return generateCode_1.mergeContents({
|
||||
tag: "react-native-siri-shortcut",
|
||||
src,
|
||||
newSrc: "#import <RNSiriShortcuts/RNSiriShortcuts.h>",
|
||||
anchor: /#import "AppDelegate\.h"/,
|
||||
offset: 1,
|
||||
comment: "//",
|
||||
});
|
||||
}
|
||||
exports.addSiriShortcutAppDelegateImport = addSiriShortcutAppDelegateImport;
|
||||
function addSiriShortcutAppDelegateInit(src) {
|
||||
return generateCode_1.mergeContents({
|
||||
tag: "react-native-siri-shortcut-delegate",
|
||||
src,
|
||||
newSrc: [
|
||||
" BOOL shortcutResult = [RNSSSiriShortcuts application:application continueUserActivity:userActivity restorationHandler:restorationHandler];",
|
||||
" if (shortcutResult) {",
|
||||
" return [super application:application continueUserActivity:userActivity restorationHandler:restorationHandler] || shortcutResult;",
|
||||
" }",
|
||||
].join("\n"),
|
||||
anchor: / return \[super application:application continueUserActivity:userActivity restorationHandler:restorationHandler\] \|\| result;/,
|
||||
offset: -1,
|
||||
comment: "//",
|
||||
});
|
||||
}
|
||||
exports.addSiriShortcutAppDelegateInit = addSiriShortcutAppDelegateInit;
|
||||
/** Append the siri entitlement on iOS */
|
||||
const withSiriEntitlements = (config) => {
|
||||
return config_plugins_1.withEntitlementsPlist(config, (config) => {
|
||||
config.modResults["com.apple.developer.siri"] = true;
|
||||
return config;
|
||||
});
|
||||
};
|
||||
const withSiriShortcutAppDelegate = (config) => {
|
||||
return config_plugins_1.withAppDelegate(config, (config) => {
|
||||
if (["objc", "objcpp"].includes(config.modResults.language)) {
|
||||
try {
|
||||
config.modResults.contents = addSiriShortcutAppDelegateImport(config.modResults.contents).contents;
|
||||
config.modResults.contents = addSiriShortcutAppDelegateInit(config.modResults.contents).contents;
|
||||
}
|
||||
catch (error) {
|
||||
if (error.code === "ERR_NO_MATCH") {
|
||||
throw new Error(`Cannot add Siri Shortcut to the project's AppDelegate because it's malformed. Please report this with a copy of your project AppDelegate.`);
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
else {
|
||||
throw new Error("Cannot setup Siri Shortcut because the AppDelegate is not Objective C");
|
||||
}
|
||||
return config;
|
||||
});
|
||||
};
|
||||
const pkg = {
|
||||
// Prevent this plugin from being run more than once.
|
||||
// This pattern enables users to safely migrate off of this
|
||||
// out-of-tree `@config-plugins/react-native-siri-shortcut` to a future
|
||||
// upstream plugin in `react-native-siri-shortcut`
|
||||
name: "react-native-siri-shortcut",
|
||||
// Indicates that this plugin is dangerously linked to a module,
|
||||
// and might not work with the latest version of that module.
|
||||
version: "UNVERSIONED",
|
||||
};
|
||||
exports.default = config_plugins_1.createRunOncePlugin(withReactNativeSiriShortcut, pkg.name, pkg.version);
|
||||
@@ -1 +0,0 @@
|
||||
module.exports = require('expo-module-scripts/jest-preset-plugin');
|
||||
-306
@@ -1,306 +0,0 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`addSiriShortcutAppDelegateImport adds import to Expo Modules AppDelegate 1`] = `
|
||||
"
|
||||
#import \\"AppDelegate.h\\"
|
||||
// @generated begin react-native-siri-shortcut - expo prebuild (DO NOT MODIFY) sync-34828decdfd158f5b96fe11a1e590a684e296e0e
|
||||
#import <RNSiriShortcuts/RNSiriShortcuts.h>
|
||||
// @generated end react-native-siri-shortcut
|
||||
|
||||
#import <React/RCTBridge.h>
|
||||
#import <React/RCTBundleURLProvider.h>
|
||||
#import <React/RCTRootView.h>
|
||||
#import <React/RCTLinkingManager.h>
|
||||
#import <React/RCTConvert.h>
|
||||
|
||||
#import <React/RCTAppSetupUtils.h>
|
||||
|
||||
#if RCT_NEW_ARCH_ENABLED
|
||||
#import <React/CoreModulesPlugins.h>
|
||||
#import <React/RCTCxxBridgeDelegate.h>
|
||||
#import <React/RCTFabricSurfaceHostingProxyRootView.h>
|
||||
#import <React/RCTSurfacePresenter.h>
|
||||
#import <React/RCTSurfacePresenterBridgeAdapter.h>
|
||||
#import <ReactCommon/RCTTurboModuleManager.h>
|
||||
|
||||
#import <react/config/ReactNativeConfig.h>
|
||||
|
||||
@interface AppDelegate () <RCTCxxBridgeDelegate, RCTTurboModuleManagerDelegate> {
|
||||
RCTTurboModuleManager *_turboModuleManager;
|
||||
RCTSurfacePresenterBridgeAdapter *_bridgeAdapter;
|
||||
std::shared_ptr<const facebook::react::ReactNativeConfig> _reactNativeConfig;
|
||||
facebook::react::ContextContainer::Shared _contextContainer;
|
||||
}
|
||||
@end
|
||||
#endif
|
||||
|
||||
@implementation AppDelegate
|
||||
|
||||
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
|
||||
{
|
||||
RCTAppSetupPrepareApp(application);
|
||||
|
||||
RCTBridge *bridge = [self.reactDelegate createBridgeWithDelegate:self launchOptions:launchOptions];
|
||||
|
||||
#if RCT_NEW_ARCH_ENABLED
|
||||
_contextContainer = std::make_shared<facebook::react::ContextContainer const>();
|
||||
_reactNativeConfig = std::make_shared<facebook::react::EmptyReactNativeConfig const>();
|
||||
_contextContainer->insert(\\"ReactNativeConfig\\", _reactNativeConfig);
|
||||
_bridgeAdapter = [[RCTSurfacePresenterBridgeAdapter alloc] initWithBridge:bridge contextContainer:_contextContainer];
|
||||
bridge.surfacePresenter = _bridgeAdapter.surfacePresenter;
|
||||
#endif
|
||||
|
||||
UIView *rootView = [self.reactDelegate createRootViewWithBridge:bridge moduleName:@\\"main\\" initialProperties:nil];
|
||||
|
||||
rootView.backgroundColor = [UIColor whiteColor];
|
||||
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
|
||||
UIViewController *rootViewController = [self.reactDelegate createRootViewController];
|
||||
rootViewController.view = rootView;
|
||||
self.window.rootViewController = rootViewController;
|
||||
[self.window makeKeyAndVisible];
|
||||
|
||||
[super application:application didFinishLaunchingWithOptions:launchOptions];
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (NSArray<id<RCTBridgeModule>> *)extraModulesForBridge:(RCTBridge *)bridge
|
||||
{
|
||||
// If you'd like to export some custom RCTBridgeModules, add them here!
|
||||
return @[];
|
||||
}
|
||||
|
||||
- (NSURL *)sourceURLForBridge:(RCTBridge *)bridge
|
||||
{
|
||||
#if DEBUG
|
||||
return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@\\"index\\"];
|
||||
#else
|
||||
return [[NSBundle mainBundle] URLForResource:@\\"main\\" withExtension:@\\"jsbundle\\"];
|
||||
#endif
|
||||
}
|
||||
|
||||
// Linking API
|
||||
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
|
||||
return [super application:application openURL:url options:options] || [RCTLinkingManager application:application openURL:url options:options];
|
||||
}
|
||||
|
||||
// Universal Links
|
||||
- (BOOL)application:(UIApplication *)application continueUserActivity:(nonnull NSUserActivity *)userActivity restorationHandler:(nonnull void (^)(NSArray<id<UIUserActivityRestoring>> * _Nullable))restorationHandler {
|
||||
BOOL result = [RCTLinkingManager application:application continueUserActivity:userActivity restorationHandler:restorationHandler];
|
||||
return [super application:application continueUserActivity:userActivity restorationHandler:restorationHandler] || result;
|
||||
}
|
||||
|
||||
// Explicitly define remote notification delegates to ensure compatibility with some third-party libraries
|
||||
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
|
||||
{
|
||||
return [super application:application didRegisterForRemoteNotificationsWithDeviceToken:deviceToken];
|
||||
}
|
||||
|
||||
// Explicitly define remote notification delegates to ensure compatibility with some third-party libraries
|
||||
- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error
|
||||
{
|
||||
return [super application:application didFailToRegisterForRemoteNotificationsWithError:error];
|
||||
}
|
||||
|
||||
// Explicitly define remote notification delegates to ensure compatibility with some third-party libraries
|
||||
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
|
||||
{
|
||||
return [super application:application didReceiveRemoteNotification:userInfo fetchCompletionHandler:completionHandler];
|
||||
}
|
||||
|
||||
#if RCT_NEW_ARCH_ENABLED
|
||||
|
||||
#pragma mark - RCTCxxBridgeDelegate
|
||||
|
||||
- (std::unique_ptr<facebook::react::JSExecutorFactory>)jsExecutorFactoryForBridge:(RCTBridge *)bridge
|
||||
{
|
||||
_turboModuleManager = [[RCTTurboModuleManager alloc] initWithBridge:bridge
|
||||
delegate:self
|
||||
jsInvoker:bridge.jsCallInvoker];
|
||||
return RCTAppSetupDefaultJsExecutorFactory(bridge, _turboModuleManager);
|
||||
}
|
||||
|
||||
#pragma mark RCTTurboModuleManagerDelegate
|
||||
|
||||
- (Class)getModuleClassFromName:(const char *)name
|
||||
{
|
||||
return RCTCoreModulesClassProvider(name);
|
||||
}
|
||||
|
||||
- (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:(const std::string &)name
|
||||
jsInvoker:(std::shared_ptr<facebook::react::CallInvoker>)jsInvoker
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
- (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:(const std::string &)name
|
||||
initParams:
|
||||
(const facebook::react::ObjCTurboModule::InitParams &)params
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
- (id<RCTTurboModule>)getModuleInstanceFromClass:(Class)moduleClass
|
||||
{
|
||||
return RCTAppSetupDefaultModuleFromClass(moduleClass);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@end
|
||||
"
|
||||
`;
|
||||
|
||||
exports[`addSiriShortcutAppDelegateInit adds init to Expo Modules AppDelegate 1`] = `
|
||||
"
|
||||
#import \\"AppDelegate.h\\"
|
||||
|
||||
#import <React/RCTBridge.h>
|
||||
#import <React/RCTBundleURLProvider.h>
|
||||
#import <React/RCTRootView.h>
|
||||
#import <React/RCTLinkingManager.h>
|
||||
#import <React/RCTConvert.h>
|
||||
|
||||
#import <React/RCTAppSetupUtils.h>
|
||||
|
||||
#if RCT_NEW_ARCH_ENABLED
|
||||
#import <React/CoreModulesPlugins.h>
|
||||
#import <React/RCTCxxBridgeDelegate.h>
|
||||
#import <React/RCTFabricSurfaceHostingProxyRootView.h>
|
||||
#import <React/RCTSurfacePresenter.h>
|
||||
#import <React/RCTSurfacePresenterBridgeAdapter.h>
|
||||
#import <ReactCommon/RCTTurboModuleManager.h>
|
||||
|
||||
#import <react/config/ReactNativeConfig.h>
|
||||
|
||||
@interface AppDelegate () <RCTCxxBridgeDelegate, RCTTurboModuleManagerDelegate> {
|
||||
RCTTurboModuleManager *_turboModuleManager;
|
||||
RCTSurfacePresenterBridgeAdapter *_bridgeAdapter;
|
||||
std::shared_ptr<const facebook::react::ReactNativeConfig> _reactNativeConfig;
|
||||
facebook::react::ContextContainer::Shared _contextContainer;
|
||||
}
|
||||
@end
|
||||
#endif
|
||||
|
||||
@implementation AppDelegate
|
||||
|
||||
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
|
||||
{
|
||||
RCTAppSetupPrepareApp(application);
|
||||
|
||||
RCTBridge *bridge = [self.reactDelegate createBridgeWithDelegate:self launchOptions:launchOptions];
|
||||
|
||||
#if RCT_NEW_ARCH_ENABLED
|
||||
_contextContainer = std::make_shared<facebook::react::ContextContainer const>();
|
||||
_reactNativeConfig = std::make_shared<facebook::react::EmptyReactNativeConfig const>();
|
||||
_contextContainer->insert(\\"ReactNativeConfig\\", _reactNativeConfig);
|
||||
_bridgeAdapter = [[RCTSurfacePresenterBridgeAdapter alloc] initWithBridge:bridge contextContainer:_contextContainer];
|
||||
bridge.surfacePresenter = _bridgeAdapter.surfacePresenter;
|
||||
#endif
|
||||
|
||||
UIView *rootView = [self.reactDelegate createRootViewWithBridge:bridge moduleName:@\\"main\\" initialProperties:nil];
|
||||
|
||||
rootView.backgroundColor = [UIColor whiteColor];
|
||||
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
|
||||
UIViewController *rootViewController = [self.reactDelegate createRootViewController];
|
||||
rootViewController.view = rootView;
|
||||
self.window.rootViewController = rootViewController;
|
||||
[self.window makeKeyAndVisible];
|
||||
|
||||
[super application:application didFinishLaunchingWithOptions:launchOptions];
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (NSArray<id<RCTBridgeModule>> *)extraModulesForBridge:(RCTBridge *)bridge
|
||||
{
|
||||
// If you'd like to export some custom RCTBridgeModules, add them here!
|
||||
return @[];
|
||||
}
|
||||
|
||||
- (NSURL *)sourceURLForBridge:(RCTBridge *)bridge
|
||||
{
|
||||
#if DEBUG
|
||||
return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@\\"index\\"];
|
||||
#else
|
||||
return [[NSBundle mainBundle] URLForResource:@\\"main\\" withExtension:@\\"jsbundle\\"];
|
||||
#endif
|
||||
}
|
||||
|
||||
// Linking API
|
||||
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
|
||||
return [super application:application openURL:url options:options] || [RCTLinkingManager application:application openURL:url options:options];
|
||||
}
|
||||
|
||||
// Universal Links
|
||||
- (BOOL)application:(UIApplication *)application continueUserActivity:(nonnull NSUserActivity *)userActivity restorationHandler:(nonnull void (^)(NSArray<id<UIUserActivityRestoring>> * _Nullable))restorationHandler {
|
||||
// @generated begin react-native-siri-shortcut-delegate - expo prebuild (DO NOT MODIFY) sync-291450a04ff243636b0bd0aef4a614f7218690b5
|
||||
BOOL shortcutResult = [RNSSSiriShortcuts application:application continueUserActivity:userActivity restorationHandler:restorationHandler];
|
||||
if (shortcutResult) {
|
||||
return [super application:application continueUserActivity:userActivity restorationHandler:restorationHandler] || shortcutResult;
|
||||
}
|
||||
// @generated end react-native-siri-shortcut-delegate
|
||||
BOOL result = [RCTLinkingManager application:application continueUserActivity:userActivity restorationHandler:restorationHandler];
|
||||
return [super application:application continueUserActivity:userActivity restorationHandler:restorationHandler] || result;
|
||||
}
|
||||
|
||||
// Explicitly define remote notification delegates to ensure compatibility with some third-party libraries
|
||||
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
|
||||
{
|
||||
return [super application:application didRegisterForRemoteNotificationsWithDeviceToken:deviceToken];
|
||||
}
|
||||
|
||||
// Explicitly define remote notification delegates to ensure compatibility with some third-party libraries
|
||||
- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error
|
||||
{
|
||||
return [super application:application didFailToRegisterForRemoteNotificationsWithError:error];
|
||||
}
|
||||
|
||||
// Explicitly define remote notification delegates to ensure compatibility with some third-party libraries
|
||||
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
|
||||
{
|
||||
return [super application:application didReceiveRemoteNotification:userInfo fetchCompletionHandler:completionHandler];
|
||||
}
|
||||
|
||||
#if RCT_NEW_ARCH_ENABLED
|
||||
|
||||
#pragma mark - RCTCxxBridgeDelegate
|
||||
|
||||
- (std::unique_ptr<facebook::react::JSExecutorFactory>)jsExecutorFactoryForBridge:(RCTBridge *)bridge
|
||||
{
|
||||
_turboModuleManager = [[RCTTurboModuleManager alloc] initWithBridge:bridge
|
||||
delegate:self
|
||||
jsInvoker:bridge.jsCallInvoker];
|
||||
return RCTAppSetupDefaultJsExecutorFactory(bridge, _turboModuleManager);
|
||||
}
|
||||
|
||||
#pragma mark RCTTurboModuleManagerDelegate
|
||||
|
||||
- (Class)getModuleClassFromName:(const char *)name
|
||||
{
|
||||
return RCTCoreModulesClassProvider(name);
|
||||
}
|
||||
|
||||
- (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:(const std::string &)name
|
||||
jsInvoker:(std::shared_ptr<facebook::react::CallInvoker>)jsInvoker
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
- (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:(const std::string &)name
|
||||
initParams:
|
||||
(const facebook::react::ObjCTurboModule::InitParams &)params
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
- (id<RCTTurboModule>)getModuleInstanceFromClass:(Class)moduleClass
|
||||
{
|
||||
return RCTAppSetupDefaultModuleFromClass(moduleClass);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@end
|
||||
"
|
||||
`;
|
||||
@@ -1,146 +0,0 @@
|
||||
// SDK +45: https://github.com/expo/expo/blob/sdk-45/templates/expo-template-bare-minimum/ios/HelloWorld/AppDelegate.m
|
||||
export const ExpoModulesAppDelegate = `
|
||||
#import "AppDelegate.h"
|
||||
|
||||
#import <React/RCTBridge.h>
|
||||
#import <React/RCTBundleURLProvider.h>
|
||||
#import <React/RCTRootView.h>
|
||||
#import <React/RCTLinkingManager.h>
|
||||
#import <React/RCTConvert.h>
|
||||
|
||||
#import <React/RCTAppSetupUtils.h>
|
||||
|
||||
#if RCT_NEW_ARCH_ENABLED
|
||||
#import <React/CoreModulesPlugins.h>
|
||||
#import <React/RCTCxxBridgeDelegate.h>
|
||||
#import <React/RCTFabricSurfaceHostingProxyRootView.h>
|
||||
#import <React/RCTSurfacePresenter.h>
|
||||
#import <React/RCTSurfacePresenterBridgeAdapter.h>
|
||||
#import <ReactCommon/RCTTurboModuleManager.h>
|
||||
|
||||
#import <react/config/ReactNativeConfig.h>
|
||||
|
||||
@interface AppDelegate () <RCTCxxBridgeDelegate, RCTTurboModuleManagerDelegate> {
|
||||
RCTTurboModuleManager *_turboModuleManager;
|
||||
RCTSurfacePresenterBridgeAdapter *_bridgeAdapter;
|
||||
std::shared_ptr<const facebook::react::ReactNativeConfig> _reactNativeConfig;
|
||||
facebook::react::ContextContainer::Shared _contextContainer;
|
||||
}
|
||||
@end
|
||||
#endif
|
||||
|
||||
@implementation AppDelegate
|
||||
|
||||
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
|
||||
{
|
||||
RCTAppSetupPrepareApp(application);
|
||||
|
||||
RCTBridge *bridge = [self.reactDelegate createBridgeWithDelegate:self launchOptions:launchOptions];
|
||||
|
||||
#if RCT_NEW_ARCH_ENABLED
|
||||
_contextContainer = std::make_shared<facebook::react::ContextContainer const>();
|
||||
_reactNativeConfig = std::make_shared<facebook::react::EmptyReactNativeConfig const>();
|
||||
_contextContainer->insert("ReactNativeConfig", _reactNativeConfig);
|
||||
_bridgeAdapter = [[RCTSurfacePresenterBridgeAdapter alloc] initWithBridge:bridge contextContainer:_contextContainer];
|
||||
bridge.surfacePresenter = _bridgeAdapter.surfacePresenter;
|
||||
#endif
|
||||
|
||||
UIView *rootView = [self.reactDelegate createRootViewWithBridge:bridge moduleName:@"main" initialProperties:nil];
|
||||
|
||||
rootView.backgroundColor = [UIColor whiteColor];
|
||||
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
|
||||
UIViewController *rootViewController = [self.reactDelegate createRootViewController];
|
||||
rootViewController.view = rootView;
|
||||
self.window.rootViewController = rootViewController;
|
||||
[self.window makeKeyAndVisible];
|
||||
|
||||
[super application:application didFinishLaunchingWithOptions:launchOptions];
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (NSArray<id<RCTBridgeModule>> *)extraModulesForBridge:(RCTBridge *)bridge
|
||||
{
|
||||
// If you'd like to export some custom RCTBridgeModules, add them here!
|
||||
return @[];
|
||||
}
|
||||
|
||||
- (NSURL *)sourceURLForBridge:(RCTBridge *)bridge
|
||||
{
|
||||
#if DEBUG
|
||||
return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index"];
|
||||
#else
|
||||
return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];
|
||||
#endif
|
||||
}
|
||||
|
||||
// Linking API
|
||||
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
|
||||
return [super application:application openURL:url options:options] || [RCTLinkingManager application:application openURL:url options:options];
|
||||
}
|
||||
|
||||
// Universal Links
|
||||
- (BOOL)application:(UIApplication *)application continueUserActivity:(nonnull NSUserActivity *)userActivity restorationHandler:(nonnull void (^)(NSArray<id<UIUserActivityRestoring>> * _Nullable))restorationHandler {
|
||||
BOOL result = [RCTLinkingManager application:application continueUserActivity:userActivity restorationHandler:restorationHandler];
|
||||
return [super application:application continueUserActivity:userActivity restorationHandler:restorationHandler] || result;
|
||||
}
|
||||
|
||||
// Explicitly define remote notification delegates to ensure compatibility with some third-party libraries
|
||||
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
|
||||
{
|
||||
return [super application:application didRegisterForRemoteNotificationsWithDeviceToken:deviceToken];
|
||||
}
|
||||
|
||||
// Explicitly define remote notification delegates to ensure compatibility with some third-party libraries
|
||||
- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error
|
||||
{
|
||||
return [super application:application didFailToRegisterForRemoteNotificationsWithError:error];
|
||||
}
|
||||
|
||||
// Explicitly define remote notification delegates to ensure compatibility with some third-party libraries
|
||||
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
|
||||
{
|
||||
return [super application:application didReceiveRemoteNotification:userInfo fetchCompletionHandler:completionHandler];
|
||||
}
|
||||
|
||||
#if RCT_NEW_ARCH_ENABLED
|
||||
|
||||
#pragma mark - RCTCxxBridgeDelegate
|
||||
|
||||
- (std::unique_ptr<facebook::react::JSExecutorFactory>)jsExecutorFactoryForBridge:(RCTBridge *)bridge
|
||||
{
|
||||
_turboModuleManager = [[RCTTurboModuleManager alloc] initWithBridge:bridge
|
||||
delegate:self
|
||||
jsInvoker:bridge.jsCallInvoker];
|
||||
return RCTAppSetupDefaultJsExecutorFactory(bridge, _turboModuleManager);
|
||||
}
|
||||
|
||||
#pragma mark RCTTurboModuleManagerDelegate
|
||||
|
||||
- (Class)getModuleClassFromName:(const char *)name
|
||||
{
|
||||
return RCTCoreModulesClassProvider(name);
|
||||
}
|
||||
|
||||
- (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:(const std::string &)name
|
||||
jsInvoker:(std::shared_ptr<facebook::react::CallInvoker>)jsInvoker
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
- (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:(const std::string &)name
|
||||
initParams:
|
||||
(const facebook::react::ObjCTurboModule::InitParams &)params
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
- (id<RCTTurboModule>)getModuleInstanceFromClass:(Class)moduleClass
|
||||
{
|
||||
return RCTAppSetupDefaultModuleFromClass(moduleClass);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@end
|
||||
`;
|
||||
@@ -1,42 +0,0 @@
|
||||
import {
|
||||
addSiriShortcutAppDelegateImport,
|
||||
addSiriShortcutAppDelegateInit,
|
||||
} from "../withReactNativeSiriShortcut";
|
||||
import { ExpoModulesAppDelegate } from "./fixtures/AppDelegate";
|
||||
|
||||
describe(addSiriShortcutAppDelegateImport, () => {
|
||||
it(`adds import to Expo Modules AppDelegate`, () => {
|
||||
const results = addSiriShortcutAppDelegateImport(ExpoModulesAppDelegate);
|
||||
// matches a static snapshot
|
||||
expect(results.contents).toMatchSnapshot();
|
||||
expect(results.contents).toMatch(/react-native-siri-shortcut/);
|
||||
expect(results.contents).toMatch(/RNSiriShortcuts\/RNSiriShortcuts\.h/);
|
||||
// did add new content
|
||||
expect(results.didMerge).toBe(true);
|
||||
// didn't remove old content
|
||||
expect(results.didClear).toBe(false);
|
||||
});
|
||||
|
||||
it(`fails to add to a malformed app delegate`, () => {
|
||||
expect(() => addSiriShortcutAppDelegateImport(`foobar`)).toThrow(/foobar/);
|
||||
});
|
||||
});
|
||||
describe(addSiriShortcutAppDelegateInit, () => {
|
||||
it(`adds init to Expo Modules AppDelegate`, () => {
|
||||
const results = addSiriShortcutAppDelegateInit(ExpoModulesAppDelegate);
|
||||
// matches a static snapshot
|
||||
expect(results.contents).toMatchSnapshot();
|
||||
expect(results.contents).toMatch(/react-native-siri-shortcut-delegate/);
|
||||
expect(results.contents).toMatch(
|
||||
/RNSSSiriShortcuts application:application/
|
||||
);
|
||||
// did add new content
|
||||
expect(results.didMerge).toBe(true);
|
||||
// didn't remove old content
|
||||
expect(results.didClear).toBe(false);
|
||||
});
|
||||
|
||||
it(`fails to add to a malformed app delegate`, () => {
|
||||
expect(() => addSiriShortcutAppDelegateInit(`foobar`)).toThrow(/foobar/);
|
||||
});
|
||||
});
|
||||
@@ -1,119 +0,0 @@
|
||||
import {
|
||||
ConfigPlugin,
|
||||
createRunOncePlugin,
|
||||
withAppDelegate,
|
||||
withInfoPlist,
|
||||
withEntitlementsPlist,
|
||||
} from "@expo/config-plugins";
|
||||
import {
|
||||
mergeContents,
|
||||
MergeResults,
|
||||
} from "@expo/config-plugins/build/utils/generateCode";
|
||||
|
||||
/**
|
||||
* Apply react-native-siri-shortcut configuration for Expo SDK 44 projects.
|
||||
*/
|
||||
const withReactNativeSiriShortcut: ConfigPlugin<void | string[]> = (
|
||||
config,
|
||||
activityTypes
|
||||
) => {
|
||||
withSiriShortcutAppDelegate(config);
|
||||
withSiriEntitlements(config);
|
||||
|
||||
const items = activityTypes || [];
|
||||
|
||||
if (!Array.isArray(items) || !items.length) {
|
||||
return config;
|
||||
}
|
||||
return withReactNativeSiriShortcutInfoPlist(config, items);
|
||||
};
|
||||
|
||||
const withReactNativeSiriShortcutInfoPlist: ConfigPlugin<string[]> = (
|
||||
config,
|
||||
activityTypes
|
||||
) => {
|
||||
return withInfoPlist(config, (config) => {
|
||||
config.modResults.NSUserActivityTypes = activityTypes;
|
||||
return config;
|
||||
});
|
||||
};
|
||||
|
||||
export function addSiriShortcutAppDelegateImport(src: string): MergeResults {
|
||||
return mergeContents({
|
||||
tag: "react-native-siri-shortcut",
|
||||
src,
|
||||
newSrc: "#import <RNSiriShortcuts/RNSiriShortcuts.h>",
|
||||
anchor: /#import "AppDelegate\.h"/,
|
||||
offset: 1,
|
||||
comment: "//",
|
||||
});
|
||||
}
|
||||
|
||||
export function addSiriShortcutAppDelegateInit(src: string): MergeResults {
|
||||
return mergeContents({
|
||||
tag: "react-native-siri-shortcut-delegate",
|
||||
src,
|
||||
newSrc: [
|
||||
" BOOL shortcutResult = [RNSSSiriShortcuts application:application continueUserActivity:userActivity restorationHandler:restorationHandler];",
|
||||
" if (shortcutResult) {",
|
||||
" return [super application:application continueUserActivity:userActivity restorationHandler:restorationHandler] || shortcutResult;",
|
||||
" }",
|
||||
].join("\n"),
|
||||
anchor:
|
||||
/ return \[super application:application continueUserActivity:userActivity restorationHandler:restorationHandler\] \|\| result;/,
|
||||
offset: -1,
|
||||
comment: "//",
|
||||
});
|
||||
}
|
||||
|
||||
/** Append the siri entitlement on iOS */
|
||||
const withSiriEntitlements: ConfigPlugin = (config) => {
|
||||
return withEntitlementsPlist(config, (config) => {
|
||||
config.modResults["com.apple.developer.siri"] = true;
|
||||
return config;
|
||||
});
|
||||
};
|
||||
|
||||
const withSiriShortcutAppDelegate: ConfigPlugin = (config) => {
|
||||
return withAppDelegate(config, (config) => {
|
||||
if (["objc", "objcpp"].includes(config.modResults.language)) {
|
||||
try {
|
||||
config.modResults.contents = addSiriShortcutAppDelegateImport(
|
||||
config.modResults.contents
|
||||
).contents;
|
||||
config.modResults.contents = addSiriShortcutAppDelegateInit(
|
||||
config.modResults.contents
|
||||
).contents;
|
||||
} catch (error: any) {
|
||||
if (error.code === "ERR_NO_MATCH") {
|
||||
throw new Error(
|
||||
`Cannot add Siri Shortcut to the project's AppDelegate because it's malformed. Please report this with a copy of your project AppDelegate.`
|
||||
);
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
} else {
|
||||
throw new Error(
|
||||
"Cannot setup Siri Shortcut because the AppDelegate is not Objective C"
|
||||
);
|
||||
}
|
||||
return config;
|
||||
});
|
||||
};
|
||||
|
||||
const pkg = {
|
||||
// Prevent this plugin from being run more than once.
|
||||
// This pattern enables users to safely migrate off of this
|
||||
// out-of-tree `@config-plugins/react-native-siri-shortcut` to a future
|
||||
// upstream plugin in `react-native-siri-shortcut`
|
||||
name: "react-native-siri-shortcut",
|
||||
// Indicates that this plugin is dangerously linked to a module,
|
||||
// and might not work with the latest version of that module.
|
||||
version: "UNVERSIONED",
|
||||
};
|
||||
|
||||
export default createRunOncePlugin(
|
||||
withReactNativeSiriShortcut,
|
||||
pkg.name,
|
||||
pkg.version
|
||||
);
|
||||
@@ -4976,6 +4976,15 @@ airbnb-prop-types@^2.16.0:
|
||||
prop-types-exact "^1.2.0"
|
||||
react-is "^16.13.1"
|
||||
|
||||
airbridge-react-native-sdk@^1.4.5:
|
||||
version "1.4.5"
|
||||
resolved "https://registry.yarnpkg.com/airbridge-react-native-sdk/-/airbridge-react-native-sdk-1.4.5.tgz#281d370b4ff3f4491b80d8a0d6d771de5024c4b9"
|
||||
integrity sha512-gdpm+p5m6pk5CPQ/hrW+ll5qs3xFunwMDZR3A4v8oRpGSoqDQrelBflWwf3B/ay9dSFwBARfdOsj4H+Mho/LpQ==
|
||||
dependencies:
|
||||
lodash.isfunction "^3.0.9"
|
||||
lodash.isplainobject "^4.0.6"
|
||||
lodash.isstring "^4.0.1"
|
||||
|
||||
ajv-errors@^1.0.0:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/ajv-errors/-/ajv-errors-1.0.1.tgz#f35986aceb91afadec4102fbd85014950cefa64d"
|
||||
@@ -9060,11 +9069,6 @@ fast-diff@^1.1.2:
|
||||
resolved "https://registry.yarnpkg.com/fast-diff/-/fast-diff-1.2.0.tgz#73ee11982d86caaf7959828d519cfe927fac5f03"
|
||||
integrity sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==
|
||||
|
||||
[email protected]:
|
||||
version "0.0.2"
|
||||
resolved "https://registry.yarnpkg.com/fast-extend/-/fast-extend-0.0.2.tgz#f5ec42cf40b9460f521a6387dfb52deeed671dbd"
|
||||
integrity sha1-9exCz0C5Rg9SGmOH37Ut7u1nHb0=
|
||||
|
||||
fast-glob@^2.2.6:
|
||||
version "2.2.7"
|
||||
resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-2.2.7.tgz#6953857c3afa475fff92ee6015d52da70a4cd39d"
|
||||
@@ -9537,11 +9541,6 @@ fs-minipass@^2.0.0, fs-minipass@^2.1.0:
|
||||
dependencies:
|
||||
minipass "^3.0.0"
|
||||
|
||||
fs-monkey@^0.3.3:
|
||||
version "0.3.3"
|
||||
resolved "https://registry.yarnpkg.com/fs-monkey/-/fs-monkey-0.3.3.tgz#7960bb2b1fa2653731b9d0e2e84812a7e8b3664a"
|
||||
integrity sha512-FNUvuTAJ3CqCQb5ELn+qCbGR/Zllhf2HtwsdAtBi59s1WeCjKMT81fHcSu7dwIskqGVK+MmOrb7VOBlq3/SItw==
|
||||
|
||||
fs-readdir-recursive@^1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz#e32fc030a2ccee44a6b5371308da54be0b397d27"
|
||||
@@ -13144,6 +13143,11 @@ lodash.isequal@^4.5.0:
|
||||
resolved "https://registry.yarnpkg.com/lodash.isequal/-/lodash.isequal-4.5.0.tgz#415c4478f2bcc30120c22ce10ed3226f7d3e18e0"
|
||||
integrity sha1-QVxEePK8wwEgwizhDtMib30+GOA=
|
||||
|
||||
lodash.isfunction@^3.0.9:
|
||||
version "3.0.9"
|
||||
resolved "https://registry.yarnpkg.com/lodash.isfunction/-/lodash.isfunction-3.0.9.tgz#06de25df4db327ac931981d1bdb067e5af68d051"
|
||||
integrity sha512-AirXNj15uRIMMPihnkInB4i3NHeb4iBtNg9WRWuK2o31S+ePwwNmDPaTL3o7dTJ+VXNZim7rFs4rxN4YU1oUJw==
|
||||
|
||||
lodash.ismatch@^4.4.0:
|
||||
version "4.4.0"
|
||||
resolved "https://registry.yarnpkg.com/lodash.ismatch/-/lodash.ismatch-4.4.0.tgz#756cb5150ca3ba6f11085a78849645f188f85f37"
|
||||
@@ -13576,14 +13580,6 @@ [email protected]:
|
||||
resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748"
|
||||
integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=
|
||||
|
||||
memfs@^2.15.5:
|
||||
version "2.17.1"
|
||||
resolved "https://registry.yarnpkg.com/memfs/-/memfs-2.17.1.tgz#bfcc11b6308214b4fb33eaca101132722d22e103"
|
||||
integrity sha512-4kAcqibPAd8DN8/UIW/6OwvbhNq6MqwsQ0pxjo+2ZmxPlQAbn9TAepnRpdeYfw4Qq0Y+QqwE6wngLUowo2fcjg==
|
||||
dependencies:
|
||||
fast-extend "0.0.2"
|
||||
fs-monkey "^0.3.3"
|
||||
|
||||
memory-cache@~0.2.0:
|
||||
version "0.2.0"
|
||||
resolved "https://registry.yarnpkg.com/memory-cache/-/memory-cache-0.2.0.tgz#7890b01d52c00c8ebc9d533e1f8eb17e3034871a"
|
||||
@@ -16941,11 +16937,6 @@ [email protected]:
|
||||
resolved "https://registry.yarnpkg.com/react-native-safe-area-context/-/react-native-safe-area-context-4.2.4.tgz#4df42819759c4d3c74252c8678c2772cfa2271a6"
|
||||
integrity sha512-OOX+W2G4YYufvryonn6Kw6YnyT8ZThkxPHZBD04NLHaZmicUaaDVII/PZ3M5fD1o5N62+T+8K4bCS5Un2ggvkA==
|
||||
|
||||
react-native-siri-shortcut@^3.1.0:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/react-native-siri-shortcut/-/react-native-siri-shortcut-3.1.0.tgz#920adf41eb6c72c93ef8571259c8d35358e50e71"
|
||||
integrity sha512-MM0f7HS3ADU2gUh0Q6n935uhdfA3KgjpN8hEEhf2RSf4azcRNh8zNMwZD08pGSrP9/JYj1kYndQ0oytpwPyk/A==
|
||||
|
||||
[email protected]:
|
||||
version "0.17.7"
|
||||
resolved "https://registry.yarnpkg.com/react-native-web/-/react-native-web-0.17.7.tgz#038899dbc94467a0ca0be214b88a30e0c117b176"
|
||||
|
||||
Reference in new issue
Block a user