feat: implement proxy mode setting for video playback with retry, none, and always options

This commit is contained in:
kuekhaoyang
2026-01-25 14:40:38 +08:00
parent f4b16bac2d
commit 2aa90a4d4f
8 changed files with 141 additions and 39 deletions
+27 -5
View File
@@ -42,20 +42,37 @@ export function VideoPlayer({
const SAVE_INTERVAL = 5000; // 5 seconds throttle
// Get showModeIndicator setting
// Get showModeIndicator and proxyMode settings
const [showModeIndicator, setShowModeIndicator] = useState(false);
const [proxyMode, setProxyMode] = useState<'retry' | 'none' | 'always'>('retry');
useEffect(() => {
// Initial value
setShowModeIndicator(settingsStore.getSettings().showModeIndicator);
const settings = settingsStore.getSettings();
setShowModeIndicator(settings.showModeIndicator);
setProxyMode(settings.proxyMode);
// Subscribe to changes
const unsubscribe = settingsStore.subscribe(() => {
setShowModeIndicator(settingsStore.getSettings().showModeIndicator);
const newSettings = settingsStore.getSettings();
setShowModeIndicator(newSettings.showModeIndicator);
setProxyMode(newSettings.proxyMode);
});
return () => unsubscribe();
}, []);
// Initialize useProxy based on proxyMode when the component mounts or proxyMode changes
// We use a separate effect for this to react to setting changes
useEffect(() => {
if (proxyMode === 'always') {
setUseProxy(true);
} else if (proxyMode === 'none') {
setUseProxy(false);
}
// For 'retry', we assume it starts as false (direct), which is the default state of useProxy
}, [proxyMode]);
// Use reactive hook to subscribe to history updates
// This ensures the component re-renders when history is hydrated from localStorage
@@ -134,8 +151,13 @@ export function VideoPlayer({
const handleVideoError = (error: string) => {
console.error('Video playback error:', error);
// Auto-retry with proxy if not already using it
if (!useProxy) {
// Auto-retry with proxy if:
// 1. Not already using proxy
// 2. Proxy mode is NOT 'none' (so 'retry' or potentially 'always' if it somehow failed locally)
// 3. Proxy mode is 'retry' (specifically for the auto-switch logic)
// Note: If mode is 'always', we are already using proxy. If it fails, we show error.
if (!useProxy && proxyMode === 'retry') {
setUseProxy(true);
setShouldAutoPlay(true); // Force autoplay after proxy retry
setVideoError('');
@@ -164,7 +186,7 @@ export function VideoPlayer({
setUseProxy(prev => !prev);
};
const finalPlayUrl = useProxy
const finalPlayUrl = useProxy || proxyMode === 'always'
? `/api/proxy?url=${encodeURIComponent(playUrl)}&retry=${retryCount}` // Add retry param to force fresh request
: playUrl;
@@ -21,6 +21,7 @@ export function usePlayerSettings() {
adFilterMode: stored.adFilterMode,
adKeywords: stored.adKeywords,
fullscreenType: stored.fullscreenType,
proxyMode: stored.proxyMode,
};
});
@@ -39,6 +40,7 @@ export function usePlayerSettings() {
adFilterMode: stored.adFilterMode,
adKeywords: stored.adKeywords,
fullscreenType: stored.fullscreenType,
proxyMode: stored.proxyMode,
});
});
return unsubscribe;
@@ -95,6 +97,10 @@ export function usePlayerSettings() {
updateSetting('fullscreenType', value);
}, [updateSetting]);
const setProxyMode = useCallback((value: 'retry' | 'none' | 'always') => {
updateSetting('proxyMode', value);
}, [updateSetting]);
return {
...settings,
setAutoNextEpisode,
@@ -107,5 +113,6 @@ export function usePlayerSettings() {
setAdFilterMode,
setAdKeywords,
setFullscreenType,
setProxyMode,
};
}