dev #6

Merged
codey merged 6 commits from dev into master 2026-02-27 10:43:39 -05:00
Showing only changes of commit 8263d582a6 - Show all commits

View File

@@ -140,7 +140,6 @@ export default function Player({ user }: PlayerProps) {
// Accept bare array or { options: [...] }
setTypeaheadOptions(Array.isArray(data) ? data : data.options || []);
} catch (error) {
console.error('Typeahead: error', error);
setTypeaheadOptions([]);
}
};
@@ -208,7 +207,6 @@ export default function Player({ user }: PlayerProps) {
const [liveDownloadRate, setLiveDownloadRate] = useState<number | null>(null); // Actual download speed
const [actualPlayingLevel, setActualPlayingLevel] = useState<number>(-1); // Actual HLS.js level being played
// Basic mount diagnostics so we can see logs even if HLS never initializes
useEffect(() => {
return () => {};
}, []);
@@ -310,9 +308,8 @@ export default function Player({ user }: PlayerProps) {
import('hls.js').then(({ default: Hls }) => {
// Double-check audio element still exists after async import
if (!audioElement.current) return;
if (!Hls.isSupported()) {
console.error("HLS not supported");
return;
}
@@ -420,12 +417,9 @@ export default function Player({ user }: PlayerProps) {
let networkRecoveryTimeout: ReturnType<typeof setTimeout> | null = null;
hls.on(Hls.Events.ERROR, (_event, data) => {
// Chromium sometimes stutters then fires a fatal error; recover aggressively
const details = data?.details || 'unknown';
console.warn('[Radio] HLS error', data?.type, details, 'fatal:', data?.fatal);
if (!data.fatal) {
// Try to keep playback alive on buffer stalls
if (details === Hls.ErrorDetails.BUFFER_STALLED_ERROR) {
try { hls.startLoad(); } catch (_) { /* ignore */ }
}
@@ -434,7 +428,6 @@ export default function Player({ user }: PlayerProps) {
switch (data.type) {
case Hls.ErrorTypes.NETWORK_ERROR: {
console.warn('[Radio] network error, reinitializing stream');
hls.destroy();
hlsInstance.current = null;
setIsPlaying(false);
@@ -443,11 +436,9 @@ export default function Player({ user }: PlayerProps) {
break;
}
case Hls.ErrorTypes.MEDIA_ERROR: {
console.warn('[Radio] media error, attempting recovery');
try {
hls.recoverMediaError();
} catch (err) {
console.error('[Radio] media recovery failed, restarting', err);
hls.destroy();
hlsInstance.current = null;
initializeStream(activeStationRef.current);
@@ -455,7 +446,6 @@ export default function Player({ user }: PlayerProps) {
break;
}
default: {
console.error('[Radio] unrecoverable error, restarting');
hls.destroy();
hlsInstance.current = null;
setIsPlaying(false);
@@ -536,7 +526,6 @@ export default function Player({ user }: PlayerProps) {
// Handle station changes: reset and start new stream
useEffect(() => {
console.info('[Radio] station effect', activeStation);
// Batch all state resets to minimize re-renders
// Use startTransition to mark this as a non-urgent update
const resetState = () => {
@@ -562,7 +551,6 @@ export default function Player({ user }: PlayerProps) {
resetState();
// Defer stream initialization to next frame to keep UI responsive
requestAnimationFrame(() => {
console.info('[Radio] initializeStream from station effect', activeStation);
initializeStream(activeStation);
});
});
@@ -694,7 +682,6 @@ export default function Player({ user }: PlayerProps) {
// Check if connection appears dead
if (ws.readyState !== WebSocket.OPEN || isStale) {
console.warn('WebSocket connection appears stale, reconnecting...');
// Force close and let onclose handle reconnection
ws.close();
}
@@ -730,7 +717,7 @@ export default function Player({ user }: PlayerProps) {
}
// Ignore any other message types that don't contain track data
} catch (error) {
console.error('Error parsing WebSocket message:', error);
// ignore malformed messages
}
};
@@ -753,9 +740,8 @@ export default function Player({ user }: PlayerProps) {
}, delay);
};
ws.onerror = function (error) {
console.error('Radio WebSocket error:', error);
// Don't set error state here - let onclose handle reconnection
ws.onerror = function () {
// Let onclose handle reconnection
};
wsInstance.current = ws;
@@ -876,7 +862,7 @@ export default function Player({ user }: PlayerProps) {
toast.error("Skip failed.");
}
} catch (error) {
console.error("Error skipping track:", error);
// ignore errors
toast.error("Skip failed.");
}
};
@@ -898,7 +884,7 @@ export default function Player({ user }: PlayerProps) {
toast.error("Reshuffle failed.");
}
} catch (error) {
console.error("Error reshuffling queue:", error);
// ignore errors
toast.error("Reshuffle failed.");
}
};
@@ -922,7 +908,7 @@ export default function Player({ user }: PlayerProps) {
toast.error("Queue shift failed.");
}
} catch (error) {
console.error("Error shifting queue:", error);
// ignore errors
toast.error("Queue shift failed.");
}
};
@@ -951,7 +937,7 @@ export default function Player({ user }: PlayerProps) {
toast.update(toastId, { render: "Play Now failed.", type: "error", autoClose: 3000 });
}
} catch (error) {
console.error("Error playing song immediately:", error);
// ignore errors
toast.update(toastId, { render: "Play Now failed.", type: "error", autoClose: 3000 });
}
};
@@ -980,7 +966,7 @@ export default function Player({ user }: PlayerProps) {
toast.update(toastId, { render: "Song request failed.", type: "error", autoClose: 3000 });
}
} catch (error) {
console.error("Error requesting song:", error);
// ignore errors
toast.update(toastId, { render: "Song request failed.", type: "error", autoClose: 3000 });
}
};
@@ -1004,7 +990,7 @@ export default function Player({ user }: PlayerProps) {
toast.error("Remove from queue failed.");
}
} catch (error) {
console.error("Error removing from queue:", error);
// ignore errors
toast.error("Remove from queue failed.");
}
};
@@ -1030,7 +1016,7 @@ export default function Player({ user }: PlayerProps) {
fetchQueue(); // Refresh to get correct state
}
} catch (error) {
console.error("Error reordering queue:", error);
// ignore errors
toast.error("Reorder failed.");
fetchQueue();
}
@@ -1114,7 +1100,7 @@ export default function Player({ user }: PlayerProps) {
setNextTrack(null);
}
} catch (error) {
console.error("Error fetching next track:", error);
// ignore errors
setNextTrack(null);
}
};
@@ -1125,7 +1111,7 @@ export default function Player({ user }: PlayerProps) {
const actualRows = rows ?? queueRowsRef.current;
const actualSearch = search ?? queueSearchRef.current;
const start = actualPage * actualRows;
// console.log("Fetching queue for station (ref):", activeStationRef.current);
//
try {
const response = await authFetch(`${API_URL}/radio/get_queue`, {
method: "POST",
@@ -1145,19 +1131,19 @@ export default function Player({ user }: PlayerProps) {
: data.recordsTotal ?? 0
);
} catch (error) {
console.error("Error fetching queue:", error);
// ignore errors
}
};
useEffect(() => {
if (isQueueVisible) {
// console.log("Fetching queue for station:", activeStation);
//
fetchQueue(queuePage, queueRows, queueSearch);
}
}, [isQueueVisible, queuePage, queueRows, queueSearch, activeStation]);
useEffect(() => {
// console.log("Active station changed to:", activeStation);
//
if (isQueueVisible) {
fetchQueue(queuePage, queueRows, queueSearch);
}
@@ -1174,7 +1160,7 @@ export default function Player({ user }: PlayerProps) {
useEffect(() => {
if (isQueueVisible) {
// console.log("Track changed, refreshing queue for station:", activeStation);
//
fetchQueue(queuePage, queueRows, queueSearch);
}
}, [currentTrackUuid]);
@@ -1405,7 +1391,6 @@ export default function Player({ user }: PlayerProps) {
await audio.play();
setIsPlaying(true);
} catch (err) {
console.warn('Playback failed, reinitializing stream:', err);
// Reinitialize stream on playback failure
initializeStream(activeStation);
}