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