descent
descent copied to clipboard
Add track and artist play counts to extended info
Feature Request
One of the primary reasons I love last.fm is for the stats. I would love an option to display a users play counts for track and artist on the visualizer. I imagine this would be displayed next to the song info. It could be added into the extended info setting or an additional setting could be added.
Suggested Method of Implementation
To implement, you would need to add another last.fm api call. The API method is track.getInfo and you supply the username, track name, and artist. The relevant field returned by the call is 'userplaycount'. url is like this:
http://ws.audioscrobbler.com/2.0/?method=track.getInfo&user=${urlUser}&api_key=${key}&track=${currentTrack}&artist=${currentArtist}&format=json
Potentially this same approach could be used to also add an artist play count option using the artist.getInfo API method.
I know you already have the extended info option but that only shows total user play count, which I find less interesting. This could be an extension to that setting, or it's own setting.
I may take a stab at doing this myself but am not super familiar with javascript coding yet.
As a final note, I've been using the descent visualizer for a while now (year+) and it's excellent. Thanks for all the work @JasonPuglisi!
Thanks for the idea, and I'm glad you're enjoying the project! Maybe this can be an addition to the extended info line, like this:
Could give the user options to turn each of those three data points on/off, but I don't think it hurts to have all of them displayed. If you have another idea, feel free to suggest.
The "now playing" API calls that Descent makes every few seconds should have both the track and artist IDs that we need to fetch the track info you mentioned.
If you wanna try implementing this, I can give some guidance on where I think things should go. I'm happy to answer any questions you have about JavaScript and work through it. Let me know! Otherwise, I'll implement this the next time I feel like coding haha. I don't think it will be very complicated!
That sounds great. I'll see if I can find some time to look at it in the next couple weeks.
Sorry for the delay, I wanted to provide some guidance earlier! I would start here: https://github.com/JasonPuglisi/descent/blob/4960b3a972d7b5949fb79f0ab98612060a109cbb/source/js/utility/metadata.js
In updateState
, there's a block where we update the metadata state from the Last.fm API to be pushed to the UI: https://github.com/JasonPuglisi/descent/blob/4960b3a972d7b5949fb79f0ab98612060a109cbb/source/js/utility/metadata.js#L50
We can pass the metadata
object created here to a new function. I would put a new function in the file under fetchMetadata
, and call it fetchScrobbles
. Pass metadata
to fetchScrobbles
and use it to call the track.getInfo
(https://www.last.fm/api/show/track.getInfo) and artist.getInfo
(https://www.last.fm/api/show/artist.getInfo) methods. You can pretty much copy the format from fetchMetadata
above to make the AJAX calls. The trickiest part is handling the responses asynchronously since either of them could be returned before the other.
The success
function for each AJAX call should extract the userplaycount
from each API response and pass it to another function. I would create this new function under setMetadata
and call it setScrobbles
. It might make sense to take multiple parameters in this function, such as setScrobbles(trackScrobbles, artistScrobbles)
. That way, for each API response you get. you can pass the value you have, and pass null
for the other one. You can update global variables for this data just like we do in setMetadata
. For instance, there's already a variable resources.track.current.scrobbles
. There could be new ones resources.track.current.trackScrobbles
and resources.track.current.artistScrobbles
. Just remember to only set each of these is there's a value passed to the function for it, and not null
/undefined
.
With the global data set, we need to update the UI. First step is adding new HTML elements to put the data in. Look here: https://github.com/JasonPuglisi/descent/blob/4960b3a972d7b5949fb79f0ab98612060a109cbb/views/now.pug#L68
The indentation can be messy, so I'll do this piece. Here's what's there already:
p.scrobbles.hide
b
span.scrobbleCount
| scrobbles
We need to add a new piece for the extra info:
p.scrobbles.hide
b
span.scrobbleCount
| scrobbles
span.extraScrobbles.hide
| •
b
span.trackScrobbleCount
| this song •
b
span.artistScrobbleCount
| this artist
I haven't tested this but I think it should achieve the styling from my screenshot above, including bolding the numbers. Some of the spacing might be off, but we can fix it later. Notice the new extraScrobbles
element uses .hide
to hide itself by default. We'll need to keep this hidden until both the track and artist scrobble data are loaded from the API. If one or neither load, it will still display the user's total scrobble count by itself.
Finally, we can put the data into here. Go back to metadata.js
. Look for the function updateMetadata
and the last part where we update scrobbles: https://github.com/JasonPuglisi/descent/blob/4960b3a972d7b5949fb79f0ab98612060a109cbb/source/js/utility/metadata.js#L181
Slightly above, we set the variable scrobbles
. Make two new ones trackScrobbles
and artistScrobbles
for the new global data you made previously. Use this line as guidance to update the new data: $('.scrobbles .scrobbleCount').text(scrobbles ? scrobbles : '');
. For example, $('.scrobbles .trackScrobbleCount').text(trackScrobbles ? trackScrobbles : '');
. Since this info is hidden by default, you should also put a new toggleDisplay
under the existing one. You only want it to toggle when both pieces of data are loaded: toggleDisplay('.scrobbles', trackScrobbles && artistScrobbles);
Now that the UI is ready to be updated, we need to make sure it happens when the API calls are successful. At the end of your setScrobbles
function, call updateMetadata
. I think everything should be working now!
When new tracks load, we need to hide this extra data again until it's loaded. Find somewhere good to put toggleDisplay('.scrobbles', false);
so it works reliably on each state change. There's an edge case here where a new track loads between the time the scrobble API call starts and finishes, so the API response data is actually displayed for the track that was playing previously. If you want, ignore this part for now and we can think about it once the main functionality is in place.
This turned out longer than expected, but it should be everything you need to get it to work. Feel free to deviate and ask questions as needed. If it's overwhelming or you decide you don't want to code it, I'm happy to do so! Good luck
Last.fm wouldn't let me use mbid
s in the API requests, but artist and track names should work fine. This seems to have turned out pretty good!
Is this new feature supposed to show 0 scrobbles when the track is new in my library? Currently I'm listening to my new Spotify Release Radar playlist, and most tracks do not have any scrobbles yet, so I do not see a counter for track and artist scrobbles, only my usual total scrobbles. Now I am listening to a known artist (Heinz Rudolf Kunze with 12 total scrobbles in my library) with a new track, but the artist scrobbles are not shown either. Maybe the feature is not live yet?
OK, now I see the new info, might have just taken some time to reach Germany. 😉
I think if both the artist and track scrobble counts are 0, it might treat it as an error and not display. I'll try to test it out later!
Otherwise yeah, caching of the old JavaScript might delay when people see the new feature.
Looks like 0 artist and 0 track scrobble counts show up fine, so probably just a cache thing!