TRip changes/AudioPlayer hls setting tweaks

This commit is contained in:
2025-08-11 15:52:38 -04:00
parent fe6a45bc1d
commit ccea5db9e9
3 changed files with 40 additions and 10 deletions

View File

@@ -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
});

View File

@@ -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

View File

@@ -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 = () => (
<span
className="inline-block ml-2 h-4 w-4 border-2 border-t-2 border-gray-300 border-t-blue-600 rounded-full animate-spin"
aria-label="Loading"
/>
);
// 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 && (
<>
<Accordion multiple className="mt-4">
<Accordion
multiple
className="mt-4"
activeIndex={expandedAlbums}
onTabChange={(e) => 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}`}
/>
<span>{album}</span>
<span className="flex items-center">
{album}
{loadingAlbumId === id && <Spinner />}
</span>
<small className="ml-2 text-neutral-500 dark:text-neutral-400">({release_date})</small>
</div>
}
>
{allTracks.length > 0 ? (
<ul className="text-sm">