- {/* 侧边栏 - 桌面端显示,移动端隐藏 */}
-
-
-
-
- {/* 主内容区域 */}
-
- {/* 桌面端左上角返回按钮 */}
- {['/play', '/live'].includes(activePath) && (
-
-
-
- )}
-
- {/* 桌面端顶部按钮 */}
-
-
-
+ {/* 主要布局容器 */}
+
+ {/* 侧边栏 - 桌面端显示,移动端隐藏 */}
+
+
- {/* 主内容 */}
-
- {children}
-
+ {/* 主内容区域 */}
+
+ {/* 桌面端左上角返回按钮 */}
+ {['/play', '/live'].includes(activePath) && (
+
+
+
+ )}
+
+ {/* 桌面端顶部按钮 */}
+
+
+
+
+
+
+ {/* 主内容 */}
+
+ {children}
+
+
+
+
+ {/* 移动端底部导航 */}
+
+
-
- {/* 移动端底部导航 */}
-
-
-
-
+
);
};
diff --git a/src/components/UpdateNotification.tsx b/src/components/UpdateNotification.tsx
new file mode 100644
index 0000000..bf89c05
--- /dev/null
+++ b/src/components/UpdateNotification.tsx
@@ -0,0 +1,45 @@
+'use client';
+
+import { useEffect, useState } from 'react';
+
+import { getAuthInfoFromBrowserCookie } from '@/lib/auth';
+import { UpdateStatus } from '@/lib/version_check';
+
+import { useVersionCheck } from './VersionCheckProvider';
+import { VersionPanel } from './VersionPanel';
+
+export const UpdateNotification: React.FC = () => {
+ const { updateStatus, isChecking } = useVersionCheck();
+ const [isOwner, setIsOwner] = useState(false);
+ const [isVersionPanelOpen, setIsVersionPanelOpen] = useState(false);
+
+ useEffect(() => {
+ // 检查认证信息
+ const authInfo = getAuthInfoFromBrowserCookie();
+ setIsOwner(authInfo?.role === 'owner');
+ }, []);
+
+ // 检查中、不是站长或没有更新时不渲染任何内容
+ if (isChecking || !isOwner || updateStatus !== UpdateStatus.HAS_UPDATE) {
+ return null;
+ }
+
+ return (
+ <>
+
+
+ {/* 版本面板 */}
+
setIsVersionPanelOpen(false)}
+ />
+ >
+ );
+};
diff --git a/src/components/UserMenu.tsx b/src/components/UserMenu.tsx
index 80f1669..2fa2765 100644
--- a/src/components/UserMenu.tsx
+++ b/src/components/UserMenu.tsx
@@ -20,8 +20,9 @@ import { createPortal } from 'react-dom';
import { getAuthInfoFromBrowserCookie } from '@/lib/auth';
import { clearAllDanmakuCache } from '@/lib/danmaku/api';
import { CURRENT_VERSION } from '@/lib/version';
-import { checkForUpdates, UpdateStatus } from '@/lib/version_check';
+import { UpdateStatus } from '@/lib/version_check';
+import { useVersionCheck } from './VersionCheckProvider';
import { VersionPanel } from './VersionPanel';
interface AuthInfo {
@@ -31,6 +32,7 @@ interface AuthInfo {
export const UserMenu: React.FC = () => {
const router = useRouter();
+ const { updateStatus, isChecking } = useVersionCheck();
const [isOpen, setIsOpen] = useState(false);
const [isSettingsOpen, setIsSettingsOpen] = useState(false);
const [isChangePasswordOpen, setIsChangePasswordOpen] = useState(false);
@@ -106,10 +108,6 @@ export const UserMenu: React.FC = () => {
const [passwordLoading, setPasswordLoading] = useState(false);
const [passwordError, setPasswordError] = useState('');
- // 版本检查相关状态
- const [updateStatus, setUpdateStatus] = useState(null);
- const [isChecking, setIsChecking] = useState(true);
-
// 清除弹幕缓存相关状态
const [isClearingCache, setIsClearingCache] = useState(false);
const [clearCacheMessage, setClearCacheMessage] = useState(null);
@@ -203,22 +201,6 @@ export const UserMenu: React.FC = () => {
}
}, []);
- // 版本检查
- useEffect(() => {
- const checkUpdate = async () => {
- try {
- const status = await checkForUpdates();
- setUpdateStatus(status);
- } catch (error) {
- console.warn('版本检查失败:', error);
- } finally {
- setIsChecking(false);
- }
- };
-
- checkUpdate();
- }, []);
-
// 点击外部区域关闭下拉框
useEffect(() => {
const handleClickOutside = (event: MouseEvent) => {
diff --git a/src/components/VersionCheckProvider.tsx b/src/components/VersionCheckProvider.tsx
new file mode 100644
index 0000000..bf666a3
--- /dev/null
+++ b/src/components/VersionCheckProvider.tsx
@@ -0,0 +1,45 @@
+'use client';
+
+import { createContext, useContext, useEffect, useState } from 'react';
+
+import { checkForUpdates, UpdateStatus } from '@/lib/version_check';
+
+interface VersionCheckContextType {
+ updateStatus: UpdateStatus | null;
+ isChecking: boolean;
+}
+
+const VersionCheckContext = createContext({
+ updateStatus: null,
+ isChecking: true,
+});
+
+export const useVersionCheck = () => useContext(VersionCheckContext);
+
+export const VersionCheckProvider: React.FC<{ children: React.ReactNode }> = ({
+ children,
+}) => {
+ const [updateStatus, setUpdateStatus] = useState(null);
+ const [isChecking, setIsChecking] = useState(true);
+
+ useEffect(() => {
+ const checkUpdate = async () => {
+ try {
+ const status = await checkForUpdates();
+ setUpdateStatus(status);
+ } catch (error) {
+ console.warn('版本检查失败:', error);
+ } finally {
+ setIsChecking(false);
+ }
+ };
+
+ checkUpdate();
+ }, []);
+
+ return (
+
+ {children}
+
+ );
+};