mirror of
https://github.com/tapframe/NuvioStreaming.git
synced 2026-04-06 17:59:39 +00:00
This update introduces a new episode layout setting, allowing users to choose between vertical and horizontal card styles for episode displays. The SeriesContent component has been refactored to support both layouts, improving the user experience with a more dynamic presentation of episodes. Additionally, new styles and components have been added for the horizontal layout, including gradient overlays and progress indicators, enhancing visual appeal and functionality. The settings screen has also been updated to allow users to toggle between layout styles seamlessly.
113 lines
No EOL
3.5 KiB
TypeScript
113 lines
No EOL
3.5 KiB
TypeScript
import { useState, useEffect, useCallback } from 'react';
|
|
import AsyncStorage from '@react-native-async-storage/async-storage';
|
|
|
|
// Simple event emitter for settings changes
|
|
class SettingsEventEmitter {
|
|
private listeners: Array<() => void> = [];
|
|
|
|
addListener(listener: () => void) {
|
|
this.listeners.push(listener);
|
|
return () => {
|
|
this.listeners = this.listeners.filter(l => l !== listener);
|
|
};
|
|
}
|
|
|
|
emit() {
|
|
this.listeners.forEach(listener => listener());
|
|
}
|
|
}
|
|
|
|
// Singleton instance for app-wide access
|
|
export const settingsEmitter = new SettingsEventEmitter();
|
|
|
|
export interface AppSettings {
|
|
enableDarkMode: boolean;
|
|
enableNotifications: boolean;
|
|
streamQuality: 'auto' | 'low' | 'medium' | 'high';
|
|
enableSubtitles: boolean;
|
|
enableBackgroundPlayback: boolean;
|
|
cacheLimit: number;
|
|
useExternalPlayer: boolean;
|
|
preferredPlayer: 'internal' | 'vlc' | 'infuse' | 'outplayer' | 'vidhub' | 'external';
|
|
showHeroSection: boolean;
|
|
featuredContentSource: 'tmdb' | 'catalogs';
|
|
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
|
|
episodeLayoutStyle: 'vertical' | 'horizontal'; // Layout style for episode cards
|
|
}
|
|
|
|
export const DEFAULT_SETTINGS: AppSettings = {
|
|
enableDarkMode: true,
|
|
enableNotifications: true,
|
|
streamQuality: 'auto',
|
|
enableSubtitles: true,
|
|
enableBackgroundPlayback: false,
|
|
cacheLimit: 1024,
|
|
useExternalPlayer: false,
|
|
preferredPlayer: 'internal',
|
|
showHeroSection: true,
|
|
featuredContentSource: 'tmdb',
|
|
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
|
|
episodeLayoutStyle: 'horizontal', // Default to the new horizontal layout
|
|
};
|
|
|
|
const SETTINGS_STORAGE_KEY = 'app_settings';
|
|
|
|
export const useSettings = () => {
|
|
const [settings, setSettings] = useState<AppSettings>(DEFAULT_SETTINGS);
|
|
|
|
useEffect(() => {
|
|
loadSettings();
|
|
|
|
// Subscribe to settings changes
|
|
const unsubscribe = settingsEmitter.addListener(() => {
|
|
loadSettings();
|
|
});
|
|
|
|
return unsubscribe;
|
|
}, []);
|
|
|
|
const loadSettings = async () => {
|
|
try {
|
|
const storedSettings = await AsyncStorage.getItem(SETTINGS_STORAGE_KEY);
|
|
if (storedSettings) {
|
|
setSettings(JSON.parse(storedSettings));
|
|
}
|
|
} catch (error) {
|
|
console.error('Failed to load settings:', error);
|
|
}
|
|
};
|
|
|
|
const updateSetting = useCallback(async <K extends keyof AppSettings>(
|
|
key: K,
|
|
value: AppSettings[K],
|
|
emitEvent: boolean = true
|
|
) => {
|
|
const newSettings = { ...settings, [key]: value };
|
|
try {
|
|
await AsyncStorage.setItem(SETTINGS_STORAGE_KEY, JSON.stringify(newSettings));
|
|
setSettings(newSettings);
|
|
console.log(`Setting updated: ${key}`, value);
|
|
|
|
// Notify all subscribers that settings have changed (if requested)
|
|
if (emitEvent) {
|
|
console.log('Emitting settings change event');
|
|
settingsEmitter.emit();
|
|
}
|
|
} catch (error) {
|
|
console.error('Failed to save settings:', error);
|
|
}
|
|
}, [settings]);
|
|
|
|
return {
|
|
settings,
|
|
updateSetting,
|
|
};
|
|
};
|
|
|
|
export default useSettings; |