Add internal providers toggle to settings and update HDRezka service logic

This commit is contained in:
tapframe 2025-05-27 22:16:43 +05:30
parent 259d071e95
commit 10aa799626
4 changed files with 67 additions and 6 deletions

View file

@ -34,6 +34,7 @@ export interface AppSettings {
selectedHeroCatalogs: string[]; // Array of catalog IDs to display in hero section
logoSourcePreference: 'metahub' | 'tmdb'; // Preferred source for title logos
tmdbLanguagePreference: string; // Preferred language for TMDB logos (ISO 639-1 code)
enableInternalProviders: boolean; // Toggle for internal providers like HDRezka
}
export const DEFAULT_SETTINGS: AppSettings = {
@ -50,6 +51,7 @@ export const DEFAULT_SETTINGS: AppSettings = {
selectedHeroCatalogs: [], // Empty array means all catalogs are selected
logoSourcePreference: 'metahub', // Default to Metahub as first source
tmdbLanguagePreference: 'en', // Default to English
enableInternalProviders: true, // Enable internal providers by default
};
const SETTINGS_STORAGE_KEY = 'app_settings';

View file

@ -406,6 +406,17 @@ const SettingsScreen: React.FC = () => {
onPress={() => navigation.navigate('CatalogSettings')}
badge={catalogCount}
/>
<SettingItem
title="Internal Providers"
description="Enable or disable built-in providers like HDRezka"
icon="source"
renderControl={() => (
<CustomSwitch
value={settings.enableInternalProviders}
onValueChange={(value) => updateSetting('enableInternalProviders', value)}
/>
)}
/>
<SettingItem
title="Home Screen"
description="Customize layout and content"

View file

@ -318,6 +318,13 @@ export const StreamsScreen = () => {
logger.log("🏁 Stream loading finished. Processing results.");
const currentStreamsData = type === 'series' ? episodeStreams : groupedStreams;
// Find all providers that returned streams
const providersWithStreams = Object.entries(currentStreamsData)
.filter(([_, data]) => data.streams && data.streams.length > 0)
.map(([providerId]) => providerId);
logger.log(`📊 Providers with streams: ${providersWithStreams.join(', ')}`);
// Update simple loading flag: all expected providers are no longer loading
setLoadingProviders(prevLoading => {
@ -334,8 +341,8 @@ export const StreamsScreen = () => {
expectedProviders.forEach(providerId => {
if (newStatus[providerId]) { // Ensure the provider entry exists
const providerHasStreams = currentStreamsData[providerId] &&
currentStreamsData[providerId].streams &&
currentStreamsData[providerId].streams.length > 0;
currentStreamsData[providerId].streams &&
currentStreamsData[providerId].streams.length > 0;
newStatus[providerId] = {
...newStatus[providerId], // Preserve timeStarted
@ -362,14 +369,33 @@ export const StreamsScreen = () => {
});
// Update the set of available providers based on what actually loaded streams
const providersWithStreams = new Set(Object.keys(currentStreamsData));
setAvailableProviders(providersWithStreams);
const providersWithStreamsSet = new Set(providersWithStreams);
setAvailableProviders(providersWithStreamsSet);
// Reset loadStartTime to signify the end of this loading cycle
setLoadStartTime(0);
setLoadStartTime(0);
}
}, [loadingStreams, loadingEpisodeStreams, groupedStreams, episodeStreams, type /* loadStartTime is intentionally omitted from deps here */]);
// Add useEffect to update availableProviders whenever streams change
useEffect(() => {
if (!loadingStreams && !loadingEpisodeStreams) {
const streams = type === 'series' ? episodeStreams : groupedStreams;
// Only include providers that actually have streams
const providers = new Set(
Object.entries(streams)
.filter(([_, data]) => data.streams && data.streams.length > 0)
.map(([providerId]) => providerId)
);
setAvailableProviders(providers);
// Also reset the selected provider to 'all' if the current selection is no longer available
if (selectedProvider !== 'all' && !providers.has(selectedProvider)) {
setSelectedProvider('all');
}
}
}, [type, groupedStreams, episodeStreams, loadingStreams, loadingEpisodeStreams, selectedProvider]);
React.useEffect(() => {
if (type === 'series' && episodeId) {
logger.log(`🎬 Loading episode streams for: ${episodeId}`);
@ -628,10 +654,20 @@ export const StreamsScreen = () => {
const filterItems = useMemo(() => {
const installedAddons = stremioService.getInstalledAddons();
const streams = type === 'series' ? episodeStreams : groupedStreams;
// Make sure we include all providers with streams, not just those in availableProviders
const allProviders = new Set([
...availableProviders,
...Object.keys(streams).filter(key =>
streams[key] &&
streams[key].streams &&
streams[key].streams.length > 0
)
]);
return [
{ id: 'all', name: 'All Providers' },
...Array.from(availableProviders)
...Array.from(allProviders)
.sort((a, b) => {
// Always put HDRezka at the top
if (a === 'hdrezka') return -1;

View file

@ -2,6 +2,8 @@ import { logger } from '../utils/logger';
import { Stream } from '../types/metadata';
import { tmdbService } from './tmdbService';
import axios from 'axios';
import { settingsEmitter } from '../hooks/useSettings';
import AsyncStorage from '@react-native-async-storage/async-storage';
// Use node-fetch if available, otherwise fallback to global fetch
let fetchImpl: typeof fetch;
@ -418,6 +420,16 @@ class HDRezkaService {
try {
logger.log(`[HDRezka] Getting streams for ${mediaType} with ID: ${mediaId}`);
// First check if internal providers are enabled
const settingsJson = await AsyncStorage.getItem('app_settings');
if (settingsJson) {
const settings = JSON.parse(settingsJson);
if (settings.enableInternalProviders === false) {
logger.log('[HDRezka] Internal providers are disabled in settings, skipping HDRezka');
return [];
}
}
// First, extract the actual title from TMDB if this is an ID
let title = mediaId;
let year: number | undefined = undefined;