1
0
Fork 0
mirror of https://github.com/sussy-code/smov.git synced 2024-12-20 14:37:43 +01:00

Drop subtitles

This commit is contained in:
Isra 2024-03-16 14:55:29 -05:00
parent 2a0e46a97d
commit 57d3f69efa
3 changed files with 82 additions and 3 deletions

View file

@ -316,7 +316,7 @@
"unknownOption": "Unknown" "unknownOption": "Unknown"
}, },
"subtitles": { "subtitles": {
"customChoice": "Select subtitle from file", "customChoice": "Drop or upload file",
"customizeLabel": "Customize", "customizeLabel": "Customize",
"offChoice": "Off", "offChoice": "Off",
"settings": { "settings": {

View file

@ -0,0 +1,51 @@
import { useEffect, useState } from "react";
import type { DragEvent, ReactNode } from "react";
interface FileDropHandlerProps {
children: ReactNode;
className: string;
onDrop: (event: DragEvent<HTMLDivElement>) => void;
onDraggingChange: (isDragging: boolean) => void;
}
export function FileDropHandler(props: FileDropHandlerProps) {
const [dragging, setDragging] = useState(false);
const handleDragEnter = (event: DragEvent<HTMLDivElement>) => {
event.preventDefault();
setDragging(true);
};
const handleDragLeave = (event: DragEvent<HTMLDivElement>) => {
if (!event.currentTarget.contains(event.relatedTarget as Node)) {
setDragging(false);
}
};
const handleDragOver = (event: DragEvent<HTMLDivElement>) => {
event.preventDefault();
};
const handleDrop = (event: DragEvent<HTMLDivElement>) => {
event.preventDefault();
setDragging(false);
props.onDrop(event);
};
useEffect(() => {
props.onDraggingChange(dragging);
}, [dragging, props]);
return (
<section
onDragEnter={handleDragEnter}
onDragLeave={handleDragLeave}
onDragOver={handleDragOver}
onDrop={handleDrop}
className={props.className}
>
{props.children}
</section>
);
}

View file

@ -5,6 +5,7 @@ import { useAsyncFn } from "react-use";
import { convert } from "subsrt-ts"; import { convert } from "subsrt-ts";
import { subtitleTypeList } from "@/backend/helpers/subs"; import { subtitleTypeList } from "@/backend/helpers/subs";
import { FileDropHandler } from "@/components/DropFile";
import { FlagIcon } from "@/components/FlagIcon"; import { FlagIcon } from "@/components/FlagIcon";
import { useCaptions } from "@/components/player/hooks/useCaptions"; import { useCaptions } from "@/components/player/hooks/useCaptions";
import { Menu } from "@/components/player/internals/ContextMenu"; import { Menu } from "@/components/player/internals/ContextMenu";
@ -123,6 +124,8 @@ export function CaptionsView({ id }: { id: string }) {
const { selectCaptionById, disable } = useCaptions(); const { selectCaptionById, disable } = useCaptions();
const captionList = usePlayerStore((s) => s.captionList); const captionList = usePlayerStore((s) => s.captionList);
const getHlsCaptionList = usePlayerStore((s) => s.display?.getCaptionList); const getHlsCaptionList = usePlayerStore((s) => s.display?.getCaptionList);
const [dragging, setDragging] = useState(false);
const setCaption = usePlayerStore((s) => s.setCaption);
const captions = useMemo( const captions = useMemo(
() => () =>
@ -162,7 +165,31 @@ export function CaptionsView({ id }: { id: string }) {
}); });
return ( return (
<> <FileDropHandler
className={`transition duration-300 ${dragging ? "brightness-50" : ""}`}
onDraggingChange={(isDragging) => {
setDragging(isDragging);
}}
onDrop={(event) => {
const files = event.dataTransfer.files;
if (!files || files.length === 0) return;
const reader = new FileReader();
reader.addEventListener("load", (e) => {
if (!e.target || typeof e.target.result !== "string") return;
const converted = convert(e.target.result, "srt");
setCaption({
language: "custom",
srtData: converted,
id: "custom-caption",
});
});
reader.readAsText(files[0]);
}}
>
<div> <div>
<Menu.BackLink <Menu.BackLink
onClick={() => router.navigate("/")} onClick={() => router.navigate("/")}
@ -182,6 +209,7 @@ export function CaptionsView({ id }: { id: string }) {
<Input value={searchQuery} onInput={setSearchQuery} /> <Input value={searchQuery} onInput={setSearchQuery} />
</div> </div>
</div> </div>
<Menu.ScrollToActiveSection className="!pt-1 mt-2 pb-3"> <Menu.ScrollToActiveSection className="!pt-1 mt-2 pb-3">
<CaptionOption onClick={() => disable()} selected={!selectedCaptionId}> <CaptionOption onClick={() => disable()} selected={!selectedCaptionId}>
{t("player.menus.subtitles.offChoice")} {t("player.menus.subtitles.offChoice")}
@ -189,7 +217,7 @@ export function CaptionsView({ id }: { id: string }) {
<CustomCaptionOption /> <CustomCaptionOption />
{content} {content}
</Menu.ScrollToActiveSection> </Menu.ScrollToActiveSection>
</> </FileDropHandler>
); );
} }