This commit is contained in:
truewhile
2026-09-01 18:55:05 +08:00
parent 5c9e7fcaa6
commit db64a6c093
49 changed files with 1140 additions and 162 deletions
+2 -2
View File
@@ -39,8 +39,8 @@ export function APIConfigsPanel() {
)}
{!loading && (
<div className="glass-panel overflow-hidden">
<table className="w-full text-left text-sm">
<div className="glass-panel table-scroll">
<table className="min-w-[640px] w-full text-left text-sm">
<thead className="border-b border-gray-200 text-xs uppercase tracking-wider text-sand-500">
<tr>
<th className="px-4 py-3">服务</th>
+1 -1
View File
@@ -53,7 +53,7 @@ export function Layout() {
const isPlayPage = location.pathname.startsWith('/play')
return (
<div className="flex h-screen w-screen overflow-hidden bg-[var(--app-bg)] text-[var(--app-text)] font-body select-none">
<div className="flex h-[100dvh] min-h-0 w-full overflow-hidden bg-[var(--app-bg)] text-[var(--app-text)] font-body select-none">
<LayoutSidebars
sidebar={sidebar}
isAdmin={permissions.isAdmin}
+10 -8
View File
@@ -43,7 +43,7 @@ export function LayoutHeader({
hideSearch,
}: LayoutHeaderProps) {
return (
<header className="relative flex h-20 shrink-0 items-center justify-between gap-4 border-b border-[var(--app-border)] bg-[var(--app-header-bg)] px-4 backdrop-blur-md z-30 md:px-8">
<header className="relative z-30 flex h-16 shrink-0 items-center justify-between gap-2 border-b border-[var(--app-border)] bg-[var(--app-header-bg)] px-3 backdrop-blur-md sm:h-20 sm:gap-4 sm:px-4 md:px-8">
{/* Left: Mobile Menu button or Brand Logo */}
<div className="flex items-center gap-3 shrink-0">
<button
@@ -71,7 +71,7 @@ export function LayoutHeader({
</div>
{/* Middle: Search Box */}
<div className="flex-1 max-w-xl mx-auto">
<div className="flex min-w-0 flex-1 max-w-xl mx-auto">
{!hideSearch && <LayoutHeaderSearch />}
</div>
@@ -155,8 +155,8 @@ function LayoutHeaderSearch() {
<div ref={containerRef} className="relative w-full">
<div className="relative flex items-center">
<Search
size={16}
className="absolute left-3.5 text-[var(--app-muted)] pointer-events-none transition-colors group-focus-within:text-brand-500"
size={15}
className="absolute left-3 text-[var(--app-muted)] pointer-events-none transition-colors group-focus-within:text-brand-500 sm:left-3.5 sm:text-[16px]"
/>
<input
type="text"
@@ -169,8 +169,8 @@ function LayoutHeaderSearch() {
if (results.length > 0) setIsOpen(true)
}}
onKeyDown={handleKeyDown}
placeholder="搜索电影、剧集、演员…"
className="w-full h-10 pl-10 pr-9 rounded-2xl border border-[var(--app-border)] bg-[var(--app-panel)] text-sm text-[var(--app-text)] placeholder:text-[var(--app-muted)] shadow-sm outline-none transition-all duration-200 focus:border-brand-500 focus:ring-2 focus:ring-brand-500/20 focus:bg-[var(--app-panel-elevated)]"
placeholder="搜索媒体…"
className="w-full h-9 sm:h-10 pl-8 sm:pl-10 pr-8 sm:pr-9 rounded-xl sm:rounded-2xl border border-[var(--app-border)] bg-[var(--app-panel)] text-xs sm:text-sm text-[var(--app-text)] placeholder:text-[var(--app-muted)] shadow-sm outline-none transition-all duration-200 focus:border-brand-500 focus:ring-2 focus:ring-brand-500/20 focus:bg-[var(--app-panel-elevated)]"
/>
{loading ? (
<LoaderCircle size={15} className="absolute right-3.5 text-brand-500 animate-spin" />
@@ -288,8 +288,10 @@ function LayoutHeaderActions({
}: LayoutHeaderActionsProps) {
return (
<div className="flex shrink-0 items-center gap-2 sm:gap-3 md:gap-4">
<LayoutThemeToggle mode={themeMode} onChange={onThemeChange} />
<span className="hidden h-6 w-px bg-[var(--app-border)] sm:block" />
<div className="hidden items-center gap-3 sm:flex md:gap-4">
<LayoutThemeToggle mode={themeMode} onChange={onThemeChange} />
<span className="h-6 w-px bg-[var(--app-border)]" />
</div>
<LayoutUserMenu
user={user}
isOpen={isProfileOpen}
+23 -22
View File
@@ -324,7 +324,7 @@ export function PlayerControls({
onMouseLeave={() => setControlsHovered(false)}
onClick={(e) => e.stopPropagation()}
>
<div className="flex items-center gap-2.5 text-white">
<div className="flex flex-wrap items-center gap-2 text-white sm:flex-nowrap sm:gap-2.5">
{/* 上一集 */}
<button
onClick={onPrevEpisode}
@@ -362,24 +362,25 @@ export function PlayerControls({
<SkipForward size={18} />
</button>
<input
type="range"
min={0}
max={duration || 0}
step={0.1}
value={displayTime}
onMouseDown={handleSeekStart}
onTouchStart={handleSeekStart}
onChange={(e) => handleSeekChange(Number(e.target.value))}
onMouseUp={(e) => handleSeekEnd(Number((e.target as HTMLInputElement).value))}
onTouchEnd={(e) => handleSeekEnd(Number((e.target as HTMLInputElement).value))}
className="min-w-0 flex-1 cursor-pointer accent-rose-500"
aria-label="播放进度"
/>
<span className="shrink-0 font-mono text-xs tabular-nums text-white/85">
{formatTime(displayTime)} / {formatTime(duration)}
</span>
<div className="order-2 flex min-w-0 basis-full items-center gap-2 sm:order-none sm:basis-auto sm:flex-1">
<input
type="range"
min={0}
max={duration || 0}
step={0.1}
value={displayTime}
onMouseDown={handleSeekStart}
onTouchStart={handleSeekStart}
onChange={(e) => handleSeekChange(Number(e.target.value))}
onMouseUp={(e) => handleSeekEnd(Number((e.target as HTMLInputElement).value))}
onTouchEnd={(e) => handleSeekEnd(Number((e.target as HTMLInputElement).value))}
className="min-w-0 flex-1 cursor-pointer accent-rose-500"
aria-label="播放进度"
/>
<span className="shrink-0 font-mono text-[10px] tabular-nums text-white/85 sm:text-xs">
{formatTime(displayTime)} / {formatTime(duration)}
</span>
</div>
{pipSupported && (
<button
@@ -456,7 +457,7 @@ export function PlayerControls({
title={hasPlaylist ? '选集列表' : '当前无更多剧集'}
>
<ListVideo size={15} />
选集
<span className="hidden sm:inline">选集</span>
</button>
)}
@@ -472,7 +473,7 @@ export function PlayerControls({
title="弹幕设置"
>
<MessageSquareText size={15} />
弹幕
<span className="hidden sm:inline">弹幕</span>
{danmakuEnabled && <span className="h-1.5 w-1.5 rounded-full bg-lime-400" />}
</button>
@@ -490,7 +491,7 @@ export function PlayerControls({
step={0.05}
value={muted ? 0 : volume}
onChange={(e) => changeVolume(Number(e.target.value))}
className="w-16 accent-rose-500"
className="hidden w-16 accent-rose-500 sm:block"
aria-label="音量"
/>
+1 -1
View File
@@ -115,7 +115,7 @@ export function PlayerDanmakuPanel({
// 面板悬浮于视频上方:阻止点击冒泡,避免触发视频区域的播放/暂停切换。
<div
onClick={(e) => e.stopPropagation()}
className="absolute right-4 top-16 z-30 w-80 rounded-2xl border border-white/15 bg-black/85 p-4 text-white shadow-2xl backdrop-blur-md"
className="absolute inset-x-3 top-12 bottom-3 z-30 w-auto overflow-y-auto rounded-2xl border border-white/15 bg-black/85 p-4 text-white shadow-2xl backdrop-blur-md sm:inset-x-auto sm:right-4 sm:top-16 sm:bottom-auto sm:w-80"
>
<div className="mb-3 flex items-center justify-between">
<div className="flex items-center gap-2 text-sm font-semibold">
+1 -1
View File
@@ -89,7 +89,7 @@ export function PlayerPlaylistPanel({
return (
<div
onClick={(e) => e.stopPropagation()}
className="absolute right-4 top-16 bottom-20 z-30 flex w-80 sm:w-96 flex-col rounded-2xl border border-white/15 bg-black/85 text-white shadow-2xl backdrop-blur-md overflow-hidden"
className="absolute inset-x-3 top-12 bottom-3 z-30 flex flex-col overflow-hidden rounded-2xl border border-white/15 bg-black/85 text-white shadow-2xl backdrop-blur-md sm:inset-x-auto sm:right-4 sm:top-16 sm:bottom-20 sm:w-96"
>
{/* 头部 */}
<div className="flex items-center justify-between border-b border-white/10 px-4 py-3 shrink-0">
+5 -5
View File
@@ -22,17 +22,17 @@ export function openManageLibrariesDialog(): Promise<void> {
function ManageLibrariesDialog({ onClose }: { onClose: () => void }) {
return (
<div
className="fixed inset-0 z-[100] flex items-center justify-center bg-black/35 p-4 backdrop-blur-sm"
className="fixed inset-0 z-[100] flex items-center justify-center bg-black/35 p-2 sm:p-4 backdrop-blur-sm"
onClick={onClose}
>
<div
role="dialog"
aria-modal="true"
className="flex h-[85vh] w-full max-w-5xl flex-col overflow-hidden rounded-3xl border border-white/70 bg-white shadow-2xl"
className="flex h-[calc(100dvh-1rem)] sm:h-[85vh] w-full max-w-5xl flex-col overflow-hidden rounded-2xl sm:rounded-3xl border border-white/70 bg-white shadow-2xl"
onClick={(event) => event.stopPropagation()}
>
<div className="flex items-center justify-between border-b border-gray-100 px-6 py-4">
<h3 className="font-display text-lg font-bold text-ink-600">管理媒体库</h3>
<div className="flex items-center justify-between border-b border-gray-100 px-4 py-3 sm:px-6 sm:py-4">
<h3 className="font-display text-base sm:text-lg font-bold text-ink-600">管理媒体库</h3>
<button
type="button"
onClick={onClose}
@@ -42,7 +42,7 @@ function ManageLibrariesDialog({ onClose }: { onClose: () => void }) {
<X size={20} />
</button>
</div>
<div className="flex-1 overflow-y-auto p-6">
<div className="flex-1 overflow-y-auto p-3 sm:p-6">
<AdminLibraryPanel />
</div>
</div>