diff --git a/front/packages/models/src/resources/watch-item.ts b/front/packages/models/src/resources/watch-item.ts
index 620530d4..e063f749 100644
--- a/front/packages/models/src/resources/watch-item.ts
+++ b/front/packages/models/src/resources/watch-item.ts
@@ -119,7 +119,7 @@ const WatchMovieP = z.preprocess(
/**
* The title of this episode.
*/
- name: z.string(),
+ name: z.string().nullable(),
/**
* The sumarry of this episode.
*/
@@ -179,15 +179,15 @@ const WatchEpisodeP = WatchMovieP.and(
/**
* The season in witch this episode is in.
*/
- seasonNumber: z.number(),
+ seasonNumber: z.number().nullable(),
/**
* The number of this episode is it's season.
*/
- episodeNumber: z.number(),
+ episodeNumber: z.number().nullable(),
/**
* The absolute number of this episode. It's an episode number that is not reset to 1 after a new season.
*/
- absoluteNumber: z.number(),
+ absoluteNumber: z.number().nullable(),
/**
* The episode that come before this one if you follow usual watch orders. If this is the first
* episode or this is a movie, it will be null.
diff --git a/front/packages/primitives/src/progress.tsx b/front/packages/primitives/src/progress.tsx
index e95b2c3c..aa44e61d 100644
--- a/front/packages/primitives/src/progress.tsx
+++ b/front/packages/primitives/src/progress.tsx
@@ -18,19 +18,21 @@
* along with Kyoo. If not, see .
*/
-import { Platform, View, ViewProps } from "react-native";
+import { ActivityIndicator, Platform, View } from "react-native";
import { Circle, Svg } from "react-native-svg";
-import { px, useYoshiki } from "yoshiki/native";
+import { px, Stylable, useYoshiki } from "yoshiki/native";
-// TODO: Use moti on native
export const CircularProgress = ({
size = 48,
tickness = 5,
color,
...props
-}: { size?: number; tickness?: number; color?: string } & ViewProps) => {
+}: { size?: number; tickness?: number; color?: string } & Stylable) => {
const { css, theme } = useYoshiki();
+ if (Platform.OS !== "web")
+ return ;
+
return (
*/}
- setMouseMoved(false)}
+ setMouseMoved(false)}
+ onPress={Platform.OS === "web" ? () => setPlay(!isPlaying) : show}
{...css({
flexGrow: 1,
// @ts-ignore
- // cursor: displayControls ? "unset" : "none",
bg: "black",
})}
>
+
>
);
};
diff --git a/front/packages/ui/src/player/state.tsx b/front/packages/ui/src/player/state.tsx
index c38a679b..1683bce7 100644
--- a/front/packages/ui/src/player/state.tsx
+++ b/front/packages/ui/src/player/state.tsx
@@ -20,7 +20,7 @@
import { Font, Track, WatchItem } from "@kyoo/models";
import { atom, useAtom, useSetAtom } from "jotai";
-import { RefObject, useEffect, useRef, useState } from "react";
+import { RefObject, useEffect, useLayoutEffect, useRef, useState } from "react";
import { createParam } from "solito";
import { ResizeMode, Video as NativeVideo, VideoProps } from "expo-av";
import SubtitleOctopus from "libass-wasm";
@@ -34,8 +34,7 @@ enum PlayMode {
const playModeAtom = atom(PlayMode.Direct);
-export const playAtom = atom(true);
-
+export const playAtom = atom(true);
export const loadAtom = atom(false);
export const progressAtom = atom(0);
export const bufferedAtom = atom(0);
@@ -69,10 +68,13 @@ export const [_, fullscreenAtom] = bakedAtom(false, async (_, set, value, baker)
let hls: Hls | null = null;
-export const Video = ({ links, ...props }: { links?: WatchItem["link"] } & VideoProps) => {
+export const Video = ({
+ links,
+ setError,
+ ...props
+}: { links?: WatchItem["link"]; setError: (error: string | undefined) => void } & VideoProps) => {
// const player = useRef(null);
// const setPlayer = useSetAtom(playerAtom);
- // const setLoad = useSetAtom(loadAtom);
// const setVolume = useSetAtom(_volumeAtom);
// const setMuted = useSetAtom(_mutedAtom);
// const setFullscreen = useSetAtom(fullscreenAtom);
@@ -80,6 +82,12 @@ export const Video = ({ links, ...props }: { links?: WatchItem["link"] } & Video
const ref = useRef(null);
const [isPlaying, setPlay] = useAtom(playAtom);
+ const setLoad = useSetAtom(loadAtom);
+
+ useLayoutEffect(() => {
+ setLoad(true);
+ }, [])
+
const [progress, setProgress] = useAtom(progressAtom);
const [buffered, setBuffered] = useAtom(bufferedAtom);
const [duration, setDuration] = useAtom(durationAtom);
@@ -134,9 +142,13 @@ export const Video = ({ links, ...props }: { links?: WatchItem["link"] } & Video
source={links ? { uri: links.direct } : undefined}
shouldPlay={isPlaying}
onPlaybackStatusUpdate={(status) => {
- // TODO: Handle error state
- if (!status.isLoaded) return;
+ if (!status.isLoaded) {
+ setLoad(true);
+ if (status.error) setError(status.error);
+ return;
+ }
+ setLoad(status.isPlaying !== status.shouldPlay);
setPlay(status.shouldPlay);
setProgress(status.positionMillis);
setBuffered(status.playableDurationMillis ?? 0);