diff --git a/front/packages/models/src/resources/watch-info.ts b/front/packages/models/src/resources/watch-info.ts index 70e42414..0af76722 100644 --- a/front/packages/models/src/resources/watch-info.ts +++ b/front/packages/models/src/resources/watch-info.ts @@ -135,48 +135,58 @@ export type Chapter = z.infer; /** * The transcoder's info for this item. This include subtitles, fonts, chapters... */ -export const WatchInfoP = z.object({ - /** - * The sha1 of the video file. - */ - sha: z.string(), - /** - * The duration of the video (in seconds). - */ - length: z.number(), - /** - * The internal path of the video file. - */ - path: z.string(), - /** - * The extension used to store this video file. - */ - extension: z.string(), - /** - * The container of the video file of this episode. Common containers are mp4, mkv, avi and so on. - */ - container: z.string(), - /** - * The video track. - */ - video: VideoP, - /** - * The list of audio tracks. - */ - audios: z.array(AudioP), - /** - * The list of subtitles tracks. - */ - subtitles: z.array(SubtitleP), - /** - * The list of fonts that can be used to display subtitles. - */ - fonts: z.array(z.string().transform(imageFn)), - /** - * The list of chapters. See Chapter for more information. - */ - chapters: z.array(ChapterP), -}); +export const WatchInfoP = z + .object({ + /** + * The sha1 of the video file. + */ + sha: z.string(), + /** + * The duration of the video (in seconds). + */ + length: z.number(), + /** + * The internal path of the video file. + */ + path: z.string(), + /** + * The extension used to store this video file. + */ + extension: z.string(), + /** + * The container of the video file of this episode. Common containers are mp4, mkv, avi and so on. + */ + container: z.string(), + /** + * The video track. + */ + video: VideoP, + /** + * The list of audio tracks. + */ + audios: z.array(AudioP), + /** + * The list of subtitles tracks. + */ + subtitles: z.array(SubtitleP), + /** + * The list of fonts that can be used to display subtitles. + */ + fonts: z.array(z.string().transform(imageFn)), + /** + * The list of chapters. See Chapter for more information. + */ + chapters: z.array(ChapterP), + }) + .transform((x) => { + const hour = Math.floor(x.length / 3600); + const minutes = Math.ceil((x.length % 3600) / 60); + const duration = hour ? `${hour}h` : "" + `${minutes}m`; + return { + ...x, + duration, + }; + }); /** * A watch info for a video diff --git a/front/packages/ui/src/components/media-info.tsx b/front/packages/ui/src/components/media-info.tsx index 9b532912..ceb32bdd 100644 --- a/front/packages/ui/src/components/media-info.tsx +++ b/front/packages/ui/src/components/media-info.tsx @@ -23,11 +23,10 @@ import { Button, HR, P, Popup, Skeleton } from "@kyoo/primitives"; import { Fetch } from "../fetch"; import { useTranslation } from "react-i18next"; import { View } from "react-native"; -import { useYoshiki } from "yoshiki"; import { NativeCssFunc } from "yoshiki/src/native/type"; const MediaInfoTable = ({ - mediaInfo: { path, video, container, audios, subtitles }, + mediaInfo: { path, video, container, audios, subtitles, duration }, css, }: { css: NativeCssFunc; @@ -62,6 +61,7 @@ const MediaInfoTable = ({ { [t("mediainfo.file")]: path?.replace(/^\/video\//, ""), [t("mediainfo.container")]: container, + [t("mediainfo.duration")]: duration, }, { [t("mediainfo.video")]: video diff --git a/front/translations/en.json b/front/translations/en.json index 846b8253..73cf116b 100644 --- a/front/translations/en.json +++ b/front/translations/en.json @@ -183,6 +183,7 @@ "audio": "Audio", "subtitles": "Subtitles", "forced": "Forced", - "default": "Default" + "default": "Default", + "duration": "Duration" } } diff --git a/front/translations/fr.json b/front/translations/fr.json index 35e4ef80..36f10f1d 100644 --- a/front/translations/fr.json +++ b/front/translations/fr.json @@ -183,6 +183,7 @@ "audio": "Audio", "subtitles": "Sous titres", "forced": "Forcé", - "default": "Par Défaut" + "default": "Par Défaut", + "duration": "Duration" } }