feat(subtitles): 补字幕第 1 步——上传字幕 / zip,识别语言与季集,配对写入视频同目录,历史与撤销

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
rootandClaude Opus 5.5 committed 2026-10-03 01:08:05 +08:00
1 parent feee481915
commit ef29bd62ce
22 files changed
+1554 -2

No files matched your search

@@ -14,6 +14,7 @@ import {
ArrowLeft,
CalendarClock,
CalendarPlus,
Captions,
ChevronRight,
ExternalLink,
FolderTree,
@@ -88,6 +89,7 @@ import { useReleaseSearchLauncher } from "~/components/search/search-sections.ts
import { EmbyBadge } from "~/components/search/work-card.tsx";
import { CELL_LABEL, type CellKind, cellKind } from "~/components/subscriptions/model.ts";
import { SubscriptionFormDialog } from "~/components/subscriptions/subscription-form.tsx";
import { SubtitleDialog } from "~/components/subtitles/subtitle-dialog.tsx";
import { Button } from "~/components/ui/button.tsx";
import { errorMessage } from "~/lib/api.ts";
import { useUiPrefs } from "~/lib/ui-prefs.ts";
@@ -1104,6 +1106,7 @@ export default function LibraryDetailPage() {
const entity = useEntityDetail(id);
const [merging, setMerging] = useState(false);
const [subscribing, setSubscribing] = useState(false);
const [subtitling, setSubtitling] = useState(false);
const launcher = useReleaseSearchLauncher();
const ms = mediaServers.useList();
@@ -1193,6 +1196,12 @@ export default function LibraryDetailPage() {
合并作品
</Button>
) : null}
{e.status !== "merged" ? (
<Button variant="outline" size="sm" onClick={() => setSubtitling(true)}>
<Captions />
补字幕
</Button>
) : null}
<EntityNamingButton entityId={e.id} kind={e.kind} />
</div>
<TechInfo className="-mt-3 mb-5" items={[{ label: "作品 ID", value: e.id, wide: true }]} />
@@ -1230,6 +1239,9 @@ export default function LibraryDetailPage() {
onClose={() => setSubscribing(false)}
/>
) : null}
{subtitling ? (
<SubtitleDialog entityId={e.id} title={e.title} open onOpenChange={(o) => !o && setSubtitling(false)} />
) : null}
{launcher.dialog}
</>
);