//
(function Genre() {
const { CosmosAsync, Player } = Spicetify;
/**
* Fetch genre from artist
*
* @param artistURI {string}
* @return {Promise}
*/
const fetchGenres = async (artistURI) => {
const res = await CosmosAsync.get(
`https://api.spotify.com/v1/artists/${artistURI}`
);
// noinspection JSUnresolvedVariable
return res.genres.slice(0, 3) // Only keep the first 3 genres
};
/**
* Fetch playlist from The Sound of Spotify for a given genre
* @param {String} genre
* @return {String|null}
*/
const fetchSoundOfSpotifyPlaylist = async (genre) => {
const query = encodeURIComponent(`The Sound of ${genre}`);
// Check localStorage for playlist
const cached = localStorage.getItem(`everynoise:${query}`);
if (cached !== null) {
return cached;
}
// Search for playlist and check results for the everynoise account
const re = new RegExp(`^the sound of ${genre.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}$`, 'i');
const res = await CosmosAsync.get(`https://api.spotify.com/v1/search?q=${query}&type=playlist`)
for (const item of res.playlists.items) {
if (item.owner.id === "thesoundsofspotify" && re.test(item.name)) {
localStorage.setItem(`everynoise:${genre}`, item.uri);
return item.uri
}
}
return null;
};
// Store the current playback id
let playback = null;
/**
*
* @type {Node}
*/
let genreContainer = null;
let infoContainer = document.querySelector('div.main-trackInfo-container');
/**
* Remove genre injection in the UI
*/
const cleanInjection = () => {
if (genreContainer !== null) {
try {
infoContainer.removeChild(genreContainer);
} catch (e) {}
}
};
/**
* Inject genres to UI
*/
const inject = () => {
Player.addEventListener('onprogress', async () => {
if (Player.data.track.metadata.hasOwnProperty('artist_uri')) {
// If the registered song isn't the same as the one currently being played then fetch genres
if (playback !== Player.data.playback_id) {
// Save the new track
playback = Player.data.playback_id;
const id = Player.data.track.metadata.artist_uri.split(':')[2];
const genres = await fetchGenres(id);
cleanInjection();
genreContainer = document.createElement('div');
// noinspection JSUndefinedPropertyAssignment
genreContainer.className = 'main-trackInfo-genres ellipsis-one-line main-type-finale';
// noinspection JSUnresolvedVariable
genreContainer.style.color = 'var(--spice-extratext)';
for (const i in genres) {
let element;
const uri = await fetchSoundOfSpotifyPlaylist(genres[i]);
if (uri !== null) {
element = document.createElement('a');
element.innerHTML = genres[i];
element.href = uri;
} else {
element = document.createElement('span');
}
element.innerHTML = genres[i];
element.style.fontSize ="11px";
genreContainer.appendChild(element);
if (i < genres.length-1) {
const separator = document.createElement('span');
separator.innerHTML = ', ';
genreContainer.appendChild(separator);
}
}
infoContainer = document.querySelector('div.main-trackInfo-container');
if(!infoContainer) cleanInjection();
infoContainer.appendChild(genreContainer);
}
} else {
cleanInjection();
}
});
};
if (!CosmosAsync) {
setTimeout(Genre, 500);
} else {
inject();
}
})();