diff --git a/src/hooks/useProviderScrape.tsx b/src/hooks/useProviderScrape.tsx index 9191b1dc..d208b82c 100644 --- a/src/hooks/useProviderScrape.tsx +++ b/src/hooks/useProviderScrape.tsx @@ -175,28 +175,12 @@ export function useScrape() { const failedSources = playerState.failedSources; const failedEmbeds = playerState.failedEmbeds; - // Get media-specific failures - const mediaFailureKey = { - type: media.type, - tmdbId: media.tmdbId, - ...(media.type === "show" && media.episode && media.season - ? { - seasonNumber: media.season.number, - episodeNumber: media.episode.number, - } - : {}), - }; - const mediaFailures = playerState.getMediaFailures(mediaFailureKey); - const mediaFailedSources = mediaFailures.failedSources; - const mediaFailedEmbeds = mediaFailures.failedEmbeds; - // Start with all available sources (filtered by disabled and failed ones) let baseSourceOrder = allSources .filter( (source) => !(disabledSources || []).includes(source.id) && - !failedSources.includes(source.id) && - !mediaFailedSources.includes(source.id), + !failedSources.includes(source.id), ) .map((source) => source.id); @@ -238,17 +222,15 @@ export function useScrape() { } } - // Collect all failed embed IDs across all sources (both global and media-specific) + // Collect all failed embed IDs across all sources const allFailedEmbedIds = Object.values(failedEmbeds).flat(); - const allMediaFailedEmbedIds = Object.values(mediaFailedEmbeds).flat(); // Filter out disabled and failed embeds from the embed order const filteredEmbedOrder = enableEmbedOrder ? (preferredEmbedOrder || []).filter( (id) => !(disabledEmbeds || []).includes(id) && - !allFailedEmbedIds.includes(id) && - !allMediaFailedEmbedIds.includes(id), + !allFailedEmbedIds.includes(id), ) : undefined; diff --git a/src/pages/parts/player/PlaybackErrorPart.tsx b/src/pages/parts/player/PlaybackErrorPart.tsx index e03692c9..dfc90c55 100644 --- a/src/pages/parts/player/PlaybackErrorPart.tsx +++ b/src/pages/parts/player/PlaybackErrorPart.tsx @@ -24,10 +24,9 @@ export function PlaybackErrorPart(props: PlaybackErrorPartProps) { const playbackError = usePlayerStore((s) => s.interface.error); const currentSourceId = usePlayerStore((s) => s.sourceId); const currentEmbedId = usePlayerStore((s) => s.embedId); - const meta = usePlayerStore((s) => s.meta); - const addMediaFailedSource = usePlayerStore((s) => s.addMediaFailedSource); - const addMediaFailedEmbed = usePlayerStore((s) => s.addMediaFailedEmbed); - const getMediaFailures = usePlayerStore((s) => s.getMediaFailures); + const addFailedSource = usePlayerStore((s) => s.addFailedSource); + const addFailedEmbed = usePlayerStore((s) => s.addFailedEmbed); + const failedEmbeds = usePlayerStore((s) => s.failedEmbeds); const modal = useModal("error"); const settingsRouter = useOverlayRouter("settings"); const hasOpenedSettings = useRef(false); @@ -41,7 +40,7 @@ export function PlaybackErrorPart(props: PlaybackErrorPartProps) { // Mark the failed source/embed and handle UI when a playback error occurs useEffect(() => { - if (playbackError && currentSourceId && meta) { + if (playbackError && currentSourceId) { // Only mark source/embed as failed for fatal errors const isFatalError = playbackError.type === "hls" @@ -49,37 +48,21 @@ export function PlaybackErrorPart(props: PlaybackErrorPartProps) { : playbackError.type === "htmlvideo"; if (isFatalError) { - // Create media failure key - const mediaFailureKey = { - type: meta.type, - tmdbId: meta.tmdbId, - ...(meta.type === "show" && meta.episode && meta.season - ? { - seasonNumber: meta.season.number, - episodeNumber: meta.episode.number, - } - : {}), - }; - - // Get current media failures - const mediaFailures = getMediaFailures(mediaFailureKey); - // If there's an active embed, disable that embed instead of the source if (currentEmbedId) { - addMediaFailedEmbed(mediaFailureKey, currentSourceId, currentEmbedId); + addFailedEmbed(currentSourceId, currentEmbedId); // Check if all embeds for this source have now failed // If so, disable the entire source - const failedEmbedsForSource = - mediaFailures.failedEmbeds[currentSourceId] || []; + const failedEmbedsForSource = failedEmbeds[currentSourceId] || []; // For now, we'll assume if we have 2+ failed embeds for a source, disable it // This is a simple heuristic - we could make it more sophisticated if (failedEmbedsForSource.length >= 2) { - addMediaFailedSource(mediaFailureKey, currentSourceId); + addFailedSource(currentSourceId); } } else { // No embed active, disable the source - addMediaFailedSource(mediaFailureKey, currentSourceId); + addFailedSource(currentSourceId); } } @@ -95,10 +78,9 @@ export function PlaybackErrorPart(props: PlaybackErrorPartProps) { playbackError, currentSourceId, currentEmbedId, - meta, - getMediaFailures, - addMediaFailedSource, - addMediaFailedEmbed, + failedEmbeds, + addFailedSource, + addFailedEmbed, settingsRouter, setLastSuccessfulSource, enableAutoResumeOnPlaybackError, diff --git a/src/setup/App.tsx b/src/setup/App.tsx index ad6c0b19..ff6bf327 100644 --- a/src/setup/App.tsx +++ b/src/setup/App.tsx @@ -41,10 +41,7 @@ import { RegisterPage } from "@/pages/Register"; import { SupportPage } from "@/pages/Support"; import { Layout } from "@/setup/Layout"; import { useHistoryListener } from "@/stores/history"; -import { - useClearMediaFailuresOnNavigation, - useClearModalsOnNavigation, -} from "@/stores/interface/overlayStack"; +import { useClearModalsOnNavigation } from "@/stores/interface/overlayStack"; import { LanguageProvider } from "@/stores/language"; const DeveloperPage = lazy(() => import("@/pages/DeveloperPage")); @@ -110,7 +107,6 @@ function App() { useOnlineListener(); useGlobalKeyboardEvents(); useClearModalsOnNavigation(); - useClearMediaFailuresOnNavigation(); const maintenance = false; // Shows maintance page const [showDowntime, setShowDowntime] = useState(maintenance); diff --git a/src/stores/interface/overlayStack.ts b/src/stores/interface/overlayStack.ts index e2b11f84..c84a9f90 100644 --- a/src/stores/interface/overlayStack.ts +++ b/src/stores/interface/overlayStack.ts @@ -3,8 +3,6 @@ import { useLocation } from "react-router-dom"; import { create } from "zustand"; import { immer } from "zustand/middleware/immer"; -import { usePlayerStore } from "@/stores/player/store"; - type OverlayType = "volume" | "subtitle" | "speed" | null; interface ModalData { @@ -77,15 +75,3 @@ export function useClearModalsOnNavigation() { clearAllModals(); }, [location.pathname, clearAllModals]); } - -// Hook to clear media failures on navigation -export function useClearMediaFailuresOnNavigation() { - const location = useLocation(); - const clearAllMediaFailures = usePlayerStore( - (state) => state.clearAllMediaFailures, - ); - - useEffect(() => { - clearAllMediaFailures(); - }, [location.pathname, clearAllMediaFailures]); -} diff --git a/src/stores/player/slices/mediaFailures.ts b/src/stores/player/slices/mediaFailures.ts deleted file mode 100644 index 40d48026..00000000 --- a/src/stores/player/slices/mediaFailures.ts +++ /dev/null @@ -1,112 +0,0 @@ -import { MakeSlice } from "@/stores/player/slices/types"; - -export interface MediaFailureKey { - type: "movie" | "show"; - tmdbId: string; - seasonNumber?: number; - episodeNumber?: number; -} - -export interface MediaFailuresSlice { - mediaFailures: Record< - string, - { - failedSources: string[]; - failedEmbeds: Record; - } - >; - getMediaFailureKey(meta: MediaFailureKey): string; - getMediaFailures(meta: MediaFailureKey): { - failedSources: string[]; - failedEmbeds: Record; - }; - addMediaFailedSource(meta: MediaFailureKey, sourceId: string): void; - addMediaFailedEmbed( - meta: MediaFailureKey, - sourceId: string, - embedId: string, - ): void; - clearMediaFailures(meta: MediaFailureKey): void; - clearAllMediaFailures(): void; - reset(): void; -} - -function createMediaFailureKey(meta: MediaFailureKey): string { - const baseKey = `${meta.type}-${meta.tmdbId}`; - if ( - meta.type === "show" && - meta.seasonNumber !== undefined && - meta.episodeNumber !== undefined - ) { - return `${baseKey}-s${meta.seasonNumber}e${meta.episodeNumber}`; - } - return baseKey; -} - -export const createMediaFailuresSlice: MakeSlice = ( - set, - get, -) => ({ - mediaFailures: {}, - - getMediaFailureKey(meta) { - return createMediaFailureKey(meta); - }, - - getMediaFailures(meta) { - const key = createMediaFailureKey(meta); - return get().mediaFailures[key] || { failedSources: [], failedEmbeds: {} }; - }, - - addMediaFailedSource(meta, sourceId) { - const key = createMediaFailureKey(meta); - set((s) => { - if (!s.mediaFailures[key]) { - s.mediaFailures[key] = { failedSources: [], failedEmbeds: {} }; - } - if (!s.mediaFailures[key].failedSources.includes(sourceId)) { - s.mediaFailures[key].failedSources = [ - ...s.mediaFailures[key].failedSources, - sourceId, - ]; - } - }); - }, - - addMediaFailedEmbed(meta, sourceId, embedId) { - const key = createMediaFailureKey(meta); - set((s) => { - if (!s.mediaFailures[key]) { - s.mediaFailures[key] = { failedSources: [], failedEmbeds: {} }; - } - if (!s.mediaFailures[key].failedEmbeds[sourceId]) { - s.mediaFailures[key].failedEmbeds[sourceId] = []; - } - if (!s.mediaFailures[key].failedEmbeds[sourceId].includes(embedId)) { - s.mediaFailures[key].failedEmbeds[sourceId] = [ - ...s.mediaFailures[key].failedEmbeds[sourceId], - embedId, - ]; - } - }); - }, - - clearMediaFailures(meta) { - const key = createMediaFailureKey(meta); - set((s) => { - delete s.mediaFailures[key]; - }); - }, - - clearAllMediaFailures() { - set((s) => { - s.mediaFailures = {}; - }); - }, - - reset() { - set((s) => { - s.mediaFailures = {}; - }); - }, -}); diff --git a/src/stores/player/slices/types.ts b/src/stores/player/slices/types.ts index b1edac5d..6f358945 100644 --- a/src/stores/player/slices/types.ts +++ b/src/stores/player/slices/types.ts @@ -3,7 +3,6 @@ import { StateCreator } from "zustand"; import { CastingSlice } from "@/stores/player/slices/casting"; import { DisplaySlice } from "@/stores/player/slices/display"; import { InterfaceSlice } from "@/stores/player/slices/interface"; -import { MediaFailuresSlice } from "@/stores/player/slices/mediaFailures"; import { PlayingSlice } from "@/stores/player/slices/playing"; import { ProgressSlice } from "@/stores/player/slices/progress"; import { SourceSlice } from "@/stores/player/slices/source"; @@ -15,8 +14,7 @@ export type AllSlices = InterfaceSlice & SourceSlice & DisplaySlice & CastingSlice & - ThumbnailSlice & - MediaFailuresSlice; + ThumbnailSlice; export type MakeSlice = StateCreator< AllSlices, [["zustand/immer", never]], diff --git a/src/stores/player/store.ts b/src/stores/player/store.ts index 34d97637..2235c30f 100644 --- a/src/stores/player/store.ts +++ b/src/stores/player/store.ts @@ -4,7 +4,6 @@ import { immer } from "zustand/middleware/immer"; import { createCastingSlice } from "@/stores/player/slices/casting"; import { createDisplaySlice } from "@/stores/player/slices/display"; import { createInterfaceSlice } from "@/stores/player/slices/interface"; -import { createMediaFailuresSlice } from "@/stores/player/slices/mediaFailures"; import { createPlayingSlice } from "@/stores/player/slices/playing"; import { createProgressSlice } from "@/stores/player/slices/progress"; import { createSourceSlice } from "@/stores/player/slices/source"; @@ -20,6 +19,5 @@ export const usePlayerStore = create( ...createDisplaySlice(...a), ...createCastingSlice(...a), ...createThumbnailSlice(...a), - ...createMediaFailuresSlice(...a), })), );