diff --git a/CHANGELOG b/CHANGELOG
index 270a6ce..9405e03 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,3 +1,13 @@
+## [8.9.5] - 2025-09-21
+
+### Added
+- 添加内置主题,支持用户自定义CSS
+### Changed
+- 优化搜索页面缓存机制
+### Fixed
+- 镜像健康检查问题
+- 弹幕功能适配移动端
+
## [8.9.0] - 2025-09-15
### Added
diff --git a/Dockerfile b/Dockerfile
index ac2cfc9..eb2ec89 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -95,9 +95,45 @@ USER nextjs
# 暴露HTTP和WebSocket端口
EXPOSE 3000 3001
+# 创建健康检查脚本
+RUN echo '#!/usr/bin/env node\n\
+const http = require("http");\n\
+const options = {\n\
+ hostname: "localhost",\n\
+ port: 3000,\n\
+ path: "/api/health",\n\
+ method: "GET",\n\
+ timeout: 5000\n\
+};\n\
+\n\
+const req = http.request(options, (res) => {\n\
+ if (res.statusCode === 200) {\n\
+ console.log("Health check passed");\n\
+ process.exit(0);\n\
+ } else {\n\
+ console.log(`Health check failed with status: ${res.statusCode}`);\n\
+ process.exit(1);\n\
+ }\n\
+});\n\
+\n\
+req.on("error", (err) => {\n\
+ console.log(`Health check error: ${err.message}`);\n\
+ process.exit(1);\n\
+});\n\
+\n\
+req.on("timeout", () => {\n\
+ console.log("Health check timeout");\n\
+ req.destroy();\n\
+ process.exit(1);\n\
+});\n\
+\n\
+req.setTimeout(5000);\n\
+req.end();' > /app/healthcheck.js && \
+ chmod +x /app/healthcheck.js
+
# 添加健康检查
HEALTHCHECK --interval=30s --timeout=10s --start-period=40s --retries=3 \
- CMD curl -f http://localhost:3000/api/health || exit 1
+ CMD node /app/healthcheck.js
# 设置WebSocket端口环境变量
ENV WS_PORT=3001
diff --git a/VERSION.txt b/VERSION.txt
index 3ecb398..a37b21d 100644
--- a/VERSION.txt
+++ b/VERSION.txt
@@ -1 +1 @@
-8.9.0
\ No newline at end of file
+8.9.5
\ No newline at end of file
diff --git a/public/theme-init.js b/public/theme-init.js
new file mode 100644
index 0000000..3a8a1c9
--- /dev/null
+++ b/public/theme-init.js
@@ -0,0 +1,48 @@
+// 主题初始化脚本 - 立即执行,避免主题闪烁
+(function () {
+ try {
+ // 应用主题函数
+ function applyTheme(themeId, css) {
+ const html = document.documentElement;
+
+ // 移除所有主题属性
+ html.removeAttribute('data-theme');
+
+ // 应用主题
+ if (themeId !== 'default') {
+ html.setAttribute('data-theme', themeId);
+ }
+
+ // 应用自定义CSS
+ if (css) {
+ let customStyleEl = document.getElementById('init-theme-css');
+ if (!customStyleEl) {
+ customStyleEl = document.createElement('style');
+ customStyleEl.id = 'init-theme-css';
+ document.head.appendChild(customStyleEl);
+ }
+ customStyleEl.textContent = css;
+ }
+ }
+
+ // 从localStorage获取保存的主题
+ const savedTheme = localStorage.getItem('app-theme');
+ const savedCustomCSS = localStorage.getItem('app-custom-css') || '';
+
+ // 立即应用已保存的主题(如果有)
+ if (savedTheme) {
+ applyTheme(savedTheme, savedCustomCSS);
+ console.log('主题已初始化(本地设置):', savedTheme);
+ } else {
+ // 没有用户设置时,先应用默认主题
+ applyTheme('default', '');
+ console.log('主题已初始化(默认)');
+ }
+
+ // 注意:GlobalThemeLoader会在React组件挂载后进一步处理全站配置
+ } catch (error) {
+ console.error('主题初始化失败:', error);
+ }
+})();
+
+
diff --git a/src/app/admin/page.tsx b/src/app/admin/page.tsx
index b43ac83..9c21c92 100644
--- a/src/app/admin/page.tsx
+++ b/src/app/admin/page.tsx
@@ -38,7 +38,7 @@ import {
Users,
Video,
} from 'lucide-react';
-import { GripVertical } from 'lucide-react';
+import { GripVertical, Palette } from 'lucide-react';
import Image from 'next/image';
import { Suspense, useCallback, useEffect, useMemo, useRef, useState } from 'react';
import { createPortal } from 'react-dom';
@@ -47,6 +47,7 @@ import { AdminConfig, AdminConfigResult } from '../../lib/admin.types';
import { getAuthInfoFromBrowserCookie } from '@/lib/auth';
import DataMigration from '@/components/DataMigration';
+import ThemeManager from '@/components/ThemeManager';
import PageLayout from '@/components/PageLayout';
// 统一按钮样式系统
@@ -5210,6 +5211,7 @@ function AdminPageClient() {
categoryConfig: false,
configFile: false,
dataMigration: false,
+ themeManager: false,
});
// 机器码管理状态
@@ -5447,6 +5449,21 @@ function AdminPageClient() {
)}
+
+ {/* 主题定制标签 */}
+
+ }
+ isExpanded={expandedTabs.themeManager}
+ onToggle={() => toggleTab('themeManager')}
+ >
+
+
diff --git a/src/app/api/admin/site/route.ts b/src/app/api/admin/site/route.ts
index aedbe73..ce69f8a 100644
--- a/src/app/api/admin/site/route.ts
+++ b/src/app/api/admin/site/route.ts
@@ -40,6 +40,7 @@ export async function POST(request: NextRequest) {
DisableYellowFilter,
FluidSearch,
RequireDeviceCode,
+ CustomTheme,
} = body as {
SiteName: string;
Announcement: string;
@@ -52,6 +53,10 @@ export async function POST(request: NextRequest) {
DisableYellowFilter: boolean;
FluidSearch: boolean;
RequireDeviceCode: boolean;
+ CustomTheme?: {
+ selectedTheme: string;
+ customCSS: string;
+ };
};
// 参数校验
@@ -66,7 +71,11 @@ export async function POST(request: NextRequest) {
typeof DoubanImageProxy !== 'string' ||
typeof DisableYellowFilter !== 'boolean' ||
typeof FluidSearch !== 'boolean' ||
- typeof RequireDeviceCode !== 'boolean'
+ typeof RequireDeviceCode !== 'boolean' ||
+ (CustomTheme && (
+ typeof CustomTheme.selectedTheme !== 'string' ||
+ typeof CustomTheme.customCSS !== 'string'
+ ))
) {
return NextResponse.json({ error: '参数格式错误' }, { status: 400 });
}
@@ -97,6 +106,7 @@ export async function POST(request: NextRequest) {
DisableYellowFilter,
FluidSearch,
RequireDeviceCode,
+ CustomTheme,
};
// 写入数据库
diff --git a/src/app/api/admin/theme/route.ts b/src/app/api/admin/theme/route.ts
new file mode 100644
index 0000000..5130bfa
--- /dev/null
+++ b/src/app/api/admin/theme/route.ts
@@ -0,0 +1,139 @@
+import { NextResponse } from 'next/server';
+import { getAuthInfoFromCookie } from '@/lib/auth';
+import { db } from '@/lib/db';
+import { AdminConfig } from '@/lib/admin.types';
+import { headers, cookies } from 'next/headers';
+
+export async function GET() {
+ try {
+ // 创建一个模拟的NextRequest对象来使用getAuthInfoFromCookie
+ const cookieStore = cookies();
+ const authCookie = cookieStore.get('auth');
+
+ if (!authCookie) {
+ return NextResponse.json({ error: '未授权' }, { status: 401 });
+ }
+
+ let authData;
+ try {
+ const decoded = decodeURIComponent(authCookie.value);
+ authData = JSON.parse(decoded);
+ } catch (error) {
+ return NextResponse.json({ error: '认证信息无效' }, { status: 401 });
+ }
+
+ const config = await db.getAdminConfig();
+ const themeConfig = config?.ThemeConfig || {
+ defaultTheme: 'default' as const,
+ customCSS: '',
+ allowUserCustomization: true,
+ };
+
+ return NextResponse.json({
+ success: true,
+ data: themeConfig,
+ });
+ } catch (error) {
+ console.error('获取主题配置失败:', error);
+ return NextResponse.json(
+ { error: '获取主题配置失败' },
+ { status: 500 }
+ );
+ }
+}
+
+export async function POST(request: Request) {
+ try {
+ // 获取认证信息
+ const cookieStore = cookies();
+ const authCookie = cookieStore.get('auth');
+
+ if (!authCookie) {
+ return NextResponse.json({ error: '未授权' }, { status: 401 });
+ }
+
+ let authData;
+ try {
+ const decoded = decodeURIComponent(authCookie.value);
+ authData = JSON.parse(decoded);
+ } catch (error) {
+ return NextResponse.json({ error: '认证信息无效' }, { status: 401 });
+ }
+
+ // 检查是否为管理员
+ if (authData.role !== 'admin' && authData.role !== 'owner') {
+ return NextResponse.json({ error: '权限不足,仅管理员可设置全局主题' }, { status: 403 });
+ }
+
+ const body = await request.json();
+ const { defaultTheme, customCSS, allowUserCustomization } = body;
+
+ // 验证主题名称
+ const validThemes = ['default', 'minimal', 'warm', 'fresh'];
+ if (!validThemes.includes(defaultTheme)) {
+ return NextResponse.json({ error: '无效的主题名称' }, { status: 400 });
+ }
+
+ // 获取当前配置
+ const currentConfig = await db.getAdminConfig();
+
+ // 如果没有配置,创建一个基础配置
+ let baseConfig: AdminConfig;
+ if (!currentConfig) {
+ baseConfig = {
+ ConfigSubscribtion: {
+ URL: "",
+ AutoUpdate: false,
+ LastCheck: "",
+ },
+ ConfigFile: "",
+ SiteConfig: {
+ SiteName: "OrangeTV",
+ Announcement: "",
+ SearchDownstreamMaxPage: 10,
+ SiteInterfaceCacheTime: 30,
+ DoubanProxyType: "direct",
+ DoubanProxy: "",
+ DoubanImageProxyType: "direct",
+ DoubanImageProxy: "",
+ DisableYellowFilter: false,
+ FluidSearch: true,
+ RequireDeviceCode: false,
+ },
+ UserConfig: {
+ Users: [],
+ },
+ SourceConfig: [],
+ CustomCategories: [],
+ };
+ } else {
+ baseConfig = currentConfig;
+ }
+
+ // 更新主题配置
+ const updatedConfig: AdminConfig = {
+ ...baseConfig,
+ ThemeConfig: {
+ defaultTheme: defaultTheme as 'default' | 'minimal' | 'warm' | 'fresh',
+ customCSS: customCSS || '',
+ allowUserCustomization: allowUserCustomization !== false,
+ },
+ };
+
+ console.log('保存主题配置:', updatedConfig.ThemeConfig);
+ await db.saveAdminConfig(updatedConfig);
+ console.log('主题配置保存成功');
+
+ return NextResponse.json({
+ success: true,
+ message: '主题配置已更新',
+ data: updatedConfig.ThemeConfig,
+ });
+ } catch (error) {
+ console.error('更新主题配置失败:', error);
+ return NextResponse.json(
+ { error: '更新主题配置失败', details: error instanceof Error ? error.message : '未知错误' },
+ { status: 500 }
+ );
+ }
+}
diff --git a/src/app/api/theme/route.ts b/src/app/api/theme/route.ts
new file mode 100644
index 0000000..a0393ea
--- /dev/null
+++ b/src/app/api/theme/route.ts
@@ -0,0 +1,31 @@
+import { NextResponse } from 'next/server';
+import { db } from '@/lib/db';
+
+export async function GET() {
+ try {
+ const config = await db.getAdminConfig();
+ const themeConfig = config?.ThemeConfig || {
+ defaultTheme: 'default' as const,
+ customCSS: '',
+ allowUserCustomization: true,
+ };
+
+ return NextResponse.json({
+ success: true,
+ data: themeConfig,
+ });
+ } catch (error) {
+ console.error('获取主题配置失败:', error);
+ return NextResponse.json(
+ {
+ success: false,
+ data: {
+ defaultTheme: 'default' as const,
+ customCSS: '',
+ allowUserCustomization: true,
+ }
+ },
+ { status: 200 } // 返回默认配置而不是错误
+ );
+ }
+}
diff --git a/src/app/globals.css b/src/app/globals.css
index 879ba30..e730ab7 100644
--- a/src/app/globals.css
+++ b/src/app/globals.css
@@ -36,6 +36,1294 @@
:root {
--foreground-rgb: 255, 255, 255;
+
+ /* 默认主题(当前蓝色系主题) */
+ --color-primary-50: 240, 249, 255;
+ --color-primary-100: 224, 242, 254;
+ --color-primary-200: 186, 230, 253;
+ --color-primary-300: 125, 211, 252;
+ --color-primary-400: 56, 189, 248;
+ --color-primary-500: 14, 165, 233;
+ --color-primary-600: 2, 132, 199;
+ --color-primary-700: 3, 105, 161;
+ --color-primary-800: 7, 89, 133;
+ --color-primary-900: 12, 74, 110;
+ --color-dark: 34, 34, 34;
+
+ /* 主题颜色变量(默认使用蓝色系) */
+ --color-theme-bg: 255, 255, 255;
+ --color-theme-surface: 249, 250, 251;
+ --color-theme-accent: 14, 165, 233;
+ --color-theme-text: 17, 24, 39;
+ --color-theme-text-secondary: 107, 114, 128;
+ --color-theme-border: 229, 231, 235;
+ --color-theme-success: 34, 197, 94;
+ --color-theme-warning: 245, 158, 11;
+ --color-theme-error: 239, 68, 68;
+ --color-theme-info: 59, 130, 246;
+}
+
+.dark {
+ /* 默认深色主题 */
+ --color-theme-bg: 17, 24, 39;
+ --color-theme-surface: 31, 41, 55;
+ --color-theme-accent: 56, 189, 248;
+ --color-theme-text: 243, 244, 246;
+ --color-theme-text-secondary: 156, 163, 175;
+ --color-theme-border: 75, 85, 99;
+ --color-theme-success: 74, 222, 128;
+ --color-theme-warning: 251, 191, 36;
+ --color-theme-error: 248, 113, 113;
+ --color-theme-info: 96, 165, 250;
+}
+
+/* 视频卡片播放按钮hover填充颜色适配 */
+
+/* 极简主题视频卡片播放按钮适配 */
+[data-theme="minimal"] .hover\:fill-blue-500:hover {
+ fill: rgb(82, 82, 82) !important;
+}
+
+[data-theme="minimal"].dark .hover\:fill-blue-500:hover {
+ fill: rgb(163, 163, 163) !important;
+}
+
+/* 暖色主题视频卡片播放按钮适配 */
+[data-theme="warm"] .hover\:fill-blue-500:hover {
+ fill: rgb(234, 88, 12) !important;
+}
+
+[data-theme="warm"].dark .hover\:fill-blue-500:hover {
+ fill: rgb(251, 146, 60) !important;
+}
+
+/* 视频卡片hover时资源名称和视频名称适配 */
+
+/* 极简主题视频卡片文字适配 */
+[data-theme="minimal"] .group-hover\:text-blue-600:hover,
+[data-theme="minimal"] .group:hover .group-hover\:text-blue-600 {
+ color: rgb(64, 64, 64) !important;
+}
+[data-theme="minimal"] .group-hover\:text-blue-400:hover,
+[data-theme="minimal"] .group:hover .group-hover\:text-blue-400 {
+ color: rgb(163, 163, 163) !important;
+}
+[data-theme="minimal"] .group-hover\:border-blue-500\/60:hover,
+[data-theme="minimal"] .group:hover .group-hover\:border-blue-500\/60 {
+ border-color: rgb(82, 82, 82, 0.6) !important;
+}
+
+[data-theme="minimal"].dark .group-hover\:text-blue-600:hover,
+[data-theme="minimal"].dark .group:hover .group-hover\:text-blue-600 {
+ color: rgb(163, 163, 163) !important;
+}
+[data-theme="minimal"].dark .group-hover\:text-blue-400:hover,
+[data-theme="minimal"].dark .group:hover .group-hover\:text-blue-400 {
+ color: rgb(163, 163, 163) !important;
+}
+
+/* 暖色主题视频卡片文字适配 */
+[data-theme="warm"] .group-hover\:text-blue-600:hover,
+[data-theme="warm"] .group:hover .group-hover\:text-blue-600 {
+ color: rgb(194, 65, 12) !important;
+}
+[data-theme="warm"] .group-hover\:text-blue-400:hover,
+[data-theme="warm"] .group:hover .group-hover\:text-blue-400 {
+ color: rgb(251, 146, 60) !important;
+}
+[data-theme="warm"] .group-hover\:border-blue-500\/60:hover,
+[data-theme="warm"] .group:hover .group-hover\:border-blue-500\/60 {
+ border-color: rgb(234, 88, 12, 0.6) !important;
+}
+
+[data-theme="warm"].dark .group-hover\:text-blue-600:hover,
+[data-theme="warm"].dark .group:hover .group-hover\:text-blue-600 {
+ color: rgb(251, 146, 60) !important;
+}
+[data-theme="warm"].dark .group-hover\:text-blue-400:hover,
+[data-theme="warm"].dark .group:hover .group-hover\:text-blue-400 {
+ color: rgb(251, 146, 60) !important;
+}
+
+/* 清新主题视频卡片文字适配 */
+[data-theme="fresh"] .group-hover\:text-blue-600:hover,
+[data-theme="fresh"] .group:hover .group-hover\:text-blue-600 {
+ color: rgb(22, 163, 74) !important;
+}
+[data-theme="fresh"] .group-hover\:text-blue-400:hover,
+[data-theme="fresh"] .group:hover .group-hover\:text-blue-400 {
+ color: rgb(22, 163, 74) !important;
+}
+[data-theme="fresh"] .group-hover\:border-blue-500\/60:hover,
+[data-theme="fresh"] .group:hover .group-hover\:border-blue-500\/60 {
+ border-color: rgb(63, 204, 113, 0.6) !important;
+}
+
+[data-theme="fresh"].dark .group-hover\:text-blue-600:hover,
+[data-theme="fresh"].dark .group:hover .group-hover\:text-blue-600 {
+ color: rgb(74, 222, 128) !important;
+}
+[data-theme="fresh"].dark .group-hover\:text-blue-400:hover,
+[data-theme="fresh"].dark .group:hover .group-hover\:text-blue-400 {
+ color: rgb(74, 222, 128) !important;
+}
+
+/* 侧边栏hover颜色适配 */
+
+/* 极简主题侧边栏适配 */
+[data-theme="minimal"] .hover\:text-blue-600:hover {
+ color: rgb(82, 82, 82) !important;
+}
+[data-theme="minimal"] .hover\:text-blue-700:hover {
+ color: rgb(64, 64, 64) !important;
+}
+[data-theme="minimal"] .group-hover\:text-blue-600:hover,
+[data-theme="minimal"] .group:hover .group-hover\:text-blue-600 {
+ color: rgb(82, 82, 82) !important;
+}
+[data-theme="minimal"] .group-data-\[active\=true\]\:text-blue-700,
+[data-theme="minimal"] .group[data-active="true"] .group-data-\[active\=true\]\:text-blue-700 {
+ color: rgb(64, 64, 64) !important;
+}
+[data-theme="minimal"] .data-\[active\=true\]\:text-blue-700[data-active="true"] {
+ color: rgb(64, 64, 64) !important;
+}
+[data-theme="minimal"] .data-\[active\=true\]\:bg-blue-500\/20[data-active="true"] {
+ background-color: rgb(82, 82, 82, 0.2) !important;
+}
+
+[data-theme="minimal"].dark .hover\:text-blue-400:hover {
+ color: rgb(163, 163, 163) !important;
+}
+[data-theme="minimal"].dark .hover\:text-blue-300:hover {
+ color: rgb(163, 163, 163) !important;
+}
+[data-theme="minimal"].dark .group-hover\:text-blue-400:hover,
+[data-theme="minimal"].dark .group:hover .group-hover\:text-blue-400 {
+ color: rgb(163, 163, 163) !important;
+}
+[data-theme="minimal"].dark .group-data-\[active\=true\]\:text-blue-400,
+[data-theme="minimal"].dark .group[data-active="true"] .group-data-\[active\=true\]\:text-blue-400 {
+ color: rgb(163, 163, 163) !important;
+}
+[data-theme="minimal"].dark .data-\[active\=true\]\:text-blue-400[data-active="true"] {
+ color: rgb(163, 163, 163) !important;
+}
+[data-theme="minimal"].dark .data-\[active\=true\]\:bg-blue-500\/10[data-active="true"] {
+ background-color: rgb(163, 163, 163, 0.1) !important;
+}
+
+/* 暖色主题侧边栏适配 */
+[data-theme="warm"] .hover\:text-blue-600:hover {
+ color: rgb(234, 88, 12) !important;
+}
+[data-theme="warm"] .hover\:text-blue-700:hover {
+ color: rgb(194, 65, 12) !important;
+}
+[data-theme="warm"] .group-hover\:text-blue-600:hover,
+[data-theme="warm"] .group:hover .group-hover\:text-blue-600 {
+ color: rgb(234, 88, 12) !important;
+}
+[data-theme="warm"] .group-data-\[active\=true\]\:text-blue-700,
+[data-theme="warm"] .group[data-active="true"] .group-data-\[active\=true\]\:text-blue-700 {
+ color: rgb(194, 65, 12) !important;
+}
+[data-theme="warm"] .data-\[active\=true\]\:text-blue-700[data-active="true"] {
+ color: rgb(194, 65, 12) !important;
+}
+[data-theme="warm"] .data-\[active\=true\]\:bg-blue-500\/20[data-active="true"] {
+ background-color: rgb(234, 88, 12, 0.2) !important;
+}
+
+[data-theme="warm"].dark .hover\:text-blue-400:hover {
+ color: rgb(251, 146, 60) !important;
+}
+[data-theme="warm"].dark .hover\:text-blue-300:hover {
+ color: rgb(251, 146, 60) !important;
+}
+[data-theme="warm"].dark .group-hover\:text-blue-400:hover,
+[data-theme="warm"].dark .group:hover .group-hover\:text-blue-400 {
+ color: rgb(251, 146, 60) !important;
+}
+[data-theme="warm"].dark .group-data-\[active\=true\]\:text-blue-400,
+[data-theme="warm"].dark .group[data-active="true"] .group-data-\[active\=true\]\:text-blue-400 {
+ color: rgb(251, 146, 60) !important;
+}
+[data-theme="warm"].dark .data-\[active\=true\]\:text-blue-400[data-active="true"] {
+ color: rgb(251, 146, 60) !important;
+}
+[data-theme="warm"].dark .data-\[active\=true\]\:bg-blue-500\/10[data-active="true"] {
+ background-color: rgb(251, 146, 60, 0.1) !important;
+}
+
+/* 搜索页面聚焦状态和加载元素适配 */
+
+/* 极简主题搜索页面适配 */
+[data-theme="minimal"] .focus\:ring-blue-400:focus {
+ box-shadow: 0 0 0 3px rgb(115, 115, 115, 0.5) !important;
+}
+[data-theme="minimal"] .focus\:ring-blue-400\/50:focus {
+ box-shadow: 0 0 0 3px rgb(115, 115, 115, 0.25) !important;
+}
+[data-theme="minimal"] .border-t-blue-500 {
+ border-top-color: rgb(115, 115, 115) !important;
+}
+[data-theme="minimal"] .border-b-2.border-blue-500 {
+ border-bottom-color: rgb(115, 115, 115) !important;
+}
+[data-theme="minimal"] .hover\:shadow-blue-500\/50:hover {
+ box-shadow: 0 25px 50px -12px rgb(115, 115, 115, 0.5) !important;
+}
+
+[data-theme="minimal"].dark .focus\:ring-blue-400:focus {
+ box-shadow: 0 0 0 3px rgb(163, 163, 163, 0.5) !important;
+}
+[data-theme="minimal"].dark .focus\:ring-blue-400\/50:focus {
+ box-shadow: 0 0 0 3px rgb(163, 163, 163, 0.25) !important;
+}
+[data-theme="minimal"].dark .border-t-blue-500 {
+ border-top-color: rgb(163, 163, 163) !important;
+}
+[data-theme="minimal"].dark .border-b-2.border-blue-500 {
+ border-bottom-color: rgb(163, 163, 163) !important;
+}
+[data-theme="minimal"].dark .hover\:shadow-blue-500\/50:hover {
+ box-shadow: 0 25px 50px -12px rgb(163, 163, 163, 0.5) !important;
+}
+
+/* 暖色主题搜索页面适配 */
+[data-theme="warm"] .focus\:ring-blue-400:focus {
+ box-shadow: 0 0 0 3px rgb(249, 115, 22, 0.5) !important;
+}
+[data-theme="warm"] .focus\:ring-blue-400\/50:focus {
+ box-shadow: 0 0 0 3px rgb(249, 115, 22, 0.25) !important;
+}
+[data-theme="warm"] .border-t-blue-500 {
+ border-top-color: rgb(249, 115, 22) !important;
+}
+[data-theme="warm"] .border-b-2.border-blue-500 {
+ border-bottom-color: rgb(249, 115, 22) !important;
+}
+[data-theme="warm"] .hover\:shadow-blue-500\/50:hover {
+ box-shadow: 0 25px 50px -12px rgb(249, 115, 22, 0.5) !important;
+}
+
+[data-theme="warm"].dark .focus\:ring-blue-400:focus {
+ box-shadow: 0 0 0 3px rgb(251, 146, 60, 0.5) !important;
+}
+[data-theme="warm"].dark .focus\:ring-blue-400\/50:focus {
+ box-shadow: 0 0 0 3px rgb(251, 146, 60, 0.25) !important;
+}
+[data-theme="warm"].dark .border-t-blue-500 {
+ border-top-color: rgb(251, 146, 60) !important;
+}
+[data-theme="warm"].dark .border-b-2.border-blue-500 {
+ border-bottom-color: rgb(251, 146, 60) !important;
+}
+[data-theme="warm"].dark .hover\:shadow-blue-500\/50:hover {
+ box-shadow: 0 25px 50px -12px rgb(251, 146, 60, 0.5) !important;
+}
+
+/* 播放页视频加载元素适配 */
+
+/* 极简主题播放页加载适配 */
+[data-theme="minimal"] .from-blue-500 {
+ --tw-gradient-from: rgb(115, 115, 115) !important;
+}
+[data-theme="minimal"] .to-blue-600 {
+ --tw-gradient-to: rgb(82, 82, 82) !important;
+}
+
+[data-theme="minimal"].dark .from-blue-500 {
+ --tw-gradient-from: rgb(163, 163, 163) !important;
+}
+[data-theme="minimal"].dark .to-blue-600 {
+ --tw-gradient-to: rgb(212, 212, 212) !important;
+}
+
+/* 暖色主题播放页加载适配 */
+[data-theme="warm"] .from-blue-500 {
+ --tw-gradient-from: rgb(249, 115, 22) !important;
+}
+[data-theme="warm"] .to-blue-600 {
+ --tw-gradient-to: rgb(234, 88, 12) !important;
+}
+
+[data-theme="warm"].dark .from-blue-500 {
+ --tw-gradient-from: rgb(251, 146, 60) !important;
+}
+[data-theme="warm"].dark .to-blue-600 {
+ --tw-gradient-to: rgb(253, 186, 116) !important;
+}
+
+/* 清新主题搜索页面适配 */
+[data-theme="fresh"] .focus\:ring-blue-400:focus {
+ box-shadow: 0 0 0 3px rgb(63, 204, 113, 0.5) !important;
+}
+[data-theme="fresh"] .focus\:ring-blue-400\/50:focus {
+ box-shadow: 0 0 0 3px rgb(63, 204, 113, 0.25) !important;
+}
+[data-theme="fresh"] .border-t-blue-500 {
+ border-top-color: rgb(63, 204, 113) !important;
+}
+[data-theme="fresh"] .border-b-2.border-blue-500 {
+ border-bottom-color: rgb(63, 204, 113) !important;
+}
+[data-theme="fresh"] .hover\:shadow-blue-500\/50:hover {
+ box-shadow: 0 25px 50px -12px rgb(63, 204, 113, 0.5) !important;
+}
+
+[data-theme="fresh"].dark .focus\:ring-blue-400:focus {
+ box-shadow: 0 0 0 3px rgb(74, 222, 128, 0.5) !important;
+}
+[data-theme="fresh"].dark .focus\:ring-blue-400\/50:focus {
+ box-shadow: 0 0 0 3px rgb(74, 222, 128, 0.25) !important;
+}
+[data-theme="fresh"].dark .border-t-blue-500 {
+ border-top-color: rgb(74, 222, 128) !important;
+}
+[data-theme="fresh"].dark .border-b-2.border-blue-500 {
+ border-bottom-color: rgb(74, 222, 128) !important;
+}
+[data-theme="fresh"].dark .hover\:shadow-blue-500\/50:hover {
+ box-shadow: 0 25px 50px -12px rgb(74, 222, 128, 0.5) !important;
+}
+
+/* 清新主题播放页加载适配 */
+[data-theme="fresh"] .from-blue-500 {
+ --tw-gradient-from: rgb(63, 204, 113) !important;
+}
+[data-theme="fresh"] .to-blue-600 {
+ --tw-gradient-to: rgb(22, 163, 74) !important;
+}
+
+[data-theme="fresh"].dark .from-blue-500 {
+ --tw-gradient-from: rgb(74, 222, 128) !important;
+}
+[data-theme="fresh"].dark .to-blue-600 {
+ --tw-gradient-to: rgb(134, 239, 172) !important;
+}
+
+/* 极简主题 */
+[data-theme="minimal"] {
+ --color-primary-50: 250, 250, 250;
+ --color-primary-100: 245, 245, 245;
+ --color-primary-200: 229, 229, 229;
+ --color-primary-300: 212, 212, 212;
+ --color-primary-400: 163, 163, 163;
+ --color-primary-500: 115, 115, 115;
+ --color-primary-600: 82, 82, 82;
+ --color-primary-700: 64, 64, 64;
+ --color-primary-800: 38, 38, 38;
+ --color-primary-900: 23, 23, 23;
+
+ --color-theme-bg: 255, 255, 255;
+ --color-theme-surface: 252, 252, 252;
+ --color-theme-accent: 82, 82, 82;
+ --color-theme-text: 23, 23, 23;
+ --color-theme-text-secondary: 115, 115, 115;
+ --color-theme-border: 229, 229, 229;
+ --color-theme-success: 34, 197, 94;
+ --color-theme-warning: 245, 158, 11;
+ --color-theme-error: 239, 68, 68;
+ --color-theme-info: 115, 115, 115;
+}
+
+/* 极简主题蓝色元素覆盖 */
+[data-theme="minimal"] .text-blue-600 {
+ color: rgb(82, 82, 82) !important;
+}
+[data-theme="minimal"] .text-blue-700 {
+ color: rgb(64, 64, 64) !important;
+}
+[data-theme="minimal"] .text-blue-400 {
+ color: rgb(163, 163, 163) !important;
+}
+[data-theme="minimal"] .bg-blue-500\/20 {
+ background-color: rgb(82, 82, 82, 0.2) !important;
+}
+[data-theme="minimal"] .bg-blue-500\/10 {
+ background-color: rgb(82, 82, 82, 0.1) !important;
+}
+[data-theme="minimal"] .bg-blue-500 {
+ background-color: rgb(82, 82, 82) !important;
+}
+[data-theme="minimal"] .fill-blue-500,
+[data-theme="minimal"] .hover\\:fill-blue-500:hover {
+ fill: rgb(82, 82, 82) !important;
+}
+[data-theme="minimal"] .border-blue-500\/30 {
+ border-color: rgb(82, 82, 82, 0.3) !important;
+}
+[data-theme="minimal"] .hover\\:text-blue-600:hover {
+ color: rgb(82, 82, 82) !important;
+}
+[data-theme="minimal"] .bg-blue-100 {
+ background-color: rgb(245, 245, 245) !important;
+}
+[data-theme="minimal"] .text-blue-800 {
+ color: rgb(38, 38, 38) !important;
+}
+[data-theme="minimal"] .hover\\:bg-blue-200:hover {
+ background-color: rgb(229, 229, 229) !important;
+}
+
+[data-theme="minimal"].dark {
+ --color-theme-bg: 18, 18, 18;
+ --color-theme-surface: 28, 28, 28;
+ --color-theme-accent: 163, 163, 163;
+ --color-theme-text: 250, 250, 250;
+ --color-theme-text-secondary: 163, 163, 163;
+ --color-theme-border: 64, 64, 64;
+ --color-theme-success: 74, 222, 128;
+ --color-theme-warning: 251, 191, 36;
+ --color-theme-error: 248, 113, 113;
+ --color-theme-info: 163, 163, 163;
+}
+
+/* 极简主题深色模式蓝色元素覆盖 */
+[data-theme="minimal"].dark .text-blue-600 {
+ color: rgb(163, 163, 163) !important;
+}
+[data-theme="minimal"].dark .text-blue-700 {
+ color: rgb(212, 212, 212) !important;
+}
+[data-theme="minimal"].dark .text-blue-400 {
+ color: rgb(163, 163, 163) !important;
+}
+[data-theme="minimal"].dark .bg-blue-500\/20 {
+ background-color: rgb(163, 163, 163, 0.2) !important;
+}
+[data-theme="minimal"].dark .bg-blue-500\/10 {
+ background-color: rgb(163, 163, 163, 0.1) !important;
+}
+[data-theme="minimal"].dark .bg-blue-500 {
+ background-color: rgb(163, 163, 163) !important;
+}
+[data-theme="minimal"].dark .fill-blue-500,
+[data-theme="minimal"].dark .hover\\:fill-blue-500:hover {
+ fill: rgb(163, 163, 163) !important;
+}
+[data-theme="minimal"].dark .border-blue-500\/30 {
+ border-color: rgb(163, 163, 163, 0.3) !important;
+}
+[data-theme="minimal"].dark .hover\\:text-blue-400:hover {
+ color: rgb(163, 163, 163) !important;
+}
+[data-theme="minimal"].dark .bg-blue-900\/40 {
+ background-color: rgb(38, 38, 38, 0.4) !important;
+}
+[data-theme="minimal"].dark .hover\\:bg-blue-900\/60:hover {
+ background-color: rgb(38, 38, 38, 0.6) !important;
+}
+[data-theme="minimal"].dark .text-blue-200 {
+ color: rgb(212, 212, 212) !important;
+}
+
+/* 暖色主题 */
+[data-theme="warm"] {
+ --color-primary-50: 255, 247, 237;
+ --color-primary-100: 255, 237, 213;
+ --color-primary-200: 254, 215, 170;
+ --color-primary-300: 253, 186, 116;
+ --color-primary-400: 251, 146, 60;
+ --color-primary-500: 249, 115, 22;
+ --color-primary-600: 234, 88, 12;
+ --color-primary-700: 194, 65, 12;
+ --color-primary-800: 154, 52, 18;
+ --color-primary-900: 124, 45, 18;
+
+ --color-theme-bg: 255, 253, 247;
+ --color-theme-surface: 254, 250, 240;
+ --color-theme-accent: 234, 88, 12;
+ --color-theme-text: 124, 45, 18;
+ --color-theme-text-secondary: 154, 52, 18;
+ --color-theme-border: 253, 230, 138;
+ --color-theme-success: 22, 163, 74;
+ --color-theme-warning: 217, 119, 6;
+ --color-theme-error: 220, 38, 38;
+ --color-theme-info: 194, 65, 12;
+}
+
+/* 暖色主题蓝色元素覆盖 */
+[data-theme="warm"] .text-blue-600 {
+ color: rgb(234, 88, 12) !important;
+}
+[data-theme="warm"] .text-blue-700 {
+ color: rgb(194, 65, 12) !important;
+}
+[data-theme="warm"] .text-blue-400 {
+ color: rgb(251, 146, 60) !important;
+}
+[data-theme="warm"] .bg-blue-500\/20 {
+ background-color: rgb(234, 88, 12, 0.2) !important;
+}
+[data-theme="warm"] .bg-blue-500\/10 {
+ background-color: rgb(234, 88, 12, 0.1) !important;
+}
+[data-theme="warm"] .bg-blue-500 {
+ background-color: rgb(234, 88, 12) !important;
+}
+[data-theme="warm"] .fill-blue-500,
+[data-theme="warm"] .hover\\:fill-blue-500:hover {
+ fill: rgb(234, 88, 12) !important;
+}
+[data-theme="warm"] .border-blue-500\/30 {
+ border-color: rgb(234, 88, 12, 0.3) !important;
+}
+[data-theme="warm"] .hover\\:text-blue-600:hover {
+ color: rgb(234, 88, 12) !important;
+}
+[data-theme="warm"] .bg-blue-100 {
+ background-color: rgb(255, 237, 213) !important;
+}
+[data-theme="warm"] .text-blue-800 {
+ color: rgb(154, 52, 18) !important;
+}
+[data-theme="warm"] .hover\\:bg-blue-200:hover {
+ background-color: rgb(254, 215, 170) !important;
+}
+
+[data-theme="warm"].dark {
+ --color-theme-bg: 28, 25, 23;
+ --color-theme-surface: 41, 37, 36;
+ --color-theme-accent: 251, 146, 60;
+ --color-theme-text: 254, 243, 199;
+ --color-theme-text-secondary: 214, 158, 46;
+ --color-theme-border: 87, 83, 78;
+ --color-theme-success: 74, 222, 128;
+ --color-theme-warning: 251, 191, 36;
+ --color-theme-error: 248, 113, 113;
+ --color-theme-info: 251, 146, 60;
+}
+
+/* 暖色主题深色模式蓝色元素覆盖 */
+[data-theme="warm"].dark .text-blue-600 {
+ color: rgb(251, 146, 60) !important;
+}
+[data-theme="warm"].dark .text-blue-700 {
+ color: rgb(253, 186, 116) !important;
+}
+[data-theme="warm"].dark .text-blue-400 {
+ color: rgb(251, 146, 60) !important;
+}
+[data-theme="warm"].dark .bg-blue-500\/20 {
+ background-color: rgb(251, 146, 60, 0.2) !important;
+}
+[data-theme="warm"].dark .bg-blue-500\/10 {
+ background-color: rgb(251, 146, 60, 0.1) !important;
+}
+[data-theme="warm"].dark .bg-blue-500 {
+ background-color: rgb(251, 146, 60) !important;
+}
+[data-theme="warm"].dark .fill-blue-500,
+[data-theme="warm"].dark .hover\\:fill-blue-500:hover {
+ fill: rgb(251, 146, 60) !important;
+}
+[data-theme="warm"].dark .border-blue-500\/30 {
+ border-color: rgb(251, 146, 60, 0.3) !important;
+}
+[data-theme="warm"].dark .hover\\:text-blue-400:hover {
+ color: rgb(251, 146, 60) !important;
+}
+[data-theme="warm"].dark .bg-blue-900\/40 {
+ background-color: rgb(154, 52, 18, 0.4) !important;
+}
+[data-theme="warm"].dark .hover\\:bg-blue-900\/60:hover {
+ background-color: rgb(154, 52, 18, 0.6) !important;
+}
+[data-theme="warm"].dark .text-blue-200 {
+ color: rgb(253, 186, 116) !important;
+}
+
+/* 通用蓝色样式覆盖 - 用于其他可能的蓝色元素 */
+
+/* 清新主题 */
+[data-theme="fresh"] {
+ --color-primary-50: 240, 253, 244;
+ --color-primary-100: 220, 252, 231;
+ --color-primary-200: 187, 247, 208;
+ --color-primary-300: 134, 239, 172;
+ --color-primary-400: 74, 222, 128;
+ --color-primary-500: 63, 204, 113;
+ --color-primary-600: 22, 163, 74;
+ --color-primary-700: 21, 128, 61;
+ --color-primary-800: 22, 101, 52;
+ --color-primary-900: 20, 83, 45;
+
+ --color-theme-bg: 247, 253, 249;
+ --color-theme-surface: 240, 253, 244;
+ --color-theme-accent: 63, 204, 113;
+ --color-theme-text: 20, 83, 45;
+ --color-theme-text-secondary: 22, 101, 52;
+ --color-theme-border: 187, 247, 208;
+ --color-theme-success: 34, 197, 94;
+ --color-theme-warning: 245, 158, 11;
+ --color-theme-error: 239, 68, 68;
+ --color-theme-info: 63, 204, 113;
+}
+
+/* 清新主题蓝色元素覆盖 */
+/* 注意:移除了通用的 .text-blue-* 覆盖,只保留有条件的状态覆盖 */
+[data-theme="fresh"] .bg-blue-500\/20 {
+ background-color: rgb(63, 204, 113, 0.2) !important;
+}
+[data-theme="fresh"] .bg-blue-500\/10 {
+ background-color: rgb(63, 204, 113, 0.1) !important;
+}
+[data-theme="fresh"] .bg-blue-500 {
+ background-color: rgb(63, 204, 113) !important;
+}
+[data-theme="fresh"] .hover\:fill-blue-500:hover {
+ fill: rgb(63, 204, 113) !important;
+}
+[data-theme="fresh"] .border-blue-500\/30 {
+ border-color: rgb(63, 204, 113, 0.3) !important;
+}
+[data-theme="fresh"] .hover\:text-blue-600:hover {
+ color: rgb(22, 163, 74) !important;
+}
+[data-theme="fresh"] .bg-blue-100 {
+ background-color: rgb(220, 252, 231) !important;
+}
+/* 注意:移除了 .text-blue-800 的通用覆盖 */
+[data-theme="fresh"] .hover\:bg-blue-200:hover {
+ background-color: rgb(187, 247, 208) !important;
+}
+[data-theme="fresh"] .border-blue-200 {
+ border-color: rgb(187, 247, 208) !important;
+}
+[data-theme="fresh"] .border-blue-300 {
+ border-color: rgb(134, 239, 172) !important;
+}
+[data-theme="fresh"] .border-blue-500 {
+ border-color: rgb(63, 204, 113) !important;
+}
+[data-theme="fresh"] .bg-blue-600 {
+ background-color: rgb(22, 163, 74) !important;
+}
+[data-theme="fresh"] .hover\:bg-blue-600:hover {
+ background-color: rgb(21, 128, 61) !important;
+}
+[data-theme="fresh"] .hover\:bg-blue-700:hover {
+ background-color: rgb(21, 128, 61) !important;
+}
+[data-theme="fresh"] .focus\:ring-blue-500:focus {
+ box-shadow: 0 0 0 3px rgb(63, 204, 113, 0.1) !important;
+}
+/* 版本面板和品牌元素适配 */
+[data-theme="fresh"] .bg-blue-100 {
+ background-color: rgb(220, 252, 231) !important;
+}
+[data-theme="fresh"] .text-blue-800 {
+ color: rgb(22, 101, 52) !important;
+}
+[data-theme="fresh"] .text-blue-700 {
+ color: rgb(21, 128, 61) !important;
+}
+[data-theme="fresh"] .text-blue-600 {
+ color: rgb(22, 163, 74) !important;
+}
+[data-theme="fresh"] .text-blue-500 {
+ color: rgb(34, 197, 94) !important;
+}
+/* 登录页面和按钮适配 */
+[data-theme="fresh"] .bg-blue-600 {
+ background-color: rgb(22, 163, 74) !important;
+}
+[data-theme="fresh"] .focus\:ring-blue-500:focus {
+ --tw-ring-color: rgb(34, 197, 94) !important;
+}
+[data-theme="fresh"] .bg-blue-50 {
+ background-color: rgb(240, 253, 244) !important;
+}
+[data-theme="fresh"] .border-blue-200 {
+ border-color: rgb(187, 247, 208) !important;
+}
+[data-theme="fresh"] .peer-focus\:text-blue-600:focus {
+ color: rgb(22, 163, 74) !important;
+}
+[data-theme="fresh"] .peer:focus ~ .peer-focus\:text-blue-600 {
+ color: rgb(22, 163, 74) !important;
+}
+
+[data-theme="fresh"].dark {
+ --color-theme-bg: 20, 29, 24;
+ --color-theme-surface: 31, 41, 35;
+ --color-theme-accent: 74, 222, 128;
+ --color-theme-text: 240, 253, 244;
+ --color-theme-text-secondary: 187, 247, 208;
+ --color-theme-border: 75, 85, 79;
+ --color-theme-success: 74, 222, 128;
+ --color-theme-warning: 251, 191, 36;
+ --color-theme-error: 248, 113, 113;
+ --color-theme-info: 74, 222, 128;
+}
+
+/* 清新主题深色模式蓝色元素覆盖 */
+/* 注意:移除了通用的 .text-blue-* 覆盖,只保留有条件的状态覆盖 */
+[data-theme="fresh"].dark .bg-blue-500\/20 {
+ background-color: rgb(74, 222, 128, 0.2) !important;
+}
+[data-theme="fresh"].dark .bg-blue-500\/10 {
+ background-color: rgb(74, 222, 128, 0.1) !important;
+}
+[data-theme="fresh"].dark .bg-blue-500 {
+ background-color: rgb(74, 222, 128) !important;
+}
+[data-theme="fresh"].dark .hover\:fill-blue-500:hover {
+ fill: rgb(74, 222, 128) !important;
+}
+[data-theme="fresh"].dark .border-blue-500\/30 {
+ border-color: rgb(74, 222, 128, 0.3) !important;
+}
+[data-theme="fresh"].dark .hover\:text-blue-400:hover {
+ color: rgb(74, 222, 128) !important;
+}
+[data-theme="fresh"].dark .bg-blue-900\/40 {
+ background-color: rgb(22, 101, 52, 0.4) !important;
+}
+[data-theme="fresh"].dark .hover\:bg-blue-900\/60:hover {
+ background-color: rgb(22, 101, 52, 0.6) !important;
+}
+/* 注意:移除了 .text-blue-200 的通用覆盖 */
+[data-theme="fresh"].dark .border-blue-200 {
+ border-color: rgb(22, 101, 52) !important;
+}
+[data-theme="fresh"].dark .border-blue-300 {
+ border-color: rgb(22, 163, 74) !important;
+}
+[data-theme="fresh"].dark .border-blue-500 {
+ border-color: rgb(74, 222, 128) !important;
+}
+[data-theme="fresh"].dark .bg-blue-600 {
+ background-color: rgb(74, 222, 128) !important;
+}
+[data-theme="fresh"].dark .hover\:bg-blue-600:hover {
+ background-color: rgb(134, 239, 172) !important;
+}
+[data-theme="fresh"].dark .hover\:bg-blue-700:hover {
+ background-color: rgb(134, 239, 172) !important;
+}
+[data-theme="fresh"].dark .focus\:ring-blue-500:focus {
+ box-shadow: 0 0 0 3px rgb(74, 222, 128, 0.1) !important;
+}
+/* 深色模式版本面板和品牌元素适配 */
+[data-theme="fresh"].dark .bg-blue-900\/30 {
+ background-color: rgb(22, 101, 52, 0.3) !important;
+}
+[data-theme="fresh"].dark .text-blue-300 {
+ color: rgb(134, 239, 172) !important;
+}
+[data-theme="fresh"].dark .text-blue-400 {
+ color: rgb(74, 222, 128) !important;
+}
+[data-theme="fresh"].dark .text-blue-500 {
+ color: rgb(74, 222, 128) !important;
+}
+/* 深色模式登录页面适配 */
+[data-theme="fresh"].dark .bg-blue-600 {
+ background-color: rgb(34, 197, 94) !important;
+}
+[data-theme="fresh"].dark .bg-blue-900\/20 {
+ background-color: rgb(20, 83, 45, 0.2) !important;
+}
+[data-theme="fresh"].dark .border-blue-800 {
+ border-color: rgb(22, 101, 52) !important;
+}
+[data-theme="fresh"].dark .peer-focus\:dark\:text-blue-400:focus {
+ color: rgb(74, 222, 128) !important;
+}
+[data-theme="fresh"].dark .peer:focus ~ .peer-focus\:dark\:text-blue-400 {
+ color: rgb(74, 222, 128) !important;
+}
+[data-theme="fresh"].dark .text-blue-200 {
+ color: rgb(134, 239, 172) !important;
+}
+[data-theme="fresh"].dark .bg-blue-800\/40 {
+ background-color: rgb(22, 101, 52, 0.4) !important;
+}
+
+/* 极简主题额外覆盖 */
+[data-theme="minimal"] .bg-blue-50 {
+ background-color: rgb(250, 250, 250) !important;
+}
+[data-theme="minimal"] .hover\\:bg-blue-50:hover {
+ background-color: rgb(250, 250, 250) !important;
+}
+[data-theme="minimal"] .text-blue-500 {
+ color: rgb(115, 115, 115) !important;
+}
+/* 极简主题登录页面适配 */
+[data-theme="minimal"] .bg-blue-600 {
+ background-color: rgb(82, 82, 82) !important;
+}
+[data-theme="minimal"] .focus\:ring-blue-500:focus {
+ --tw-ring-color: rgb(115, 115, 115) !important;
+}
+[data-theme="minimal"] .bg-blue-50 {
+ background-color: rgb(250, 250, 250) !important;
+}
+[data-theme="minimal"] .border-blue-200 {
+ border-color: rgb(229, 229, 229) !important;
+}
+[data-theme="minimal"] .peer-focus\:text-blue-600:focus {
+ color: rgb(82, 82, 82) !important;
+}
+[data-theme="minimal"] .peer:focus ~ .peer-focus\:text-blue-600 {
+ color: rgb(82, 82, 82) !important;
+}
+[data-theme="minimal"] .hover\\:text-blue-500:hover {
+ color: rgb(115, 115, 115) !important;
+}
+
+[data-theme="minimal"].dark .bg-blue-50 {
+ background-color: rgb(28, 28, 28) !important;
+}
+[data-theme="minimal"].dark .hover\\:bg-blue-50:hover {
+ background-color: rgb(28, 28, 28) !important;
+}
+[data-theme="minimal"].dark .text-blue-500 {
+ color: rgb(163, 163, 163) !important;
+}
+/* 极简主题深色模式登录页面适配 */
+[data-theme="minimal"].dark .bg-blue-600 {
+ background-color: rgb(115, 115, 115) !important;
+}
+[data-theme="minimal"].dark .bg-blue-900\/20 {
+ background-color: rgb(64, 64, 64, 0.2) !important;
+}
+[data-theme="minimal"].dark .border-blue-800 {
+ border-color: rgb(82, 82, 82) !important;
+}
+[data-theme="minimal"].dark .peer-focus\:dark\:text-blue-400:focus {
+ color: rgb(163, 163, 163) !important;
+}
+[data-theme="minimal"].dark .peer:focus ~ .peer-focus\:dark\:text-blue-400 {
+ color: rgb(163, 163, 163) !important;
+}
+[data-theme="minimal"].dark .hover\\:text-blue-500:hover {
+ color: rgb(163, 163, 163) !important;
+}
+
+/* 暖色主题额外覆盖 */
+[data-theme="warm"] .bg-blue-50 {
+ background-color: rgb(255, 247, 237) !important;
+}
+[data-theme="warm"] .hover\\:bg-blue-50:hover {
+ background-color: rgb(255, 247, 237) !important;
+}
+[data-theme="warm"] .text-blue-500 {
+ color: rgb(249, 115, 22) !important;
+}
+[data-theme="warm"] .hover\\:text-blue-500:hover {
+ color: rgb(249, 115, 22) !important;
+}
+
+[data-theme="warm"].dark .bg-blue-50 {
+ background-color: rgb(41, 37, 36) !important;
+}
+[data-theme="warm"].dark .hover\\:bg-blue-50:hover {
+ background-color: rgb(41, 37, 36) !important;
+}
+[data-theme="warm"].dark .text-blue-500 {
+ color: rgb(251, 146, 60) !important;
+}
+/* 暖色主题深色模式登录页面适配 */
+[data-theme="warm"].dark .bg-blue-600 {
+ background-color: rgb(251, 146, 60) !important;
+}
+[data-theme="warm"].dark .bg-blue-900\/20 {
+ background-color: rgb(154, 52, 18, 0.2) !important;
+}
+[data-theme="warm"].dark .border-blue-800 {
+ border-color: rgb(194, 65, 12) !important;
+}
+[data-theme="warm"].dark .peer-focus\:dark\:text-blue-400:focus {
+ color: rgb(251, 146, 60) !important;
+}
+[data-theme="warm"].dark .peer:focus ~ .peer-focus\:dark\:text-blue-400 {
+ color: rgb(251, 146, 60) !important;
+}
+[data-theme="warm"].dark .hover\\:text-blue-500:hover {
+ color: rgb(251, 146, 60) !important;
+}
+
+/* 清新主题额外覆盖 */
+[data-theme="fresh"] .bg-blue-50 {
+ background-color: rgb(240, 253, 244) !important;
+}
+[data-theme="fresh"] .hover\\:bg-blue-50:hover {
+ background-color: rgb(240, 253, 244) !important;
+}
+/* 保留hover状态的覆盖 */
+[data-theme="fresh"] .hover\\:text-blue-500:hover {
+ color: rgb(63, 204, 113) !important;
+}
+
+[data-theme="fresh"].dark .bg-blue-50 {
+ background-color: rgb(31, 41, 35) !important;
+}
+[data-theme="fresh"].dark .hover\\:bg-blue-50:hover {
+ background-color: rgb(31, 41, 35) !important;
+}
+/* 保留hover状态的覆盖 */
+[data-theme="fresh"].dark .hover\\:text-blue-500:hover {
+ color: rgb(74, 222, 128) !important;
+}
+
+/* VideoCard 和其他组件的蓝色样式覆盖 */
+
+/* 极简主题组件样式覆盖 */
+[data-theme="minimal"] .border-blue-200 {
+ border-color: rgb(229, 229, 229) !important;
+}
+[data-theme="minimal"] .text-blue-300 {
+ color: rgb(163, 163, 163) !important;
+}
+
+[data-theme="minimal"].dark .bg-blue-900\/20 {
+ background-color: rgb(23, 23, 23, 0.2) !important;
+}
+[data-theme="minimal"].dark .border-blue-800 {
+ border-color: rgb(38, 38, 38) !important;
+}
+[data-theme="minimal"].dark .bg-blue-900\/30 {
+ background-color: rgb(23, 23, 23, 0.3) !important;
+}
+
+/* 暖色主题组件样式覆盖 */
+[data-theme="warm"] .border-blue-200 {
+ border-color: rgb(253, 230, 138) !important;
+}
+[data-theme="warm"] .peer-focus\:text-blue-600:focus {
+ color: rgb(234, 88, 12) !important;
+}
+[data-theme="warm"] .peer:focus ~ .peer-focus\:text-blue-600 {
+ color: rgb(234, 88, 12) !important;
+}
+[data-theme="warm"] .text-blue-300 {
+ color: rgb(251, 146, 60) !important;
+}
+
+[data-theme="warm"].dark .bg-blue-900\/20 {
+ background-color: rgb(124, 45, 18, 0.2) !important;
+}
+[data-theme="warm"].dark .border-blue-800 {
+ border-color: rgb(154, 52, 18) !important;
+}
+[data-theme="warm"].dark .bg-blue-900\/30 {
+ background-color: rgb(124, 45, 18, 0.3) !important;
+}
+
+/* 补充更多蓝色元素覆盖 */
+
+/* 极简主题补充覆盖 */
+[data-theme="minimal"] .text-blue-900 {
+ color: rgb(23, 23, 23) !important;
+}
+[data-theme="minimal"] .bg-blue-200 {
+ background-color: rgb(229, 229, 229) !important;
+}
+[data-theme="minimal"] .bg-blue-300 {
+ background-color: rgb(212, 212, 212) !important;
+}
+[data-theme="minimal"] .bg-blue-600 {
+ background-color: rgb(82, 82, 82) !important;
+}
+[data-theme="minimal"] .bg-blue-700 {
+ background-color: rgb(64, 64, 64) !important;
+}
+[data-theme="minimal"] .border-blue-100 {
+ border-color: rgb(245, 245, 245) !important;
+}
+[data-theme="minimal"] .border-blue-300 {
+ border-color: rgb(212, 212, 212) !important;
+}
+[data-theme="minimal"] .border-blue-500 {
+ border-color: rgb(115, 115, 115) !important;
+}
+[data-theme="minimal"] .hover\\:border-blue-300:hover {
+ border-color: rgb(212, 212, 212) !important;
+}
+[data-theme="minimal"] .hover\\:bg-blue-700:hover {
+ background-color: rgb(64, 64, 64) !important;
+}
+[data-theme="minimal"] .focus\\:ring-blue-500:focus {
+ box-shadow: 0 0 0 3px rgb(115, 115, 115, 0.1) !important;
+}
+
+[data-theme="minimal"].dark .text-blue-900 {
+ color: rgb(250, 250, 250) !important;
+}
+[data-theme="minimal"].dark .bg-blue-200 {
+ background-color: rgb(64, 64, 64) !important;
+}
+[data-theme="minimal"].dark .bg-blue-300 {
+ background-color: rgb(82, 82, 82) !important;
+}
+[data-theme="minimal"].dark .bg-blue-600 {
+ background-color: rgb(163, 163, 163) !important;
+}
+[data-theme="minimal"].dark .bg-blue-700 {
+ background-color: rgb(212, 212, 212) !important;
+}
+[data-theme="minimal"].dark .border-blue-100 {
+ border-color: rgb(38, 38, 38) !important;
+}
+[data-theme="minimal"].dark .border-blue-300 {
+ border-color: rgb(82, 82, 82) !important;
+}
+[data-theme="minimal"].dark .border-blue-500 {
+ border-color: rgb(163, 163, 163) !important;
+}
+[data-theme="minimal"].dark .hover\\:border-blue-300:hover {
+ border-color: rgb(82, 82, 82) !important;
+}
+[data-theme="minimal"].dark .hover\\:bg-blue-700:hover {
+ background-color: rgb(212, 212, 212) !important;
+}
+[data-theme="minimal"].dark .focus\\:ring-blue-500:focus {
+ box-shadow: 0 0 0 3px rgb(163, 163, 163, 0.1) !important;
+}
+
+/* 暖色主题补充覆盖 */
+[data-theme="warm"] .text-blue-900 {
+ color: rgb(124, 45, 18) !important;
+}
+[data-theme="warm"] .bg-blue-200 {
+ background-color: rgb(254, 215, 170) !important;
+}
+[data-theme="warm"] .bg-blue-300 {
+ background-color: rgb(253, 186, 116) !important;
+}
+[data-theme="warm"] .bg-blue-600 {
+ background-color: rgb(234, 88, 12) !important;
+}
+[data-theme="warm"] .bg-blue-700 {
+ background-color: rgb(194, 65, 12) !important;
+}
+[data-theme="warm"] .border-blue-100 {
+ border-color: rgb(255, 237, 213) !important;
+}
+[data-theme="warm"] .border-blue-300 {
+ border-color: rgb(253, 186, 116) !important;
+}
+[data-theme="warm"] .border-blue-500 {
+ border-color: rgb(249, 115, 22) !important;
+}
+[data-theme="warm"] .hover\\:border-blue-300:hover {
+ border-color: rgb(253, 186, 116) !important;
+}
+[data-theme="warm"] .hover\\:bg-blue-700:hover {
+ background-color: rgb(194, 65, 12) !important;
+}
+[data-theme="warm"] .focus\\:ring-blue-500:focus {
+ box-shadow: 0 0 0 3px rgb(249, 115, 22, 0.1) !important;
+}
+
+[data-theme="warm"].dark .text-blue-900 {
+ color: rgb(254, 243, 199) !important;
+}
+[data-theme="warm"].dark .bg-blue-200 {
+ background-color: rgb(154, 52, 18) !important;
+}
+[data-theme="warm"].dark .bg-blue-300 {
+ background-color: rgb(194, 65, 12) !important;
+}
+[data-theme="warm"].dark .bg-blue-600 {
+ background-color: rgb(251, 146, 60) !important;
+}
+[data-theme="warm"].dark .bg-blue-700 {
+ background-color: rgb(253, 186, 116) !important;
+}
+[data-theme="warm"].dark .border-blue-100 {
+ border-color: rgb(87, 83, 78) !important;
+}
+[data-theme="warm"].dark .border-blue-300 {
+ border-color: rgb(194, 65, 12) !important;
+}
+[data-theme="warm"].dark .border-blue-500 {
+ border-color: rgb(251, 146, 60) !important;
+}
+[data-theme="warm"].dark .hover\\:border-blue-300:hover {
+ border-color: rgb(194, 65, 12) !important;
+}
+[data-theme="warm"].dark .hover\\:bg-blue-700:hover {
+ background-color: rgb(253, 186, 116) !important;
+}
+[data-theme="warm"].dark .focus\\:ring-blue-500:focus {
+ box-shadow: 0 0 0 3px rgb(251, 146, 60, 0.1) !important;
+}
+
+/* 导航组件蓝色元素覆盖 - 直接覆盖具体元素,避免复杂选择器 */
+
+/* 极简主题导航覆盖 */
+/* 选中状态背景和文字颜色 */
+[data-theme="minimal"] *[data-active="true"] {
+ background-color: rgb(82, 82, 82, 0.2) !important;
+ color: rgb(64, 64, 64) !important;
+}
+[data-theme="minimal"] .group[data-active="true"] svg {
+ color: rgb(64, 64, 64) !important;
+}
+
+[data-theme="minimal"].dark *[data-active="true"] {
+ background-color: rgb(163, 163, 163, 0.1) !important;
+ color: rgb(163, 163, 163) !important;
+}
+[data-theme="minimal"].dark .group[data-active="true"] svg {
+ color: rgb(163, 163, 163) !important;
+}
+
+/* hover状态文字颜色 */
+[data-theme="minimal"] .hover\\:text-blue-300:hover {
+ color: rgb(115, 115, 115) !important;
+}
+[data-theme="minimal"].dark .dark\\:hover\\:text-blue-300:hover {
+ color: rgb(163, 163, 163) !important;
+}
+
+/* 暖色主题导航覆盖 */
+[data-theme="warm"] *[data-active="true"] {
+ background-color: rgb(234, 88, 12, 0.2) !important;
+ color: rgb(194, 65, 12) !important;
+}
+[data-theme="warm"] .group[data-active="true"] svg {
+ color: rgb(194, 65, 12) !important;
+}
+
+[data-theme="warm"].dark *[data-active="true"] {
+ background-color: rgb(251, 146, 60, 0.1) !important;
+ color: rgb(251, 146, 60) !important;
+}
+[data-theme="warm"].dark .group[data-active="true"] svg {
+ color: rgb(251, 146, 60) !important;
+}
+
+[data-theme="warm"] .hover\\:text-blue-300:hover {
+ color: rgb(234, 88, 12) !important;
+}
+[data-theme="warm"].dark .dark\\:hover\\:text-blue-300:hover {
+ color: rgb(251, 146, 60) !important;
+}
+
+/* 清新主题侧边栏hover颜色适配 */
+[data-theme="fresh"] .hover\:text-blue-600:hover {
+ color: rgb(22, 163, 74) !important;
+}
+[data-theme="fresh"] .hover\:text-blue-700:hover {
+ color: rgb(21, 128, 61) !important;
+}
+[data-theme="fresh"] .group-hover\:text-blue-600:hover,
+[data-theme="fresh"] .group:hover .group-hover\:text-blue-600 {
+ color: rgb(22, 163, 74) !important;
+}
+[data-theme="fresh"] .group-data-\[active\=true\]\:text-blue-700,
+[data-theme="fresh"] .group[data-active="true"] .group-data-\[active\=true\]\:text-blue-700 {
+ color: rgb(21, 128, 61) !important;
+}
+[data-theme="fresh"] .data-\[active\=true\]\:text-blue-700[data-active="true"] {
+ color: rgb(21, 128, 61) !important;
+}
+[data-theme="fresh"] .data-\[active\=true\]\:bg-blue-500\20[data-active="true"] {
+ background-color: rgb(63, 204, 113, 0.2) !important;
+}
+
+[data-theme="fresh"].dark .hover\:text-blue-400:hover {
+ color: rgb(74, 222, 128) !important;
+}
+[data-theme="fresh"].dark .hover\:text-blue-300:hover {
+ color: rgb(74, 222, 128) !important;
+}
+[data-theme="fresh"].dark .group-hover\:text-blue-400:hover,
+[data-theme="fresh"].dark .group:hover .group-hover\:text-blue-400 {
+ color: rgb(74, 222, 128) !important;
+}
+[data-theme="fresh"].dark .group-data-\[active\=true\]\:text-blue-400,
+[data-theme="fresh"].dark .group[data-active="true"] .group-data-\[active\=true\]\:text-blue-400 {
+ color: rgb(74, 222, 128) !important;
+}
+[data-theme="fresh"].dark .data-\[active\=true\]\:text-blue-400[data-active="true"] {
+ color: rgb(74, 222, 128) !important;
+}
+[data-theme="fresh"].dark .data-\[active\=true\]\:bg-blue-500\10[data-active="true"] {
+ background-color: rgb(74, 222, 128, 0.1) !important;
+}
+[data-theme="fresh"].dark .dark\\:hover\\:text-blue-300:hover {
+ color: rgb(74, 222, 128) !important;
+}
+
+/* 清新主题导航覆盖 */
+/* 选中状态背景和文字颜色 */
+[data-theme="fresh"] *[data-active="true"] {
+ background-color: rgb(63, 204, 113, 0.2) !important;
+ color: rgb(21, 128, 61) !important;
+}
+
+[data-theme="fresh"].dark *[data-active="true"] {
+ background-color: rgb(74, 222, 128, 0.1) !important;
+ color: rgb(74, 222, 128) !important;
+}
+
+/* 视频卡片播放按钮和标签元素覆盖 */
+
+/* 极简主题视频卡片覆盖 */
+[data-theme="minimal"] .fill-blue-500,
+[data-theme="minimal"] .hover\\:fill-blue-500:hover {
+ fill: rgb(82, 82, 82) !important;
+}
+[data-theme="minimal"] .bg-blue-400 {
+ background-color: rgb(115, 115, 115) !important;
+}
+[data-theme="minimal"] .hover\\:bg-blue-600:hover {
+ background-color: rgb(64, 64, 64) !important;
+}
+
+[data-theme="minimal"].dark .fill-blue-500,
+[data-theme="minimal"].dark .hover\\:fill-blue-500:hover {
+ fill: rgb(163, 163, 163) !important;
+}
+[data-theme="minimal"].dark .hover\\:bg-blue-600:hover {
+ background-color: rgb(212, 212, 212) !important;
+}
+
+/* 暖色主题视频卡片覆盖 */
+[data-theme="warm"] .fill-blue-500,
+[data-theme="warm"] .hover\\:fill-blue-500:hover {
+ fill: rgb(234, 88, 12) !important;
+}
+[data-theme="warm"] .bg-blue-400 {
+ background-color: rgb(249, 115, 22) !important;
+}
+[data-theme="warm"] .hover\\:bg-blue-600:hover {
+ background-color: rgb(194, 65, 12) !important;
+}
+
+[data-theme="warm"].dark .fill-blue-500,
+[data-theme="warm"].dark .hover\\:fill-blue-500:hover {
+ fill: rgb(251, 146, 60) !important;
+}
+[data-theme="warm"].dark .hover\\:bg-blue-600:hover {
+ background-color: rgb(253, 186, 116) !important;
+}
+
+/* 清新主题视频卡片覆盖 */
+[data-theme="fresh"] .hover\\:fill-blue-500:hover {
+ fill: rgb(63, 204, 113) !important;
+}
+[data-theme="fresh"] .bg-blue-400 {
+ background-color: rgb(74, 222, 128) !important;
+}
+[data-theme="fresh"] .hover\\:bg-blue-600:hover {
+ background-color: rgb(21, 128, 61) !important;
+}
+
+[data-theme="fresh"].dark .hover\\:fill-blue-500:hover {
+ fill: rgb(74, 222, 128) !important;
+}
+[data-theme="fresh"].dark .hover\\:bg-blue-600:hover {
+ background-color: rgb(134, 239, 172) !important;
}
html,
@@ -63,6 +1351,73 @@ html:not(.dark) body {
background-attachment: fixed;
}
+/* 主题背景渐变覆盖 */
+[data-theme="minimal"]:not(.dark) body {
+ background: linear-gradient(
+ 180deg,
+ #fafafa 0%,
+ #f5f5f5 25%,
+ #f0f0f0 50%,
+ #ebebeb 75%,
+ #e5e5e5 100%
+ );
+ background-attachment: fixed;
+}
+
+[data-theme="warm"]:not(.dark) body {
+ background: linear-gradient(
+ 180deg,
+ #fffdf7 0%,
+ #fefaf0 25%,
+ #fef7e0 50%,
+ #fef3c7 75%,
+ #fde68a 100%
+ );
+ background-attachment: fixed;
+}
+
+[data-theme="fresh"]:not(.dark) body {
+ background: linear-gradient(
+ 180deg,
+ #f7fdf9 0%,
+ #f0fdf4 25%,
+ #ecfdf5 50%,
+ #d1fae5 75%,
+ #a7f3d0 100%
+ );
+ background-attachment: fixed;
+}
+
+.dark body {
+ background: linear-gradient(
+ 180deg,
+ rgb(var(--color-theme-bg)) 0%,
+ rgb(var(--color-theme-surface)) 100%
+ );
+ background-attachment: fixed;
+}
+
+/* 通用主题类 */
+.theme-transition {
+ transition: background-color 0.3s ease, border-color 0.3s ease, color 0.3s ease;
+}
+
+.theme-card {
+ @apply bg-theme-surface border border-theme-border rounded-lg shadow-sm theme-transition;
+}
+
+.theme-button {
+ @apply bg-theme-accent text-white border border-theme-accent rounded-lg px-4 py-2 hover:opacity-90 theme-transition;
+}
+
+.theme-button-secondary {
+ @apply bg-theme-surface text-theme-text border border-theme-border rounded-lg px-4 py-2 hover:bg-theme-accent/10 theme-transition;
+}
+
+.theme-input {
+ @apply bg-theme-surface text-theme-text border border-theme-border rounded-lg px-3 py-2 focus:outline-none focus:ring-2 focus:ring-theme-accent/50 theme-transition;
+}
+
/* 自定义滚动条样式 */
::-webkit-scrollbar {
width: 8px;
@@ -168,6 +1523,27 @@ html:not(.dark)::view-transition-new(root) {
animation-name: slide-from-bottom;
}
+/* 确保自定义主题色类在所有主题下正确显示 */
+.bg-theme-accent {
+ background-color: rgb(var(--color-theme-accent)) !important;
+}
+
+.text-theme-accent {
+ color: rgb(var(--color-theme-accent)) !important;
+}
+
+.border-theme-accent {
+ border-color: rgb(var(--color-theme-accent)) !important;
+}
+
+.hover\:bg-theme-accent\/5:hover {
+ background-color: rgb(var(--color-theme-accent), 0.05) !important;
+}
+
+.hover\:bg-theme-accent\/10:hover {
+ background-color: rgb(var(--color-theme-accent), 0.1) !important;
+}
+
/* 强制播放器内部的 video 元素高度为 100%,并保持内容完整显示 */
div[data-media-provider] video {
height: 100%;
diff --git a/src/app/layout.tsx b/src/app/layout.tsx
index 8fb5d66..9f72b19 100644
--- a/src/app/layout.tsx
+++ b/src/app/layout.tsx
@@ -11,6 +11,7 @@ import { GlobalErrorIndicator } from '../components/GlobalErrorIndicator';
import { SiteProvider } from '../components/SiteProvider';
import { ThemeProvider } from '../components/ThemeProvider';
import { ToastProvider } from '../components/Toast';
+import GlobalThemeLoader from '../components/GlobalThemeLoader';
const inter = Inter({ subsets: ['latin'] });
export const dynamic = 'force-dynamic';
@@ -110,6 +111,9 @@ export default async function RootLayout({
__html: `window.RUNTIME_CONFIG = ${JSON.stringify(runtimeConfig)};`,
}}
/>
+
+ {/* 主题初始化脚本 - 立即执行避免主题闪烁 */}
+
+
{children}
diff --git a/src/app/login/page.tsx b/src/app/login/page.tsx
index 2805ccb..56c4c63 100644
--- a/src/app/login/page.tsx
+++ b/src/app/login/page.tsx
@@ -12,6 +12,7 @@ import MachineCode from '@/lib/machine-code';
import { useSite } from '@/components/SiteProvider';
import { ThemeToggle } from '@/components/ThemeToggle';
+import GlobalThemeLoader from '@/components/GlobalThemeLoader';
// 版本显示组件
function VersionDisplay() {
@@ -195,6 +196,7 @@ function LoginPageClient() {
return (
+
diff --git a/src/app/page.tsx b/src/app/page.tsx
index 9caac96..3ec3cbf 100644
--- a/src/app/page.tsx
+++ b/src/app/page.tsx
@@ -23,6 +23,7 @@ import { DoubanItem } from '@/lib/types';
import CapsuleSwitch from '@/components/CapsuleSwitch';
import ContinueWatching from '@/components/ContinueWatching';
import PageLayout from '@/components/PageLayout';
+import { useThemeInit } from '@/hooks/useTheme';
import ScrollableRow from '@/components/ScrollableRow';
import { useSite } from '@/components/SiteProvider';
import VideoCard from '@/components/VideoCard';
@@ -515,6 +516,8 @@ function HomeClient() {
}
export default function Home() {
+ // 初始化主题
+ useThemeInit();
return (
diff --git a/src/app/play/page.tsx b/src/app/play/page.tsx
index a8da66b..5b262c8 100644
--- a/src/app/play/page.tsx
+++ b/src/app/play/page.tsx
@@ -1797,6 +1797,37 @@ function PlayPageClient() {
typeof window !== 'undefined' &&
typeof (window as any).webkitConvertPointFromNodeToPage === 'function';
+ // 检测是否为移动端设备
+ const isMobile = typeof window !== 'undefined' && (
+ /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent) ||
+ window.innerWidth <= 768
+ );
+
+ // 根据设备类型调整弹幕配置
+ const getDanmuConfig = () => {
+ if (isMobile) {
+ return {
+ fontSize: 20, // 移动端字体稍小
+ margin: [5, '20%'], // 移动端边距更小
+ minWidth: 150, // 移动端最小宽度更小
+ maxWidth: 300, // 移动端最大宽度限制
+ maxlength: 30, // 移动端字符长度限制
+ placeholder: '发弹幕~', // 移动端简化提示文字
+ };
+ } else {
+ return {
+ fontSize: 25, // 桌面端正常字体
+ margin: [10, '25%'], // 桌面端正常边距
+ minWidth: 200, // 桌面端最小宽度
+ maxWidth: 500, // 桌面端最大宽度
+ maxlength: 50, // 桌面端字符长度
+ placeholder: '发个弹幕呗~', // 桌面端完整提示文字
+ };
+ }
+ };
+
+ const danmuConfig = getDanmuConfig();
+
// 非WebKit浏览器且播放器已存在,使用switch方法切换
if (!isWebkit && artPlayerRef.current) {
artPlayerRef.current.switch = videoUrl;
@@ -1977,26 +2008,54 @@ function PlayPageClient() {
return [];
}
},
- speed: 5,
+ speed: isMobile ? 4 : 5, // 移动端弹幕速度稍慢
opacity: 1,
- fontSize: 25,
+ fontSize: danmuConfig.fontSize,
color: '#FFFFFF',
mode: 0,
- margin: [10, '25%'],
+ margin: danmuConfig.margin,
antiOverlap: true,
useWorker: true,
synchronousPlayback: false,
- filter: (danmu: any) => danmu.text.length < 50,
- lockTime: 5,
- maxLength: 100,
- minWidth: 200,
- maxWidth: 500,
+ filter: (danmu: any) => danmu.text.length < (isMobile ? 30 : 50),
+ lockTime: isMobile ? 3 : 5, // 移动端锁定时间更短
+ maxLength: isMobile ? 80 : 100, // 移动端最大长度限制
+ minWidth: danmuConfig.minWidth,
+ maxWidth: danmuConfig.maxWidth,
theme: 'dark',
// 核心配置:启用弹幕发送功能
panel: true, // 启用弹幕输入面板
emit: true, // 启用弹幕发送
- placeholder: '发个弹幕呗~',
- maxlength: 50,
+ placeholder: danmuConfig.placeholder,
+ maxlength: danmuConfig.maxlength,
+ // 移动端专用配置
+ ...(isMobile && {
+ panelStyle: {
+ fontSize: '14px',
+ padding: '8px 12px',
+ borderRadius: '20px',
+ background: 'rgba(0, 0, 0, 0.8)',
+ backdropFilter: 'blur(10px)',
+ border: '1px solid rgba(255, 255, 255, 0.2)',
+ color: '#ffffff',
+ outline: 'none',
+ width: '100%',
+ maxWidth: '280px',
+ boxSizing: 'border-box',
+ },
+ buttonStyle: {
+ fontSize: '12px',
+ padding: '6px 12px',
+ borderRadius: '16px',
+ background: 'linear-gradient(45deg, #3b82f6, #1d4ed8)',
+ border: 'none',
+ color: '#ffffff',
+ cursor: 'pointer',
+ marginLeft: '8px',
+ minWidth: '50px',
+ outline: 'none',
+ },
+ }),
beforeVisible: (danmu: any) => {
return !danmu.text.includes('广告');
},
@@ -2021,7 +2080,7 @@ function PlayPageClient() {
mode: danmu.mode || 0,
time: (artPlayerRef.current?.currentTime || 0) + 0.5,
border: false,
- size: 25
+ size: isMobile ? 18 : 25 // 移动端弹幕字体更小
};
// 手动触发弹幕显示(如果beforeEmit的返回值不能正常显示)
diff --git a/src/app/search/page.tsx b/src/app/search/page.tsx
index 8adc13d..b222dc7 100644
--- a/src/app/search/page.tsx
+++ b/src/app/search/page.tsx
@@ -45,6 +45,229 @@ function SearchPageClient() {
const groupRefs = useRef
@@ -893,16 +1218,8 @@ function SearchPageClient() {