d70d9d5fbd
- Implemented separate sound effects volume control in settings. - Updated backend to handle new `sfx_volume` parameter. - Enhanced UI to include sound effects volume slider in admin panel. - Integrated sound effects for various user interactions (clicks, navigation, alerts). - Added a new global sound engine to manage audio synthesis without external files. - Updated documentation for Docker deployment and Windows packaging. - Refactored audio context management to ensure sound effects are available post user interaction.
57 lines
2.0 KiB
JavaScript
57 lines
2.0 KiB
JavaScript
import { useEffect } from 'react';
|
|
import { useNavigate, useLocation } from 'react-router-dom';
|
|
import { Sfx } from './sounds';
|
|
|
|
/* =========================================================
|
|
页面循环导航 —— 左右方向键切换大屏页面
|
|
顺序:数据大屏 → 数字孪生 → AI 助手 → 媒体轮播(循环)
|
|
管理后台不参与循环切换,仅在登录后进入
|
|
← 向左切换 · → 向右切换
|
|
========================================================= */
|
|
|
|
export const PAGE_ORDER = [
|
|
{ path: '/', label: '数据大屏' },
|
|
{ path: '/twin', label: '数字孪生' },
|
|
{ path: '/ai', label: 'AI 助手' },
|
|
{ path: '/voice', label: '语音对话' },
|
|
{ path: '/wall', label: '企业展示墙' },
|
|
{ path: '/screen', label: '媒体轮播' },
|
|
];
|
|
|
|
/**
|
|
* 左右方向键循环切换页面。
|
|
* 在任意页面使用;当前路径不在 PAGE_ORDER 中时不响应。
|
|
* 输入框/文本域内按键不触发页面切换(避免影响输入)。
|
|
*/
|
|
export function usePageNav() {
|
|
const navigate = useNavigate();
|
|
const location = useLocation();
|
|
|
|
useEffect(() => {
|
|
const onKey = (e) => {
|
|
const t = e.target;
|
|
if (t && (t.tagName === 'INPUT' || t.tagName === 'TEXTAREA' || t.isContentEditable)) return;
|
|
const idx = PAGE_ORDER.findIndex((p) => p.path === location.pathname);
|
|
if (idx === -1) return;
|
|
const n = PAGE_ORDER.length;
|
|
if (e.key === 'ArrowRight') {
|
|
Sfx.page();
|
|
navigate(PAGE_ORDER[(idx + 1) % n].path);
|
|
} else if (e.key === 'ArrowLeft') {
|
|
Sfx.page();
|
|
navigate(PAGE_ORDER[(idx - 1 + n) % n].path);
|
|
}
|
|
};
|
|
window.addEventListener('keydown', onKey);
|
|
return () => window.removeEventListener('keydown', onKey);
|
|
}, [navigate, location.pathname]);
|
|
|
|
return null;
|
|
}
|
|
|
|
/** 获取当前页在循环中的位置(-1 表示不在循环中) */
|
|
export function usePageIndex() {
|
|
const location = useLocation();
|
|
return PAGE_ORDER.findIndex((p) => p.path === location.pathname);
|
|
}
|