mirror of
https://github.com/Rain-kl/OpenFlare.git
synced 2026-09-29 14:06:36 +08:00
63cd906cfc
- Merge all files inside openflare-server to the repository root directory. - Relocate agent, relay, and flared subprojects from internal/ to internal/apps/. - Combine docker-compose files and update build context paths to root. - Update GitHub workflows and Dockerfiles to refer to new directories and package names. - Rewrite Go package imports across all files. - Resolve database renew test race condition and clean up docs.
55 lines
1.4 KiB
TypeScript
55 lines
1.4 KiB
TypeScript
"use client"
|
|
|
|
import {createContext, useCallback, useContext, useRef, useState} from "react"
|
|
|
|
interface BellRingContextType {
|
|
isRinging: boolean
|
|
triggerRing: () => void
|
|
}
|
|
|
|
const BellRingContext = createContext<BellRingContextType | undefined>(undefined)
|
|
|
|
/**
|
|
* 铃铛响铃动画上下文提供者
|
|
* 用于在 toast 通知时触发顶栏铃铛的响铃动画
|
|
*/
|
|
export function BellRingProvider({ children }: { children: React.ReactNode }) {
|
|
const [isRinging, setIsRinging] = useState(false)
|
|
const timeoutRef = useRef<NodeJS.Timeout | null>(null)
|
|
|
|
const triggerRing = useCallback(() => {
|
|
// 如果正在响铃,立即重新开始动画
|
|
if (timeoutRef.current) {
|
|
clearTimeout(timeoutRef.current)
|
|
}
|
|
setIsRinging(false)
|
|
requestAnimationFrame(() => {
|
|
requestAnimationFrame(() => {
|
|
setIsRinging(true)
|
|
timeoutRef.current = setTimeout(() => {
|
|
setIsRinging(false)
|
|
timeoutRef.current = null
|
|
}, 600)
|
|
})
|
|
})
|
|
}, [])
|
|
|
|
return (
|
|
<BellRingContext.Provider value={{ isRinging, triggerRing }}>
|
|
{children}
|
|
</BellRingContext.Provider>
|
|
)
|
|
}
|
|
|
|
/**
|
|
* 使用铃铛响铃动画的 Hook
|
|
* @returns {{ isRinging: boolean, triggerRing: () => void }}
|
|
*/
|
|
export function useBellRing() {
|
|
const context = useContext(BellRingContext)
|
|
if (context === undefined) {
|
|
throw new Error("useBellRing must be used within a BellRingProvider")
|
|
}
|
|
return context
|
|
}
|