fix(settings): stabilize update check status

This commit is contained in:
kuekhaoyang
2026-04-12 12:34:09 +08:00
parent 833077a1f6
commit a205393da0
5 changed files with 48 additions and 49 deletions
+6
View File
@@ -1,5 +1,11 @@
# Changelog
## 4.9.2 - 2026-04-12
- 设置页首次自动检查更新时不再让“检查更新”按钮自己持续转圈。
- 移除会反复闪烁的“正在整理结果”提示,避免用户误以为页面异常。
- 手动点击“检查更新”时才显示按钮转圈,状态反馈与用户操作保持一致。
## 4.9.1 - 2026-04-12
- 移除仅支持 Node.js 的 `/api/site-icon` 路由,避免 `next-on-pages` 因非 Edge 路由中止构建。
+11 -1
View File
@@ -4,8 +4,18 @@
"name": "KVideo",
"branch": "main"
},
"currentVersion": "4.9.1",
"currentVersion": "4.9.2",
"releases": [
{
"version": "4.9.2",
"publishedAt": "2026-04-12",
"title": "修复检查更新状态闪烁",
"notes": [
"设置页首次自动检查更新时不再让“检查更新”按钮自己持续转圈。",
"移除会反复闪烁的“正在整理结果”提示,避免用户误以为页面异常。",
"手动点击“检查更新”时才显示按钮转圈,状态反馈与用户操作保持一致。"
]
},
{
"version": "4.9.1",
"publishedAt": "2026-04-12",
+28 -45
View File
@@ -1,7 +1,7 @@
'use client';
import Link from 'next/link';
import { useEffect, useEffectEvent, useState, useTransition } from 'react';
import { useEffect, useEffectEvent, useState } from 'react';
import { ExternalLink, RefreshCw } from 'lucide-react';
import { SettingsSection } from './SettingsSection';
import type { AppReleaseEntry, AppUpdateResponse } from '@/lib/types/app-update';
@@ -107,11 +107,12 @@ function ReleaseNotesBlock({
export function AppVersionSettings() {
const [data, setData] = useState<AppUpdateResponse | null>(null);
const [hasLoaded, setHasLoaded] = useState(false);
const [isPending, startTransition] = useTransition();
const [isRefreshing, setIsRefreshing] = useState(false);
const fetchUpdateInfo = useEffectEvent(async () => {
setIsRefreshing(true);
const fetchUpdateInfo = useEffectEvent(async (manual: boolean = false) => {
if (manual) {
setIsRefreshing(true);
}
try {
const response = await fetch('/api/app-update', {
@@ -126,53 +127,36 @@ export function AppVersionSettings() {
}
const payload = (await response.json()) as AppUpdateResponse;
startTransition(() => {
setData(payload);
setHasLoaded(true);
});
setData(payload);
setHasLoaded(true);
} catch (error) {
setHasLoaded(true);
setData((previous) => ({
currentVersion: previous?.currentVersion || '未知',
currentRelease: previous?.currentRelease || null,
latestVersion: previous?.latestVersion || previous?.currentVersion || '未知',
latestRelease: previous?.latestRelease || previous?.currentRelease || null,
status: 'check-failed',
updateAvailable: false,
checkedAt: new Date().toISOString(),
checkedRemotely: false,
usedRemoteManifest: false,
source: previous?.source || DEFAULT_SOURCE,
error: error instanceof Error ? error.message : '未知错误',
}));
} finally {
setIsRefreshing(false);
if (manual) {
setIsRefreshing(false);
}
}
});
useEffect(() => {
void fetchUpdateInfo().catch((error) => {
startTransition(() => {
setHasLoaded(true);
setData((previous) => ({
currentVersion: previous?.currentVersion || '未知',
currentRelease: previous?.currentRelease || null,
latestVersion: previous?.latestVersion || previous?.currentVersion || '未知',
latestRelease: previous?.latestRelease || previous?.currentRelease || null,
status: 'check-failed',
updateAvailable: false,
checkedAt: new Date().toISOString(),
checkedRemotely: false,
usedRemoteManifest: false,
source: previous?.source || DEFAULT_SOURCE,
error: error instanceof Error ? error.message : '未知错误',
}));
});
});
}, [fetchUpdateInfo, startTransition]);
void fetchUpdateInfo(false);
}, []);
const handleRefresh = () => {
void fetchUpdateInfo().catch((error) => {
startTransition(() => {
setData((previous) =>
previous
? {
...previous,
status: 'check-failed',
error: error instanceof Error ? error.message : '未知错误',
checkedAt: new Date().toISOString(),
}
: previous,
);
setHasLoaded(true);
});
});
void fetchUpdateInfo(true);
};
const statusMeta = getStatusMeta(data);
@@ -215,7 +199,6 @@ export function AppVersionSettings() {
<p className="mt-3 text-sm text-[var(--text-color-secondary)]">{statusMeta.description}</p>
<p className="mt-2 text-xs text-[var(--text-color-secondary)]">
{hasLoaded ? formatDateLabel(data?.checkedAt) : '正在检查'}
{isPending ? '(正在整理结果)' : ''}
</p>
</div>
</div>
+2 -2
View File
@@ -1,12 +1,12 @@
{
"name": "kvideo",
"version": "4.9.1",
"version": "4.9.2",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "kvideo",
"version": "4.9.1",
"version": "4.9.2",
"dependencies": {
"@dnd-kit/core": "^6.3.1",
"@dnd-kit/sortable": "^10.0.0",
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "kvideo",
"version": "4.9.1",
"version": "4.9.2",
"private": true,
"scripts": {
"dev": "next dev --port ${PORT:-3000}",