/** * Global toast helper backed by native UI. * * Usage: * import { Toast } from '@/utils/toast.utils'; * * Toast.success('操作成功!'); * Toast.error('操作失败!'); * Toast.warning('注意!'); */ import { NativeModules, Platform, ToastAndroid } from 'react-native'; export type ToastType = 'default' | 'success' | 'error' | 'warning' | 'info'; export interface ToastConfig { message?: string; text1?: string; duration?: number; type?: ToastType; backgroundColor?: string; textColor?: string; icon?: string; } type NativeToastModule = { show: (options: { message?: string; text1?: string; duration?: number; type?: ToastType; backgroundColor?: string; textColor?: string; icon?: string; }) => void; }; const DEFAULT_DURATION = 2000; const MIN_DURATION = 1000; const MAX_DURATION = 10000; // 增强类型安全性:添加运行时检查确保模块存在且具有预期的方法 const nativeToast = NativeModules.NativeToastManager && typeof NativeModules.NativeToastManager.show === 'function' ? NativeModules.NativeToastManager as NativeToastModule : undefined; const clampDuration = (duration?: number) => { const value = typeof duration === 'number' ? duration : DEFAULT_DURATION; return Math.min(Math.max(value, MIN_DURATION), MAX_DURATION); }; const resolveMessage = (config: ToastConfig) => { const raw = (config.message ?? config.text1 ?? '').toString(); return raw.trim(); }; const showOnAndroid = (message: string, duration: number) => { const toastDuration = duration >= 3000 ? ToastAndroid.LONG : ToastAndroid.SHORT; ToastAndroid.showWithGravity(message, toastDuration, ToastAndroid.CENTER); }; const showNative = (config: ToastConfig) => { const message = resolveMessage(config); if (!message) { console.warn('Toast invoked without message content'); return; } const duration = clampDuration(config.duration); const type = config.type ?? 'default'; if (Platform.OS === 'android') { showOnAndroid(message, duration); return; } if (nativeToast?.show) { nativeToast.show({ ...config, message, duration, type, }); return; } // 为不支持的平台提供更明显的用户反馈 if (Platform.OS === 'web') { // 在 Web 环境下使用 console.warn 并尝试使用浏览器原生 alert console.warn(`Toast: ${message}`); try { // 仅在重要消息时使用 alert,避免过度打扰用户 if (config.type === 'error' || config.type === 'warning') { alert(message); } } catch (e) { // 忽略 alert 错误 } } else { console.log(`Toast: ${message}`); } }; export const Toast = { show: (config: ToastConfig) => { showNative(config); }, success: (message: string, duration?: number) => { showNative({ message, duration, type: 'success' }); }, error: (message: string, duration?: number) => { showNative({ message, duration, type: 'error' }); }, warning: (message: string, duration?: number) => { showNative({ message, duration, type: 'warning' }); }, info: (message: string, duration?: number) => { showNative({ message, duration, type: 'info' }); }, };