import React, { useCallback, useState } from 'react'; import { Platform, useWindowDimensions } from 'react-native'; import { ColorProps } from '@shopify/restyle'; import { NativeSyntheticEvent, TextLayoutEventData } from 'react-native/Libraries/Types/CoreEventTypes'; import { useSafeAreaInsets } from 'react-native-safe-area-context'; import Toast, { ToastConfig, ToastConfigParams } from 'react-native-toast-message'; import { AppBox } from '../layout'; import { AppText } from '../text'; import { AppButton } from '~/view/components/buttons'; import { AppIcon, IconName } from '~/view/components/images_and_icons'; import { AppTheme, useAppTheme } from '~/view/theme'; type AppSnackbarType = 'success' | 'error' | 'info'; type BaseSnackbarProps = { actionBtnTitle?: string; onActionPress?: () => void; onHide?: () => void; }; // TODO: AppToast will be replaced by this component export class AppSnackbar { static show(t: AppSnackbarType, text: string | undefined, props?: BaseSnackbarProps) { Toast.show({ type: mapType(t), text1: text, autoHide: true, visibilityTime: props?.onActionPress ? 5000 : 3000, position: 'top', topOffset: 0, props }); } static hide() { Toast.hide(); } } const mapType = (t: AppSnackbarType) => { switch (t) { case 'success': return '_success'; case 'error': return '_error'; case 'info': return 'info'; } }; export const SNACKBAR_CONFIG: ToastConfig = { // workaround of // https://github.com/calintamas/react-native-toast-message/issues/428 success: () => null, error: () => null, info: props => , _success: props => , _error: props => }; const SuccessSnackbar = (props: ToastConfigParams) => { return ; }; const ErrorSnackbar = (props: ToastConfigParams) => { return ; }; const InfoSnackbar = (props: ToastConfigParams) => { return ( ); }; const SnackbarTemplate = ({ text1, props, icon, color, textColor }: ToastConfigParams & { icon: IconName; color: ColorProps['color']; textColor?: ColorProps['color']; }) => { const insets = useSafeAreaInsets(); const { width } = useWindowDimensions(); const { spacing } = useAppTheme(); const [lines, setLines] = useState(0); const onTextLayout = useCallback((e: NativeSyntheticEvent) => { setLines(e.nativeEvent.lines.length); }, []); const centered = !props.onActionPress && lines <= 1; return ( {text1} {props.onActionPress && ( )} ); }; const containerStyle = (top: number) => ({ marginTop: Platform.select({ android: top ? top + 4 : 8, ios: top ? top + 4 : 8 }) });