diff --git a/front/packages/models/src/accounts.tsx b/front/packages/models/src/accounts.tsx
index aa4555a8..f2071a21 100644
--- a/front/packages/models/src/accounts.tsx
+++ b/front/packages/models/src/accounts.tsx
@@ -157,7 +157,7 @@ export const AccountProvider = ({
if (user.id !== selectedRef.current.id) return;
const nUser = { ...selectedRef.current, ...user };
updateAccount(nUser.id, nUser);
- }, [user]);
+ }, [user, userIsSuccess, userIsPlaceholder]);
const queryClient = useQueryClient();
const oldSelected = useRef<{ id: string; token: string } | null>(
diff --git a/front/packages/models/src/resources/watch-info.ts b/front/packages/models/src/resources/watch-info.ts
index 82e624bd..a0a10d86 100644
--- a/front/packages/models/src/resources/watch-info.ts
+++ b/front/packages/models/src/resources/watch-info.ts
@@ -18,21 +18,10 @@
* along with Kyoo. If not, see .
*/
-import i18next from "i18next";
import { z } from "zod";
import { imageFn } from "../traits";
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
*/
@@ -97,10 +86,7 @@ export const TrackP = z.object({
});
export type Track = z.infer;
-export const AudioP = TrackP.transform((x) => ({
- ...x,
- displayName: getDisplayName(x),
-}));
+export const AudioP = TrackP;
export type Audio = z.infer;
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)..
*/
link: z.string().transform(imageFn).nullable(),
-}).transform((x) => ({
- ...x,
- displayName: getDisplayName(x),
-}));
+});
export type Subtitle = z.infer;
export const ChapterP = z.object({
diff --git a/front/packages/primitives/src/themes/theme.tsx b/front/packages/primitives/src/themes/theme.tsx
index dfe6447b..7f1a37e5 100644
--- a/front/packages/primitives/src/themes/theme.tsx
+++ b/front/packages/primitives/src/themes/theme.tsx
@@ -27,7 +27,9 @@ import { useTheme, useYoshiki } from "yoshiki/native";
import "yoshiki/native";
import { catppuccin } from "./catppuccin";
-type FontList = Partial, string>>;
+type FontList = Partial<
+ Record, string>
+>;
type Mode = {
mode: "light" | "dark" | "auto";
diff --git a/front/packages/ui/src/components/context-menus.tsx b/front/packages/ui/src/components/context-menus.tsx
index af9e6673..ea2904b6 100644
--- a/front/packages/ui/src/components/context-menus.tsx
+++ b/front/packages/ui/src/components/context-menus.tsx
@@ -95,7 +95,7 @@ export const EpisodesContext = ({
{Object.values(WatchStatusV).map((x) => (
}`)}
onSelect={() => mutation.mutate(x)}
selected={x === status}
/>
diff --git a/front/packages/ui/src/components/media-info.tsx b/front/packages/ui/src/components/media-info.tsx
index ae7d9099..77b2dc65 100644
--- a/front/packages/ui/src/components/media-info.tsx
+++ b/front/packages/ui/src/components/media-info.tsx
@@ -31,16 +31,19 @@ import { useTranslation } from "react-i18next";
import { View } from "react-native";
import { useYoshiki } from "yoshiki/native";
import { Fetch } from "../fetch";
+import { useDisplayName } from "../utils";
const MediaInfoTable = ({
mediaInfo: { path, video, container, audios, subtitles, duration, size },
}: {
mediaInfo: Partial;
}) => {
+ const getDisplayName = useDisplayName();
const { t } = useTranslation();
const { css } = useYoshiki();
+
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) {
return undefined;
}
@@ -48,15 +51,16 @@ const MediaInfoTable = ({
return trackTable.reduce(
(collected, audioTrack, index) => {
// If there is only one track, we do not need to show an index
- collected[singleTrack ? t(s) : `${t(s)} ${index + 1}`] = [
- audioTrack.displayName,
- // Only show it if there is more than one track
- audioTrack.isDefault && !singleTrack ? t("mediainfo.default") : undefined,
- audioTrack.isForced ? t("mediainfo.forced") : undefined,
- audioTrack.codec,
- ]
- .filter((x) => x !== undefined)
- .join(" - ");
+ collected[singleTrack ? t(`mediainfo.${type}`) : `${t(`mediainfo.${type}`)} ${index + 1}`] =
+ [
+ getDisplayName(audioTrack),
+ // Only show it if there is more than one track
+ audioTrack.isDefault && !singleTrack ? t("mediainfo.default") : undefined,
+ audioTrack.isForced ? t("mediainfo.forced") : undefined,
+ audioTrack.codec,
+ ]
+ .filter((x) => x !== undefined)
+ .join(" - ");
return collected;
},
{} as Record,
@@ -81,10 +85,10 @@ const MediaInfoTable = ({
},
audios === undefined
? { [t("mediainfo.audio")]: undefined }
- : formatTrackTable(audios, "mediainfo.audio"),
+ : formatTrackTable(audios, "audio"),
subtitles === undefined
? { [t("mediainfo.subtitles")]: undefined }
- : formatTrackTable(subtitles, "mediainfo.subtitles"),
+ : formatTrackTable(subtitles, "subtitles"),
] as const
).filter((x) => x !== undefined) as Record[];
return (
diff --git a/front/packages/ui/src/player/components/hover.tsx b/front/packages/ui/src/player/components/hover.tsx
index db0f8b45..b4170e6f 100644
--- a/front/packages/ui/src/player/components/hover.tsx
+++ b/front/packages/ui/src/player/components/hover.tsx
@@ -295,6 +295,7 @@ export const HoverTouch = ({ children, ...props }: { children: ReactNode }) => {
playerWidth.current = e.nativeEvent.layout.width;
}}
{...css(
+ // @ts-expect-error Web only property (cursor: unset)
{
flexDirection: "row",
justifyContent: "center",
@@ -304,7 +305,6 @@ export const HoverTouch = ({ children, ...props }: { children: ReactNode }) => {
left: 0,
right: 0,
bottom: 0,
- // @ts-expect-error Web only property
cursor: hover ? "unset" : "none",
},
props,
diff --git a/front/packages/ui/src/player/components/right-buttons.tsx b/front/packages/ui/src/player/components/right-buttons.tsx
index 28ecb01f..cb790538 100644
--- a/front/packages/ui/src/player/components/right-buttons.tsx
+++ b/front/packages/ui/src/player/components/right-buttons.tsx
@@ -31,6 +31,7 @@ import { Platform, View } from "react-native";
import { type Stylable, useYoshiki } from "yoshiki/native";
import { fullscreenAtom, subtitleAtom } from "../state";
import { AudiosMenu, QualitiesMenu } from "../video";
+import { useDisplayName } from "../../utils";
export const RightButtons = ({
audios,
@@ -48,6 +49,7 @@ export const RightButtons = ({
} & Stylable) => {
const { css } = useYoshiki();
const { t } = useTranslation();
+ const getDisplayName = useDisplayName();
const [isFullscreen, setFullscreen] = useAtom(fullscreenAtom);
const [selectedSubtitle, setSubtitle] = useAtom(subtitleAtom);
@@ -72,7 +74,7 @@ export const RightButtons = ({
{subtitles.map((x) => (
setSubtitle(x)}
diff --git a/front/packages/ui/src/utils.ts b/front/packages/ui/src/utils.ts
new file mode 100644
index 00000000..26ea0b75
--- /dev/null
+++ b/front/packages/ui/src/utils.ts
@@ -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})`;
+ };
+};