diff --git a/client/public/changelog.md b/client/public/changelog.md new file mode 100644 index 0000000..8894af9 --- /dev/null +++ b/client/public/changelog.md @@ -0,0 +1,11 @@ +# 更新说明 + +> 本文档记录 Luxsin B9 控制器的功能更新与问题修复,每次发布新版本后在此追加记录。 + +## v1.0.0 + +### 新功能 +- 首页新增「更新说明」入口,支持在线查看版本更新记录 + +### 修复 +- 无 diff --git a/client/src/App.tsx b/client/src/App.tsx index ac02904..02fa6ad 100644 --- a/client/src/App.tsx +++ b/client/src/App.tsx @@ -16,6 +16,7 @@ import IOPage from "./pages/IOPage"; import VUPage from "./pages/VUPage"; import SelectPage from "./pages/SelectPage"; import CommunityPage from "./pages/CommunityPage"; +import ChangelogPage from "./pages/ChangelogPage"; import { AIDrawerProvider } from "./contexts/AIDrawerContext"; import DesktopAIShell from "./components/DesktopAIShell"; import { appShellColumnClass, appShellOuterClass } from "./lib/appShell"; @@ -66,6 +67,7 @@ function AppRouter() { + diff --git a/client/src/locales/data-de.json b/client/src/locales/data-de.json index d3f13fa..0fe089b 100644 --- a/client/src/locales/data-de.json +++ b/client/src/locales/data-de.json @@ -31,7 +31,9 @@ "powerOffToastDemo": "Demomodus: Vom Gerät getrennt.", "powerOffToastSent": "Abschaltbefehl gesendet.", "doubleClickHint": "Doppelklick zum Eintreten", - "backToLegacy": "Alte Version" + "backToLegacy": "Alte Version", + "changelog": "Neuerungen", + "changelogLoadFailed": "Laden fehlgeschlagen, bitte später erneut versuchen" }, "vuPage": { "title": "VU-Meter Galerie" diff --git a/client/src/locales/data-en.json b/client/src/locales/data-en.json index 9bc24bb..14e6e53 100644 --- a/client/src/locales/data-en.json +++ b/client/src/locales/data-en.json @@ -31,7 +31,9 @@ "powerOffToastDemo": "Demo mode: disconnected from the device.", "powerOffToastSent": "Shutdown command sent.", "doubleClickHint": "Double-click to enter", - "backToLegacy": "Legacy version" + "backToLegacy": "Legacy version", + "changelog": "What's New", + "changelogLoadFailed": "Failed to load, please try again later" }, "vuPage": { "title": "VU meter gallery" diff --git a/client/src/locales/data-es.json b/client/src/locales/data-es.json index 9c94c39..c12a85c 100644 --- a/client/src/locales/data-es.json +++ b/client/src/locales/data-es.json @@ -31,7 +31,9 @@ "powerOffToastDemo": "Modo demo: desconectado del dispositivo.", "powerOffToastSent": "Comando de apagado enviado.", "doubleClickHint": "Doble clic para entrar", - "backToLegacy": "Versión anterior" + "backToLegacy": "Versión anterior", + "changelog": "Novedades", + "changelogLoadFailed": "Error al cargar, inténtelo de nuevo más tarde" }, "vuPage": { "title": "Galería de VU-metro" diff --git a/client/src/locales/data-fr.json b/client/src/locales/data-fr.json index e5241f5..78f653f 100644 --- a/client/src/locales/data-fr.json +++ b/client/src/locales/data-fr.json @@ -31,7 +31,9 @@ "powerOffToastDemo": "Mode démo : déconnecté de l'appareil.", "powerOffToastSent": "Commande d'extinction envoyée.", "doubleClickHint": "Double-clic pour entrer", - "backToLegacy": "Ancienne version" + "backToLegacy": "Ancienne version", + "changelog": "Nouveautés", + "changelogLoadFailed": "Échec du chargement, veuillez réessayer plus tard" }, "vuPage": { "title": "Galerie VU-mètre" diff --git a/client/src/locales/data-zh-HK.json b/client/src/locales/data-zh-HK.json index abc3cf0..2a304e1 100644 --- a/client/src/locales/data-zh-HK.json +++ b/client/src/locales/data-zh-HK.json @@ -31,7 +31,9 @@ "powerOffToastDemo": "演示模式:已中斷與裝置的連線", "powerOffToastSent": "已傳送關機指令", "doubleClickHint": "按兩下進入", - "backToLegacy": "返回舊版" + "backToLegacy": "返回舊版", + "changelog": "更新說明", + "changelogLoadFailed": "載入失敗,請稍後再試" }, "vuPage": { "title": "VU 表庫" diff --git a/client/src/locales/data-zh.json b/client/src/locales/data-zh.json index d31fdcd..720bca2 100644 --- a/client/src/locales/data-zh.json +++ b/client/src/locales/data-zh.json @@ -31,7 +31,9 @@ "powerOffToastDemo": "演示模式:已断开与设备的连接", "powerOffToastSent": "已发送关机指令", "doubleClickHint": "双击进入", - "backToLegacy": "返回旧版" + "backToLegacy": "返回旧版", + "changelog": "更新说明", + "changelogLoadFailed": "加载失败,请稍后重试" }, "vuPage": { "title": "VU 表库" diff --git a/client/src/pages/ChangelogPage.tsx b/client/src/pages/ChangelogPage.tsx new file mode 100644 index 0000000..d529532 --- /dev/null +++ b/client/src/pages/ChangelogPage.tsx @@ -0,0 +1,92 @@ +/* ============================================================ + CHANGELOG PAGE — Release notes / 更新说明 + Content is loaded from /changelog.md (public dir) at runtime, + so updating the notes only requires editing that markdown file. + ============================================================ */ +import BottomNav from "@/components/BottomNav"; +import { useDevice } from "@/contexts/DeviceContext"; +import { usePageTitleWithConnection } from "@/hooks/usePageTitleWithConnection"; +import { resolveLocalePack } from "@/locales/resolveLocale"; +import localeZh from "@/locales/data-zh.json"; +import { ChevronLeft } from "lucide-react"; +import { useEffect, useMemo, useState } from "react"; +import { useLocation } from "wouter"; +import { Streamdown } from "streamdown"; + +type HomeLocale = NonNullable<(typeof localeZh)["home"]>; + +export default function ChangelogPage() { + const [, setLocation] = useLocation(); + const { deviceState } = useDevice(); + + const homeText = useMemo((): HomeLocale => { + const pack = resolveLocalePack(deviceState?.language); + return (pack.home ?? {}) as HomeLocale; + }, [deviceState?.language]); + + const pageTitle = usePageTitleWithConnection(homeText.changelog ?? "更新说明"); + + const [content, setContent] = useState(null); + const [failed, setFailed] = useState(false); + + useEffect(() => { + let cancelled = false; + fetch(`${import.meta.env.BASE_URL}changelog.md`) + .then((res) => { + if (!res.ok) throw new Error(`HTTP ${res.status}`); + return res.text(); + }) + .then((text) => { + if (!cancelled) setContent(text); + }) + .catch(() => { + if (!cancelled) setFailed(true); + }); + return () => { + cancelled = true; + }; + }, []); + + return ( + + + setLocation("/")} + className="mr-4 text-white/60 active:text-white transition-colors" + aria-label="Back" + > + + + {pageTitle} + + + + + + {failed ? ( + {homeText.changelogLoadFailed ?? "加载失败,请稍后重试"} + ) : content ? ( + + {content} + + ) : ( + + + + )} + + + + + + ); +} diff --git a/client/src/pages/Home.tsx b/client/src/pages/Home.tsx index dc3b959..0ed2e9c 100644 --- a/client/src/pages/Home.tsx +++ b/client/src/pages/Home.tsx @@ -44,6 +44,7 @@ import { SquareArrowRightEnter, SquareArrowRightExit, FileMusic, + BookOpenCheck, Minus, Plus, } from "lucide-react"; @@ -954,6 +955,11 @@ export default function Home() { thumbnail={`${import.meta.env.BASE_URL}images/vu/vu${(ds.vu ?? 0) + 1}.png`} onClick={() => setLocation("/vu")} /> + } + label={homeText.changelog ?? "更新说明"} + onClick={() => setLocation("/changelog")} + />
{homeText.changelogLoadFailed ?? "加载失败,请稍后重试"}