From 40eb846a685d05505c9fa6f3cd407efca01d8234 Mon Sep 17 00:00:00 2001
From: Pas <74743263+Pasithea0@users.noreply.github.com>
Date: Sun, 19 Oct 2025 18:32:58 -0600
Subject: [PATCH] Revert "Delete duplicate code and unify source selecting
views"
This reverts commit 28d03a06a584824295b87a2e7162e50aa828d7fc.
---
.../atoms/settings/SourceSelectingView.tsx | 9 +-
src/pages/parts/player/SourceSelectPart.tsx | 167 +++++++++++++++++-
2 files changed, 162 insertions(+), 14 deletions(-)
diff --git a/src/components/player/atoms/settings/SourceSelectingView.tsx b/src/components/player/atoms/settings/SourceSelectingView.tsx
index 33381010..6b058ee1 100644
--- a/src/components/player/atoms/settings/SourceSelectingView.tsx
+++ b/src/components/player/atoms/settings/SourceSelectingView.tsx
@@ -21,7 +21,6 @@ export interface SourceSelectionViewProps {
export interface EmbedSelectionViewProps {
id: string;
sourceId: string | null;
- onBack?: () => void;
}
export function EmbedOption(props: {
@@ -61,11 +60,7 @@ export function EmbedOption(props: {
);
}
-export function EmbedSelectionView({
- sourceId,
- id,
- onBack,
-}: EmbedSelectionViewProps) {
+export function EmbedSelectionView({ sourceId, id }: EmbedSelectionViewProps) {
const { t } = useTranslation();
const router = useOverlayRouter(id);
const { run, watching, notfound, loading, items, errored } =
@@ -131,7 +126,7 @@ export function EmbedSelectionView({
return (
<>
-
router.navigate("/source"))}>
+ router.navigate("/source")}>
{sourceName}
{content}
diff --git a/src/pages/parts/player/SourceSelectPart.tsx b/src/pages/parts/player/SourceSelectPart.tsx
index c5efdbae..cd371b7d 100644
--- a/src/pages/parts/player/SourceSelectPart.tsx
+++ b/src/pages/parts/player/SourceSelectPart.tsx
@@ -1,20 +1,164 @@
import { ScrapeMedia } from "@p-stream/providers";
-import React from "react";
+import React, { ReactNode, useEffect, useMemo, useRef } from "react";
import { useTranslation } from "react-i18next";
+import { getCachedMetadata } from "@/backend/helpers/providerApi";
+import { Loading } from "@/components/layout/Loading";
import {
- EmbedSelectionView,
- SourceSelectionView,
-} from "@/components/player/atoms/settings/SourceSelectingView";
+ useEmbedScraping,
+ useSourceScraping,
+} from "@/components/player/hooks/useSourceSelection";
import { Menu } from "@/components/player/internals/ContextMenu";
+import { SelectableLink } from "@/components/player/internals/ContextMenu/Links";
+import { usePreferencesStore } from "@/stores/preferences";
+
+// Embed option component
+function EmbedOption(props: {
+ embedId: string;
+ url: string;
+ sourceId: string;
+ routerId: string;
+}) {
+ const { t } = useTranslation();
+ const unknownEmbedName = t("player.menus.sources.unknownOption");
+
+ const embedName = useMemo(() => {
+ if (!props.embedId) return unknownEmbedName;
+ const sourceMeta = getCachedMetadata().find((s) => s.id === props.embedId);
+ return sourceMeta?.name ?? unknownEmbedName;
+ }, [props.embedId, unknownEmbedName]);
+
+ const { run, errored, loading } = useEmbedScraping(
+ props.routerId,
+ props.sourceId,
+ props.url,
+ props.embedId,
+ );
+
+ return (
+
+
+ {embedName}
+
+
+ );
+}
+
+// Embed selection view (when a source is selected)
+function EmbedSelectionView(props: {
+ sourceId: string;
+ routerId: string;
+ onBack: () => void;
+}) {
+ const { t } = useTranslation();
+ const { run, notfound, loading, items, errored } = useSourceScraping(
+ props.sourceId,
+ props.routerId,
+ );
+
+ const sourceName = useMemo(() => {
+ if (!props.sourceId) return "...";
+ const sourceMeta = getCachedMetadata().find((s) => s.id === props.sourceId);
+ return sourceMeta?.name ?? "...";
+ }, [props.sourceId]);
+
+ const lastSourceId = useRef(null);
+ useEffect(() => {
+ if (lastSourceId.current === props.sourceId) return;
+ lastSourceId.current = props.sourceId;
+ if (!props.sourceId) return;
+ run();
+ }, [run, props.sourceId]);
+
+ let content: ReactNode = null;
+ if (loading)
+ content = (
+
+
+
+ );
+ else if (notfound)
+ content = (
+
+ {t("player.menus.sources.noStream.text")}
+
+ );
+ else if (items?.length === 0)
+ content = (
+
+ {t("player.menus.sources.noEmbeds.text")}
+
+ );
+ else if (errored)
+ content = (
+
+ {t("player.menus.sources.failed.text")}
+
+ );
+ else if (items && props.sourceId)
+ content = items.map((v) => (
+
+ ));
+
+ return (
+ <>
+ {sourceName}
+ {content}
+ >
+ );
+}
// Main source selection view
-export function SourceSelectPart(_props: { media: ScrapeMedia }) {
+export function SourceSelectPart(props: { media: ScrapeMedia }) {
const { t } = useTranslation();
const [selectedSourceId, setSelectedSourceId] = React.useState(
null,
);
const routerId = "manualSourceSelect";
+ const preferredSourceOrder = usePreferencesStore((s) => s.sourceOrder);
+ const enableSourceOrder = usePreferencesStore((s) => s.enableSourceOrder);
+
+ const sources = useMemo(() => {
+ const metaType = props.media.type;
+ if (!metaType) return [];
+ const allSources = getCachedMetadata()
+ .filter((v) => v.type === "source")
+ .filter((v) => v.mediaTypes?.includes(metaType));
+
+ if (!enableSourceOrder || preferredSourceOrder.length === 0) {
+ return allSources;
+ }
+
+ // Sort sources according to preferred order
+ const orderedSources = [];
+ const remainingSources = [...allSources];
+
+ // Add sources in preferred order
+ for (const sourceId of preferredSourceOrder) {
+ const sourceIndex = remainingSources.findIndex((s) => s.id === sourceId);
+ if (sourceIndex !== -1) {
+ orderedSources.push(remainingSources[sourceIndex]);
+ remainingSources.splice(sourceIndex, 1);
+ }
+ }
+
+ // Add remaining sources that weren't in the preferred order
+ orderedSources.push(...remainingSources);
+
+ return orderedSources;
+ }, [props.media.type, preferredSourceOrder, enableSourceOrder]);
if (selectedSourceId) {
return (
@@ -23,7 +167,7 @@ export function SourceSelectPart(_props: { media: ScrapeMedia }) {
setSelectedSourceId(null)}
/>
@@ -37,7 +181,16 @@ export function SourceSelectPart(_props: { media: ScrapeMedia }) {
{t("player.menus.sources.title")}
-
+
+ {sources.map((v) => (
+ setSelectedSourceId(v.id)}
+ >
+ {v.name}
+
+ ))}
+