'use client' import React, { createContext, useCallback, useContext, useEffect, useMemo, useState } from 'react' interface ProgressState { open: boolean title: string progress: number } interface ProgressToastContextValue { /** 显示或更新进度提示 */ show: (params: { title?: string; progress?: number }) => void /** 仅更新进度或标题 */ update: (params: { title?: string; progress?: number }) => void /** 隐藏提示 */ hide: () => void /** 当前状态(只读) */ state: ProgressState } const ProgressToastContext = createContext(null) export const H5ProgressToastProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => { const [state, setState] = useState({ open: false, title: 'processing...', progress: 0 }) const hide = useCallback(() => setState(prev => ({ ...prev, open: false })), []) const show = useCallback((params: { title?: string; progress?: number }) => { setState(prev => ({ open: true, title: params.title ?? prev.title, progress: typeof params.progress === 'number' ? params.progress : prev.progress, })) }, []) const update = useCallback((params: { title?: string; progress?: number }) => { setState(prev => ({ open: prev.open || true, title: params.title ?? prev.title, progress: typeof params.progress === 'number' ? params.progress : prev.progress, })) }, []) // 进度到100自动隐藏 useEffect(() => { if (!state.open) return if (state.progress >= 100) { const timer = setTimeout(() => hide(), 600) return () => clearTimeout(timer) } }, [state.open, state.progress, hide]) const value = useMemo(() => ({ show, update, hide, state }), [show, update, hide, state]) return ( {children} ) } export function useH5ProgressToast() { const ctx = useContext(ProgressToastContext) if (!ctx) throw new Error('useH5ProgressToast must be used within H5ProgressToastProvider') return ctx } interface UIProps { open: boolean title: string progress: number } /** * H5样式的顶部居中进度提示,贴合截图风格。 * 无遮罩;进度为0-100。 */ const H5ProgressToastUI: React.FC = ({ open, title, progress }) => { if (!open) return null const pct = Math.max(0, Math.min(100, Math.round(progress))) return (
{title}
{pct}% {pct >= 100 ? 'completed' : ''}
) } export default H5ProgressToastProvider