mirror of
https://github.com/sussy-code/smov.git
synced 2024-12-29 16:07:40 +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>
|
||||
</OverlayPage>
|
||||
<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>
|
||||
<CaptionsView id={id} />
|
||||
</Menu.CardWithScrollable>
|
||||
|
@ -68,6 +74,17 @@ function SettingsOverlay({ id }: { id: string }) {
|
|||
<OpenSubtitlesCaptionView id={id} />
|
||||
</Menu.Card>
|
||||
</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}>
|
||||
<Menu.Card>
|
||||
<CaptionSettingsView id={id} />
|
||||
|
|
|
@ -16,3 +16,4 @@ export * from "./VolumeChangedPopout";
|
|||
export * from "./NextEpisodeButton";
|
||||
export * from "./Chromecast";
|
||||
export * from "./CastingNotification";
|
||||
export * from "./Captions";
|
||||
|
|
|
@ -120,7 +120,13 @@ function useSubtitleList(subs: CaptionListItem[], searchQuery: string) {
|
|||
}, [subs, searchQuery, unknownChoice]);
|
||||
}
|
||||
|
||||
export function CaptionsView({ id }: { id: string }) {
|
||||
export function CaptionsView({
|
||||
id,
|
||||
backLink,
|
||||
}: {
|
||||
id: string;
|
||||
backLink?: true;
|
||||
}) {
|
||||
const { t } = useTranslation();
|
||||
const router = useOverlayRouter(id);
|
||||
const selectedCaptionId = usePlayerStore((s) => s.caption.selected?.id);
|
||||
|
@ -213,20 +219,36 @@ export function CaptionsView({ id }: { id: string }) {
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<Menu.BackLink
|
||||
onClick={() => router.navigate("/")}
|
||||
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.BackLink>
|
||||
{backLink ? (
|
||||
<Menu.BackLink
|
||||
onClick={() => router.navigate("/")}
|
||||
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.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>
|
||||
<FileDropHandler
|
||||
className={`transition duration-300 ${dragging ? "opacity-20" : ""}`}
|
||||
|
@ -239,7 +261,13 @@ export function CaptionsView({ id }: { id: string }) {
|
|||
<Input value={searchQuery} onInput={setSearchQuery} />
|
||||
<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"
|
||||
>
|
||||
<Icon icon={Icons.WEB} />
|
||||
|
@ -259,7 +287,13 @@ export function CaptionsView({ id }: { id: string }) {
|
|||
{t("player.menus.subtitles.empty")}
|
||||
<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"
|
||||
>
|
||||
{t("player.menus.subtitles.scrapeButton")}
|
||||
|
|
|
@ -73,7 +73,13 @@ function useSubtitleList(subs: CaptionListItem[], searchQuery: string) {
|
|||
}, [subs, searchQuery, unknownChoice]);
|
||||
}
|
||||
|
||||
export function OpenSubtitlesCaptionView({ id }: { id: string }) {
|
||||
export function OpenSubtitlesCaptionView({
|
||||
id,
|
||||
overlayBackLink,
|
||||
}: {
|
||||
id: string;
|
||||
overlayBackLink?: boolean;
|
||||
}) {
|
||||
const { t } = useTranslation();
|
||||
const router = useOverlayRouter(id);
|
||||
const selectedCaptionId = usePlayerStore((s) => s.caption.selected?.id);
|
||||
|
@ -124,7 +130,11 @@ export function OpenSubtitlesCaptionView({ id }: { id: string }) {
|
|||
return (
|
||||
<>
|
||||
<div>
|
||||
<Menu.BackLink onClick={() => router.navigate("/captions")}>
|
||||
<Menu.BackLink
|
||||
onClick={() =>
|
||||
router.navigate(overlayBackLink ? "/captionsOverlay" : "/captions")
|
||||
}
|
||||
>
|
||||
{t("player.menus.subtitles.OpenSubtitlesChoice")}
|
||||
</Menu.BackLink>
|
||||
</div>
|
||||
|
|
|
@ -111,7 +111,10 @@ export function PlayerPart(props: PlayerPartProps) {
|
|||
) : null}
|
||||
{status === playerStatus.PLAYBACK_ERROR ||
|
||||
status === playerStatus.PLAYING ? (
|
||||
<Player.Settings />
|
||||
<>
|
||||
<Player.Captions />
|
||||
<Player.Settings />
|
||||
</>
|
||||
) : null}
|
||||
<Player.Fullscreen />
|
||||
</div>
|
||||
|
@ -121,7 +124,12 @@ export function PlayerPart(props: PlayerPartProps) {
|
|||
<div className="flex justify-center space-x-3">
|
||||
{status === playerStatus.PLAYING ? <Player.Pip /> : null}
|
||||
<Player.Episodes />
|
||||
{status === playerStatus.PLAYING ? <Player.Settings /> : null}
|
||||
{status === playerStatus.PLAYING ? (
|
||||
<>
|
||||
<Player.Captions />
|
||||
<Player.Settings />
|
||||
</>
|
||||
) : null}
|
||||
</div>
|
||||
<div>
|
||||
<Player.Fullscreen />
|
||||
|
|
Loading…
Reference in a new issue