Files
OpenFlare/frontend/contexts/bell-ring-context.tsx
T
ryan 63cd906cfc refactor(repo): consolidate openflare-server to root and move subprojects to internal/apps
- 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.
2026-06-19 14:23:29 +08:00

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
}