From de77e6c7867beb20e3a5193e98b12490db332893 Mon Sep 17 00:00:00 2001 From: lpf Date: Mon, 9 Mar 2026 16:50:19 +0800 Subject: [PATCH] feat(webui): add github and version check actions --- webui/src/components/Header.tsx | 66 +++++++++++++++++++++++++++++++-- webui/src/i18n/index.ts | 16 ++++++++ 2 files changed, 79 insertions(+), 3 deletions(-) diff --git a/webui/src/components/Header.tsx b/webui/src/components/Header.tsx index 1c1d8fc..782af27 100644 --- a/webui/src/components/Header.tsx +++ b/webui/src/components/Header.tsx @@ -1,19 +1,60 @@ import React from 'react'; -import { Terminal, Globe, Menu, Moon, SunMedium } from 'lucide-react'; +import { Terminal, Globe, Github, Menu, Moon, RefreshCw, SunMedium } from 'lucide-react'; import { useTranslation } from 'react-i18next'; import { useAppContext } from '../context/AppContext'; import { useUI } from '../context/UIContext'; +const REPO_URL = 'https://github.com/YspCoder/clawgo'; + +function normalizeVersion(value: string) { + return String(value || '').trim().replace(/^v/i, ''); +} + const Header: React.FC = () => { const { t, i18n } = useTranslation(); - const { isGatewayOnline, setSidebarOpen, sidebarCollapsed } = useAppContext(); - const { theme, toggleTheme } = useUI(); + const { isGatewayOnline, setSidebarOpen, sidebarCollapsed, gatewayVersion, webuiVersion } = useAppContext(); + const { theme, toggleTheme, notify } = useUI(); + const [checkingVersion, setCheckingVersion] = React.useState(false); const toggleLang = () => { const nextLang = i18n.language === 'en' ? 'zh' : 'en'; i18n.changeLanguage(nextLang); }; + const checkVersion = async () => { + setCheckingVersion(true); + try { + const response = await fetch('https://api.github.com/repos/YspCoder/clawgo/releases/latest', { + headers: { Accept: 'application/vnd.github+json' }, + }); + if (!response.ok) { + throw new Error(`GitHub API ${response.status}`); + } + const data = await response.json(); + const latest = normalizeVersion(data?.tag_name || ''); + const currentGateway = normalizeVersion(gatewayVersion); + const currentWebUI = normalizeVersion(webuiVersion); + const isCurrent = latest && latest === currentGateway && latest === currentWebUI; + await notify({ + title: isCurrent ? t('versionCheckUpToDateTitle') : t('versionCheckUpdateTitle'), + message: isCurrent + ? t('versionCheckUpToDateMessage', { version: latest || '-' }) + : t('versionCheckUpdateMessage', { + latest: latest || '-', + gateway: currentGateway || '-', + webui: currentWebUI || '-', + }), + }); + } catch (error) { + await notify({ + title: t('versionCheckFailedTitle'), + message: t('versionCheckFailedMessage', { error: error instanceof Error ? error.message : String(error) }), + }); + } finally { + setCheckingVersion(false); + } + }; + return (
@@ -52,6 +93,25 @@ const Header: React.FC = () => {
+ + + + + +