mirror of
https://github.com/sussy-code/smov.git
synced 2024-12-20 14:37:43 +01:00
Add a shortcut to subtitle settings in the bottomControls of player
This commit is contained in:
parent
9f6738a0f4
commit
b378f0533a
6 changed files with 119 additions and 21 deletions
28
src/components/player/atoms/Captions.tsx
Normal file
28
src/components/player/atoms/Captions.tsx
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
import { useEffect } from "react";
|
||||||
|
|
||||||
|
import { Icons } from "@/components/Icon";
|
||||||
|
import { OverlayAnchor } from "@/components/overlays/OverlayAnchor";
|
||||||
|
import { VideoPlayerButton } from "@/components/player/internals/Button";
|
||||||
|
import { useOverlayRouter } from "@/hooks/useOverlayRouter";
|
||||||
|
import { usePlayerStore } from "@/stores/player/store";
|
||||||
|
|
||||||
|
export function Captions() {
|
||||||
|
const router = useOverlayRouter("settings");
|
||||||
|
const setHasOpenOverlay = usePlayerStore((s) => s.setHasOpenOverlay);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setHasOpenOverlay(router.isRouterActive);
|
||||||
|
}, [setHasOpenOverlay, router.isRouterActive]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<OverlayAnchor id={router.id}>
|
||||||
|
<VideoPlayerButton
|
||||||
|
onClick={() => {
|
||||||
|
router.open();
|
||||||
|
router.navigate("/captionsOverlay");
|
||||||
|
}}
|
||||||
|
icon={Icons.CAPTIONS}
|
||||||
|
/>
|
||||||
|
</OverlayAnchor>
|
||||||
|
);
|
||||||
|
}
|
|
@ -54,6 +54,12 @@ function SettingsOverlay({ id }: { id: string }) {
|
||||||
</Menu.Card>
|
</Menu.Card>
|
||||||
</OverlayPage>
|
</OverlayPage>
|
||||||
<OverlayPage id={id} path="/captions" width={343} height={431}>
|
<OverlayPage id={id} path="/captions" width={343} height={431}>
|
||||||
|
<Menu.CardWithScrollable>
|
||||||
|
<CaptionsView id={id} backLink />
|
||||||
|
</Menu.CardWithScrollable>
|
||||||
|
</OverlayPage>
|
||||||
|
{/* This is used by the captions shortcut in bottomControls of player */}
|
||||||
|
<OverlayPage id={id} path="/captionsOverlay" width={343} height={431}>
|
||||||
<Menu.CardWithScrollable>
|
<Menu.CardWithScrollable>
|
||||||
<CaptionsView id={id} />
|
<CaptionsView id={id} />
|
||||||
</Menu.CardWithScrollable>
|
</Menu.CardWithScrollable>
|
||||||
|
@ -68,6 +74,17 @@ function SettingsOverlay({ id }: { id: string }) {
|
||||||
<OpenSubtitlesCaptionView id={id} />
|
<OpenSubtitlesCaptionView id={id} />
|
||||||
</Menu.Card>
|
</Menu.Card>
|
||||||
</OverlayPage>
|
</OverlayPage>
|
||||||
|
{/* This is used by the captions shortcut in bottomControls of player */}
|
||||||
|
<OverlayPage
|
||||||
|
id={id}
|
||||||
|
path="/captions/opensubtitlesOverlay"
|
||||||
|
width={343}
|
||||||
|
height={431}
|
||||||
|
>
|
||||||
|
<Menu.Card>
|
||||||
|
<OpenSubtitlesCaptionView id={id} overlayBackLink />
|
||||||
|
</Menu.Card>
|
||||||
|
</OverlayPage>
|
||||||
<OverlayPage id={id} path="/captions/settings" width={343} height={450}>
|
<OverlayPage id={id} path="/captions/settings" width={343} height={450}>
|
||||||
<Menu.Card>
|
<Menu.Card>
|
||||||
<CaptionSettingsView id={id} />
|
<CaptionSettingsView id={id} />
|
||||||
|
|
|
@ -16,3 +16,4 @@ export * from "./VolumeChangedPopout";
|
||||||
export * from "./NextEpisodeButton";
|
export * from "./NextEpisodeButton";
|
||||||
export * from "./Chromecast";
|
export * from "./Chromecast";
|
||||||
export * from "./CastingNotification";
|
export * from "./CastingNotification";
|
||||||
|
export * from "./Captions";
|
||||||
|
|
|
@ -120,7 +120,13 @@ function useSubtitleList(subs: CaptionListItem[], searchQuery: string) {
|
||||||
}, [subs, searchQuery, unknownChoice]);
|
}, [subs, searchQuery, unknownChoice]);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function CaptionsView({ id }: { id: string }) {
|
export function CaptionsView({
|
||||||
|
id,
|
||||||
|
backLink,
|
||||||
|
}: {
|
||||||
|
id: string;
|
||||||
|
backLink?: true;
|
||||||
|
}) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const router = useOverlayRouter(id);
|
const router = useOverlayRouter(id);
|
||||||
const selectedCaptionId = usePlayerStore((s) => s.caption.selected?.id);
|
const selectedCaptionId = usePlayerStore((s) => s.caption.selected?.id);
|
||||||
|
@ -213,20 +219,36 @@ export function CaptionsView({ id }: { id: string }) {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Menu.BackLink
|
{backLink ? (
|
||||||
onClick={() => router.navigate("/")}
|
<Menu.BackLink
|
||||||
rightSide={
|
onClick={() => router.navigate("/")}
|
||||||
<button
|
rightSide={
|
||||||
type="button"
|
<button
|
||||||
onClick={() => router.navigate("/captions/settings")}
|
type="button"
|
||||||
className="-mr-2 -my-1 px-2 p-[0.4em] rounded tabbable hover:bg-video-context-light hover:bg-opacity-10"
|
onClick={() => router.navigate("/captions/settings")}
|
||||||
>
|
className="-mr-2 -my-1 px-2 p-[0.4em] rounded tabbable hover:bg-video-context-light hover:bg-opacity-10"
|
||||||
{t("player.menus.subtitles.customizeLabel")}
|
>
|
||||||
</button>
|
{t("player.menus.subtitles.customizeLabel")}
|
||||||
}
|
</button>
|
||||||
>
|
}
|
||||||
{t("player.menus.subtitles.title")}
|
>
|
||||||
</Menu.BackLink>
|
{t("player.menus.subtitles.title")}
|
||||||
|
</Menu.BackLink>
|
||||||
|
) : (
|
||||||
|
<Menu.Title
|
||||||
|
rightSide={
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
onClick={() => router.navigate("/captions/settings")}
|
||||||
|
className="-mr-2 -my-1 px-2 p-[0.4em] rounded tabbable hover:bg-video-context-light hover:bg-opacity-10"
|
||||||
|
>
|
||||||
|
{t("player.menus.subtitles.customizeLabel")}
|
||||||
|
</button>
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{t("player.menus.subtitles.title")}
|
||||||
|
</Menu.Title>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
<FileDropHandler
|
<FileDropHandler
|
||||||
className={`transition duration-300 ${dragging ? "opacity-20" : ""}`}
|
className={`transition duration-300 ${dragging ? "opacity-20" : ""}`}
|
||||||
|
@ -239,7 +261,13 @@ export function CaptionsView({ id }: { id: string }) {
|
||||||
<Input value={searchQuery} onInput={setSearchQuery} />
|
<Input value={searchQuery} onInput={setSearchQuery} />
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={() => router.navigate("/captions/opensubtitles")}
|
onClick={() =>
|
||||||
|
router.navigate(
|
||||||
|
backLink
|
||||||
|
? "/captions/opensubtitles"
|
||||||
|
: "/captions/opensubtitlesOverlay",
|
||||||
|
)
|
||||||
|
}
|
||||||
className="p-[0.5em] rounded tabbable hover:bg-video-context-hoverColor hover:bg-opacity-50"
|
className="p-[0.5em] rounded tabbable hover:bg-video-context-hoverColor hover:bg-opacity-50"
|
||||||
>
|
>
|
||||||
<Icon icon={Icons.WEB} />
|
<Icon icon={Icons.WEB} />
|
||||||
|
@ -259,7 +287,13 @@ export function CaptionsView({ id }: { id: string }) {
|
||||||
{t("player.menus.subtitles.empty")}
|
{t("player.menus.subtitles.empty")}
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={() => router.navigate("/captions/opensubtitles")}
|
onClick={() =>
|
||||||
|
router.navigate(
|
||||||
|
backLink
|
||||||
|
? "/captions/opensubtitles"
|
||||||
|
: "/captions/opensubtitlesOverlay",
|
||||||
|
)
|
||||||
|
}
|
||||||
className="p-1 w-3/4 rounded tabbable duration-200 bg-opacity-10 bg-video-context-light hover:bg-opacity-20"
|
className="p-1 w-3/4 rounded tabbable duration-200 bg-opacity-10 bg-video-context-light hover:bg-opacity-20"
|
||||||
>
|
>
|
||||||
{t("player.menus.subtitles.scrapeButton")}
|
{t("player.menus.subtitles.scrapeButton")}
|
||||||
|
|
|
@ -73,7 +73,13 @@ function useSubtitleList(subs: CaptionListItem[], searchQuery: string) {
|
||||||
}, [subs, searchQuery, unknownChoice]);
|
}, [subs, searchQuery, unknownChoice]);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function OpenSubtitlesCaptionView({ id }: { id: string }) {
|
export function OpenSubtitlesCaptionView({
|
||||||
|
id,
|
||||||
|
overlayBackLink,
|
||||||
|
}: {
|
||||||
|
id: string;
|
||||||
|
overlayBackLink?: boolean;
|
||||||
|
}) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const router = useOverlayRouter(id);
|
const router = useOverlayRouter(id);
|
||||||
const selectedCaptionId = usePlayerStore((s) => s.caption.selected?.id);
|
const selectedCaptionId = usePlayerStore((s) => s.caption.selected?.id);
|
||||||
|
@ -124,7 +130,11 @@ export function OpenSubtitlesCaptionView({ id }: { id: string }) {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div>
|
<div>
|
||||||
<Menu.BackLink onClick={() => router.navigate("/captions")}>
|
<Menu.BackLink
|
||||||
|
onClick={() =>
|
||||||
|
router.navigate(overlayBackLink ? "/captionsOverlay" : "/captions")
|
||||||
|
}
|
||||||
|
>
|
||||||
{t("player.menus.subtitles.OpenSubtitlesChoice")}
|
{t("player.menus.subtitles.OpenSubtitlesChoice")}
|
||||||
</Menu.BackLink>
|
</Menu.BackLink>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -111,7 +111,10 @@ export function PlayerPart(props: PlayerPartProps) {
|
||||||
) : null}
|
) : null}
|
||||||
{status === playerStatus.PLAYBACK_ERROR ||
|
{status === playerStatus.PLAYBACK_ERROR ||
|
||||||
status === playerStatus.PLAYING ? (
|
status === playerStatus.PLAYING ? (
|
||||||
<Player.Settings />
|
<>
|
||||||
|
<Player.Captions />
|
||||||
|
<Player.Settings />
|
||||||
|
</>
|
||||||
) : null}
|
) : null}
|
||||||
<Player.Fullscreen />
|
<Player.Fullscreen />
|
||||||
</div>
|
</div>
|
||||||
|
@ -121,7 +124,12 @@ export function PlayerPart(props: PlayerPartProps) {
|
||||||
<div className="flex justify-center space-x-3">
|
<div className="flex justify-center space-x-3">
|
||||||
{status === playerStatus.PLAYING ? <Player.Pip /> : null}
|
{status === playerStatus.PLAYING ? <Player.Pip /> : null}
|
||||||
<Player.Episodes />
|
<Player.Episodes />
|
||||||
{status === playerStatus.PLAYING ? <Player.Settings /> : null}
|
{status === playerStatus.PLAYING ? (
|
||||||
|
<>
|
||||||
|
<Player.Captions />
|
||||||
|
<Player.Settings />
|
||||||
|
</>
|
||||||
|
) : null}
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<Player.Fullscreen />
|
<Player.Fullscreen />
|
||||||
|
|
Loading…
Reference in a new issue