diff --git a/src/assets/locales/en.json b/src/assets/locales/en.json
index 76d045c62..f1f2c9b4b 100644
--- a/src/assets/locales/en.json
+++ b/src/assets/locales/en.json
@@ -776,12 +776,17 @@
"original": {
"cardTitle": "Original File",
"cardDesc": "Download the video file directly",
- "description": "Download the original video file from the source. This option will be huge in file size (up to 80gb+).",
- "downloadButton": "wip"
+ "description": "Download the original video file from the source. This option will be massive in file size (up to 80gb+) due to the files being high quality and contain multiple dub/sub options in one .",
+ "downloadButton": "Download",
+ "loading": "Fetching available downloads...",
+ "error": "Couldn't load downloads right now. Try again later.",
+ "noResults": "No direct downloads available for this title yet.",
+ "selfhosted": "This feature is only available on pstream.net"
},
"stream": {
"cardTitle": "Stream Link",
- "cardDesc": "Copy the HLS playlist URL"
+ "cardDesc": "Copy the HLS playlist URL",
+ "description": "Copy the streaming link (HLS playlist) for use with external tools. This is a temporary link from the current stream source and may expire."
},
"onAndroid": {
"1": "To download on Android, click the download button then, on the new page, tap and hold on the video, then select save.",
diff --git a/src/components/player/atoms/settings/Downloads.tsx b/src/components/player/atoms/settings/Downloads.tsx
index a417f2376..2df3c2825 100644
--- a/src/components/player/atoms/settings/Downloads.tsx
+++ b/src/components/player/atoms/settings/Downloads.tsx
@@ -1,4 +1,6 @@
-import { useCallback, useMemo } from "react";
+import { fetchGridData } from "@p-stream/providers";
+import type { GridData } from "@p-stream/providers";
+import { useCallback, useEffect, useMemo, useState } from "react";
import { Trans, useTranslation } from "react-i18next";
import { useCopyToClipboard } from "react-use";
@@ -11,6 +13,9 @@ import { convertSubtitlesToSrtDataurl } from "@/components/player/utils/captions
import { useIsDesktopApp } from "@/hooks/useIsDesktopApp";
import { useOverlayRouter } from "@/hooks/useOverlayRouter";
import { usePlayerStore } from "@/stores/player/store";
+// I swear
+
+// If any of you abuse my api I swear to god I'll turn it down and never make shit again so please don't. Y'all arent supposed to use this.
export function useDownloadLink() {
const source = usePlayerStore((s) => s.source);
@@ -51,7 +56,30 @@ function StyleTrans(props: { k: string }) {
function OriginalFileView({ id }: { id: string }) {
const router = useOverlayRouter(id);
const { t } = useTranslation();
+ const meta = usePlayerStore((s) => s.meta);
const selectedCaption = usePlayerStore((s) => s.caption?.selected);
+ const [data, setData] = useState(null);
+ const [loading, setLoading] = useState(false);
+ const [error, setError] = useState(false);
+
+ const tmdbId = meta?.tmdbId;
+
+ useEffect(() => {
+ if (!tmdbId) return;
+ let cancelled = false;
+ setLoading(true);
+ setError(false);
+
+ fetchGridData(tmdbId).then((json) => {
+ if (!cancelled) setData(json);
+ }).catch(() => {
+ if (!cancelled) setError(true);
+ }).finally(() => {
+ if (!cancelled) setLoading(false);
+ });
+
+ return () => { cancelled = true; };
+ }, [tmdbId]);
const openSubtitleDownload = useCallback(() => {
const dataUrl = selectedCaption
@@ -61,18 +89,55 @@ function OriginalFileView({ id }: { id: string }) {
window.open(dataUrl);
}, [selectedCaption]);
+ const hasDownloads = data?.downloads && data.downloads.length > 0;
+
return (
<>
router.navigate("/download")}>
{t("player.menus.downloads.original.cardTitle")}
-
- {t("player.menus.downloads.original.description")}
-
-
+ {loading && (
+
+ {t("player.menus.downloads.original.loading")}
+
+ )}
+ {error && (
+
+ {t("player.menus.downloads.original.error")}
+
+ )}
+ {!loading && !error && !hasDownloads && (
+
+ {t("player.menus.downloads.original.noResults")}
+
+ )}
+ {hasDownloads && data?.downloads.map((dl, i) => (
+