feat: add SFX volume control and improve audio feedback
- 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.
This commit is contained in:
+33
-15
@@ -2,27 +2,45 @@ import React from "react";
|
||||
import ReactDOM from "react-dom/client";
|
||||
import App from "./App";
|
||||
import { ThemeProvider } from "@appica/ui-react/providers/theme-provider";
|
||||
import { API_BASE } from "./config";
|
||||
import { getApiBase } from "./config";
|
||||
import { invoke } from "@tauri-apps/api/core";
|
||||
import "./styles/global.css";
|
||||
|
||||
/* =========================================================
|
||||
启动引导(打包部署关键):
|
||||
渲染前先从后端 GET /api/config 拉取运行时配置
|
||||
(MQTT 地址/账号、API 基址),写入 window.__DPM_*__,
|
||||
之后 api.js / mqtt.js 均以惰性读取方式生效。
|
||||
后端不可达时静默使用内置默认(Tauri 打包回退 127.0.0.1)。
|
||||
启动引导(打包部署关键)—— 地址解析优先级:
|
||||
1. exe 旁 config.json(Tauri 命令读取,部署免重打包改 IP)★
|
||||
2. 后端 GET /api/config(MQTT 地址/账号,后端 .env 为准)
|
||||
3. 内置默认(Tauri 打包回退 127.0.0.1 / 浏览器用当前主机)
|
||||
结果写入 window.__DPM_*__,api.js / mqtt.js 惰性读取生效。
|
||||
========================================================= */
|
||||
async function bootstrapRuntimeConfig() {
|
||||
// 1) exe 旁 config.json(最高优先):{api_base, mqtt_url, mqtt_username, mqtt_password}
|
||||
try {
|
||||
const res = await fetch(`${API_BASE()}/api/config`, { cache: 'no-store' });
|
||||
if (!res.ok) return;
|
||||
const cfg = await res.json();
|
||||
// 仅覆盖 MQTT 连接信息(后端 .env 为准);API 基址以前端实际可达地址为准
|
||||
if (cfg.mqtt_url) window.__DPM_MQTT__ = cfg.mqtt_url;
|
||||
if (cfg.mqtt_username) window.__DPM_MQTT_USER__ = cfg.mqtt_username;
|
||||
if (cfg.mqtt_password) window.__DPM_MQTT_PASS__ = cfg.mqtt_password;
|
||||
// eslint-disable-next-line no-console
|
||||
if (cfg.mqtt_url) console.info(`[bootstrap] MQTT -> ${cfg.mqtt_url}`);
|
||||
const raw = await invoke("read_runtime_config");
|
||||
if (raw) {
|
||||
const cfg = JSON.parse(raw);
|
||||
if (cfg.api_base) window.__DPM_API__ = cfg.api_base;
|
||||
if (cfg.mqtt_url) window.__DPM_MQTT__ = cfg.mqtt_url;
|
||||
if (cfg.mqtt_username) window.__DPM_MQTT_USER__ = cfg.mqtt_username;
|
||||
if (cfg.mqtt_password) window.__DPM_MQTT_PASS__ = cfg.mqtt_password;
|
||||
// eslint-disable-next-line no-console
|
||||
if (cfg.mqtt_url) console.info(`[bootstrap] config.json MQTT -> ${cfg.mqtt_url}`);
|
||||
}
|
||||
} catch {
|
||||
/* 浏览器开发环境或未注册命令:跳过 */
|
||||
}
|
||||
|
||||
// 2) 后端 /api/config(MQTT 地址/账号;API 基址以前端实际可达地址为准)
|
||||
try {
|
||||
const res = await fetch(`${getApiBase()}/api/config`, { cache: 'no-store' });
|
||||
if (res.ok) {
|
||||
const cfg = await res.json();
|
||||
if (cfg.mqtt_url) window.__DPM_MQTT__ = cfg.mqtt_url;
|
||||
if (cfg.mqtt_username) window.__DPM_MQTT_USER__ = cfg.mqtt_username;
|
||||
if (cfg.mqtt_password) window.__DPM_MQTT_PASS__ = cfg.mqtt_password;
|
||||
// eslint-disable-next-line no-console
|
||||
if (cfg.mqtt_url) console.info(`[bootstrap] /api/config MQTT -> ${cfg.mqtt_url}`);
|
||||
}
|
||||
} catch {
|
||||
/* 后端不可达:使用内置默认地址 */
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user