mirror of
https://github.com/MoonTechLab/LunaTV.git
synced 2026-02-28 01:13:15 +08:00
新增开关支持关闭网页直播
This commit is contained in:
@@ -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 |
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* 启用网页直播 */}
|
||||
<div>
|
||||
<div className='flex items-center justify-between'>
|
||||
<label
|
||||
className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2"
|
||||
>
|
||||
启用网页直播
|
||||
</label>
|
||||
<button
|
||||
type='button'
|
||||
onClick={() =>
|
||||
setSiteSettings((prev) => ({
|
||||
...prev,
|
||||
EnableWebLive: !prev.EnableWebLive,
|
||||
}))
|
||||
}
|
||||
className={`relative inline-flex h-6 w-11 items-center rounded-full transition-colors focus:outline-none focus:ring-2 focus:ring-green-500 focus:ring-offset-2 ${siteSettings.EnableWebLive
|
||||
? buttonStyles.toggleOn
|
||||
: buttonStyles.toggleOff
|
||||
}`}
|
||||
>
|
||||
<span
|
||||
className={`inline-block h-4 w-4 transform rounded-full ${buttonStyles.toggleThumb} transition-transform ${siteSettings.EnableWebLive
|
||||
? buttonStyles.toggleThumbOn
|
||||
: buttonStyles.toggleThumbOff
|
||||
}`}
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
<p className='mt-1 text-xs text-gray-500 dark:text-gray-400'>
|
||||
网页直播性能较差,会导致服务器内存泄露。
|
||||
</p>
|
||||
</div>
|
||||
|
||||
|
||||
{/* 操作按钮 */}
|
||||
<div className='flex justify-end'>
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
|
||||
// 写入数据库
|
||||
|
||||
@@ -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 (
|
||||
|
||||
@@ -1606,7 +1606,38 @@ const FavoriteIcon = ({ filled }: { filled: boolean }) => {
|
||||
export default function LivePage() {
|
||||
return (
|
||||
<Suspense fallback={<div>Loading...</div>}>
|
||||
<LivePageClient />
|
||||
<LivePageGuard />
|
||||
</Suspense>
|
||||
);
|
||||
}
|
||||
|
||||
function LivePageGuard() {
|
||||
const [enabled, setEnabled] = useState<boolean | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
const runtimeConfig = (window as any).RUNTIME_CONFIG;
|
||||
setEnabled(!!runtimeConfig?.ENABLE_WEB_LIVE);
|
||||
}, []);
|
||||
|
||||
if (enabled === null) {
|
||||
return <div>Loading...</div>;
|
||||
}
|
||||
|
||||
if (!enabled) {
|
||||
return (
|
||||
<PageLayout activePath='/live'>
|
||||
<div className='flex flex-col items-center justify-center min-h-[60vh] text-center px-4'>
|
||||
<Radio className='h-16 w-16 text-gray-300 dark:text-gray-600 mb-4' />
|
||||
<h2 className='text-xl font-semibold text-gray-700 dark:text-gray-300 mb-2'>
|
||||
网页直播未开启
|
||||
</h2>
|
||||
<p className='text-gray-500 dark:text-gray-400 max-w-md'>
|
||||
当前站点未启用网页直播功能,请联系站点管理员开启。
|
||||
</p>
|
||||
</div>
|
||||
</PageLayout>
|
||||
);
|
||||
}
|
||||
|
||||
return <LivePageClient />;
|
||||
}
|
||||
|
||||
@@ -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',
|
||||
},
|
||||
];
|
||||
});
|
||||
}
|
||||
}, []);
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@ export interface AdminConfig {
|
||||
DoubanImageProxy: string;
|
||||
DisableYellowFilter: boolean;
|
||||
FluidSearch: boolean;
|
||||
EnableWebLive: boolean;
|
||||
};
|
||||
UserConfig: {
|
||||
Users: {
|
||||
|
||||
Reference in New Issue
Block a user