From a182c64f82757e29bb63033d27e732ed5254d810 Mon Sep 17 00:00:00 2001 From: zhilv Date: Sun, 26 Apr 2026 20:45:39 +0800 Subject: [PATCH] =?UTF-8?q?=F0=9F=94=96=20release(v0.1.4):=20bump=20versio?= =?UTF-8?q?n=20and=20UI=20optimizations?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Remove unused version display logic and update summary - Add silent audio playback to prevent browser tab throttling - Update CourseWorkspace and Setting components - Bump version from 0.1.3 to 0.1.4 Co-Authored-By: Claude Opus 4.6 --- package.json | 2 +- src/App.tsx | 126 ++--- src/components/account/CourseWorkspace.tsx | 8 +- src/pages/settings/Setting.tsx | 614 ++++++++++----------- 4 files changed, 362 insertions(+), 388 deletions(-) diff --git a/package.json b/package.json index 345d4c7..91cf99d 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "frontend", "private": true, - "version": "0.1.3", + "version": "0.1.4", "type": "module", "scripts": { "dev": "vite", diff --git a/src/App.tsx b/src/App.tsx index a2a0c4e..656f9f8 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -137,9 +137,6 @@ const renderInlineLinks = (text: string): JSX.Element[] => { const App: ParentComponent = (props) => { const location = useLocation(); const [version] = createResource(versionApi); - const [copyState, setCopyState] = createSignal<"idle" | "done" | "error">( - "idle", - ); const [updateDialogOpen, setUpdateDialogOpen] = createSignal(false); const [updateCheckState, setUpdateCheckState] = createSignal("idle"); @@ -197,31 +194,6 @@ const App: ParentComponent = (props) => { return error instanceof Error ? error.message : "版本信息获取失败"; }); - const versionPayloadText = createMemo(() => - [ - `Version: ${versionText()}`, - `Mode: ${modeText()}`, - `Commit: ${commitText()}`, - `Build: ${buildText()}`, - `Author: ${authorText()}`, - `Email: ${emailText()}`, - ].join("\n"), - ); - const updateSummaryText = createMemo(() => { - if (updateCheckState() === "checking") { - return "更新检查中..."; - } - if (updateCheckState() === "available") { - return `发现新版本:${latestRelease()?.tag_name ?? "-"}`; - } - if (updateCheckState() === "latest") { - return "已是最新版本"; - } - if (updateCheckState() === "error") { - return updateCheckError() || "更新检查失败"; - } - return "未检查更新"; - }); const releaseNotesBlocks = createMemo(() => parseMarkdownBlocks(latestRelease()?.body ?? ""), ); @@ -231,6 +203,14 @@ const App: ParentComponent = (props) => { const releaseLink = createMemo( () => latestRelease()?.html_url || RELEASES_PAGE_URL, ); + const safeValue = (value: string) => (value === "unknown" ? "-" : value); + const hasUpdateBadge = createMemo(() => updateCheckState() === "available"); + const updateDialogTitle = createMemo(() => { + if (updateCheckState() === "available") { + return `发现更新 ${latestRelease()?.tag_name ?? ""}`; + } + return "更新信息"; + }); onMount(() => { const unsubscribe = settingsStore.subscribe((state) => { @@ -242,16 +222,6 @@ const App: ParentComponent = (props) => { }); }); - const handleCopyVersion = async () => { - try { - await navigator.clipboard.writeText(versionPayloadText()); - setCopyState("done"); - } catch { - setCopyState("error"); - } - - window.setTimeout(() => setCopyState("idle"), 1800); - }; const performUpdateCheck = async (manual = false) => { if (updateCheckState() === "checking") { return; @@ -276,17 +246,17 @@ const App: ParentComponent = (props) => { setRuntimeTarget(target); const hasNewVersion = isRemoteVersionNewer(versionText(), release.tag_name); + setLatestRelease(release); + setMatchedAsset(resolveAssetForRuntime(release.assets, target)); + if (!hasNewVersion) { setUpdateCheckState("latest"); if (manual) { - setLatestRelease(release); - setMatchedAsset(resolveAssetForRuntime(release.assets, target)); + setUpdateDialogOpen(true); } return; } - setLatestRelease(release); - setMatchedAsset(resolveAssetForRuntime(release.assets, target)); setUpdateCheckState("available"); setUpdateDialogOpen(true); } catch (error) { @@ -425,48 +395,48 @@ const App: ParentComponent = (props) => {

{asideList().find((item) => isActive(item.url))?.label ?? "账号"}

-

- 模式: {modeText()} -

-

- 调试: {isDebugMode() ? "已开启" : "已关闭"} -

-

- Runtime -

-
-

Version: {versionText()}

-

Commit: {commitText()}

-

Build: {buildText()}

-

Author: {authorText()}

-

Email: {emailText()}

-
-

- 更新: {updateSummaryText()} -

-
+
- +
+ + 系统诊断信息 + +
+

+ Mode: {safeValue(modeText())} +

+

Commit: {safeValue(commitText())}

+

Build: {safeValue(buildText())}

+

Author: {safeValue(authorText())}

+

Email: {safeValue(emailText())}

+
+
+ {updateCheckState() === "error" ? ( +

+ {updateCheckError() || "更新检查失败"} +

+ ) : null} {versionErrorText() ? (

{versionErrorText()}

) : null} @@ -488,7 +458,7 @@ const App: ParentComponent = (props) => { } setUpdateDialogOpen(false); }} - title={`发现更新 ${latestRelease()?.tag_name ?? ""}`} + title={updateDialogTitle()} widthClass="max-w-3xl" closeOnOverlay={downloadState() !== "downloading"} footer={ diff --git a/src/components/account/CourseWorkspace.tsx b/src/components/account/CourseWorkspace.tsx index 3e1125e..d14c7f8 100644 --- a/src/components/account/CourseWorkspace.tsx +++ b/src/components/account/CourseWorkspace.tsx @@ -283,7 +283,13 @@ const CourseWorkspace = (props: CourseWorkspaceProps) => { > {(item) => ( - + )} diff --git a/src/pages/settings/Setting.tsx b/src/pages/settings/Setting.tsx index 8ff17e6..1639086 100644 --- a/src/pages/settings/Setting.tsx +++ b/src/pages/settings/Setting.tsx @@ -1,4 +1,4 @@ -import { createMemo, createSignal, For, onCleanup, onMount } from "solid-js"; +import { createMemo, createSignal, For, onCleanup, onMount } from "solid-js"; import { fetchDebugConfig, updateDebugConfig } from "~/service/debugLog"; import { hostApi } from "~/service/wk"; import { getMergedHosts, settingsStore } from "~/store/settings"; @@ -117,367 +117,365 @@ const Setting = () => { void refreshDebugConfig(); }); + const panelClass = + "rounded-[28px] border border-white/80 bg-white/85 p-5 shadow-[0_18px_50px_-28px_rgba(15,23,42,0.25)]"; + const sectionCardClass = "rounded-2xl border border-zinc-200 bg-zinc-50/80 p-4"; + return (
-
+
-

- Settings Center +

+ Preference Center

偏好设置

- 管理本地缓存、界面偏好和 Host 来源策略 + 统一管理本地缓存、界面体验和 Host 来源策略

-
-

本地优先

-

+

+

策略:本地优先

+

远端 Host 获取后会与本地列表合并去重

-
-
-
-
+
+
+
+
-

本地数据

-

- 管理本地缓存数据 -

+

本地数据

+

管理本地缓存数据

-
-
-
-

账号缓存

-

账号、课程和登录信息

+
+
+
+
+

账号缓存

+

账号、课程和登录信息

+
+
-
-
-
-

记录缓存

-

课程记录和筛选类型

+
+
+
+

记录缓存

+

课程记录和筛选类型

+
+
-
-
-
-

日志缓存

-

任务日志历史

+
+
+
+

日志缓存

+

任务日志历史

+
+
-
-
+
-
-

界面偏好

-

- 根据你的使用习惯调整侧栏、日志和展示密度 -

-
+
+
+

界面偏好

+

+ 根据使用习惯调整日志行为、展示密度和侧栏尺寸 +

+
-
-
-
-
-

手动开启调试

-

- 开启后显示后端日志页,并应用本地代理 / SSL 调试配置 +

+
+
+
+

手动开启调试

+

+ 开启后显示后端日志页,并应用本地代理 / SSL 调试配置 +

+
+ + void handleDebugToggle(event.currentTarget.checked) + } + /> +
+
+

后端状态:{backendDebugState()?.enabled ? "已开启" : "已关闭"}

+

编译模式:{backendDebugState()?.buildMode ?? "-"}

+

+ 本地代理: + {backendDebugState()?.proxyConfigured + ? backendDebugState()?.proxy + : "未配置"} +

+

+ 跳过 SSL 校验: + {backendDebugState()?.skipSSLVerify ? "已配置" : "未配置"}

+ {debugError() ? ( +
+ {debugError()} +
+ ) : null} +
+ +
+
+
+

日志自动滚动

+

新日志出现时自动滚动到底部

+
+ + settingsStore + .getState() + .setAutoScrollLogs(event.currentTarget.checked) + } + /> +
+
+ +
+
+
+

显示日志时间戳

+

日志输出追加格式化时间

+
+ + settingsStore + .getState() + .setShowLogTimestamps(event.currentTarget.checked) + } + /> +
+
+ +
+ +
+ +
+ +
+ +
+ +
+
+
+
+ +
+
+
+

Host 配置策略

+

+ 远端 Host 后续通过接口请求,本地 Host 手动添加,最终合并并去重,优先保留本地配置。 +

+
+ +
+
+

添加本地 Host

+ +
+
- void handleDebugToggle(event.currentTarget.checked) - } + class="rounded-xl border border-zinc-200 bg-white px-4 py-3 transition outline-none focus:border-cyan-400" + value={hostLabel()} + onInput={(event) => setHostLabel(event.currentTarget.value)} + placeholder="名称,如:校内测试" + /> + setHostValue(event.currentTarget.value)} + placeholder="Host,如:example.com" />
-
-

后端状态:{backendDebugState()?.enabled ? "已开启" : "已关闭"}

-

- 编译模式:{backendDebugState()?.buildMode ?? "-"} -

-

- 本地代理: - {backendDebugState()?.proxyConfigured - ? backendDebugState()?.proxy - : "未配置"} -

-

- 跳过 SSL 校验: - {backendDebugState()?.skipSSLVerify ? "已配置" : "未配置"} -

-
- {debugError() ? ( + + + {hostError() ? (
- {debugError()} + {hostError()}
) : null}
+
-
-
-
-

日志自动滚动

-

- 新日志出现时自动滚动到最底部 -

-
- - settingsStore - .getState() - .setAutoScrollLogs(event.currentTarget.checked) - } - /> -
+
+
+

Host 列表

+

本地配置优先覆盖远端

-
-
-
-

显示日志时间戳

-

- 后续日志输出可以追加格式化时间 -

-
- - settingsStore - .getState() - .setShowLogTimestamps(event.currentTarget.checked) - } - /> -
-
- -
- -
- -
- -
- -
- -
-
-
-
- -
-
-
-

Host 配置策略

-

- 远端 Host 后续通过接口请求,本地 Host - 手动添加,最终合并并去重,优先保留本地配置。 -

-
- -
-
-

添加本地 Host

- -
-
- setHostLabel(event.currentTarget.value)} - placeholder="名称,如:校内测试" - /> - setHostValue(event.currentTarget.value)} - placeholder="Host,如:example.com" - /> -
- - - {hostError() ? ( -
- {hostError()} -
- ) : null} -
- -
-
-

本地 Host

-
- - {(item) => ( -
-
-
-

- {item.label} -

-

- {item.host} -

+
+
+

本地 Host

+
+ + {(item) => ( +
+
+
+

{item.label}

+

{item.host}

+
+
-
-
- )} - + )} + +
-
-
-

合并结果

-
- - {(item) => ( -
-

{item.label}

-

{item.host}

-

- 来源:{item.source === "local" ? "本地优先" : "远端"} -

-
- )} -
+
+

合并结果

+
+ + {(item) => ( +
+

{item.label}

+

{item.host}

+

+ 来源:{item.source === "local" ? "本地优先" : "远端"} +

+
+ )} +
+
-
+