mirror of
https://github.com/zoriya/Kyoo.git
synced 2025-05-24 02:02:36 -04:00
Cleanup type errors
This commit is contained in:
parent
0124275d8c
commit
150a9dbd53
@ -157,7 +157,7 @@ export const AccountProvider = ({
|
|||||||
if (user.id !== selectedRef.current.id) return;
|
if (user.id !== selectedRef.current.id) return;
|
||||||
const nUser = { ...selectedRef.current, ...user };
|
const nUser = { ...selectedRef.current, ...user };
|
||||||
updateAccount(nUser.id, nUser);
|
updateAccount(nUser.id, nUser);
|
||||||
}, [user]);
|
}, [user, userIsSuccess, userIsPlaceholder]);
|
||||||
|
|
||||||
const queryClient = useQueryClient();
|
const queryClient = useQueryClient();
|
||||||
const oldSelected = useRef<{ id: string; token: string } | null>(
|
const oldSelected = useRef<{ id: string; token: string } | null>(
|
||||||
|
@ -18,21 +18,10 @@
|
|||||||
* along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
* along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import i18next from "i18next";
|
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
import { imageFn } from "../traits";
|
import { imageFn } from "../traits";
|
||||||
import { QualityP } from "./quality";
|
import { QualityP } from "./quality";
|
||||||
|
|
||||||
const getDisplayName = (sub: Track) => {
|
|
||||||
const languageNames = new Intl.DisplayNames([i18next.language ?? "en"], { type: "language" });
|
|
||||||
const lng = sub.language ? languageNames.of(sub.language) : undefined;
|
|
||||||
|
|
||||||
if (lng && sub.title && sub.title !== lng) return `${lng} - ${sub.title}`;
|
|
||||||
if (lng) return lng;
|
|
||||||
if (sub.title) return sub.title;
|
|
||||||
return `Unknown (${sub.index})`;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A Video track
|
* A Video track
|
||||||
*/
|
*/
|
||||||
@ -97,10 +86,7 @@ export const TrackP = z.object({
|
|||||||
});
|
});
|
||||||
export type Track = z.infer<typeof TrackP>;
|
export type Track = z.infer<typeof TrackP>;
|
||||||
|
|
||||||
export const AudioP = TrackP.transform((x) => ({
|
export const AudioP = TrackP;
|
||||||
...x,
|
|
||||||
displayName: getDisplayName(x),
|
|
||||||
}));
|
|
||||||
export type Audio = z.infer<typeof AudioP>;
|
export type Audio = z.infer<typeof AudioP>;
|
||||||
|
|
||||||
export const SubtitleP = TrackP.extend({
|
export const SubtitleP = TrackP.extend({
|
||||||
@ -108,10 +94,7 @@ export const SubtitleP = TrackP.extend({
|
|||||||
* The url of this track (only if this is a subtitle)..
|
* The url of this track (only if this is a subtitle)..
|
||||||
*/
|
*/
|
||||||
link: z.string().transform(imageFn).nullable(),
|
link: z.string().transform(imageFn).nullable(),
|
||||||
}).transform((x) => ({
|
});
|
||||||
...x,
|
|
||||||
displayName: getDisplayName(x),
|
|
||||||
}));
|
|
||||||
export type Subtitle = z.infer<typeof SubtitleP>;
|
export type Subtitle = z.infer<typeof SubtitleP>;
|
||||||
|
|
||||||
export const ChapterP = z.object({
|
export const ChapterP = z.object({
|
||||||
|
@ -27,7 +27,9 @@ import { useTheme, useYoshiki } from "yoshiki/native";
|
|||||||
import "yoshiki/native";
|
import "yoshiki/native";
|
||||||
import { catppuccin } from "./catppuccin";
|
import { catppuccin } from "./catppuccin";
|
||||||
|
|
||||||
type FontList = Partial<Record<Exclude<TextStyle["fontWeight"], null | undefined>, string>>;
|
type FontList = Partial<
|
||||||
|
Record<Exclude<TextStyle["fontWeight"], null | undefined | number>, string>
|
||||||
|
>;
|
||||||
|
|
||||||
type Mode = {
|
type Mode = {
|
||||||
mode: "light" | "dark" | "auto";
|
mode: "light" | "dark" | "auto";
|
||||||
|
@ -95,7 +95,7 @@ export const EpisodesContext = ({
|
|||||||
{Object.values(WatchStatusV).map((x) => (
|
{Object.values(WatchStatusV).map((x) => (
|
||||||
<Menu.Item
|
<Menu.Item
|
||||||
key={x}
|
key={x}
|
||||||
label={t(`show.watchlistMark.${x.toLowerCase()}`)}
|
label={t(`show.watchlistMark.${x.toLowerCase() as Lowercase<WatchStatusV>}`)}
|
||||||
onSelect={() => mutation.mutate(x)}
|
onSelect={() => mutation.mutate(x)}
|
||||||
selected={x === status}
|
selected={x === status}
|
||||||
/>
|
/>
|
||||||
|
@ -31,16 +31,19 @@ import { useTranslation } from "react-i18next";
|
|||||||
import { View } from "react-native";
|
import { View } from "react-native";
|
||||||
import { useYoshiki } from "yoshiki/native";
|
import { useYoshiki } from "yoshiki/native";
|
||||||
import { Fetch } from "../fetch";
|
import { Fetch } from "../fetch";
|
||||||
|
import { useDisplayName } from "../utils";
|
||||||
|
|
||||||
const MediaInfoTable = ({
|
const MediaInfoTable = ({
|
||||||
mediaInfo: { path, video, container, audios, subtitles, duration, size },
|
mediaInfo: { path, video, container, audios, subtitles, duration, size },
|
||||||
}: {
|
}: {
|
||||||
mediaInfo: Partial<WatchInfo>;
|
mediaInfo: Partial<WatchInfo>;
|
||||||
}) => {
|
}) => {
|
||||||
|
const getDisplayName = useDisplayName();
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const { css } = useYoshiki();
|
const { css } = useYoshiki();
|
||||||
|
|
||||||
const formatBitrate = (b: number) => `${(b / 1000000).toFixed(2)} Mbps`;
|
const formatBitrate = (b: number) => `${(b / 1000000).toFixed(2)} Mbps`;
|
||||||
const formatTrackTable = (trackTable: (Audio | Subtitle)[], s: string) => {
|
const formatTrackTable = (trackTable: (Audio | Subtitle)[], type: "subtitles" | "audio") => {
|
||||||
if (trackTable.length === 0) {
|
if (trackTable.length === 0) {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
@ -48,15 +51,16 @@ const MediaInfoTable = ({
|
|||||||
return trackTable.reduce(
|
return trackTable.reduce(
|
||||||
(collected, audioTrack, index) => {
|
(collected, audioTrack, index) => {
|
||||||
// If there is only one track, we do not need to show an index
|
// If there is only one track, we do not need to show an index
|
||||||
collected[singleTrack ? t(s) : `${t(s)} ${index + 1}`] = [
|
collected[singleTrack ? t(`mediainfo.${type}`) : `${t(`mediainfo.${type}`)} ${index + 1}`] =
|
||||||
audioTrack.displayName,
|
[
|
||||||
// Only show it if there is more than one track
|
getDisplayName(audioTrack),
|
||||||
audioTrack.isDefault && !singleTrack ? t("mediainfo.default") : undefined,
|
// Only show it if there is more than one track
|
||||||
audioTrack.isForced ? t("mediainfo.forced") : undefined,
|
audioTrack.isDefault && !singleTrack ? t("mediainfo.default") : undefined,
|
||||||
audioTrack.codec,
|
audioTrack.isForced ? t("mediainfo.forced") : undefined,
|
||||||
]
|
audioTrack.codec,
|
||||||
.filter((x) => x !== undefined)
|
]
|
||||||
.join(" - ");
|
.filter((x) => x !== undefined)
|
||||||
|
.join(" - ");
|
||||||
return collected;
|
return collected;
|
||||||
},
|
},
|
||||||
{} as Record<string, string | undefined>,
|
{} as Record<string, string | undefined>,
|
||||||
@ -81,10 +85,10 @@ const MediaInfoTable = ({
|
|||||||
},
|
},
|
||||||
audios === undefined
|
audios === undefined
|
||||||
? { [t("mediainfo.audio")]: undefined }
|
? { [t("mediainfo.audio")]: undefined }
|
||||||
: formatTrackTable(audios, "mediainfo.audio"),
|
: formatTrackTable(audios, "audio"),
|
||||||
subtitles === undefined
|
subtitles === undefined
|
||||||
? { [t("mediainfo.subtitles")]: undefined }
|
? { [t("mediainfo.subtitles")]: undefined }
|
||||||
: formatTrackTable(subtitles, "mediainfo.subtitles"),
|
: formatTrackTable(subtitles, "subtitles"),
|
||||||
] as const
|
] as const
|
||||||
).filter((x) => x !== undefined) as Record<string, string | undefined>[];
|
).filter((x) => x !== undefined) as Record<string, string | undefined>[];
|
||||||
return (
|
return (
|
||||||
|
@ -295,6 +295,7 @@ export const HoverTouch = ({ children, ...props }: { children: ReactNode }) => {
|
|||||||
playerWidth.current = e.nativeEvent.layout.width;
|
playerWidth.current = e.nativeEvent.layout.width;
|
||||||
}}
|
}}
|
||||||
{...css(
|
{...css(
|
||||||
|
// @ts-expect-error Web only property (cursor: unset)
|
||||||
{
|
{
|
||||||
flexDirection: "row",
|
flexDirection: "row",
|
||||||
justifyContent: "center",
|
justifyContent: "center",
|
||||||
@ -304,7 +305,6 @@ export const HoverTouch = ({ children, ...props }: { children: ReactNode }) => {
|
|||||||
left: 0,
|
left: 0,
|
||||||
right: 0,
|
right: 0,
|
||||||
bottom: 0,
|
bottom: 0,
|
||||||
// @ts-expect-error Web only property
|
|
||||||
cursor: hover ? "unset" : "none",
|
cursor: hover ? "unset" : "none",
|
||||||
},
|
},
|
||||||
props,
|
props,
|
||||||
|
@ -31,6 +31,7 @@ import { Platform, View } from "react-native";
|
|||||||
import { type Stylable, useYoshiki } from "yoshiki/native";
|
import { type Stylable, useYoshiki } from "yoshiki/native";
|
||||||
import { fullscreenAtom, subtitleAtom } from "../state";
|
import { fullscreenAtom, subtitleAtom } from "../state";
|
||||||
import { AudiosMenu, QualitiesMenu } from "../video";
|
import { AudiosMenu, QualitiesMenu } from "../video";
|
||||||
|
import { useDisplayName } from "../../utils";
|
||||||
|
|
||||||
export const RightButtons = ({
|
export const RightButtons = ({
|
||||||
audios,
|
audios,
|
||||||
@ -48,6 +49,7 @@ export const RightButtons = ({
|
|||||||
} & Stylable) => {
|
} & Stylable) => {
|
||||||
const { css } = useYoshiki();
|
const { css } = useYoshiki();
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
const getDisplayName = useDisplayName();
|
||||||
const [isFullscreen, setFullscreen] = useAtom(fullscreenAtom);
|
const [isFullscreen, setFullscreen] = useAtom(fullscreenAtom);
|
||||||
const [selectedSubtitle, setSubtitle] = useAtom(subtitleAtom);
|
const [selectedSubtitle, setSubtitle] = useAtom(subtitleAtom);
|
||||||
|
|
||||||
@ -72,7 +74,7 @@ export const RightButtons = ({
|
|||||||
{subtitles.map((x) => (
|
{subtitles.map((x) => (
|
||||||
<Menu.Item
|
<Menu.Item
|
||||||
key={x.index}
|
key={x.index}
|
||||||
label={x.link ? x.displayName : `${x.displayName} (${x.codec})`}
|
label={x.link ? getDisplayName(x) : `${getDisplayName(x)} (${x.codec})`}
|
||||||
selected={selectedSubtitle === x}
|
selected={selectedSubtitle === x}
|
||||||
disabled={!x.link}
|
disabled={!x.link}
|
||||||
onSelect={() => setSubtitle(x)}
|
onSelect={() => setSubtitle(x)}
|
||||||
|
16
front/packages/ui/src/utils.ts
Normal file
16
front/packages/ui/src/utils.ts
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
import type { Track } from "@kyoo/models";
|
||||||
|
import { useTranslation } from "react-i18next";
|
||||||
|
|
||||||
|
export const useDisplayName = () => {
|
||||||
|
const { i18n } = useTranslation();
|
||||||
|
|
||||||
|
return (sub: Track) => {
|
||||||
|
const languageNames = new Intl.DisplayNames([i18n.language ?? "en"], { type: "language" });
|
||||||
|
const lng = sub.language ? languageNames.of(sub.language) : undefined;
|
||||||
|
|
||||||
|
if (lng && sub.title && sub.title !== lng) return `${lng} - ${sub.title}`;
|
||||||
|
if (lng) return lng;
|
||||||
|
if (sub.title) return sub.title;
|
||||||
|
return `Unknown (${sub.index})`;
|
||||||
|
};
|
||||||
|
};
|
Loading…
x
Reference in New Issue
Block a user