From 99c95b87e52ffc25152a0d53e7a6bd85061a82d5 Mon Sep 17 00:00:00 2001 From: lofyer Date: Wed, 1 Jul 2026 12:35:39 +0800 Subject: [PATCH] feat(branding): rebrand footer vendor to MesaStack, trim footer/topbar - Footer vendor label unified to "MesaStack" across all locales. - Remove footer Help button; keep version as plain text (no click). - Remove top-right GitHub star widget (delete unused github-star.tsx); keep version as plain text (no click), retain upgrade "New" badge. Co-Authored-By: Claude Opus 4.8 (1M context) --- src/components/footer/index.tsx | 27 +----- src/layouts/extraRender.tsx | 28 +------ src/layouts/github-star.tsx | 140 -------------------------------- src/locales/en-US/common.ts | 2 +- src/locales/ja-JP/common.ts | 2 +- src/locales/ru-RU/common.ts | 2 +- src/locales/tr-TR/common.ts | 2 +- src/locales/zh-CN/common.ts | 2 +- 8 files changed, 11 insertions(+), 194 deletions(-) delete mode 100644 src/layouts/github-star.tsx diff --git a/src/components/footer/index.tsx b/src/components/footer/index.tsx index 48acfc50..1f1d61a3 100644 --- a/src/components/footer/index.tsx +++ b/src/components/footer/index.tsx @@ -1,9 +1,7 @@ import { GPUStackVersionAtom } from '@/atoms/user'; import { getAtomStorage } from '@/atoms/utils'; -import VersionInfo, { modalConfig } from '@/components/version-info'; -import externalLinks from '@/constants/external-links'; import { useIntl } from '@umijs/max'; -import { Button, Divider, Modal, Typography } from 'antd'; +import { Divider, Typography } from 'antd'; import { createStyles } from 'antd-style'; import styled from 'styled-components'; @@ -33,20 +31,10 @@ const useStyles = createStyles(({ token, css }) => ({ const Footer: React.FC = () => { const intl = useIntl(); - const [modal, contextHolder] = Modal.useModal(); const { styles } = useStyles(); - const showVersion = () => { - modal.info({ - ...modalConfig, - width: 460, - content: - }); - }; - return ( <> - {contextHolder}
@@ -63,18 +51,7 @@ const Footer: React.FC = () => { - - - + {getAtomStorage(GPUStackVersionAtom)?.version}
diff --git a/src/layouts/extraRender.tsx b/src/layouts/extraRender.tsx index 4cd702c6..c39100a9 100644 --- a/src/layouts/extraRender.tsx +++ b/src/layouts/extraRender.tsx @@ -1,8 +1,6 @@ import { GPUStackVersionAtom, UpdateCheckAtom } from '@/atoms/user'; import PluginExtraField from '@/components/plugin-extra-fields'; -import VersionInfo, { modalConfig } from '@/components/version-info'; import externalLinks from '@/constants/external-links'; -import useBodyScroll from '@/hooks/use-body-scroll'; import { logout } from '@/pages/login/apis'; import { useModel } from '@@/plugin-model'; import { @@ -13,12 +11,11 @@ import { } from '@ant-design/icons'; import { DropdownActions, IconFont } from '@gpustack/core-ui'; import { history, useIntl, useNavigate } from '@umijs/max'; -import { Avatar, Button, Divider, Modal } from 'antd'; +import { Avatar, Divider } from 'antd'; import { useAtom } from 'jotai'; import { useMemo } from 'react'; import styled from 'styled-components'; import { DEFAULT_ENTER_PAGE } from '../config/settings'; -import GithubStar from './github-star'; const NewLabel = styled.span` position: relative; @@ -98,11 +95,9 @@ const CustomItem = styled.div` export const ExtraContent = (props: { isDarkTheme?: boolean }) => { const { isDarkTheme } = props; - const { saveScrollHeight, restoreScrollHeight } = useBodyScroll(); - const [modal, contextHolder] = Modal.useModal(); + const intl = useIntl(); const [version] = useAtom(GPUStackVersionAtom); const [updateCheck] = useAtom(UpdateCheckAtom); - const intl = useIntl(); const initialInfo = useModel('@@initialState') || { initialState: undefined, loading: false, @@ -140,16 +135,6 @@ export const ExtraContent = (props: { isDarkTheme?: boolean }) => { return {}; }, [isDarkTheme]); - const showVersion = () => { - saveScrollHeight(); - modal.info({ - ...modalConfig, - width: 460, - content: , - onCancel: restoreScrollHeight - }); - }; - const handleLogout = async () => { await logout(); navigate(loginPath); @@ -259,25 +244,20 @@ export const ExtraContent = (props: { isDarkTheme?: boolean }) => { return ( - {contextHolder} - {process.env.ENABLE_ENTERPRISE !== 'true' && }
- + {showUpgrade && ( diff --git a/src/layouts/github-star.tsx b/src/layouts/github-star.tsx deleted file mode 100644 index 2d03e910..00000000 --- a/src/layouts/github-star.tsx +++ /dev/null @@ -1,140 +0,0 @@ -import externalLinks from '@/constants/external-links'; -import { GithubFilled } from '@ant-design/icons'; -import { useIntl } from '@umijs/max'; -import { Tooltip } from 'antd'; -import { useEffect, useState } from 'react'; -import styled from 'styled-components'; - -const REPO = 'gpustack/gpustack'; -const CACHE_KEY = 'gpustack:github-stars'; -const CACHE_TTL = 24 * 60 * 60 * 1000; -const FETCH_TIMEOUT = 4000; - -const StarLink = styled.a` - display: inline-flex; - align-items: stretch; - height: 24px; - border-radius: var(--ant-border-radius); - border: 1px solid var(--ant-color-border-secondary); - background-color: var(--ant-color-bg-container); - color: var(--ant-color-text-secondary); - font-size: 12px; - line-height: 1; - overflow: hidden; - transition: - border-color 0.2s, - color 0.2s; - - &:hover { - border-color: var(--ant-color-border); - color: var(--ant-color-text); - } - - .seg { - display: inline-flex; - align-items: center; - gap: 6px; - padding: 0 8px; - } - - .seg + .seg { - border-left: 1px solid var(--ant-color-border-secondary); - background-color: var(--ant-color-fill-quaternary); - } - - .anticon { - font-size: 13px; - } - - .count { - font-weight: 500; - font-variant-numeric: tabular-nums; - min-width: 1.5em; - text-align: center; - } -`; - -const formatCount = (n: number): string => { - if (n >= 1000) { - const k = n / 1000; - return k >= 10 ? `${Math.round(k)}k` : `${k.toFixed(1)}k`; - } - return String(n); -}; - -type CacheEntry = { value: number; time: number }; - -const readCache = (): CacheEntry | null => { - try { - const raw = localStorage.getItem(CACHE_KEY); - if (!raw) return null; - const parsed = JSON.parse(raw); - if (typeof parsed?.value !== 'number' || typeof parsed?.time !== 'number') { - return null; - } - return parsed; - } catch { - return null; - } -}; - -const writeCache = (value: number) => { - try { - localStorage.setItem( - CACHE_KEY, - JSON.stringify({ value, time: Date.now() }) - ); - } catch { - // ignore quota errors - } -}; - -const GithubStar = () => { - const intl = useIntl(); - const [count, setCount] = useState( - () => readCache()?.value ?? null - ); - - useEffect(() => { - const cached = readCache(); - const fresh = cached && Date.now() - cached.time < CACHE_TTL; - if (fresh) return; - - const controller = new AbortController(); - const timer = setTimeout(() => controller.abort(), FETCH_TIMEOUT); - - fetch(`https://api.github.com/repos/${REPO}`, { signal: controller.signal }) - .then((r) => (r.ok ? r.json() : null)) - .then((data) => { - if (!data || typeof data.stargazers_count !== 'number') return; - setCount(data.stargazers_count); - writeCache(data.stargazers_count); - }) - .catch(() => { - // offline, blocked, rate-limited — stay hidden if no cache - }) - .finally(() => clearTimeout(timer)); - - return () => { - clearTimeout(timer); - controller.abort(); - }; - }, []); - - return ( - - - - - - - - {count != null ? formatCount(count) : 'Star'} - - - - - ); -}; - -export default GithubStar; diff --git a/src/locales/en-US/common.ts b/src/locales/en-US/common.ts index d021a646..f29d363c 100644 --- a/src/locales/en-US/common.ts +++ b/src/locales/en-US/common.ts @@ -212,7 +212,7 @@ export default { 'common.form.password': 'Password', 'common.form.username': 'Username', 'common.login.rember': 'Remember me', - 'settings.company': 'MesaStack.ai', + 'settings.company': 'MesaStack', 'common.button.help': 'Help', 'common.button.feedback': 'Feedback', 'common.button.docs': 'Documentation', diff --git a/src/locales/ja-JP/common.ts b/src/locales/ja-JP/common.ts index 253e4e12..9a6da2ed 100644 --- a/src/locales/ja-JP/common.ts +++ b/src/locales/ja-JP/common.ts @@ -212,7 +212,7 @@ export default { 'common.form.password': 'パスワード', 'common.form.username': 'ユーザー名', 'common.login.rember': 'ログイン状態を保持', - 'settings.company': 'MesaStack.ai', + 'settings.company': 'MesaStack', 'common.button.help': 'ヘルプ', 'common.button.feedback': 'フィードバック', 'common.button.docs': 'ドキュメント', diff --git a/src/locales/ru-RU/common.ts b/src/locales/ru-RU/common.ts index d01a1813..22ef1493 100644 --- a/src/locales/ru-RU/common.ts +++ b/src/locales/ru-RU/common.ts @@ -210,7 +210,7 @@ export default { 'common.form.password': 'Пароль', 'common.form.username': 'Имя пользователя', 'common.login.rember': 'Запомнить меня', - 'settings.company': 'MesaStack.ai', + 'settings.company': 'MesaStack', 'common.button.help': 'Помощь', 'common.button.feedback': 'Обратная связь', 'common.button.docs': 'Документация', diff --git a/src/locales/tr-TR/common.ts b/src/locales/tr-TR/common.ts index cfded8b1..62086589 100644 --- a/src/locales/tr-TR/common.ts +++ b/src/locales/tr-TR/common.ts @@ -215,7 +215,7 @@ export default { 'common.form.password': 'Şifre', 'common.form.username': 'Kullanıcı adı', 'common.login.rember': 'Beni hatırla', - 'settings.company': 'MesaStack.ai', + 'settings.company': 'MesaStack', 'common.button.help': 'Yardım', 'common.button.feedback': 'Geri Bildirim', 'common.button.docs': 'Dokümantasyon', diff --git a/src/locales/zh-CN/common.ts b/src/locales/zh-CN/common.ts index 869a400b..281907b6 100644 --- a/src/locales/zh-CN/common.ts +++ b/src/locales/zh-CN/common.ts @@ -203,7 +203,7 @@ export default { 'common.form.password': '密码', 'common.form.username': '用户名', 'common.login.rember': '记住我', - 'settings.company': '数澈软件', + 'settings.company': 'MesaStack', 'common.button.help': '帮助', 'common.button.feedback': '反馈', 'common.button.docs': '文档',