/* * Kyoo - A portable and vast media library solution. * Copyright (c) Kyoo. * * See AUTHORS.md and LICENSE file in the project root for full license information. * * Kyoo is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * Kyoo is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Kyoo. If not, see . */ import { type Audio, type QueryIdentifier, type Subtitle, type WatchInfo, WatchInfoP, } from "@kyoo/models"; import { Button, HR, P, Popup, Skeleton } from "@kyoo/primitives"; import { Fragment } from "react"; import { useTranslation } from "react-i18next"; import { View } from "react-native"; import { useYoshiki } from "yoshiki/native"; import { Fetch } from "../fetch"; const MediaInfoTable = ({ mediaInfo: { path, video, container, audios, subtitles, duration, size }, }: { mediaInfo: Partial; }) => { const { t } = useTranslation(); const { css } = useYoshiki(); const formatBitrate = (b: number) => `${(b / 1000000).toFixed(2)} Mbps`; const formatTrackTable = (trackTable: (Audio | Subtitle)[], s: string) => { if (trackTable.length === 0) { return undefined; } const singleTrack = trackTable.length === 1; 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(" - "); return collected; }, {} as Record, ); }; const table = ( [ { [t("mediainfo.file")]: path?.replace(/^\/video\//, ""), [t("mediainfo.container")]: container !== null ? container : t("mediainfo.nocontainer"), [t("mediainfo.duration")]: duration, [t("mediainfo.size")]: size, }, { [t("mediainfo.video")]: video ? `${video.width}x${video.height} (${video.quality}) - ${formatBitrate( video.bitrate, )} - ${video.codec}` : video === null ? t("mediainfo.novideo") : undefined, }, audios === undefined ? { [t("mediainfo.audio")]: undefined } : formatTrackTable(audios, "mediainfo.audio"), subtitles === undefined ? { [t("mediainfo.subtitles")]: undefined } : formatTrackTable(subtitles, "mediainfo.subtitles"), ] as const ).filter((x) => x !== undefined) as Record[]; return ( {table.map((g) => Object.entries(g).map(([label, value], index, l) => (

{label}

{value ?

{value}

: undefined}
{index === l.length - 1 &&
}
)), )}
); }; export const MediaInfoPopup = ({ close, mediaType, mediaSlug, }: { close: () => void; mediaType: "episode" | "movie"; mediaSlug: string; }) => { return ( {(mediaInfo) => }