diff --git a/front/packages/models/src/resources/watch-item.ts b/front/packages/models/src/resources/watch-item.ts index fdaa7e33..cf20b8dc 100644 --- a/front/packages/models/src/resources/watch-item.ts +++ b/front/packages/models/src/resources/watch-item.ts @@ -58,7 +58,7 @@ export const SubtitleP = TrackP.extend({ /* * The url of this track (only if this is a subtitle).. */ - link: z.string().transform(imageFn), + link: z.string().transform(imageFn).nullable(), }); export type Subtitle = z.infer; diff --git a/front/packages/primitives/src/menu.tsx b/front/packages/primitives/src/menu.tsx index da023622..7f9e6697 100644 --- a/front/packages/primitives/src/menu.tsx +++ b/front/packages/primitives/src/menu.tsx @@ -126,11 +126,13 @@ const MenuItem = ({ onSelect, href, icon, + disabled, ...props }: { label: string; selected?: boolean; left?: ReactElement; + disabled?: boolean; icon?: ComponentType; } & ({ onSelect: () => void; href?: undefined } | { href: string; onSelect?: undefined })) => { const { css, theme } = useYoshiki(); @@ -153,20 +155,29 @@ const MenuItem = ({ onSelect?.call(null); if (href) router.push(href); }} + disabled={disabled} {...css( - { - paddingHorizontal: ts(2), - width: percent(100), - height: ts(5), - alignItems: "center", - flexDirection: "row", - }, + [ + { + paddingHorizontal: ts(2), + width: percent(100), + height: ts(5), + alignItems: "center", + flexDirection: "row", + }, + disabled && {}, + ], props as any, )} > {left && left} {!left && icn && icn} -

+

{label}

{left && icn && icn} diff --git a/front/packages/primitives/src/menu.web.tsx b/front/packages/primitives/src/menu.web.tsx index 2b910297..b534603b 100644 --- a/front/packages/primitives/src/menu.web.tsx +++ b/front/packages/primitives/src/menu.web.tsx @@ -123,11 +123,13 @@ const MenuItem = ({ selected, onSelect, href, + disabled, ...props }: { label: string; icon?: ComponentType; left?: ReactElement; + disabled?: boolean; selected?: boolean; } & ({ onSelect: () => void; href?: undefined } | { href: string; onSelect?: undefined })) => { const { css: nCss } = useNativeYoshiki(); @@ -152,6 +154,7 @@ const MenuItem = ({ {label}

diff --git a/front/packages/ui/src/player/components/right-buttons.tsx b/front/packages/ui/src/player/components/right-buttons.tsx index 58c1b8ae..ae53a273 100644 --- a/front/packages/ui/src/player/components/right-buttons.tsx +++ b/front/packages/ui/src/player/components/right-buttons.tsx @@ -83,8 +83,9 @@ export const RightButtons = ({ {subtitles.map((x) => ( setSubtitle(x)} /> ))} diff --git a/front/packages/ui/src/player/video.web.tsx b/front/packages/ui/src/player/video.web.tsx index 39e64832..bf9a2f4c 100644 --- a/front/packages/ui/src/player/video.web.tsx +++ b/front/packages/ui/src/player/video.web.tsx @@ -18,7 +18,7 @@ * along with Kyoo. If not, see . */ -import { getToken, queryFn, Subtitle } from "@kyoo/models"; +import { getToken, Subtitle } from "@kyoo/models"; import { forwardRef, RefObject, @@ -222,7 +222,7 @@ const useSubtitle = ( subOcto = null; }; - if (!value) { + if (!value || !value.link) { removeHtmlSubtitle(); removeOctoSub(); } else if (value.codec === "vtt" || value.codec === "subrip") { @@ -233,7 +233,7 @@ const useSubtitle = ( track.kind = "subtitles"; track.label = getDisplayName(value); if (value.language) track.srclang = value.language; - track.src = value.codec === "subrip" ? await toWebVtt(value.link) : value.link; + track.src = value.codec === "subrip" ? await toWebVtt(value.link!) : value.link!; track.className = "subtitle_container"; track.default = true; track.onload = () => { diff --git a/transcoder/src/identify.rs b/transcoder/src/identify.rs index 2c0f82de..c2cdc57a 100644 --- a/transcoder/src/identify.rs +++ b/transcoder/src/identify.rs @@ -4,7 +4,6 @@ use sha1::{Digest, Sha1}; use std::{ collections::HashMap, fs, io, - iter::Map, path::PathBuf, process::Stdio, str::{self, FromStr}, @@ -84,7 +83,7 @@ pub struct Subtitle { /// Is this stream tagged as forced? (useful only for subtitles) pub is_forced: bool, /// The link to access this subtitle. - pub link: String, + pub link: Option, } #[derive(Serialize, ToSchema)] @@ -124,7 +123,8 @@ async fn extract(path: String, sha: &String, subs: &Vec) { } pub async fn identify(path: String) -> Result { - let extension_table: HashMap<&str, &str> = HashMap::from([("subrip", "srt"), ("ass", "ass")]); + let extension_table: HashMap<&str, &str> = + HashMap::from([("subrip", "srt"), ("ass", "ass"), ("vtt", "vtt")]); let mediainfo = Command::new("mediainfo") .arg("--Output=JSON") @@ -157,10 +157,7 @@ pub async fn identify(path: String) -> Result { } let extension = extension_table.get(codec.as_str()).map(|x| x.to_string()); Subtitle { - link: format!( - "/video/{sha}/subtitle/{index}.{ext}", - ext = extension.clone().unwrap_or(codec.clone()) - ), + link: extension.as_ref().map(|ext| format!("/video/{sha}/subtitle/{index}.{ext}")), index, title: a["Title"].as_str().map(|x| x.to_string()), language: a["Language"].as_str().map(|x| x.to_string()),