From ccea5db9e9b74513bfe97ab95e42f4c045f5ed3b Mon Sep 17 00:00:00 2001 From: codey Date: Mon, 11 Aug 2025 15:52:38 -0400 Subject: [PATCH] TRip changes/AudioPlayer hls setting tweaks --- src/components/AudioPlayer.jsx | 4 +-- src/components/Login.jsx | 12 +++++++-- src/components/TRip/MediaRequestForm.jsx | 34 +++++++++++++++++++----- 3 files changed, 40 insertions(+), 10 deletions(-) diff --git a/src/components/AudioPlayer.jsx b/src/components/AudioPlayer.jsx index fe78c50..54541f7 100644 --- a/src/components/AudioPlayer.jsx +++ b/src/components/AudioPlayer.jsx @@ -84,8 +84,8 @@ export default function Player() { const hls = new Hls({ lowLatencyMode: true, abrEnabled: false, - liveSyncDuration: 3, // seconds behind live edge target - liveMaxLatencyDuration: 10, // max allowed latency before catchup + liveSyncDuration: 2.5, // seconds behind live edge target + liveMaxLatencyDuration: 3.5, // max allowed latency before catchup liveCatchUpPlaybackRate: 1.05, // playback speed when catching up }); diff --git a/src/components/Login.jsx b/src/components/Login.jsx index ed605e9..8815f19 100644 --- a/src/components/Login.jsx +++ b/src/components/Login.jsx @@ -38,6 +38,14 @@ export default function LoginPage() { setLoading(true); try { + if (!username) { + setLoading(false); + return toast.error("Username is required"); + } + if (!password) { + setLoading(false); + return toast.error("Password is required"); + } const formData = new URLSearchParams(); formData.append("username", username); formData.append("password", password); @@ -113,7 +121,7 @@ export default function LoginPage() { type="text" id="username" name="username" - autoComplete="username" + autoComplete="off" value={username} onChange={(e) => setUsername(e.target.value)} required @@ -134,7 +142,7 @@ export default function LoginPage() { type="password" id="password" name="password" - autoComplete="current-password" + autoComplete="off" value={password} onChange={(e) => setPassword(e.target.value)} required diff --git a/src/components/TRip/MediaRequestForm.jsx b/src/components/TRip/MediaRequestForm.jsx index 291638a..d24ea33 100644 --- a/src/components/TRip/MediaRequestForm.jsx +++ b/src/components/TRip/MediaRequestForm.jsx @@ -19,6 +19,8 @@ export default function MediaRequestForm() { const [artistSuggestions, setArtistSuggestions] = useState([]); const [isSubmitting, setIsSubmitting] = useState(false); const [isSearching, setIsSearching] = useState(false); + const [loadingAlbumId, setLoadingAlbumId] = useState(null); + const [expandedAlbums, setExpandedAlbums] = useState([]); const debounceTimeout = useRef(null); const autoCompleteRef = useRef(null); @@ -33,6 +35,13 @@ export default function MediaRequestForm() { }; + const Spinner = () => ( + + ); + // Fetch artist suggestions for autocomplete const searchArtists = (e) => { const query = e.query.trim(); @@ -114,6 +123,7 @@ export default function MediaRequestForm() { setAlbums(data); setTracksByAlbum({}); + setExpandedAlbums([]); // Set selectedTracks for all albums as null (means tracks loading/not loaded) setSelectedTracks( @@ -197,16 +207,17 @@ export default function MediaRequestForm() { let isCancelled = false; const albumsToFetch = albums.filter((a) => !tracksByAlbum[a.id]); + if (albumsToFetch.length === 0) return; const fetchTracksSequentially = async () => { for (const album of albumsToFetch) { if (isCancelled) break; + setLoadingAlbumId(album.id); + try { - const res = await authFetch( - `${API_URL}/trip/get_tracks_by_album_id/${album.id}` - ); + const res = await authFetch(`${API_URL}/trip/get_tracks_by_album_id/${album.id}`); if (!res.ok) throw new Error("API error"); const data = await res.json(); @@ -223,6 +234,7 @@ export default function MediaRequestForm() { setSelectedTracks((prev) => ({ ...prev, [album.id]: [] })); } } + setLoadingAlbumId(null); }; fetchTracksSequentially(); @@ -232,6 +244,7 @@ export default function MediaRequestForm() { }; }, [albums, type]); + // Toggle individual track checkbox const toggleTrack = (albumId, trackId) => { setSelectedTracks((prev) => { @@ -390,7 +403,12 @@ export default function MediaRequestForm() { {type === "artist" && albums.length > 0 && ( <> - + setExpandedAlbums(e.index)} + > {albums.map(({ album, id, release_date }) => { const allTracks = tracksByAlbum[id] || []; const selected = selectedTracks[id]; @@ -418,10 +436,14 @@ export default function MediaRequestForm() { className="cursor-pointer" aria-label={`Select all tracks for album ${album}`} /> - {album} + + {album} + {loadingAlbumId === id && } + ({release_date}) } + > {allTracks.length > 0 ? (
    @@ -478,6 +500,6 @@ export default function MediaRequestForm() { )} - + ); }