From 6e18f6de6b013c60795f3402d51157cf810b9f68 Mon Sep 17 00:00:00 2001 From: Henning Hall Date: Mon, 16 Oct 2023 17:02:50 +0200 Subject: [PATCH] chore: installation error message (#716) * installation error messages * cleanup * setup node v3 --- .github/workflows/main.yml | 2 +- .github/workflows/unit-tests.yml | 2 +- README.md | 20 ++++++++++---- src/DatePickerAndroid.js | 29 ++++++-------------- src/DatePickerIOS.js | 23 +++++----------- src/index.js | 8 ++---- src/installationError.js | 47 ++++++++++++++++++++++++++++++++ src/modules.js | 44 ++++++++++++++++++++++++++++++ 8 files changed, 125 insertions(+), 50 deletions(-) create mode 100644 src/installationError.js create mode 100644 src/modules.js diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index acf801d..88147ff 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -10,7 +10,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v1 - - uses: actions/setup-node@v1 + - uses: actions/setup-node@v3 with: node-version: 12 registry-url: https://registry.npmjs.org/ diff --git a/.github/workflows/unit-tests.yml b/.github/workflows/unit-tests.yml index 33e3c02..b7e8d87 100644 --- a/.github/workflows/unit-tests.yml +++ b/.github/workflows/unit-tests.yml @@ -21,7 +21,7 @@ jobs: fetch-depth: 1 - name: Node - uses: actions/setup-node@v1 + uses: actions/setup-node@v3 - name: Install npm dependencies run: | diff --git a/README.md b/README.md index 502c9e7..46606da 100644 --- a/README.md +++ b/README.md @@ -52,17 +52,20 @@ The second option is to use the inlined picker. Place it in a View or a custom m ## Installation -1. Download package with npm or yarn +1. Download package -``` +```sh +# npm npm install react-native-date-picker -``` -``` +# yarn yarn add react-native-date-picker + +# pnpm +pnpm add react-native-date-picker ``` -2. Install pods +2. Install pods (skip for expo projects) ``` cd ios && pod install @@ -70,7 +73,12 @@ cd ios && pod install 3. Rebuild the project -``` +```sh +# expo projects +npx expo run:android +npx expo run:ios + +# non-expo projects npx react-native run-android npx react-native run-ios ``` diff --git a/src/DatePickerAndroid.js b/src/DatePickerAndroid.js index f09a790..128f36a 100644 --- a/src/DatePickerAndroid.js +++ b/src/DatePickerAndroid.js @@ -1,46 +1,33 @@ import React from 'react' -import { - NativeEventEmitter, - NativeModules, - Platform, - TurboModuleRegistry, - requireNativeComponent, -} from 'react-native' +import { NativeEventEmitter } from 'react-native' import { shouldCloseModal, shouldOpenModal } from './modal' +import { getNativeComponent, getNativeModule } from './modules' -const NativeDatePicker = - Platform.OS === 'android' - ? requireNativeComponent('RNDatePicker', DatePickerAndroid, { - nativeOnly: { onChange: true }, - }) - : null +const NativeComponent = getNativeComponent() +const NativeModule = getNativeModule() const height = 180 const timeModeWidth = 240 const defaultWidth = 310 -const NativePicker = TurboModuleRegistry - ? TurboModuleRegistry.get('RNDatePicker') - : NativeModules.RNDatePicker - class DatePickerAndroid extends React.PureComponent { render() { const props = this.getProps() if (shouldOpenModal(props, this.previousProps)) { this.isClosing = false - NativePicker.openPicker(props) + NativeModule.openPicker(props) } if (shouldCloseModal(props, this.previousProps, this.isClosing)) { this.closing = true - NativePicker.closePicker() + NativeModule.closePicker() } this.previousProps = props if (props.modal) return null - return + return } getId = () => { @@ -51,7 +38,7 @@ class DatePickerAndroid extends React.PureComponent { } componentDidMount = () => { - this.eventEmitter = new NativeEventEmitter(NativePicker) + this.eventEmitter = new NativeEventEmitter(NativeModule) this.eventEmitter.addListener('dateChange', this._onChange) this.eventEmitter.addListener('onConfirm', this._onConfirm) this.eventEmitter.addListener('onCancel', this._onCancel) diff --git a/src/DatePickerIOS.js b/src/DatePickerIOS.js index be0108a..5e1f271 100644 --- a/src/DatePickerIOS.js +++ b/src/DatePickerIOS.js @@ -1,15 +1,10 @@ import React from 'react' -import { - NativeModules, - Platform, - StyleSheet, - requireNativeComponent, -} from 'react-native' +import { StyleSheet } from 'react-native' import { shouldCloseModal, shouldOpenModal } from './modal' +import { getNativeComponent, getNativeModule } from './modules' -// TODO: Move to its own file -const RCTDatePickerIOS = - Platform.OS === 'ios' ? requireNativeComponent('RNDatePicker') : null +const NativeComponent = getNativeComponent() +const NativeModule = getNativeModule() export default class DatePickerIOS extends React.Component { _onChange = (event) => { @@ -45,15 +40,11 @@ export default class DatePickerIOS extends React.Component { if (shouldOpenModal(props, this.previousProps)) { this.isClosing = false - NativeModules.RNDatePicker.openPicker( - props, - this._onConfirm, - this._onCancel - ) + NativeModule.openPicker(props, this._onConfirm, this._onCancel) } if (shouldCloseModal(props, this.previousProps, this.isClosing)) { this.isClosing = true - NativeModules.RNDatePicker.closePicker() + NativeModule.closePicker() } this.previousProps = props @@ -61,7 +52,7 @@ export default class DatePickerIOS extends React.Component { if (props.modal) return null return ( - true} diff --git a/src/index.js b/src/index.js index 5c8f5d5..c1bdc75 100644 --- a/src/index.js +++ b/src/index.js @@ -1,15 +1,13 @@ import React from 'react' import { Appearance, Platform, Text } from 'react-native' -import DatePickerAndroid from './DatePickerAndroid' -import DatePickerIOS from './DatePickerIOS' import { colorToHex } from './colorToHex' import { throwIfInvalidProps } from './propChecker' const DatePicker = Platform.select({ - android: DatePickerAndroid, - ios: DatePickerIOS, + android: () => require('./DatePickerAndroid').default, + ios: () => require('./DatePickerIOS').default, default: () => DatePicker is not supported on this platform., -}) +})() const DatePickerWrapper = (props) => { if (__DEV__) throwIfInvalidProps(props) diff --git a/src/installationError.js b/src/installationError.js new file mode 100644 index 0000000..e2efb0a --- /dev/null +++ b/src/installationError.js @@ -0,0 +1,47 @@ +import { Platform } from 'react-native' + +const getMessage = (message) => { + return [ + 'react-native-date-picker is not installed correctly. Make sure you: ', + '', + ...message, + '', + 'Please reply in this thread if this solved your issue or not: ', + 'https://github.com/henninghall/react-native-date-picker/issues/404', + '', + "To ignore this warning, add 'global.ignoreDatePickerWarning = true' to the top of your index file.", + ].join('\n') +} + +const messages = { + ios: { + expo: getMessage([ + "1. Have rebuilt your app (with for instance 'npx expo run:ios')", + `2. Are not using Expo Go (Expo Go is unsupported). See README for more info: `, + 'https://github.com/henninghall/react-native-date-picker', + ]), + nonExpo: getMessage([ + "1. Installed pods (by for instance running 'cd ios && pod install')", + "2. Rebuilt the app (by for instance 'npx react-native run-ios')", + ]), + }, + android: { + expo: getMessage([ + "1. Have rebuilt your app (with for instance 'npx expo run:android')", + `2. Are not using Expo Go (Expo Go is unsupported). See README for more info: `, + 'https://github.com/henninghall/react-native-date-picker', + ]), + nonExpo: getMessage([ + "1. Rebuilt the app (by for instance 'npx react-native run-ios')", + ]), + }, +} + +export const getInstallationErrorMessage = () => { + try { + require('expo-constants').default + return messages[Platform.OS].expo + } catch (e) { + return messages[Platform.OS].nonExpo + } +} diff --git a/src/modules.js b/src/modules.js new file mode 100644 index 0000000..c9bbf62 --- /dev/null +++ b/src/modules.js @@ -0,0 +1,44 @@ +import { + NativeModules, + Platform, + TurboModuleRegistry, + requireNativeComponent, +} from 'react-native' +import { getInstallationErrorMessage } from './installationError' + +export const getNativeComponent = () => { + try { + switch (Platform.OS) { + case 'android': + case 'ios': + return requireNativeComponent('RNDatePicker') + default: + throw Error( + 'react-native-date-picker is not supported on this platform' + ) + } + } catch (e) { + if (global.ignoreDatePickerWarning) return null + throw Error(getInstallationErrorMessage()) + } +} + +export const getNativeModule = () => { + try { + switch (Platform.OS) { + case 'ios': + return NativeModules.RNDatePicker + case 'android': + return TurboModuleRegistry + ? TurboModuleRegistry.get('RNDatePicker') + : NativeModules.RNDatePicker + default: + throw Error( + 'react-native-date-picker is not supported on this platform' + ) + } + } catch (e) { + if (global.ignoreDatePickerWarning) return null + throw Error(getInstallationErrorMessage()) + } +}