{/* 上一集 */}
-
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="播放进度"
- />
-
-
- {formatTime(displayTime)} / {formatTime(duration)}
-
+
+ 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="播放进度"
+ />
+
+ {formatTime(displayTime)} / {formatTime(duration)}
+
+
{pipSupported && (
)}
@@ -472,7 +473,7 @@ export function PlayerControls({
title="弹幕设置"
>
- 弹幕
+
弹幕
{danmakuEnabled &&
}
@@ -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="音量"
/>
diff --git a/web/src/components/PlayerDanmakuPanel.tsx b/web/src/components/PlayerDanmakuPanel.tsx
index 076ec97..c4a00e0 100644
--- a/web/src/components/PlayerDanmakuPanel.tsx
+++ b/web/src/components/PlayerDanmakuPanel.tsx
@@ -115,7 +115,7 @@ export function PlayerDanmakuPanel({
// 面板悬浮于视频上方:阻止点击冒泡,避免触发视频区域的播放/暂停切换。
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"
>
diff --git a/web/src/components/PlayerPlaylistPanel.tsx b/web/src/components/PlayerPlaylistPanel.tsx
index c5fa915..017faa9 100644
--- a/web/src/components/PlayerPlaylistPanel.tsx
+++ b/web/src/components/PlayerPlaylistPanel.tsx
@@ -89,7 +89,7 @@ export function PlayerPlaylistPanel({
return (
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"
>
{/* 头部 */}
diff --git a/web/src/components/manageLibrariesDialog.tsx b/web/src/components/manageLibrariesDialog.tsx
index 3cc8de5..b5d90bf 100644
--- a/web/src/components/manageLibrariesDialog.tsx
+++ b/web/src/components/manageLibrariesDialog.tsx
@@ -22,17 +22,17 @@ export function openManageLibrariesDialog(): Promise
{
function ManageLibrariesDialog({ onClose }: { onClose: () => void }) {
return (
event.stopPropagation()}
>
-
-
管理媒体库
+
+
管理媒体库
-
diff --git a/web/src/index.css b/web/src/index.css
index 3e9a31c..41c73a9 100644
--- a/web/src/index.css
+++ b/web/src/index.css
@@ -277,10 +277,11 @@ body {
.badge-neutral { @apply badge bg-gray-100 text-gray-600 border border-gray-200/50; }
/* ── Page Headings ── */
- .page-heading { @apply font-display text-3xl font-extrabold tracking-tight text-gray-900; }
+ .page-heading { @apply font-display text-2xl font-extrabold tracking-tight text-gray-900 sm:text-3xl; }
.page-subtitle { @apply mt-1 text-sm text-gray-500; }
- /* ── Data Tables Redesign ── */
+ /* ── Mobile Data Tables ── */
+ .table-scroll { @apply overflow-x-auto overscroll-x-contain; -webkit-overflow-scrolling: touch; }
.data-table { @apply w-full text-left text-sm border-collapse; }
.data-table thead { @apply border-b border-gray-200 bg-gray-50/70; }
.data-table th { @apply px-5 py-4 text-xs font-bold uppercase tracking-wider text-gray-500 whitespace-nowrap; }
diff --git a/web/src/pages/AdminUsersTable.tsx b/web/src/pages/AdminUsersTable.tsx
index e1efbdf..914f88c 100644
--- a/web/src/pages/AdminUsersTable.tsx
+++ b/web/src/pages/AdminUsersTable.tsx
@@ -42,8 +42,8 @@ export function AdminUsersTable({
onDeleteUser,
}: AdminUsersTableProps) {
return (
-
-
+
+
| 用户名 |
diff --git a/web/src/pages/EmbyMountPage.tsx b/web/src/pages/EmbyMountPage.tsx
index e3b6ccb..a803a69 100644
--- a/web/src/pages/EmbyMountPage.tsx
+++ b/web/src/pages/EmbyMountPage.tsx
@@ -2,8 +2,11 @@
import { useCallback, useEffect, useState } from 'react'
import toast from 'react-hot-toast'
import {
+ ArrowDown,
+ ArrowUp,
Check,
Globe,
+ GripVertical,
Loader2,
Pencil,
Plus,
@@ -107,7 +110,7 @@ function AccountDialog({
disabled={!!existing}
/>
-
+