Files
digital-pilates/contexts/ToastContext.tsx
2025-09-02 15:50:35 +08:00

108 lines
2.7 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import SuccessToast from '@/components/ui/SuccessToast';
import { Colors } from '@/constants/Colors';
import { setToastRef } from '@/utils/toast.utils';
import React, { createContext, useContext, useEffect, useRef, useState } from 'react';
interface ToastConfig {
message: string;
duration?: number;
backgroundColor?: string;
textColor?: string;
icon?: string;
}
export interface ToastContextType {
showToast: (config: ToastConfig) => void;
showSuccess: (message: string, duration?: number) => void;
showError: (message: string, duration?: number) => void;
showWarning: (message: string, duration?: number) => void;
}
const ToastContext = createContext<ToastContextType | undefined>(undefined);
export function ToastProvider({ children }: { children: React.ReactNode }) {
const [visible, setVisible] = useState(false);
const [config, setConfig] = useState<ToastConfig>({ message: '' });
const timeoutRef = useRef<NodeJS.Timeout | null>(null);
const showToast = (toastConfig: ToastConfig) => {
// 如果已有Toast显示先隐藏
if (visible) {
setVisible(false);
// 短暂延迟后显示新Toast
setTimeout(() => {
setConfig(toastConfig);
setVisible(true);
}, 100);
} else {
setConfig(toastConfig);
setVisible(true);
}
};
const showSuccess = (message: string, duration?: number) => {
showToast({
message,
duration,
backgroundColor: Colors.light.primary, // 主题色
icon: '✓',
});
};
const showError = (message: string, duration?: number) => {
showToast({
message,
duration,
backgroundColor: '#f44336', // 红色
icon: '✕',
});
};
const showWarning = (message: string, duration?: number) => {
showToast({
message,
duration,
backgroundColor: '#ff9800', // 橙色
icon: '⚠',
});
};
const handleHide = () => {
setVisible(false);
};
const value: ToastContextType = {
showToast,
showSuccess,
showError,
showWarning,
};
// 设置全局引用
useEffect(() => {
setToastRef(value);
}, [value]);
return (
<ToastContext.Provider value={value}>
{children}
<SuccessToast
visible={visible}
message={config.message}
duration={config.duration}
backgroundColor={config.backgroundColor}
textColor={config.textColor}
icon={config.icon}
onHide={handleHide}
/>
</ToastContext.Provider>
);
}
export function useToast(): ToastContextType {
const context = useContext(ToastContext);
if (context === undefined) {
throw new Error('useToast must be used within a ToastProvider');
}
return context;
}