import React, { ReactNode } from 'react' import Text from './Text' import Block from './Block' import { Text as RNText } from 'react-native' import { ActivityIndicator } from 'react-native' // 定义insets接口 interface Insets { safeAreaInsetsBottom: number safeAreaInsetsTop: number safeAreaInsetsLeft: number safeAreaInsetsRight: number } // 定义全局变量接口 declare global { interface Window { toast?: { show: (component: ReactNode, config?: any) => void hide: () => void } loading?: { show: (component: ReactNode, config?: any) => void hide: () => void } modal?: { show: (component: ReactNode, config?: any) => void hide: () => void } actionSheet?: { show: (component: ReactNode, config?: any) => void hide: () => void } } } // 参数接口定义 interface ShowParams { renderContent?: () => ReactNode title?: string duration?: number hideBackdrop?: boolean } interface ShowActionSheetParams { itemList?: string[] renderContent?: () => ReactNode } const isString = (variable: any): variable is string => Object.prototype.toString.call(variable) === '[object String]' const Toast = (function () { // 初始化默认insets let insets: Insets = { safeAreaInsetsBottom: 0, safeAreaInsetsTop: 0, safeAreaInsetsLeft: 0, safeAreaInsetsRight: 0, } // // 使用回调函数获取insets // StaticSafeAreaInsets.getSafeAreaInsets((staticInsets) => { // insets = staticInsets // }) let toastTimer: number | null = null const show = (params?: ShowParams | string): void => { // 兼容字符串参数 const options: ShowParams = typeof params === 'string' ? { title: params } : (params || {}) const { renderContent, title, duration = 4000, hideBackdrop = true } = options hide() const renderBody = (): ReactNode => { if (renderContent) { return renderContent() } return title && {title} } ; (global as any).toast?.show( {renderBody()} , { style: {}, swipeDirection: null, hideBackdrop, onBackdropPress: () => { }, entering: false, exiting: false, }, ) if (duration > 0) { toastTimer = setTimeout(() => { hide() }, duration) } } const hide = (): void => { ; (global as any).toast?.hide() if (toastTimer) { clearTimeout(toastTimer) toastTimer = null } } // loading let loadingTimer: number | null = null const showLoading = (params?: ShowParams): void => { const { renderContent, title, duration = 1500, hideBackdrop = false } = params || {} hideLoading() const renderBody = (): ReactNode => { if (renderContent) { return renderContent() } return ( <> {!!title && ( {title} )} ) } ; (global as any).loading?.show( {renderBody()} , { style: {}, swipeDirection: null, hideBackdrop, backdropColor: 'rgba(0,0,0,0.1)', onBackdropPress: () => { }, entering: false, exiting: false, }, ) if (duration > 0) { loadingTimer = setTimeout(() => { hideLoading() }, duration) } } const hideLoading = (): void => { ; (global as any).loading?.hide() if (loadingTimer) { clearTimeout(loadingTimer) loadingTimer = null } } // modal const showModal = (ele: ReactNode, config: any = {}): void => { ; (global as any).modal?.show(ele, { swipeDirection: null, ...config, }) } const hideModal = (): void => { ; (global as any).modal?.hide() } // actionsheet // 兼容半屏组件 const showActionSheet = ({ itemList, renderContent }: ShowActionSheetParams): Promise => { return new Promise((resolve, reject) => { const handleSelect = (item: string): void => { hideActionSheet() const itemIndex = itemList?.findIndex((i) => i === item) || -1 resolve(itemIndex) } const handleCancel = (): void => { hideActionSheet() reject() } const renderBody = (): ReactNode => { if (Array.isArray(itemList)) { return ( {itemList.map((item, index) => ( handleSelect(item)} key={index} className="items-center justify-center bg-white py-[16px]" > {item} ))} 取消 ) } if (!renderContent) return null return ( {/* */} {/* 安卓闪动,向上2px */} {renderContent()} ) } ; (global as any).actionSheet?.show({renderBody()}, { style: { justifyContent: 'flex-end' }, }) }) } const hideActionSheet = (): void => { ; (global as any).actionSheet?.hide() } return { showActionSheet, hideActionSheet, showModal, hideModal, showLoading, hideLoading, show, hide, } })() export default Toast