feat(search): search recs in queue
This commit is contained in:
parent
6eda36b8df
commit
8c79e69382
3 changed files with 57 additions and 9 deletions
20
js/api.js
20
js/api.js
|
|
@ -971,6 +971,26 @@ export class LosslessAPI {
|
|||
throw new Error('Track metadata not found');
|
||||
}
|
||||
|
||||
async getTrackRecommendations(id) {
|
||||
const cached = await this.cache.get('recommendations', id);
|
||||
if (cached) return cached;
|
||||
|
||||
try {
|
||||
const response = await this.fetchWithRetry(`/recommendations/?id=${id}`, { type: 'api' });
|
||||
const json = await response.json();
|
||||
const data = json.data || json;
|
||||
|
||||
const items = data.items || [];
|
||||
const tracks = items.map((item) => this.prepareTrack(item.track || item));
|
||||
|
||||
await this.cache.set('recommendations', id, tracks);
|
||||
return tracks;
|
||||
} catch (error) {
|
||||
console.error('Failed to fetch recommendations:', error);
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
async getTrack(id, quality = 'HI_RES_LOSSLESS') {
|
||||
const cacheKey = `${id}_${quality}`;
|
||||
const cached = await this.cache.get('track', cacheKey);
|
||||
|
|
|
|||
36
js/events.js
36
js/events.js
|
|
@ -1655,17 +1655,35 @@ export function initializeTrackInteractions(player, api, mainContent, contextMen
|
|||
!e.target.closest('.remove-from-playlist-btn') &&
|
||||
!e.target.closest('.artist-link')
|
||||
) {
|
||||
const parentList = trackItem.closest('.track-list');
|
||||
const allTrackElements = Array.from(parentList.querySelectorAll('.track-item'));
|
||||
const trackList = allTrackElements.map((el) => trackDataStore.get(el)).filter(Boolean);
|
||||
const clickedTrackId = trackItem.dataset.trackId;
|
||||
const isSearch = window.location.pathname.startsWith('/search/');
|
||||
|
||||
if (trackList.length > 0) {
|
||||
const clickedTrackId = trackItem.dataset.trackId;
|
||||
const startIndex = trackList.findIndex((t) => t.id == clickedTrackId);
|
||||
if (isSearch) {
|
||||
const clickedTrack = trackDataStore.get(trackItem);
|
||||
if (clickedTrack) {
|
||||
player.setQueue([clickedTrack], 0);
|
||||
document.getElementById('shuffle-btn').classList.remove('active');
|
||||
player.playTrackFromQueue();
|
||||
|
||||
player.setQueue(trackList, startIndex);
|
||||
document.getElementById('shuffle-btn').classList.remove('active');
|
||||
player.playTrackFromQueue();
|
||||
api.getTrackRecommendations(clickedTrack.id).then((recs) => {
|
||||
if (recs && recs.length > 0) {
|
||||
player.addToQueue(recs);
|
||||
showNotification(`Added ${recs.length} recommendations to queue`);
|
||||
}
|
||||
});
|
||||
}
|
||||
} else {
|
||||
const parentList = trackItem.closest('.track-list');
|
||||
const allTrackElements = Array.from(parentList.querySelectorAll('.track-item'));
|
||||
const trackList = allTrackElements.map((el) => trackDataStore.get(el)).filter(Boolean);
|
||||
|
||||
if (trackList.length > 0) {
|
||||
const startIndex = trackList.findIndex((t) => t.id == clickedTrackId);
|
||||
|
||||
player.setQueue(trackList, startIndex);
|
||||
document.getElementById('shuffle-btn').classList.remove('active');
|
||||
player.playTrackFromQueue();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -98,6 +98,16 @@ export class MusicAPI {
|
|||
return this.tidalAPI.getMix(id);
|
||||
}
|
||||
|
||||
async getTrackRecommendations(id) {
|
||||
const p = this.getProviderFromId(id) || this.getCurrentProvider();
|
||||
const api = this.getAPI(p);
|
||||
const cleanId = this.stripProviderPrefix(id);
|
||||
if (typeof api.getTrackRecommendations === 'function') {
|
||||
return api.getTrackRecommendations(cleanId);
|
||||
}
|
||||
return [];
|
||||
}
|
||||
|
||||
// Stream methods
|
||||
async getStreamUrl(id, quality, provider = null) {
|
||||
const p = provider || this.getProviderFromId(id) || this.getCurrentProvider();
|
||||
|
|
|
|||
Loading…
Reference in a new issue