mirror of
https://github.com/Psychotoxical/psysonic.git
synced 2026-07-22 07:15:47 +00:00
fix(queue): respect rating filter in infinite queue top-up (#357)
Apply mix rating settings to infinite queue candidates and keep fetching random batches when filtered results are below the target size, so top-ups can still reach five tracks when possible.
This commit is contained in:
@@ -17,6 +17,11 @@ import { useOrbitStore } from './orbitStore';
|
||||
import { estimateLivePosition } from '../api/orbit';
|
||||
import { loudnessGainPlaceholderUntilCacheDb } from '../utils/loudnessPlaceholder';
|
||||
import { effectiveLoudnessPreAnalysisAttenuationDb } from '../utils/loudnessPreAnalysisSlider';
|
||||
import {
|
||||
enrichSongsForMixRatingFilter,
|
||||
getMixMinRatingsConfigFromAuth,
|
||||
passesMixMinRatings,
|
||||
} from '../utils/mixRatingFilter';
|
||||
|
||||
export interface Track {
|
||||
id: string;
|
||||
@@ -121,6 +126,8 @@ async function buildInfiniteQueueCandidates(
|
||||
existingIds: Set<string>,
|
||||
count = 5,
|
||||
): Promise<Track[]> {
|
||||
const RANDOM_TOPUP_BATCH_SIZE = Math.max(10, count * 2);
|
||||
const RANDOM_TOPUP_MAX_BATCHES = 8;
|
||||
const artistId = seedTrack?.artistId?.trim() || null;
|
||||
const artistName = seedTrack?.artist?.trim() || null;
|
||||
|
||||
@@ -130,22 +137,35 @@ async function buildInfiniteQueueCandidates(
|
||||
]);
|
||||
|
||||
const seedId = seedTrack?.id ?? null;
|
||||
const mixCandidates = shuffleArray(
|
||||
[...top, ...similar]
|
||||
const mixCfg = getMixMinRatingsConfigFromAuth();
|
||||
const mixedSources = [...top, ...similar];
|
||||
const filteredMixedSongs = mixCfg.enabled
|
||||
? (await enrichSongsForMixRatingFilter(mixedSources, mixCfg)).filter(s => passesMixMinRatings(s, mixCfg))
|
||||
: mixedSources;
|
||||
const out: Track[] = shuffleArray(
|
||||
filteredMixedSongs
|
||||
.map(songToTrack)
|
||||
.filter(t => t.id !== seedId && !existingIds.has(t.id)),
|
||||
)
|
||||
.slice(0, count)
|
||||
.map(t => ({ ...t, autoAdded: true as const }));
|
||||
|
||||
if (mixCandidates.length > 0) return mixCandidates;
|
||||
const seenIds = new Set<string>([...existingIds, ...out.map(t => t.id)]);
|
||||
for (let b = 0; out.length < count && b < RANDOM_TOPUP_MAX_BATCHES; b++) {
|
||||
const random = await getRandomSongs(RANDOM_TOPUP_BATCH_SIZE, seedTrack?.genre).catch(() => []);
|
||||
if (!random.length) break;
|
||||
const filteredRandomSongs = mixCfg.enabled
|
||||
? (await enrichSongsForMixRatingFilter(random, mixCfg)).filter(s => passesMixMinRatings(s, mixCfg))
|
||||
: random;
|
||||
for (const track of shuffleArray(filteredRandomSongs.map(songToTrack))) {
|
||||
if (track.id === seedId || seenIds.has(track.id)) continue;
|
||||
out.push({ ...track, autoAdded: true as const });
|
||||
seenIds.add(track.id);
|
||||
if (out.length >= count) break;
|
||||
}
|
||||
}
|
||||
|
||||
const random = await getRandomSongs(count, seedTrack?.genre).catch(() => []);
|
||||
return random
|
||||
.map(songToTrack)
|
||||
.filter(t => t.id !== seedId && !existingIds.has(t.id))
|
||||
.slice(0, count)
|
||||
.map(t => ({ ...t, autoAdded: true as const }));
|
||||
return out.slice(0, count);
|
||||
}
|
||||
|
||||
interface PlayerState {
|
||||
|
||||
Reference in New Issue
Block a user