/**
* 轻量 toast 提示 composable — 消除 AiChat / Settings / Projects / TaskDetail 4 处重复。
*
* 原 4 处各自 reactive/ref + _toastTimer + showToast + onUnmounted 清理,
* 且 Projects 用 4000ms 其余 3000ms(体验不一致 bug)。
* 本 composable 统一默认 3000ms,支持调用方按需传 durationMs。
*
* 用法:
* const { toast, showToast } = useToast()
* showToast('保存成功')
* showToast('导入失败', 'error', 4000)
* // template:
{{ toast.msg }}
*/
import { reactive, onUnmounted } from 'vue'
export type ToastType = 'info' | 'error' | 'warning'
export interface ToastState {
visible: boolean
msg: string
type: ToastType
}
let _timer: ReturnType | null = null
export function useToast(defaultDurationMs = 3000) {
const toast = reactive({
visible: false,
msg: '',
type: 'info',
})
function showToast(msg: string, type: ToastType = 'info', durationMs?: number) {
toast.msg = msg
toast.type = type
toast.visible = true
if (_timer) clearTimeout(_timer)
_timer = setTimeout(() => {
toast.visible = false
}, durationMs ?? defaultDurationMs)
}
function hideToast() {
if (_timer) {
clearTimeout(_timer)
_timer = null
}
toast.visible = false
}
onUnmounted(() => {
if (_timer) {
clearTimeout(_timer)
_timer = null
}
})
return { toast, showToast, hideToast }
}