useSoundNotification.ts 985 B

123456789101112131415161718192021222324252627282930313233343536373839
  1. import { useCallback, useEffect, useRef, useState } from "react";
  2. import { unlockSound } from "@/utils/sound";
  3. export function useSoundNotification(initialEnabled: boolean = true) {
  4. const [enabled, setEnabled] = useState(initialEnabled);
  5. const audioRef = useRef<HTMLAudioElement | null>(null);
  6. useEffect(() => {
  7. if (!enabled) return;
  8. // 尝试解锁音频(多数浏览器需用户交互后才能真正响)
  9. void unlockSound();
  10. return () => {
  11. if (audioRef.current) {
  12. audioRef.current.pause();
  13. audioRef.current = null;
  14. }
  15. };
  16. }, [enabled]);
  17. const play = useCallback(() => {
  18. if (enabled && audioRef.current) {
  19. audioRef.current.play().catch(() => {
  20. // 忽略播放错误
  21. });
  22. }
  23. }, [enabled]);
  24. const toggle = useCallback(() => {
  25. setEnabled((prev) => {
  26. const next = !prev;
  27. if (next) void unlockSound();
  28. return next;
  29. });
  30. }, []);
  31. return { enabled, toggle, play };
  32. }