(TEMPORARY) stop DDOSING apis on search
This commit is contained in:
parent
2bde639ca6
commit
015003225c
3 changed files with 45 additions and 57 deletions
|
|
@ -304,10 +304,10 @@ export class LosslessAPI {
|
|||
const data = await response.json();
|
||||
const normalized = this.normalizeSearchResponse(data, 'tracks');
|
||||
const preparedTracks = normalized.items.map((t) => this.prepareTrack(t));
|
||||
const enrichedTracks = await this.enrichTracksWithAlbumDates(preparedTracks);
|
||||
// Note: Skipping enrichTracksWithAlbumDates for search results to avoid excessive album API calls
|
||||
const result = {
|
||||
...normalized,
|
||||
items: enrichedTracks,
|
||||
items: preparedTracks,
|
||||
};
|
||||
|
||||
await this.cache.set('search_tracks', query, result);
|
||||
|
|
|
|||
|
|
@ -215,33 +215,26 @@ export const apiSettings = {
|
|||
const targetUrls = instancesObj[type] || instancesObj.api || [];
|
||||
if (targetUrls.length === 0) return [];
|
||||
|
||||
// Use cached speed results to sort if available, but DON'T run new speed tests
|
||||
// Speed tests should only run explicitly via refreshSpeedTests() to avoid
|
||||
// mass /track API calls when playing a song
|
||||
const speedCache = this.getCachedSpeedTests();
|
||||
// Construct cache key based on type
|
||||
const getCacheKey = (u) => (type === 'streaming' ? `${u}#streaming` : u);
|
||||
|
||||
const urlsToTest = targetUrls.filter((url) => !speedCache.speeds[getCacheKey(url)]);
|
||||
// Sort by cached speeds if we have any cached data
|
||||
const hasCachedData = targetUrls.some((url) => speedCache.speeds[getCacheKey(url)]);
|
||||
|
||||
if (urlsToTest.length > 0) {
|
||||
const results = await this.testSpecificUrls(urlsToTest, type);
|
||||
this.updateSpeedCache(results);
|
||||
Object.assign(speedCache, this.getCachedSpeedTests());
|
||||
}
|
||||
|
||||
const sortList = (list) => {
|
||||
return [...list].sort((a, b) => {
|
||||
if (hasCachedData) {
|
||||
const sortedList = [...targetUrls].sort((a, b) => {
|
||||
const speedA = speedCache.speeds[getCacheKey(a)]?.speed ?? Infinity;
|
||||
const speedB = speedCache.speeds[getCacheKey(b)]?.speed ?? Infinity;
|
||||
return speedA - speedB;
|
||||
});
|
||||
};
|
||||
return sortedList;
|
||||
}
|
||||
|
||||
const sortedList = sortList(targetUrls);
|
||||
|
||||
// Persist the sorted order
|
||||
instancesObj[type] = sortedList;
|
||||
this.saveInstances(instancesObj);
|
||||
|
||||
return sortedList;
|
||||
// No cached data - return in default order without testing
|
||||
return targetUrls;
|
||||
},
|
||||
|
||||
async refreshSpeedTests() {
|
||||
|
|
|
|||
69
js/ui.js
69
js/ui.js
|
|
@ -1510,44 +1510,39 @@ export class UIRenderer {
|
|||
const signal = this.searchAbortController.signal;
|
||||
|
||||
try {
|
||||
const [tracksResult, artistsResult, albumsResult, playlistsResult] = await Promise.all([
|
||||
// Optimize: Only make 2 API calls (tracks and playlists), extract artists/albums from tracks
|
||||
const [tracksResult, playlistsResult] = await Promise.all([
|
||||
this.api.searchTracks(query, { signal }),
|
||||
this.api.searchArtists(query, { signal }),
|
||||
this.api.searchAlbums(query, { signal }),
|
||||
this.api.searchPlaylists(query, { signal }),
|
||||
]);
|
||||
|
||||
let finalTracks = tracksResult.items;
|
||||
let finalArtists = artistsResult.items;
|
||||
let finalAlbums = albumsResult.items;
|
||||
let finalPlaylists = playlistsResult.items;
|
||||
|
||||
if (finalArtists.length === 0 && finalTracks.length > 0) {
|
||||
const artistMap = new Map();
|
||||
finalTracks.forEach((track) => {
|
||||
if (track.artist && !artistMap.has(track.artist.id)) {
|
||||
artistMap.set(track.artist.id, track.artist);
|
||||
}
|
||||
if (track.artists) {
|
||||
track.artists.forEach((artist) => {
|
||||
if (!artistMap.has(artist.id)) {
|
||||
artistMap.set(artist.id, artist);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
finalArtists = Array.from(artistMap.values());
|
||||
}
|
||||
// Extract artists from tracks
|
||||
const artistMap = new Map();
|
||||
finalTracks.forEach((track) => {
|
||||
if (track.artist && !artistMap.has(track.artist.id)) {
|
||||
artistMap.set(track.artist.id, track.artist);
|
||||
}
|
||||
if (track.artists) {
|
||||
track.artists.forEach((artist) => {
|
||||
if (!artistMap.has(artist.id)) {
|
||||
artistMap.set(artist.id, artist);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
let finalArtists = Array.from(artistMap.values());
|
||||
|
||||
if (finalAlbums.length === 0 && finalTracks.length > 0) {
|
||||
const albumMap = new Map();
|
||||
finalTracks.forEach((track) => {
|
||||
if (track.album && !albumMap.has(track.album.id)) {
|
||||
albumMap.set(track.album.id, track.album);
|
||||
}
|
||||
});
|
||||
finalAlbums = Array.from(albumMap.values());
|
||||
}
|
||||
// Extract albums from tracks
|
||||
const albumMap = new Map();
|
||||
finalTracks.forEach((track) => {
|
||||
if (track.album && !albumMap.has(track.album.id)) {
|
||||
albumMap.set(track.album.id, track.album);
|
||||
}
|
||||
});
|
||||
let finalAlbums = Array.from(albumMap.values());
|
||||
|
||||
if (finalTracks.length) {
|
||||
this.renderListWithTracks(tracksContainer, finalTracks, true);
|
||||
|
|
@ -1658,10 +1653,10 @@ export class UIRenderer {
|
|||
dateDisplay =
|
||||
window.innerWidth > 768
|
||||
? releaseDate.toLocaleDateString('en-US', {
|
||||
year: 'numeric',
|
||||
month: 'long',
|
||||
day: 'numeric',
|
||||
})
|
||||
year: 'numeric',
|
||||
month: 'long',
|
||||
day: 'numeric',
|
||||
})
|
||||
: year;
|
||||
}
|
||||
}
|
||||
|
|
@ -2395,9 +2390,9 @@ export class UIRenderer {
|
|||
<span>${artist.popularity}% popularity</span>
|
||||
<div class="artist-tags">
|
||||
${(artist.artistRoles || [])
|
||||
.filter((role) => role.category)
|
||||
.map((role) => `<span class="artist-tag">${role.category}</span>`)
|
||||
.join('')}
|
||||
.filter((role) => role.category)
|
||||
.map((role) => `<span class="artist-tag">${role.category}</span>`)
|
||||
.join('')}
|
||||
</div>
|
||||
`;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue