Enhance authentication flow with improved error handling and logging in requireAuthHook. Refine HLS stream initialization and metadata fetching in AudioPlayer to handle station changes gracefully. Improve toast notifications and autocomplete behavior in LyricSearch. Simplify RandomMsg logic and remove unused imports. Add track and album count display in MediaRequestForm and enhance artist selection. Introduce dark mode styles for tables and dialogs in RequestManagement.css. Adjust imports and ensure proper usage of requireAuthHook in index.astro and requests.astro.
This commit is contained in:
@@ -34,6 +34,7 @@ export default function Player({ user }) {
|
||||
const currentTrackUuid = useRef(null);
|
||||
const baseTrackElapsed = useRef(0);
|
||||
const lastUpdateTimestamp = useRef(Date.now());
|
||||
const activeStationRef = useRef(activeStation);
|
||||
|
||||
const formatTime = (seconds) => {
|
||||
const mins = String(Math.floor(seconds / 60)).padStart(2, "0");
|
||||
@@ -85,9 +86,14 @@ export default function Player({ user }) {
|
||||
const hls = new Hls({
|
||||
lowLatencyMode: true,
|
||||
abrEnabled: false,
|
||||
liveSyncDuration: 1.0, // seconds behind live edge target
|
||||
liveMaxLatencyDuration: 2.0, // max allowed latency before catchup
|
||||
liveCatchUpPlaybackRate: 1.05, // playback speed when catching up
|
||||
liveSyncDuration: 0.5, // seconds behind live edge target
|
||||
liveMaxLatencyDuration: 3.0, // max allowed latency before catchup
|
||||
liveCatchUpPlaybackRate: 1.02,
|
||||
maxBufferLength: 30,
|
||||
maxMaxBufferLength: 60,
|
||||
maxBufferHole: 0.5,
|
||||
manifestLoadingTimeOut: 4000,
|
||||
fragLoadingTimeOut: 10000, // playback speed when catching up
|
||||
});
|
||||
|
||||
hlsInstance.current = hls;
|
||||
@@ -176,10 +182,15 @@ export default function Player({ user }) {
|
||||
// Fetch metadata and lyrics periodically
|
||||
useEffect(() => {
|
||||
const fetchMetadataAndLyrics = async () => {
|
||||
// capture the station id at request time; ignore results if station changed
|
||||
const requestStation = activeStationRef.current;
|
||||
try {
|
||||
const response = await fetch(`${API_URL}/radio/np?station=${activeStation}`, { method: 'POST' });
|
||||
const response = await fetch(`${API_URL}/radio/np?station=${requestStation}`, { method: 'POST' });
|
||||
const trackData = await response.json();
|
||||
|
||||
// If station changed while request was in-flight, ignore the response
|
||||
if (requestStation !== activeStationRef.current) return;
|
||||
|
||||
if (trackData.artist === 'N/A') {
|
||||
setTrackTitle('Offline');
|
||||
setLyrics([]);
|
||||
@@ -193,7 +204,7 @@ export default function Player({ user }) {
|
||||
setTrackArtist(trackData.artist);
|
||||
setTrackGenre(trackData.genre || '');
|
||||
setTrackAlbum(trackData.album);
|
||||
setCoverArt(`${API_URL}/radio/album_art?station=${activeStation}&_=${Date.now()}`);
|
||||
setCoverArt(`${API_URL}/radio/album_art?station=${requestStation}&_=${Date.now()}`);
|
||||
|
||||
baseTrackElapsed.current = trackData.elapsed;
|
||||
lastUpdateTimestamp.current = Date.now();
|
||||
@@ -205,7 +216,7 @@ export default function Player({ user }) {
|
||||
setCurrentLyricIndex(0);
|
||||
setPageTitle(trackData.artist, trackData.song);
|
||||
|
||||
// Fetch lyrics as before
|
||||
// Fetch lyrics as before, but guard against station switches
|
||||
const lyricsResponse = await fetch(`${API_URL}/lyric/search`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
@@ -219,6 +230,7 @@ export default function Player({ user }) {
|
||||
}),
|
||||
});
|
||||
const lyricsData = await lyricsResponse.json();
|
||||
if (requestStation !== activeStationRef.current) return;
|
||||
if (!lyricsData.err && Array.isArray(lyricsData.lrc)) {
|
||||
const parsedLyrics = lyricsData.lrc.map(({ timeTag, words }) => {
|
||||
const [mins, rest] = timeTag.split(':');
|
||||
@@ -238,6 +250,8 @@ export default function Player({ user }) {
|
||||
setLyrics([]);
|
||||
}
|
||||
};
|
||||
// ensure the ref points to the current activeStation for in-flight guards
|
||||
activeStationRef.current = activeStation;
|
||||
fetchMetadataAndLyrics();
|
||||
const metadataInterval = setInterval(fetchMetadataAndLyrics, 700);
|
||||
return () => clearInterval(metadataInterval);
|
||||
@@ -272,7 +286,7 @@ export default function Player({ user }) {
|
||||
))}
|
||||
</div>
|
||||
<div className="c-containter">
|
||||
{user ? <span>Hello, {user.user}</span> : <span>Not logged in</span>}
|
||||
{user && <span>Hello, {user.user}</span>}
|
||||
< div className="music-container mt-8">
|
||||
<section className="album-cover">
|
||||
<div className="music-player__album" title="Album">
|
||||
|
||||
Reference in New Issue
Block a user