Display when subtitles are invalid on the web app

This commit is contained in:
Zoe Roux 2023-08-01 18:28:34 +09:00
parent 0f59798e73
commit 45b18eb8e6
6 changed files with 41 additions and 24 deletions

View File

@ -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<typeof SubtitleP>;

View File

@ -126,11 +126,13 @@ const MenuItem = ({
onSelect,
href,
icon,
disabled,
...props
}: {
label: string;
selected?: boolean;
left?: ReactElement;
disabled?: boolean;
icon?: ComponentType<SvgProps>;
} & ({ 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}
<P {...css({ paddingLeft: ts(2) + +!(icon || selected || left) * px(24), flexGrow: 1 })}>
<P
{...css([
{ paddingLeft: ts(2) + +!(icon || selected || left) * px(24), flexGrow: 1 },
disabled && { color: theme.overlay0 },
])}
>
{label}
</P>
{left && icn && icn}

View File

@ -123,11 +123,13 @@ const MenuItem = ({
selected,
onSelect,
href,
disabled,
...props
}: {
label: string;
icon?: ComponentType<SvgProps>;
left?: ReactElement;
disabled?: boolean;
selected?: boolean;
} & ({ onSelect: () => void; href?: undefined } | { href: string; onSelect?: undefined })) => {
const { css: nCss } = useNativeYoshiki();
@ -152,6 +154,7 @@ const MenuItem = ({
<Item
onSelect={onSelect}
href={href}
disabled={disabled}
{...css(
{
display: "flex",
@ -167,10 +170,15 @@ const MenuItem = ({
{!left && icn && icn}
{
<P
{...nCss({
paddingLeft: ts((icon || selected || left) ? 0 : 2 + +!!icon),
flexGrow: 1,
})}
{...nCss([
{
paddingLeft: ts(icon || selected || left ? 0 : 2 + +!!icon),
flexGrow: 1,
},
disabled && {
color: theme.overlay0,
},
])}
>
{label}
</P>

View File

@ -83,8 +83,9 @@ export const RightButtons = ({
{subtitles.map((x) => (
<Menu.Item
key={x.index}
label={getDisplayName(x)}
label={x.link ? getDisplayName(x) : `${getDisplayName(x)} (${x.codec})`}
selected={selectedSubtitle === x}
disabled={!x.link}
onSelect={() => setSubtitle(x)}
/>
))}

View File

@ -18,7 +18,7 @@
* along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
*/
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 = () => {

View File

@ -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<String>,
}
#[derive(Serialize, ToSchema)]
@ -124,7 +123,8 @@ async fn extract(path: String, sha: &String, subs: &Vec<Subtitle>) {
}
pub async fn identify(path: String) -> Result<MediaInfo, std::io::Error> {
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<MediaInfo, std::io::Error> {
}
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()),