diff --git a/src/app/admin/page.tsx b/src/app/admin/page.tsx
index 3c5cce0..49958b2 100644
--- a/src/app/admin/page.tsx
+++ b/src/app/admin/page.tsx
@@ -267,6 +267,7 @@ interface SiteConfig {
DoubanImageProxy: string;
DisableYellowFilter: boolean;
FluidSearch: boolean;
+ EnableWebLive: boolean;
}
// 视频源数据类型
@@ -3393,6 +3394,7 @@ const SiteConfigComponent = ({ config, refreshConfig }: { config: AdminConfig |
DoubanImageProxy: '',
DisableYellowFilter: false,
FluidSearch: true,
+ EnableWebLive: false,
});
// 豆瓣数据源相关状态
@@ -3455,6 +3457,7 @@ const SiteConfigComponent = ({ config, refreshConfig }: { config: AdminConfig |
DoubanImageProxy: config.SiteConfig.DoubanImageProxy || '',
DisableYellowFilter: config.SiteConfig.DisableYellowFilter || false,
FluidSearch: config.SiteConfig.FluidSearch || true,
+ EnableWebLive: config.SiteConfig.EnableWebLive ?? false,
});
}
}, [config]);
@@ -3907,6 +3910,40 @@ const SiteConfigComponent = ({ config, refreshConfig }: { config: AdminConfig |
+ {/* 启用网页直播 */}
+
+
+
+
+
+
+ 网页直播性能较差,会导致服务器内存泄露。
+
+
+
{/* 操作按钮 */}
diff --git a/src/app/api/admin/site/route.ts b/src/app/api/admin/site/route.ts
index b06539a..003ddb3 100644
--- a/src/app/api/admin/site/route.ts
+++ b/src/app/api/admin/site/route.ts
@@ -39,6 +39,7 @@ export async function POST(request: NextRequest) {
DoubanImageProxy,
DisableYellowFilter,
FluidSearch,
+ EnableWebLive,
} = body as {
SiteName: string;
Announcement: string;
@@ -50,6 +51,7 @@ export async function POST(request: NextRequest) {
DoubanImageProxy: string;
DisableYellowFilter: boolean;
FluidSearch: boolean;
+ EnableWebLive: boolean;
};
// 参数校验
@@ -93,6 +95,7 @@ export async function POST(request: NextRequest) {
DoubanImageProxy,
DisableYellowFilter,
FluidSearch,
+ EnableWebLive: EnableWebLive ?? false,
};
// 写入数据库
diff --git a/src/app/layout.tsx b/src/app/layout.tsx
index e24fcea..51ad3a9 100644
--- a/src/app/layout.tsx
+++ b/src/app/layout.tsx
@@ -54,6 +54,7 @@ export default async function RootLayout({
let disableYellowFilter =
process.env.NEXT_PUBLIC_DISABLE_YELLOW_FILTER === 'true';
let fluidSearch = process.env.NEXT_PUBLIC_FLUID_SEARCH !== 'false';
+ let enableWebLive = false;
let customCategories = [] as {
name: string;
type: 'movie' | 'tv';
@@ -77,6 +78,7 @@ export default async function RootLayout({
query: category.query,
}));
fluidSearch = config.SiteConfig.FluidSearch;
+ enableWebLive = config.SiteConfig.EnableWebLive ?? false;
}
// 将运行时配置注入到全局 window 对象,供客户端在运行时读取
@@ -89,6 +91,7 @@ export default async function RootLayout({
DISABLE_YELLOW_FILTER: disableYellowFilter,
CUSTOM_CATEGORIES: customCategories,
FLUID_SEARCH: fluidSearch,
+ ENABLE_WEB_LIVE: enableWebLive,
};
return (
diff --git a/src/app/live/page.tsx b/src/app/live/page.tsx
index 58d4c61..5394016 100644
--- a/src/app/live/page.tsx
+++ b/src/app/live/page.tsx
@@ -1606,7 +1606,38 @@ const FavoriteIcon = ({ filled }: { filled: boolean }) => {
export default function LivePage() {
return (
Loading...
}>
-
+
);
}
+
+function LivePageGuard() {
+ const [enabled, setEnabled] = useState(null);
+
+ useEffect(() => {
+ const runtimeConfig = (window as any).RUNTIME_CONFIG;
+ setEnabled(!!runtimeConfig?.ENABLE_WEB_LIVE);
+ }, []);
+
+ if (enabled === null) {
+ return Loading...
;
+ }
+
+ if (!enabled) {
+ return (
+
+
+
+
+ 网页直播未开启
+
+
+ 当前站点未启用网页直播功能,请联系站点管理员开启。
+
+
+
+ );
+ }
+
+ return ;
+}
diff --git a/src/components/Sidebar.tsx b/src/components/Sidebar.tsx
index 04f006c..2160df0 100644
--- a/src/components/Sidebar.tsx
+++ b/src/components/Sidebar.tsx
@@ -145,24 +145,35 @@ const Sidebar = ({ onToggle, activePath = '/' }: SidebarProps) => {
label: '综艺',
href: '/douban?type=show',
},
- {
- icon: Radio,
- label: '直播',
- href: '/live',
- },
]);
useEffect(() => {
const runtimeConfig = (window as any).RUNTIME_CONFIG;
+ if (runtimeConfig?.ENABLE_WEB_LIVE) {
+ setMenuItems((prevItems) => {
+ if (prevItems.some((item) => item.href === '/live')) return prevItems;
+ return [
+ ...prevItems,
+ {
+ icon: Radio,
+ label: '直播',
+ href: '/live',
+ },
+ ];
+ });
+ }
if (runtimeConfig?.CUSTOM_CATEGORIES?.length > 0) {
- setMenuItems((prevItems) => [
- ...prevItems,
- {
- icon: Star,
- label: '自定义',
- href: '/douban?type=custom',
- },
- ]);
+ setMenuItems((prevItems) => {
+ if (prevItems.some((item) => item.href === '/douban?type=custom')) return prevItems;
+ return [
+ ...prevItems,
+ {
+ icon: Star,
+ label: '自定义',
+ href: '/douban?type=custom',
+ },
+ ];
+ });
}
}, []);
diff --git a/src/lib/admin.types.ts b/src/lib/admin.types.ts
index e29fa00..a79857e 100644
--- a/src/lib/admin.types.ts
+++ b/src/lib/admin.types.ts
@@ -16,6 +16,7 @@ export interface AdminConfig {
DoubanImageProxy: string;
DisableYellowFilter: boolean;
FluidSearch: boolean;
+ EnableWebLive: boolean;
};
UserConfig: {
Users: {