Skip to content

Commit b3b1302

Browse files
committed
Make Chromecast configurable and improve offline handling
- Add cast.enabled config option (enabled by default) - Cast service checks if enabled before initialization - Gracefully handle offline scenarios when Cast SDK unavailable - Cast button only shows when enabled in config - Add setEnabled() method to control Cast at runtime
1 parent cf26437 commit b3b1302

File tree

3 files changed

+38
-11
lines changed

3 files changed

+38
-11
lines changed

components/Player.tsx

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,9 @@ const Player: React.FC<PlayerProps> = ({
106106

107107
// Initialize Cast Service
108108
useEffect(() => {
109+
if (!APP_CONFIG.cast.enabled) return;
110+
111+
castService.setEnabled(APP_CONFIG.cast.enabled);
109112
castService.initialize().catch(err => console.warn('Cast init failed:', err));
110113

111114
const unsubscribeState = castService.onStateChange((isConnected, deviceName) => {
@@ -333,17 +336,19 @@ const Player: React.FC<PlayerProps> = ({
333336
</div>
334337

335338
<div className="hidden lg:flex items-center gap-4 flex-1 justify-end">
336-
<button
337-
onClick={handleCastToggle}
338-
className={`w-10 h-10 flex items-center justify-center rounded-xl transition ${
339-
isCasting
340-
? 'bg-indigo-600 text-white hover:bg-indigo-700'
341-
: 'hover:bg-zinc-100 dark:hover:bg-zinc-800 text-zinc-400'
342-
}`}
343-
title={isCasting ? `Casting to ${castDeviceName}` : 'Cast'}
344-
>
345-
<i className="fa-solid fa-tv"></i>
346-
</button>
339+
{APP_CONFIG.cast.enabled && (
340+
<button
341+
onClick={handleCastToggle}
342+
className={`w-10 h-10 flex items-center justify-center rounded-xl transition ${
343+
isCasting
344+
? 'bg-indigo-600 text-white hover:bg-indigo-700'
345+
: 'hover:bg-zinc-100 dark:hover:bg-zinc-800 text-zinc-400'
346+
}`}
347+
title={isCasting ? `Casting to ${castDeviceName}` : 'Cast'}
348+
>
349+
<i className="fa-solid fa-tv"></i>
350+
</button>
351+
)}
347352
<button onClick={onShare} className="w-10 h-10 flex items-center justify-center rounded-xl hover:bg-zinc-100 dark:hover:bg-zinc-800 text-zinc-400 transition"><i className="fa-solid fa-share-nodes"></i></button>
348353
<button onClick={() => setPlaybackRate(prev => { const n = SPEEDS[(SPEEDS.indexOf(prev) + 1) % SPEEDS.length]; if(audioRef.current) audioRef.current.playbackRate = n; return n; })} className="px-3 py-1.5 bg-zinc-100 dark:bg-zinc-800 rounded-lg text-[10px] font-bold text-zinc-500 hover:text-zinc-900 dark:hover:text-white transition min-w-[50px]">{playbackRate}x</button>
349354
<button onClick={onClose} className="w-10 h-10 flex items-center justify-center rounded-xl hover:bg-zinc-100 dark:hover:bg-zinc-800 text-zinc-400 hover:text-red-500 transition-all"><i className="fa-solid fa-xmark text-lg"></i></button>

config.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ export interface AppConfig {
2323
next: string;
2424
seekPrefix: 'digit' | 'arrow';
2525
};
26+
cast: {
27+
enabled: boolean;
28+
};
2629
}
2730

2831
export const APP_CONFIG: AppConfig = {
@@ -50,5 +53,8 @@ export const APP_CONFIG: AppConfig = {
5053
forward: 'l',
5154
next: 'n',
5255
seekPrefix: 'digit'
56+
},
57+
cast: {
58+
enabled: true
5359
}
5460
};

services/castService.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,15 +82,31 @@ type CastMediaStatusListener = (status: {
8282

8383
class CastService {
8484
private isInitialized = false;
85+
private isEnabled = true;
8586
private castContext: CastContext | null = null;
8687
private remotePlayer: RemotePlayer | null = null;
8788
private remotePlayerController: RemotePlayerController | null = null;
8889
private stateChangeListeners: CastStateChangeListener[] = [];
8990
private mediaStatusListeners: CastMediaStatusListener[] = [];
9091

92+
setEnabled(enabled: boolean): void {
93+
this.isEnabled = enabled;
94+
}
95+
9196
async initialize(): Promise<boolean> {
97+
if (!this.isEnabled) {
98+
console.log('Cast is disabled in config');
99+
return false;
100+
}
101+
92102
if (this.isInitialized) return true;
93103

104+
// Check if Cast API script is loaded (online check)
105+
if (!window.__onGCastApiAvailable && !window.cast) {
106+
console.warn('Cast API not loaded - may be offline or blocked');
107+
return false;
108+
}
109+
94110
return new Promise((resolve) => {
95111
window.__onGCastApiAvailable = (isAvailable: boolean) => {
96112
if (!isAvailable) {

0 commit comments

Comments
 (0)