修正观影室管理面板设置
This commit is contained in:
@@ -7,6 +7,8 @@ import Link from 'next/link';
|
||||
import { usePathname, useSearchParams } from 'next/navigation';
|
||||
import { useEffect, useState } from 'react';
|
||||
|
||||
import { useWatchRoomContextSafe } from './WatchRoomProvider';
|
||||
|
||||
interface MobileBottomNavProps {
|
||||
/**
|
||||
* 主动指定当前激活的路径。当未提供时,自动使用 usePathname() 获取的路径。
|
||||
@@ -17,6 +19,7 @@ interface MobileBottomNavProps {
|
||||
const MobileBottomNav = ({ activePath }: MobileBottomNavProps) => {
|
||||
const pathname = usePathname();
|
||||
const searchParams = useSearchParams();
|
||||
const watchRoomContext = useWatchRoomContextSafe();
|
||||
|
||||
// 直接使用当前路由状态,确保立即响应路由变化
|
||||
const getCurrentFullPath = () => {
|
||||
@@ -52,26 +55,61 @@ const MobileBottomNav = ({ activePath }: MobileBottomNavProps) => {
|
||||
label: '直播',
|
||||
href: '/live',
|
||||
},
|
||||
{
|
||||
icon: Users,
|
||||
label: '观影室',
|
||||
href: '/watch-room',
|
||||
},
|
||||
]);
|
||||
|
||||
useEffect(() => {
|
||||
const runtimeConfig = (window as any).RUNTIME_CONFIG;
|
||||
if (runtimeConfig?.CUSTOM_CATEGORIES?.length > 0) {
|
||||
setNavItems((prevItems) => [
|
||||
...prevItems,
|
||||
{
|
||||
icon: Star,
|
||||
label: '自定义',
|
||||
href: '/douban?type=custom',
|
||||
},
|
||||
]);
|
||||
|
||||
// 基础导航项(不包括观影室)
|
||||
let items = [
|
||||
{ icon: Home, label: '首页', href: '/' },
|
||||
{
|
||||
icon: Film,
|
||||
label: '电影',
|
||||
href: '/douban?type=movie',
|
||||
},
|
||||
{
|
||||
icon: Tv,
|
||||
label: '剧集',
|
||||
href: '/douban?type=tv',
|
||||
},
|
||||
{
|
||||
icon: Cat,
|
||||
label: '动漫',
|
||||
href: '/douban?type=anime',
|
||||
},
|
||||
{
|
||||
icon: Clover,
|
||||
label: '综艺',
|
||||
href: '/douban?type=show',
|
||||
},
|
||||
{
|
||||
icon: Radio,
|
||||
label: '直播',
|
||||
href: '/live',
|
||||
},
|
||||
];
|
||||
|
||||
// 如果启用观影室,添加观影室入口
|
||||
if (watchRoomContext?.isEnabled) {
|
||||
items.push({
|
||||
icon: Users,
|
||||
label: '观影室',
|
||||
href: '/watch-room',
|
||||
});
|
||||
}
|
||||
}, []);
|
||||
|
||||
// 添加自定义分类(如果有)
|
||||
if (runtimeConfig?.CUSTOM_CATEGORIES?.length > 0) {
|
||||
items.push({
|
||||
icon: Star,
|
||||
label: '自定义',
|
||||
href: '/douban?type=custom',
|
||||
});
|
||||
}
|
||||
|
||||
setNavItems(items);
|
||||
}, [watchRoomContext?.isEnabled]);
|
||||
|
||||
const isActive = (href: string) => {
|
||||
const typeMatch = href.match(/type=([^&]+)/)?.[1];
|
||||
|
||||
+51
-15
@@ -15,6 +15,7 @@ import {
|
||||
} from 'react';
|
||||
|
||||
import { useSite } from './SiteProvider';
|
||||
import { useWatchRoomContextSafe } from './WatchRoomProvider';
|
||||
|
||||
interface SidebarContextType {
|
||||
isCollapsed: boolean;
|
||||
@@ -59,6 +60,7 @@ declare global {
|
||||
const Sidebar = ({ onToggle, activePath = '/' }: SidebarProps) => {
|
||||
const pathname = usePathname();
|
||||
const searchParams = useSearchParams();
|
||||
const watchRoomContext = useWatchRoomContextSafe();
|
||||
// 若同一次 SPA 会话中已经读取过折叠状态,则直接复用,避免闪烁
|
||||
const [isCollapsed, setIsCollapsed] = useState<boolean>(() => {
|
||||
if (
|
||||
@@ -143,26 +145,60 @@ const Sidebar = ({ onToggle, activePath = '/' }: SidebarProps) => {
|
||||
label: '直播',
|
||||
href: '/live',
|
||||
},
|
||||
{
|
||||
icon: Users,
|
||||
label: '观影室',
|
||||
href: '/watch-room',
|
||||
},
|
||||
]);
|
||||
|
||||
useEffect(() => {
|
||||
const runtimeConfig = (window as any).RUNTIME_CONFIG;
|
||||
if (runtimeConfig?.CUSTOM_CATEGORIES?.length > 0) {
|
||||
setMenuItems((prevItems) => [
|
||||
...prevItems,
|
||||
{
|
||||
icon: Star,
|
||||
label: '自定义',
|
||||
href: '/douban?type=custom',
|
||||
},
|
||||
]);
|
||||
|
||||
// 基础菜单项(不包括观影室)
|
||||
let items = [
|
||||
{
|
||||
icon: Film,
|
||||
label: '电影',
|
||||
href: '/douban?type=movie',
|
||||
},
|
||||
{
|
||||
icon: Tv,
|
||||
label: '剧集',
|
||||
href: '/douban?type=tv',
|
||||
},
|
||||
{
|
||||
icon: Cat,
|
||||
label: '动漫',
|
||||
href: '/douban?type=anime',
|
||||
},
|
||||
{
|
||||
icon: Clover,
|
||||
label: '综艺',
|
||||
href: '/douban?type=show',
|
||||
},
|
||||
{
|
||||
icon: Radio,
|
||||
label: '直播',
|
||||
href: '/live',
|
||||
},
|
||||
];
|
||||
|
||||
// 如果启用观影室,添加观影室入口
|
||||
if (watchRoomContext?.isEnabled) {
|
||||
items.push({
|
||||
icon: Users,
|
||||
label: '观影室',
|
||||
href: '/watch-room',
|
||||
});
|
||||
}
|
||||
}, []);
|
||||
|
||||
// 添加自定义分类(如果有)
|
||||
if (runtimeConfig?.CUSTOM_CATEGORIES?.length > 0) {
|
||||
items.push({
|
||||
icon: Star,
|
||||
label: '自定义',
|
||||
href: '/douban?type=custom',
|
||||
});
|
||||
}
|
||||
|
||||
setMenuItems(items);
|
||||
}, [watchRoomContext?.isEnabled]);
|
||||
|
||||
return (
|
||||
<SidebarContext.Provider value={contextValue}>
|
||||
|
||||
@@ -109,43 +109,47 @@ export function WatchRoomProvider({ children }: WatchRoomProviderProps) {
|
||||
// 加载配置
|
||||
useEffect(() => {
|
||||
const loadConfig = async () => {
|
||||
// 默认配置:启用内部服务器
|
||||
const defaultConfig: WatchRoomConfig = {
|
||||
enabled: true,
|
||||
serverType: 'internal',
|
||||
};
|
||||
|
||||
try {
|
||||
const response = await fetch('/api/admin/config');
|
||||
// 使用公共 API 获取观影室配置(不需要管理员权限)
|
||||
const response = await fetch('/api/server-config');
|
||||
if (response.ok) {
|
||||
const data = await response.json();
|
||||
// API 返回格式: { SiteName, StorageType, Version, WatchRoom }
|
||||
const watchRoomConfig: WatchRoomConfig = {
|
||||
enabled: data.watchRoom?.enabled ?? true,
|
||||
serverType: data.watchRoom?.serverType ?? 'internal',
|
||||
externalServerUrl: data.watchRoom?.externalServerUrl,
|
||||
externalServerAuth: data.watchRoom?.externalServerAuth,
|
||||
enabled: data.WatchRoom?.enabled ?? false, // 默认不启用
|
||||
serverType: data.WatchRoom?.serverType ?? 'internal',
|
||||
externalServerUrl: data.WatchRoom?.externalServerUrl,
|
||||
externalServerAuth: data.WatchRoom?.externalServerAuth,
|
||||
};
|
||||
setConfig(watchRoomConfig);
|
||||
setIsEnabled(watchRoomConfig.enabled);
|
||||
|
||||
// 如果启用了观影室,自动连接
|
||||
// 只在启用了观影室时才连接
|
||||
if (watchRoomConfig.enabled) {
|
||||
console.log('[WatchRoom] Connecting with config:', watchRoomConfig);
|
||||
await watchRoom.connect(watchRoomConfig);
|
||||
} else {
|
||||
console.log('[WatchRoom] Watch room is disabled, skipping connection');
|
||||
}
|
||||
} else {
|
||||
throw new Error('Failed to load config');
|
||||
console.error('[WatchRoom] Failed to load config:', response.status);
|
||||
// 加载配置失败时,不连接,保持禁用状态
|
||||
const defaultConfig: WatchRoomConfig = {
|
||||
enabled: false,
|
||||
serverType: 'internal',
|
||||
};
|
||||
setConfig(defaultConfig);
|
||||
setIsEnabled(false);
|
||||
}
|
||||
} catch (error) {
|
||||
console.log('[WatchRoom] Using default config (internal server enabled)');
|
||||
console.error('[WatchRoom] Error loading config:', error);
|
||||
// 加载配置失败时,不连接,保持禁用状态
|
||||
const defaultConfig: WatchRoomConfig = {
|
||||
enabled: false,
|
||||
serverType: 'internal',
|
||||
};
|
||||
setConfig(defaultConfig);
|
||||
setIsEnabled(true);
|
||||
|
||||
try {
|
||||
await watchRoom.connect(defaultConfig);
|
||||
} catch (connectError) {
|
||||
console.error('[WatchRoom] Failed to connect:', connectError);
|
||||
}
|
||||
setIsEnabled(false);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user