mirror of
https://github.com/truewhile/MeBox.git
synced 2026-10-04 12:36:37 +08:00
优化
优化
This commit is contained in:
@@ -21,6 +21,7 @@ import { SettingRow } from './SettingsRow'
|
||||
import type { StrmAccount, StrmSyncPath, StrmSyncPathInput, StrmProvider } from '../types/strm'
|
||||
import { STRM_PROVIDER_LABELS } from '../types/strm'
|
||||
import { apiErrorMessage } from './StrmManagePage'
|
||||
import { LocalDirBrowserDialog } from '../components/LocalDirBrowserDialog'
|
||||
|
||||
// ─── 弹框外壳 ────────────────────────────────────────────────────────────────
|
||||
|
||||
@@ -903,126 +904,6 @@ function ToggleRow({ label, checked, onChange }: { label: string; checked: boole
|
||||
)
|
||||
}
|
||||
|
||||
// ─── 本地目录浏览选择器(Windows 盘符 / Linux 根目录兼容) ─────────────────────
|
||||
|
||||
function LocalDirBrowserDialog({
|
||||
initialDir,
|
||||
onSelect,
|
||||
onClose,
|
||||
}: {
|
||||
initialDir?: string
|
||||
onSelect: (path: string) => void
|
||||
onClose: () => void
|
||||
}) {
|
||||
const [list, setList] = useState<{ roots: boolean; parent?: string; current?: string; children: { name: string; path: string }[] } | null>(null)
|
||||
const [loading, setLoading] = useState(true)
|
||||
|
||||
const load = async (target: string) => {
|
||||
setLoading(true)
|
||||
try {
|
||||
const data = await strmAPI.listLocalDirs(target)
|
||||
setList(data)
|
||||
} catch (err) {
|
||||
toast.error(apiErrorMessage(err))
|
||||
} finally {
|
||||
setLoading(false)
|
||||
}
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
load(initialDir ?? '').catch(() => undefined)
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [])
|
||||
|
||||
const selectable = list && !list.roots && list.current
|
||||
|
||||
return (
|
||||
<div
|
||||
className="fixed inset-0 z-[110] flex items-center justify-center bg-black/35 p-4 backdrop-blur-sm"
|
||||
onClick={onClose}
|
||||
>
|
||||
<div
|
||||
role="dialog"
|
||||
aria-modal="true"
|
||||
className="flex max-h-[80vh] w-full max-w-2xl flex-col overflow-hidden 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>
|
||||
<button type="button" onClick={onClose} className="rounded-xl p-1.5 text-ink-50 transition hover:bg-gray-100 hover:text-ink-600">
|
||||
<X size={20} />
|
||||
</button>
|
||||
</div>
|
||||
<div className="flex items-center gap-2 border-b border-gray-100 px-6 py-2.5 text-xs text-sand-500">
|
||||
{list?.roots ? (
|
||||
<span className="text-ink-50">{'选择盘符 / 根目录'}</span>
|
||||
) : (
|
||||
<>
|
||||
<button
|
||||
type="button"
|
||||
className="hover:text-brand-500"
|
||||
onClick={() => load('')}
|
||||
>
|
||||
盘符 / 根
|
||||
</button>
|
||||
<ChevronRight size={12} />
|
||||
<span className="truncate text-ink-50" title={list?.current}>
|
||||
{list?.current}
|
||||
</span>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
<div className="min-h-[260px] flex-1 overflow-y-auto p-3">
|
||||
{loading ? (
|
||||
<div className="flex justify-center py-10 text-ink-50">
|
||||
<Loader2 className="animate-spin" />
|
||||
</div>
|
||||
) : !list || list.children.length === 0 ? (
|
||||
<p className="py-10 text-center text-sm text-sand-500">该目录下没有子目录</p>
|
||||
) : (
|
||||
<div className="space-y-1">
|
||||
{(list.parent ?? '') !== '' && (!list.roots || true) && (
|
||||
<button
|
||||
type="button"
|
||||
className="flex w-full items-center gap-3 rounded-xl px-3 py-2 text-left text-sm text-ink-50 transition hover:bg-gray-50"
|
||||
onClick={() => load(list.parent ?? '')}
|
||||
>
|
||||
<FolderPlus size={16} className="text-sand-400" />
|
||||
<span>..(上级目录)</span>
|
||||
</button>
|
||||
)}
|
||||
{list.children.map((entry) => (
|
||||
<button
|
||||
key={entry.path}
|
||||
type="button"
|
||||
className="flex w-full items-center gap-3 rounded-xl px-3 py-2 text-left text-sm transition hover:bg-gray-50"
|
||||
onClick={() => load(entry.path)}
|
||||
>
|
||||
<FolderPlus size={16} className="text-brand-400" />
|
||||
<span className="flex-1 truncate text-ink-600">{entry.name}</span>
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<div className="flex items-center justify-between border-t border-gray-100 px-6 py-3">
|
||||
<span className="text-xs text-sand-500">单击目录进入下一级,最后点击「选择此目录」回填路径</span>
|
||||
<button
|
||||
type="button"
|
||||
className="neon-button"
|
||||
disabled={!selectable || loading}
|
||||
onClick={() => {
|
||||
if (list?.current) onSelect(list.current)
|
||||
}}
|
||||
>
|
||||
选择当前目录
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
// ─── 远端目录浏览选择器 ───────────────────────────────────────────────────────
|
||||
|
||||
function StrmDirBrowserDialog({
|
||||
|
||||
Reference in New Issue
Block a user