descent icon indicating copy to clipboard operation
descent copied to clipboard

Add track and artist play counts to extended info

Open ejoh1101 opened this issue 4 years ago • 3 comments

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!

ejoh1101 avatar Dec 17 '20 04:12 ejoh1101

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:

image

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!

JasonPuglisi avatar Dec 18 '20 22:12 JasonPuglisi

That sounds great. I'll see if I can find some time to look at it in the next couple weeks.

ejoh1101 avatar Dec 23 '20 18:12 ejoh1101

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

JasonPuglisi avatar Jan 07 '21 21:01 JasonPuglisi

Last.fm wouldn't let me use mbids in the API requests, but artist and track names should work fine. This seems to have turned out pretty good!

JasonPuglisi avatar Nov 26 '22 01:11 JasonPuglisi

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. 😉

hans-juergen avatar Nov 26 '22 08:11 hans-juergen

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.

JasonPuglisi avatar Nov 26 '22 15:11 JasonPuglisi

Looks like 0 artist and 0 track scrobble counts show up fine, so probably just a cache thing!

JasonPuglisi avatar Nov 26 '22 19:11 JasonPuglisi