Files
digital-pilates/contexts/ToastContext.tsx
richarjiang 78620f18ee feat: 更新依赖项并优化组件结构
- 在 package.json 和 package-lock.json 中新增 @sentry/react-native、react-native-device-info 和 react-native-purchases 依赖
- 更新统计页面,替换 CircularRing 组件为 FitnessRingsCard,增强健身数据展示
- 在布局文件中引入 ToastProvider,优化用户通知体验
- 新增 SuccessToast 组件,提供全局成功提示功能
- 更新健康数据获取逻辑,支持健身圆环数据的提取
- 优化多个组件的样式和交互,提升用户体验
2025-08-21 09:51:25 +08:00

107 lines
2.6 KiB
TypeScript
Raw 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 { 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: '#DF42D0', // 主题色
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;
}