@kirz/react-native-toolkit
Version:
Toolkit to speed up React Native development
252 lines • 15.9 kB
JavaScript
function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
import PQueue from 'p-queue';
import React, { createContext, useCallback, useMemo, useRef, useState } from 'react';
import { ActionSheetIOS, Alert, Platform, TouchableOpacity, View } from 'react-native';
import Modal from 'react-native-modal';
import { BlurView } from '../components/BlurView';
import { ControlledPromise, useTheme } from '../index';
export const AlertsContext = /*#__PURE__*/createContext({});
export function AlertsProvider(_ref) {
let {
children
} = _ref;
const theme = useTheme();
const [isActiveModalVisible, setIsActiveModalVisible] = useState(false);
const alertsStack = useRef([]);
const activeAlertRef = useRef(null);
const activeAlertAwaiter = useRef(null);
const alertsQueue = useRef(new PQueue({
concurrency: 1
}));
const alertsDefinition = theme.alerts;
const dequeueAlert = useCallback((alertDefinition, id) => {
return alertsQueue.current.add(async () => {
var _activeAlertRef$curre;
if (((_activeAlertRef$curre = activeAlertRef.current) === null || _activeAlertRef$curre === void 0 ? void 0 : _activeAlertRef$curre.id) !== id) {
alertsStack.current = alertsStack.current.filter(x => x.id !== id);
return;
}
if (!('component' in alertDefinition)) {
// can't hide system alert
alertsStack.current.pop();
} else {
activeAlertAwaiter.current = new ControlledPromise();
setIsActiveModalVisible(false);
await activeAlertAwaiter.current.wait();
activeAlertAwaiter.current = null;
}
alertsStack.current.pop();
activeAlertRef.current = alertsStack.current[alertsStack.current.length - 1] ?? null;
if (!activeAlertRef.current) {
return;
}
if (!('component' in activeAlertRef.current)) {
if ('type' in activeAlertRef.current && activeAlertRef.current.type === 'action-sheet') {
// @ts-ignore
ActionSheetIOS.showActionSheetWithOptions(...alertProps);
} else {
// @ts-ignore
Alert.alert(...activeAlertRef.current.systemAlertProps);
}
} else {
if (!activeAlertRef.current.type || activeAlertRef.current.type === 'modal') {
activeAlertAwaiter.current = new ControlledPromise();
setIsActiveModalVisible(true);
await activeAlertAwaiter.current.wait();
activeAlertAwaiter.current = null;
}
}
});
}, []);
const enqueueAlert = useCallback((alert, resolve, reject, props, name) => {
return alertsQueue.current.add(async () => {
if (activeAlertRef.current) {
activeAlertAwaiter.current = new ControlledPromise();
setIsActiveModalVisible(false);
await activeAlertAwaiter.current.wait();
activeAlertAwaiter.current = null;
}
const id = name;
const alertDefinition = typeof alert === 'function' ? alert(props ?? {}) : alert;
if (!('component' in alertDefinition)) {
var _alertDefinition$butt;
const onButtonPress = button => {
var _button$onPress;
if (!button.onPress && (!button.style || button.style === 'default' || button.style === 'destructive')) {
resolve(true);
dequeueAlert(alertDefinition, id);
return;
}
if (!button.onPress && button.style === 'cancel') {
resolve(false);
dequeueAlert(alertDefinition, id);
return;
}
button === null || button === void 0 ? void 0 : (_button$onPress = button.onPress) === null || _button$onPress === void 0 ? void 0 : _button$onPress.call(button, resolve, reject);
dequeueAlert(alertDefinition, id);
};
const alertProps = alertDefinition.type === 'action-sheet' ? [{
title: alertDefinition.title,
message: alertDefinition.message,
options: alertDefinition.buttons.map(x => x.text),
cancelButtonIndex: (() => {
const index = alertDefinition.buttons.findIndex(x => x.style === 'cancel');
return index === -1 ? undefined : index;
})(),
destructiveButtonIndex: (() => {
const index = alertDefinition.buttons.findIndex(x => x.style === 'destructive');
return index === -1 ? undefined : index;
})()
}, buttonIndex => {
onButtonPress(alertDefinition.buttons[buttonIndex]);
}] : [alertDefinition.title, alertDefinition.message, (_alertDefinition$butt = alertDefinition.buttons) !== null && _alertDefinition$butt !== void 0 && _alertDefinition$butt.length ? alertDefinition.buttons.map(button => ({
style: button.style,
text: button.text,
onPress: () => {
onButtonPress(button);
}
})) : [{
text: 'OK',
onPress: () => {
onButtonPress({
text: 'OK'
});
}
}], {
cancelable: false
}];
alertsStack.current = [...alertsStack.current, {
...alertDefinition,
...{
systemAlertProps: alertProps
},
id
}];
activeAlertRef.current = alertsStack.current[alertsStack.current.length - 1];
if (alertDefinition.type === 'action-sheet') {
// @ts-ignore
ActionSheetIOS.showActionSheetWithOptions(...alertProps);
} else {
// @ts-ignore
Alert.alert(...alertProps);
}
} else {
if (!alertDefinition.type || alertDefinition.type === 'modal') {
alertsStack.current = [...alertsStack.current, {
...alertDefinition,
id,
component: () => /*#__PURE__*/React.createElement(alertDefinition.component, {
resolve: value => {
resolve(value);
dequeueAlert(alertDefinition, id);
},
reject: value => {
reject(value);
dequeueAlert(alertDefinition, id);
},
options: {
...alertDefinition.componentProps,
...props
}
})
}];
activeAlertAwaiter.current = new ControlledPromise();
activeAlertRef.current = alertsStack.current[alertsStack.current.length - 1];
setIsActiveModalVisible(true);
await activeAlertAwaiter.current.wait();
activeAlertAwaiter.current = null;
}
}
});
}, [dequeueAlert]);
const showAlert = useCallback(async (name, props) => {
const alertDefinition = alertsDefinition[name];
if (!alertDefinition) {
throw new Error(`Alert "${name}" is not registered`);
}
return new Promise((resolve, reject) => {
enqueueAlert(alertDefinition, resolve, reject, props ?? {}, name);
});
}, [alertsDefinition, enqueueAlert]);
const hideAlert = useCallback(async name => {
const alertDefinition = alertsDefinition[name];
if (!alertDefinition) {
throw new Error(`Alert "${name}" is not registered`);
}
await dequeueAlert(alertDefinition, name);
}, [alertsDefinition, enqueueAlert]);
const contextData = useMemo(() => ({
showAlert,
hideAlert
}), [showAlert, hideAlert]);
return /*#__PURE__*/React.createElement(AlertsContext.Provider, {
value: contextData
}, children, (() => {
if (!activeAlertRef.current) {
return null;
}
if (!('component' in activeAlertRef.current)) {
return null;
}
if (!activeAlertRef.current.type || activeAlertRef.current.type === 'modal') {
var _activeAlertRef$curre2, _activeAlertRef$curre3, _activeAlertRef$curre4, _activeAlertRef$curre5, _activeAlertRef$curre6, _activeAlertRef$curre7, _activeAlertRef$curre8, _activeAlertRef$curre21, _activeAlertRef$curre22, _activeAlertRef$curre23, _activeAlertRef$curre24, _activeAlertRef$curre25, _activeAlertRef$curre32, _activeAlertRef$curre33, _activeAlertRef$curre34, _activeAlertRef$curre35, _activeAlertRef$curre36;
return /*#__PURE__*/React.createElement(Modal, _extends({}, activeAlertRef.current.modalProps, {
isVisible: isActiveModalVisible,
backdropColor: (_activeAlertRef$curre2 = activeAlertRef.current.modalProps) !== null && _activeAlertRef$curre2 !== void 0 && _activeAlertRef$curre2.blurType ? undefined : (_activeAlertRef$curre3 = activeAlertRef.current.modalProps) === null || _activeAlertRef$curre3 === void 0 ? void 0 : _activeAlertRef$curre3.backdropColor,
backdropOpacity: (_activeAlertRef$curre4 = activeAlertRef.current.modalProps) !== null && _activeAlertRef$curre4 !== void 0 && _activeAlertRef$curre4.blurType ? 1 : (_activeAlertRef$curre5 = activeAlertRef.current.modalProps) === null || _activeAlertRef$curre5 === void 0 ? void 0 : _activeAlertRef$curre5.backdropOpacity,
customBackdrop: ((_activeAlertRef$curre6 = activeAlertRef.current) === null || _activeAlertRef$curre6 === void 0 ? void 0 : (_activeAlertRef$curre7 = _activeAlertRef$curre6.modalProps) === null || _activeAlertRef$curre7 === void 0 ? void 0 : _activeAlertRef$curre7.customBackdrop) ?? ((_activeAlertRef$curre8 = activeAlertRef.current.modalProps) !== null && _activeAlertRef$curre8 !== void 0 && _activeAlertRef$curre8.blurType ? (() => {
var _activeAlertRef$curre9, _activeAlertRef$curre10, _activeAlertRef$curre11, _activeAlertRef$curre12, _activeAlertRef$curre13, _activeAlertRef$curre14, _activeAlertRef$curre15, _activeAlertRef$curre16, _activeAlertRef$curre17, _activeAlertRef$curre18, _activeAlertRef$curre19, _activeAlertRef$curre20;
const content = /*#__PURE__*/React.createElement(BlurView, _extends({}, (_activeAlertRef$curre9 = activeAlertRef.current.modalProps) === null || _activeAlertRef$curre9 === void 0 ? void 0 : _activeAlertRef$curre9.blurProps, {
animated: ((_activeAlertRef$curre10 = activeAlertRef.current.modalProps) === null || _activeAlertRef$curre10 === void 0 ? void 0 : (_activeAlertRef$curre11 = _activeAlertRef$curre10.blurProps) === null || _activeAlertRef$curre11 === void 0 ? void 0 : _activeAlertRef$curre11.animated) ?? true,
blurAmount: ((_activeAlertRef$curre12 = activeAlertRef.current.modalProps) === null || _activeAlertRef$curre12 === void 0 ? void 0 : (_activeAlertRef$curre13 = _activeAlertRef$curre12.blurProps) === null || _activeAlertRef$curre13 === void 0 ? void 0 : _activeAlertRef$curre13.blurAmount) ?? 20,
enteringAnimationDuration: ((_activeAlertRef$curre14 = activeAlertRef.current.modalProps) === null || _activeAlertRef$curre14 === void 0 ? void 0 : (_activeAlertRef$curre15 = _activeAlertRef$curre14.blurProps) === null || _activeAlertRef$curre15 === void 0 ? void 0 : _activeAlertRef$curre15.enteringAnimationDuration) ?? 200,
blurType: ((_activeAlertRef$curre16 = activeAlertRef.current.modalProps) === null || _activeAlertRef$curre16 === void 0 ? void 0 : _activeAlertRef$curre16.blurType) ?? (Platform.OS === 'ios' ? 'transparent' : 'dark'),
style: [{
flex: 1
}, (_activeAlertRef$curre17 = activeAlertRef.current.modalProps) === null || _activeAlertRef$curre17 === void 0 ? void 0 : (_activeAlertRef$curre18 = _activeAlertRef$curre17.blurProps) === null || _activeAlertRef$curre18 === void 0 ? void 0 : _activeAlertRef$curre18.style]
}));
if (!((_activeAlertRef$curre19 = activeAlertRef.current) !== null && _activeAlertRef$curre19 !== void 0 && (_activeAlertRef$curre20 = _activeAlertRef$curre19.modalProps) !== null && _activeAlertRef$curre20 !== void 0 && _activeAlertRef$curre20.onBackdropPress)) {
return content;
}
return /*#__PURE__*/React.createElement(TouchableOpacity, {
activeOpacity: 1,
onPress: activeAlertRef.current.modalProps.onBackdropPress,
style: {
flex: 1
}
}, content);
})() : undefined),
animationIn: ((_activeAlertRef$curre21 = activeAlertRef.current.modalProps) === null || _activeAlertRef$curre21 === void 0 ? void 0 : _activeAlertRef$curre21.animationIn) ?? 'bounceIn',
animationOut: ((_activeAlertRef$curre22 = activeAlertRef.current.modalProps) === null || _activeAlertRef$curre22 === void 0 ? void 0 : _activeAlertRef$curre22.animationOut) ?? 'zoomOut',
animationOutTiming: ((_activeAlertRef$curre23 = activeAlertRef.current.modalProps) === null || _activeAlertRef$curre23 === void 0 ? void 0 : _activeAlertRef$curre23.animationOutTiming) ?? 100,
useNativeDriverForBackdrop: ((_activeAlertRef$curre24 = activeAlertRef.current.modalProps) === null || _activeAlertRef$curre24 === void 0 ? void 0 : _activeAlertRef$curre24.useNativeDriverForBackdrop) ?? true,
avoidKeyboard: ((_activeAlertRef$curre25 = activeAlertRef.current.modalProps) === null || _activeAlertRef$curre25 === void 0 ? void 0 : _activeAlertRef$curre25.avoidKeyboard) ?? true,
onModalHide: () => {
var _activeAlertRef$curre26, _activeAlertRef$curre27, _activeAlertRef$curre28;
activeAlertAwaiter.current.resolve();
// @ts-ignore
activeAlertRef === null || activeAlertRef === void 0 ? void 0 : (_activeAlertRef$curre26 = activeAlertRef.current) === null || _activeAlertRef$curre26 === void 0 ? void 0 : (_activeAlertRef$curre27 = _activeAlertRef$curre26.modalProps) === null || _activeAlertRef$curre27 === void 0 ? void 0 : (_activeAlertRef$curre28 = _activeAlertRef$curre27.onModalHide) === null || _activeAlertRef$curre28 === void 0 ? void 0 : _activeAlertRef$curre28.call(_activeAlertRef$curre27);
},
onModalShow: () => {
var _activeAlertRef$curre29, _activeAlertRef$curre30, _activeAlertRef$curre31;
activeAlertAwaiter.current.resolve();
// @ts-ignore
activeAlertRef === null || activeAlertRef === void 0 ? void 0 : (_activeAlertRef$curre29 = activeAlertRef.current) === null || _activeAlertRef$curre29 === void 0 ? void 0 : (_activeAlertRef$curre30 = _activeAlertRef$curre29.modalProps) === null || _activeAlertRef$curre30 === void 0 ? void 0 : (_activeAlertRef$curre31 = _activeAlertRef$curre30.onModalShow) === null || _activeAlertRef$curre31 === void 0 ? void 0 : _activeAlertRef$curre31.call(_activeAlertRef$curre30);
},
style: [{
margin: 0
}, activeAlertRef === null || activeAlertRef === void 0 ? void 0 : (_activeAlertRef$curre32 = activeAlertRef.current) === null || _activeAlertRef$curre32 === void 0 ? void 0 : (_activeAlertRef$curre33 = _activeAlertRef$curre32.modalProps) === null || _activeAlertRef$curre33 === void 0 ? void 0 : _activeAlertRef$curre33.style],
backdropTransitionOutTiming: (activeAlertRef === null || activeAlertRef === void 0 ? void 0 : (_activeAlertRef$curre34 = activeAlertRef.current) === null || _activeAlertRef$curre34 === void 0 ? void 0 : (_activeAlertRef$curre35 = _activeAlertRef$curre34.modalProps) === null || _activeAlertRef$curre35 === void 0 ? void 0 : _activeAlertRef$curre35.backdropTransitionOutTiming) ?? 0
}), /*#__PURE__*/React.createElement(View, {
style: {
flex: 1,
justifyContent: 'center',
alignItems: 'center'
},
pointerEvents: "box-none"
}, ((_activeAlertRef$curre36 = activeAlertRef.current) === null || _activeAlertRef$curre36 === void 0 ? void 0 : _activeAlertRef$curre36.component) && /*#__PURE__*/React.createElement(activeAlertRef.current.component, null)));
}
return null;
})());
}
//# sourceMappingURL=AlertsContext.js.map