feat: 尝试支持配置视频背景

This commit is contained in:
Montia37
2025-09-08 03:03:31 +08:00
parent 743048bb25
commit 369ac3333f
7 changed files with 85 additions and 38 deletions

View File

@@ -62,9 +62,12 @@
| 名称 | 配置项 | 类型 | 默认值 | 说明 | | 名称 | 配置项 | 类型 | 默认值 | 说明 |
| :--- | :--- | :--- | :--- | :--- | | :--- | :--- | :--- | :--- | :--- |
| 背景图片链接 | `backgroundImage` | `string` | `/assets/Moonlit-Scenery.webp` | 目前仅支持单张背景图片eg: https://test.com/1.png | | 背景图片链接 | `backgroundImage` | `string` | `/assets/Moonlit-Scenery.webp` | 目前仅支持单张背景图片eg: https://test.com/1.png |
| 启用视频背景 | `enableVedioBackground` | `switch` | `false` | 启用后将使用视频作为背景 |
| 视频背景链接 | `vedioBackgroundUrl` | `string` | `/assets/Mortis_1080p30fps2Mbps.mp4` | 视频背景链接eg: https://test.com/1.mp4 ),建议使用无声视频,且视频文件较大时可能会影响加载速度 |
| 启用磨砂玻璃效果 | `enableBlur` | `switch` | `true` | 启用后将使主要容器拥有磨砂玻璃效果 |
| 磨砂玻璃模糊值 | `blurValue` | `number` | `10` | 调整模糊值大小,数值越大模糊效果越明显,建议值为 5-20为 0 则表示不启用模糊效果 | | 磨砂玻璃模糊值 | `blurValue` | `number` | `10` | 调整模糊值大小,数值越大模糊效果越明显,建议值为 5-20为 0 则表示不启用模糊效果 |
| 磨砂玻璃背景色 | `blurBackgroundColor` | `string` | `rgba(255, 255, 255, 0.5)|rgba(0, 0, 0, 0.5)` | 调整模糊背景色,推荐 rgba 颜色值,使用“|”分隔亮色模式和暗色模式的颜色值eg: rgba(255, 255, 255, 0.5)|rgba(0, 0, 0, 0.5) | | 磨砂玻璃背景色 | `blurBackgroundColor` | `string` | `rgba(255, 255, 255, 0.5)\|rgba(0, 0, 0, 0.5)` | 调整模糊背景色,推荐 rgba 颜色值,使用“\|”分隔亮色模式和暗色模式的颜色值eg: rgba(255, 255, 255, 0.5)\|rgba(0, 0, 0, 0.5) |
| 标签默认颜色列表 | `tagDefaultColorList` | `string` | `ruby,gray,gold,bronze,brown,yellow,amber,orange,tomato,red` | 标签默认颜色列表展示的标签将按顺序调用该颜色池逗号分隔可用的颜色列表请参考https://www.radix-ui.com/themes/docs/theme/color ,改完没有生效则说明填写有误) | | 标签默认颜色列表 | `tagDefaultColorList` | `string` | `ruby,gray,gold,bronze,brown,yellow,amber,orange,tomato,red` | 标签默认颜色列表展示的标签将按顺序调用该颜色池逗号分隔可用的颜色列表请参考https://www.radix-ui.com/themes/docs/theme/color ,改完没有生效则说明填写有误) |
| 启用 localStorage 配置 | `enableLocalStorage` | `switch` | `true` | 启用后将优先使用用户浏览器本地配置的视图和外观设置。关闭后将强制使用下方的主题配置,本地可调整但刷新即恢复 | | 启用 localStorage 配置 | `enableLocalStorage` | `switch` | `true` | 启用后将优先使用用户浏览器本地配置的视图和外观设置。关闭后将强制使用下方的主题配置,本地可调整但刷新即恢复 |
| 默认展示视图 | `selectedDefaultView` | `select` | `grid` | 设置默认展示视图为网格或表格 | | 默认展示视图 | `selectedDefaultView` | `select` | `grid` | 设置默认展示视图为网格或表格 |
@@ -78,7 +81,7 @@
| 启用标题栏左侧 Logo | `enableLogo` | `switch` | `false` | 启用后默认在标题栏左侧显示 Logo | | 启用标题栏左侧 Logo | `enableLogo` | `switch` | `false` | 启用后默认在标题栏左侧显示 Logo |
| Logo 图片链接 | `logoUrl` | `string` | `/assets/logo.png` | Logo 图片链接eg: https://test.com/logo.png | | Logo 图片链接 | `logoUrl` | `string` | `/assets/logo.png` | Logo 图片链接eg: https://test.com/logo.png |
| 启用标题栏标题 | `enableTitle` | `switch` | `true` | 启用后默认在顶栏左侧显示标题 | | 启用标题栏标题 | `enableTitle` | `switch` | `true` | 启用后默认在顶栏左侧显示标题 |
| 标题栏标题文本 | `titleText` | `string` | | 标题栏左侧显示的文本(留空则使用站点标题) | | 标题栏标题文本 | `titleText` | `string` |   | 标题栏左侧显示的文本(留空则使用站点标题) |
| 启用搜索按钮 | `enableSearchButton` | `switch` | `true` | 启用后默认在标题栏右侧显示搜索按钮 | | 启用搜索按钮 | `enableSearchButton` | `switch` | `true` | 启用后默认在标题栏右侧显示搜索按钮 |
| 启用管理按钮 | `enableAdminButton` | `switch` | `true` | 启用后默认在标题栏右侧显示管理按钮 | | 启用管理按钮 | `enableAdminButton` | `switch` | `true` | 启用后默认在标题栏右侧显示管理按钮 |

View File

@@ -20,6 +20,27 @@
"default": "/assets/Moonlit-Scenery.webp", "default": "/assets/Moonlit-Scenery.webp",
"help": "目前仅支持单张背景图片eg: https://test.com/1.png" "help": "目前仅支持单张背景图片eg: https://test.com/1.png"
}, },
{
"key": "enableVedioBackground",
"name": "启用视频背景",
"type": "switch",
"default": false,
"help": "启用后将使用视频作为背景"
},
{
"key": "vedioBackgroundUrl",
"name": "视频背景链接",
"type": "string",
"default": "/assets/Mortis_1080p30fps2Mbps.mp4",
"help": "视频背景链接eg: https://test.com/1.mp4建议使用无声视频且视频文件较大时可能会影响加载速度"
},
{
"key": "enableBlur",
"name": "启用磨砂玻璃效果",
"type": "switch",
"default": true,
"help": "启用后将使主要容器拥有磨砂玻璃效果"
},
{ {
"key": "blurValue", "key": "blurValue",
"name": "磨砂玻璃模糊值", "name": "磨砂玻璃模糊值",

Binary file not shown.

View File

@@ -13,7 +13,7 @@ import { useEffect, useState } from "react";
import { useLocation } from "react-router-dom"; import { useLocation } from "react-router-dom";
import { useIsMobile } from "@/hooks/useMobile"; import { useIsMobile } from "@/hooks/useMobile";
import { useConfigItem } from "@/config"; import { useConfigItem } from "@/config";
import type { Appearance } from "@/hooks/useTheme"; import { useTheme } from "@/hooks/useTheme";
import { import {
DropdownMenu, DropdownMenu,
DropdownMenuContent, DropdownMenuContent,
@@ -24,8 +24,6 @@ import {
interface HeaderProps { interface HeaderProps {
viewMode: "grid" | "table"; viewMode: "grid" | "table";
setViewMode: (mode: "grid" | "table") => void; setViewMode: (mode: "grid" | "table") => void;
appearance: Appearance;
setAppearance: (appearance: Appearance) => void;
searchTerm: string; searchTerm: string;
setSearchTerm: (term: string) => void; setSearchTerm: (term: string) => void;
} }
@@ -33,11 +31,10 @@ interface HeaderProps {
export const Header = ({ export const Header = ({
viewMode, viewMode,
setViewMode, setViewMode,
appearance,
setAppearance,
searchTerm, searchTerm,
setSearchTerm, setSearchTerm,
}: HeaderProps) => { }: HeaderProps) => {
const { appearance, setAppearance } = useTheme();
const [isSearchOpen, setIsSearchOpen] = useState(false); const [isSearchOpen, setIsSearchOpen] = useState(false);
const location = useLocation(); const location = useLocation();
const isInstancePage = location.pathname.startsWith("/instance"); const isInstancePage = location.pathname.startsWith("/instance");
@@ -56,8 +53,7 @@ export const Header = ({
}, [sitename]); }, [sitename]);
const toggleAppearance = () => { const toggleAppearance = () => {
const newAppearance = appearance === "light" ? "dark" : "light"; setAppearance(appearance === "light" ? "dark" : "light");
setAppearance(newAppearance);
}; };
return ( return (

View File

@@ -1,6 +1,8 @@
// 配置类型定义 // 配置类型定义
export interface ConfigOptions { export interface ConfigOptions {
backgroundImage?: string; // 背景图片URL backgroundImage?: string; // 背景图片URL
enableVideoBackground?: boolean; // 是否启用视频背景
videoBackgroundUrl?: string; // 视频背景URL
blurValue?: number; // 磨砂玻璃模糊值 blurValue?: number; // 磨砂玻璃模糊值
blurBackgroundColor?: string; // 磨砂玻璃背景颜色 blurBackgroundColor?: string; // 磨砂玻璃背景颜色
tagDefaultColorList?: string; // 标签默认颜色列表 tagDefaultColorList?: string; // 标签默认颜色列表
@@ -27,6 +29,8 @@ export interface ConfigOptions {
// 默认配置值 // 默认配置值
export const DEFAULT_CONFIG: ConfigOptions = { export const DEFAULT_CONFIG: ConfigOptions = {
backgroundImage: "/assets/Moonlit-Scenery.webp", backgroundImage: "/assets/Moonlit-Scenery.webp",
enableVideoBackground: false,
videoBackgroundUrl: "/assets/Mortis_1080p30fps2Mbps.mp4",
blurValue: 10, blurValue: 10,
blurBackgroundColor: "rgba(255, 255, 255, 0.5)|rgba(0, 0, 0, 0.5)", blurBackgroundColor: "rgba(255, 255, 255, 0.5)|rgba(0, 0, 0, 0.5)",
tagDefaultColorList: tagDefaultColorList:

View File

@@ -86,6 +86,16 @@ export const useTheme = () => {
return (defaultColor as Colors) || THEME_DEFAULTS.color; return (defaultColor as Colors) || THEME_DEFAULTS.color;
}); });
useEffect(() => {
if (appearance === "system") {
const systemTheme = window.matchMedia("(prefers-color-scheme: dark)")
.matches
? "dark"
: "light";
setAppearance(systemTheme);
}
}, [appearance]);
useEffect(() => { useEffect(() => {
const root = window.document.documentElement; const root = window.document.documentElement;
root.classList.remove("light", "dark"); root.classList.remove("light", "dark");

View File

@@ -21,7 +21,7 @@ import { useConfigItem } from "@/config";
// 内部应用组件,在 ConfigProvider 内部使用配置 // 内部应用组件,在 ConfigProvider 内部使用配置
export const AppContent = () => { export const AppContent = () => {
const { appearance, setAppearance, color } = useTheme(); const { appearance, color } = useTheme();
const defaultView = useConfigItem("selectedDefaultView"); const defaultView = useConfigItem("selectedDefaultView");
const enableLocalStorage = useConfigItem("enableLocalStorage"); const enableLocalStorage = useConfigItem("enableLocalStorage");
@@ -36,6 +36,8 @@ export const AppContent = () => {
return defaultView || "grid"; return defaultView || "grid";
}); });
const [searchTerm, setSearchTerm] = useState(""); const [searchTerm, setSearchTerm] = useState("");
const enableVideoBackground = useConfigItem("enableVideoBackground");
const videoBackgroundUrl = useConfigItem("videoBackgroundUrl");
useEffect(() => { useEffect(() => {
if (enableLocalStorage) { if (enableLocalStorage) {
@@ -44,33 +46,44 @@ export const AppContent = () => {
}, [enableLocalStorage, viewMode]); }, [enableLocalStorage, viewMode]);
return ( return (
<Theme <>
appearance={appearance === "system" ? "inherit" : appearance} {enableVideoBackground && videoBackgroundUrl && (
accentColor={color} <video
scaling="110%" src={videoBackgroundUrl as string}
style={{ backgroundColor: "transparent" }}> autoPlay
<div className="min-h-screen flex flex-col text-sm"> loop
<Header muted
viewMode={viewMode} playsInline
setViewMode={setViewMode} className="fixed right-0 bottom-0 min-w-full min-h-full w-auto h-auto -z-1 object-cover"></video>
appearance={appearance} )}
setAppearance={setAppearance} <Theme
searchTerm={searchTerm} appearance={appearance === "system" ? "inherit" : appearance}
setSearchTerm={setSearchTerm} accentColor={color}
/> scaling="110%"
<Suspense fallback={<Loading />}> style={{ backgroundColor: "transparent" }}>
<Routes> <div className="min-h-screen flex flex-col text-sm">
<Route <Header
path="/" viewMode={viewMode}
element={<HomePage viewMode={viewMode} searchTerm={searchTerm} />} setViewMode={setViewMode}
/> searchTerm={searchTerm}
<Route path="/instance/:uuid" element={<InstancePage />} /> setSearchTerm={setSearchTerm}
<Route path="*" element={<NotFoundPage />} /> />
</Routes> <Suspense fallback={<Loading />}>
</Suspense> <Routes>
<Footer /> <Route
</div> path="/"
</Theme> element={
<HomePage viewMode={viewMode} searchTerm={searchTerm} />
}
/>
<Route path="/instance/:uuid" element={<InstancePage />} />
<Route path="*" element={<NotFoundPage />} />
</Routes>
</Suspense>
<Footer />
</div>
</Theme>
</>
); );
}; };