From e804bb0bf40000ddea2cc33e1e605132130b65bd Mon Sep 17 00:00:00 2001 From: Joe Pitts Date: Thu, 7 May 2026 14:38:36 +0100 Subject: [PATCH 1/7] Genius artist --- examples/artist.json | 2488 +++++++++++++++++ examples/search.json | 621 ++++ .../src/components/artist/ArtistPanel.tsx | 35 + renderer/src/hooks/useArtistBrowse.ts | 33 +- renderer/src/styles/ArtistPanel.module.css | 11 +- renderer/src/test/setup.ts | 1 + renderer/src/types/globals.d.ts | 10 + src/main.ts | 68 + src/preload.ts | 3 + 9 files changed, 3255 insertions(+), 15 deletions(-) create mode 100644 examples/artist.json create mode 100644 examples/search.json diff --git a/examples/artist.json b/examples/artist.json new file mode 100644 index 0000000..afb09e3 --- /dev/null +++ b/examples/artist.json @@ -0,0 +1,2488 @@ +{ + "meta": { "status": 200 }, + "response": { + "artist": { + "alternate_names": ["OKLAMA", "Kendrick L. Duckworth", "Kendrick Duckworth", "Kendrick Lamar Duckworth", "K-Dot"], + "api_path": "/artists/1421", + "description": { + "dom": { + "tag": "root", + "children": [ + { + "tag": "p", + "children": [ + { + "tag": "a", + "attributes": { "href": "http://www.kendricklamar.com/", "rel": "noopener nofollow" }, + "children": ["Kendrick Lamar"] + }, + " Duckworth (born June 17, 1987) is an American rapper and songwriter from Compton, California." + ] + }, + "", + { + "tag": "p", + "children": [ + "He first gained major attention after the release of his 2010 mixtape ", + { + "tag": "a", + "attributes": { + "href": "https://genius.com/albums/Kendrick-lamar/Overly-dedicated", + "rel": "noopener" + }, + "data": { "api_path": "/albums/10919" }, + "children": [{ "tag": "em", "children": ["O(verly) D(edicated)"] }] + }, + ". In 2011, his album ", + { + "tag": "a", + "attributes": { "href": "https://genius.com/albums/Kendrick-lamar/Section-80", "rel": "noopener" }, + "data": { "api_path": "/albums/11160" }, + "children": [{ "tag": "em", "children": ["Section.80"] }] + }, + ", released exclusively through iTunes, instantly ranked as one of the top digital hip-hop releases of the year. In 2012, he crossed over to mainstream audiences with his major label debut, ", + { + "tag": "a", + "attributes": { + "href": "https://genius.com/albums/Kendrick-lamar/Good-kid-m-a-a-d-city", + "rel": "noopener" + }, + "data": { "api_path": "/albums/15946" }, + "children": [{ "tag": "em", "children": ["good kid, m.A.A.d city"] }] + }, + ", which was widely regarded as an instant classic. In 2015, he released ", + { + "tag": "a", + "attributes": { + "href": "https://genius.com/albums/Kendrick-lamar/To-pimp-a-butterfly", + "rel": "noopener" + }, + "data": { "api_path": "/albums/120991" }, + "children": [{ "tag": "em", "children": ["To Pimp a Butterfly"] }] + }, + " to widespread acclaim. The album debuted at No. 1 on the Billboard 200 Albums Chart. The following year, ", + { + "tag": "a", + "attributes": { + "href": "https://genius.com/albums/Kendrick-lamar/Untitled-unmastered", + "rel": "noopener" + }, + "data": { "api_path": "/albums/145606" }, + "children": [{ "tag": "em", "children": ["untitled unmastered."] }] + }, + " was released by surprise. In April of 2017, Kendrick released ", + { + "tag": "a", + "attributes": { "href": "https://genius.com/albums/Kendrick-lamar/Damn", "rel": "noopener" }, + "data": { "api_path": "/albums/337082" }, + "children": [{ "tag": "em", "children": ["DAMN."] }] + }, + " on ", + { + "tag": "a", + "attributes": { "href": "https://www.britannica.com/topic/Good-Friday", "rel": "noopener nofollow" }, + "children": ["Good Friday"] + }, + ". After five years of silence, on May 13, 2022, Kendrick released his fifth studio album, ", + { + "tag": "a", + "attributes": { + "href": "https://genius.com/albums/Kendrick-lamar/Mr-morale-the-big-steppers", + "rel": "noopener" + }, + "data": { "api_path": "/albums/657430" }, + "children": [{ "tag": "em", "children": ["Mr. Morale & The Big Steppers"] }] + }, + "." + ] + }, + "", + { + "tag": "p", + "children": [ + "Known for his storytelling, imagery, wordplay, passion and varied song structures, Kendrick brings hard-hitting lyricism with narratives to the West Coast, not traditionally known for its lyricists." + ] + }, + "", + { + "tag": "p", + "children": [ + "Kendrick Lamar’s position within the rap game is held incredibly high. Lamar was ranked at No. 2 on Billboard’s ", + { + "tag": "a", + "attributes": { + "href": "https://www.billboard.com/lists/best-rappers-all-time/2-kendrick-lamar/", + "rel": "noopener nofollow" + }, + "children": [{ "tag": "em", "children": ["10 Best Rappers of All Time"] }] + }, + " list, alongside artists like ", + { + "tag": "a", + "attributes": { "href": "https://genius.com/artists/Jay-z", "rel": "noopener" }, + "data": { "api_path": "/artists/2" }, + "children": ["Jay-Z"] + }, + ", ", + { + "tag": "a", + "attributes": { "href": "https://genius.com/artists/Nas", "rel": "noopener" }, + "data": { "api_path": "/artists/56" }, + "children": ["Nas"] + }, + ", ", + { + "tag": "a", + "attributes": { "href": "https://genius.com/artists/The-notorious-big", "rel": "noopener" }, + "data": { "api_path": "/artists/22" }, + "children": ["Notorious B.I.G."] + }, + " and more. To-date, he has also been ", + { + "tag": "a", + "attributes": { + "href": "https://www.grammy.com/artists/kendrick-lamar/17949", + "rel": "noopener nofollow" + }, + "children": ["nominated for 57 Grammy Awards"] + }, + " and has won 22 of them; with three for Best Rap Album. He is also the first rapper to win all of the Grammy Awards in the rap categories at the same ceremony; doing so in 2016 and 2018. This feat wouldn’t be accomplished again until 2024 when Atlanta veteran rapper, ", + { + "tag": "a", + "attributes": { "href": "https://genius.com/artists/Killer-mike", "rel": "noopener" }, + "data": { "api_path": "/artists/547" }, + "children": ["Killer Mike"] + }, + ", ", + { + "tag": "a", + "attributes": { "href": "https://genius.com/5047179", "rel": "noopener" }, + "data": { "api_path": "/referents/5047179" }, + "children": ["already mentioned"] + }, + " on Kendrick Lamar’s “Hood Politics” swept the three Rap categories for ", + { + "tag": "a", + "attributes": { "href": "https://genius.com/albums/Killer-mike/Michael", "rel": "noopener" }, + "data": { "api_path": "/albums/964374" }, + "children": ["MICHAEL"] + }, + ". During the 67th Grammy Awards Ceremony, Kendrick Lamar would extend his historic wins by sweeping all five categories he was nominated for, including; Best Music Video, Best Rap Performance, Best Rap Song, Song of The Year, and Record of The Year. The latter two wins, marks only ", + { + "tag": "a", + "attributes": { + "href": "https://www.billboard.com/music/awards/childish-gambino-this-is-america-wins-record-of-the-year-grammys-8497638/", + "rel": "noopener nofollow" + }, + "children": ["the second-time a rapper has accomplished this"] + }, + "." + ] + }, + "", + { + "tag": "p", + "children": [ + "Lamar is a member of the hip-hop collective ", + { + "tag": "a", + "attributes": { "href": "https://genius.com/artists/Black-hippy", "rel": "noopener" }, + "data": { "api_path": "/artists/17985" }, + "children": ["Black Hippy"] + }, + ", along with ", + { + "tag": "a", + "attributes": { "href": "https://genius.com/artists/Jay-rock", "rel": "noopener" }, + "data": { "api_path": "/artists/1403" }, + "children": ["Jay Rock"] + }, + ", ", + { + "tag": "a", + "attributes": { "href": "https://genius.com/artists/Schoolboy-q", "rel": "noopener" }, + "data": { "api_path": "/artists/11353" }, + "children": ["ScHoolboy Q"] + }, + " and ", + { + "tag": "a", + "attributes": { "href": "https://genius.com/artists/Ab-soul", "rel": "noopener" }, + "data": { "api_path": "/artists/2049" }, + "children": ["Ab-Soul"] + }, + "—all of whom came up together as a part of ", + { + "tag": "a", + "attributes": { "href": "https://genius.com/artists/Top-dawg-entertainment", "rel": "noopener" }, + "data": { "api_path": "/artists/1108010" }, + "children": ["Top Dawg Entertainment"] + }, + "; however, in 2022, it was ", + { + "tag": "a", + "attributes": { "href": "https://oklama.com/nuthoughts", "rel": "noopener nofollow" }, + "children": ["announced"] + }, + " that Kendrick would be departing TDE following the release of his fifth studio album. He is also signed to ", + { + "tag": "a", + "attributes": { "href": "https://genius.com/artists/Dr-dre", "rel": "noopener" }, + "data": { "api_path": "/artists/123" }, + "children": ["Dr. Dre"] + }, + "’s ", + { + "tag": "a", + "attributes": { "href": "https://genius.com/artists/Aftermath-entertainment/bio", "rel": "noopener" }, + "data": { "api_path": "/artists/1136259" }, + "children": ["Aftermath Entertainment"] + }, + " imprint, under ", + { + "tag": "a", + "attributes": { "href": "https://genius.com/artists/Interscope-records", "rel": "noopener" }, + "data": { "api_path": "/artists/143490" }, + "children": ["Interscope Records"] + }, + "." + ] + }, + "", + { + "tag": "p", + "children": [ + "In February of 2018, Kendrick and TDE released ", + { + "tag": "a", + "attributes": { + "href": "https://genius.com/albums/Kendrick-lamar-the-weeknd-and-sza/Black-panther-the-album-music-from-and-inspired-by", + "rel": "noopener" + }, + "data": { "api_path": "/albums/363114" }, + "children": [{ "tag": "em", "children": ["Black Panther: The Album (Music from and Inspired by)"] }] + }, + ". It debuted at No. 1 on the ", + { + "tag": "a", + "attributes": { + "href": "https://www.billboard.com/charts/billboard-200", + "rel": "noopener nofollow" + }, + "children": ["Billboard 200"] + }, + ". In April, later the same year, he won the ", + { + "tag": "a", + "attributes": { "href": "http://www.pulitzer.org/", "rel": "noopener nofollow" }, + "children": ["Pulitzer Prize"] + }, + " in music for his album, ", + { "tag": "em", "children": ["DAMN."] } + ] + }, + "", + { + "tag": "p", + "children": [ + "Several years of relative inactivity followed, with Kendrick only resurfacing for features or collaborative efforts. In March of 2020, Lamar and ", + { + "tag": "a", + "attributes": { "href": "https://genius.com/artists/Dave-free", "rel": "noopener" }, + "data": { "api_path": "/artists/27862" }, + "children": ["Dave Free"] + }, + " launched ", + { + "tag": "a", + "attributes": { "href": "https://genius.com/artists/Pglang", "rel": "noopener" }, + "data": { "api_path": "/artists/2135881" }, + "children": ["PgLang"] + }, + ", a production company whose name stands for “program language.” In August 2021, Kendrick launched a ", + { + "tag": "a", + "attributes": { "href": "http://oklama.com/", "rel": "noopener nofollow" }, + "children": ["new website"] + }, + ", where he proceeded to announce the release date for his next project in April of 2022. ", + { "tag": "em", "children": ["Mr. Morale & The Big Steppers"] }, + " appeared on Friday, May 13, as promised—a double album five years in the making." + ] + }, + "", + { + "tag": "p", + "children": [ + "Kendrick would finally surface again in 2024 with a surprise feature on ", + { + "tag": "a", + "attributes": { "href": "https://genius.com/artists/Future", "rel": "noopener" }, + "data": { "api_path": "/artists/2197" }, + "children": ["Future"] + }, + " and ", + { + "tag": "a", + "attributes": { "href": "https://genius.com/artists/Metro-boomin", "rel": "noopener" }, + "data": { "api_path": "/artists/33010" }, + "children": ["Metro Boomin"] + }, + "’s March collaboration, ", + { + "tag": "a", + "attributes": { + "href": "https://genius.com/Future-metro-boomin-and-kendrick-lamar-like-that-lyrics", + "rel": "noopener" + }, + "data": { "api_path": "/songs/10125497" }, + "children": ["“Like That.”"] + }, + " This verse kicked off Kendrick’s ", + { + "tag": "a", + "attributes": { + "href": "https://www.nytimes.com/2024/05/06/arts/music/kendrick-lamar-drake-explainer.html", + "rel": "noopener nofollow" + }, + "children": ["well-documented battle"] + }, + " against ", + { + "tag": "a", + "attributes": { "href": "https://genius.com/artists/Drake", "rel": "noopener" }, + "data": { "api_path": "/artists/130" }, + "children": ["Drake"] + }, + " which saw the Compton MC release four diss tracks. The most popular of which, ", + { + "tag": "a", + "attributes": { "href": "https://genius.com/Kendrick-lamar-not-like-us-lyrics", "rel": "noopener" }, + "data": { "api_path": "/songs/10359264" }, + "children": ["“Not Like Us,”"] + }, + " would become Kendrick’s second solo ", + { + "tag": "a", + "attributes": { + "href": "https://www.billboard.com/lists/kendrick-lamar-not-like-us-hot-100-number-one-debut/", + "rel": "noopener nofollow" + }, + "children": ["number one single"] + }, + ". The track’s ", + { + "tag": "a", + "attributes": { "href": "https://www.youtube.com/watch?v=H58vbez_m4E", "rel": "noopener nofollow" }, + "children": ["music video"] + }, + " would release on ", + { + "tag": "a", + "attributes": { + "href": "https://www.britannica.com/topic/Independence-Day-United-States-holiday", + "rel": "noopener nofollow" + }, + "children": ["July 4/Independence Day"] + }, + ", two months after its initial release." + ] + }, + "", + { + "tag": "p", + "children": [ + "Coming off the heel of the battle, Kendrick would announce ", + { + "tag": "a", + "attributes": { + "href": "https://www.youtube.com/watch?v=oIEKK_j0fss&feature=youtu.be", + "rel": "noopener nofollow" + }, + "children": ["his Superbowl Half Time performance"] + }, + " via ", + { + "tag": "a", + "attributes": { + "href": "https://x.com/kendricklamar/status/1832804013894689232", + "rel": "noopener nofollow" + }, + "children": ["his own social media accounts"] + }, + " on September 8, 2024. On November 22, 2024, K-Dot released his much-anticipated sixth studio album, ", + { + "tag": "a", + "attributes": { "href": "https://genius.com/albums/Kendrick-lamar/Gnx", "rel": "noopener" }, + "data": { "api_path": "/albums/1209251" }, + "children": [{ "tag": "em", "children": ["GNX"] }] + }, + ", after ", + { + "tag": "a", + "attributes": { "href": "https://www.youtube.com/watch?v=D7liwdjvhWc", "rel": "noopener nofollow" }, + "children": ["teasing the project"] + }, + " only thirty minutes beforehand." + ] + } + ] + } + }, + "facebook_name": "kendricklamar", + "header_image_url": "https://images.genius.com/1d39f4a8c2906db0e696e5cc4427fa92.300x300x1.png", + "id": 1421, + "image_url": "https://images.genius.com/43c7fc30a6d9fd31b239bb47cf1533f4.1000x1000x1.png", + "instagram_name": "kendricklamar", + "is_meme_verified": true, + "is_verified": true, + "name": "Kendrick Lamar", + "social_links": { + "tidal": "https://tidal.com/artist/3816041", + "shazam": "https://www.shazam.com/artist/kendrick-lamar/368183298", + "spotify": "https://open.spotify.com/intl-de/artist/2YZyLoL8N0Wb9xBt1NhZWg", + "twitter": "kendricklamar", + "youtube": "https://youtube.com/@kendricklamar", + "facebook": "kendricklamar", + "instagram": "kendricklamar", + "soundcloud": "https://soundcloud.com/kendrick-lamar-music", + "apple_music": "https://music.apple.com/de/artist/kendrick-lamar/368183298", + "amazon_music": "https://music.amazon.de/artists/B0042QIKAK" + }, + "translation_artist": false, + "twitter_name": "kendricklamar", + "url": "https://genius.com/artists/Kendrick-lamar", + "current_user_metadata": { + "permissions": ["follow", "view_activity_stream", "view_contribution_opportunities", "view_discography"], + "excluded_permissions": [ + "edit", + "edit_images", + "edit_names", + "edit_anything", + "merge", + "sort_artist_songs", + "edit_translation_artist", + "split", + "sort_artist_songs_by_lyrics_edit_proposals", + "see_short_id" + ], + "interactions": { "following": false } + }, + "followers_count": 31826, + "iq": 69426, + "artist_relationships": [ + { + "relationship_type": "member_of", + "artists": [ + { + "api_path": "/artists/17985", + "header_image_url": "https://images.genius.com/2e678143ab605d48fc9f852b589894e4.722x354x1.jpg", + "id": 17985, + "image_url": "https://images.genius.com/671e489c8dd0b99c784889fe87415033.452x452x1.jpg", + "is_meme_verified": false, + "is_verified": false, + "name": "Black Hippy", + "url": "https://genius.com/artists/Black-hippy" + } + ] + } + ], + "description_annotation": { + "_type": "referent", + "annotator_id": 1057, + "annotator_login": "dragon191", + "api_path": "/referents/6927681", + "classification": "accepted", + "fragment": "Kendrick Lamar", + "id": 6927681, + "is_description": true, + "path": "/6927681/Kendrick-lamar/Kendrick-lamar", + "range": { "content": "Kendrick Lamar" }, + "song_id": null, + "url": "https://genius.com/6927681/Kendrick-lamar/Kendrick-lamar", + "verified_annotator_ids": [], + "annotatable": { + "api_path": "/artists/1421", + "context": null, + "id": 1421, + "image_url": "https://images.genius.com/43c7fc30a6d9fd31b239bb47cf1533f4.1000x1000x1.png", + "link_title": "Kendrick Lamar", + "title": "Kendrick Lamar", + "type": "Artist", + "url": "https://genius.com/artists/Kendrick-lamar" + }, + "annotations": [ + { + "api_path": "/annotations/6927681", + "body": { + "dom": { + "tag": "root", + "children": [ + { + "tag": "p", + "children": [ + { + "tag": "a", + "attributes": { "href": "http://www.kendricklamar.com/", "rel": "noopener nofollow" }, + "children": ["Kendrick Lamar"] + }, + " Duckworth (born June 17, 1987) is an American rapper and songwriter from Compton, California." + ] + }, + "", + { + "tag": "p", + "children": [ + "He first gained major attention after the release of his 2010 mixtape ", + { + "tag": "a", + "attributes": { + "href": "https://genius.com/albums/Kendrick-lamar/Overly-dedicated", + "rel": "noopener" + }, + "data": { "api_path": "/albums/10919" }, + "children": [{ "tag": "em", "children": ["O(verly) D(edicated)"] }] + }, + ". In 2011, his album ", + { + "tag": "a", + "attributes": { + "href": "https://genius.com/albums/Kendrick-lamar/Section-80", + "rel": "noopener" + }, + "data": { "api_path": "/albums/11160" }, + "children": [{ "tag": "em", "children": ["Section.80"] }] + }, + ", released exclusively through iTunes, instantly ranked as one of the top digital hip-hop releases of the year. In 2012, he crossed over to mainstream audiences with his major label debut, ", + { + "tag": "a", + "attributes": { + "href": "https://genius.com/albums/Kendrick-lamar/Good-kid-m-a-a-d-city", + "rel": "noopener" + }, + "data": { "api_path": "/albums/15946" }, + "children": [{ "tag": "em", "children": ["good kid, m.A.A.d city"] }] + }, + ", which was widely regarded as an instant classic. In 2015, he released ", + { + "tag": "a", + "attributes": { + "href": "https://genius.com/albums/Kendrick-lamar/To-pimp-a-butterfly", + "rel": "noopener" + }, + "data": { "api_path": "/albums/120991" }, + "children": [{ "tag": "em", "children": ["To Pimp a Butterfly"] }] + }, + " to widespread acclaim. The album debuted at No. 1 on the Billboard 200 Albums Chart. The following year, ", + { + "tag": "a", + "attributes": { + "href": "https://genius.com/albums/Kendrick-lamar/Untitled-unmastered", + "rel": "noopener" + }, + "data": { "api_path": "/albums/145606" }, + "children": [{ "tag": "em", "children": ["untitled unmastered."] }] + }, + " was released by surprise. In April of 2017, Kendrick released ", + { + "tag": "a", + "attributes": { "href": "https://genius.com/albums/Kendrick-lamar/Damn", "rel": "noopener" }, + "data": { "api_path": "/albums/337082" }, + "children": [{ "tag": "em", "children": ["DAMN."] }] + }, + " on ", + { + "tag": "a", + "attributes": { + "href": "https://www.britannica.com/topic/Good-Friday", + "rel": "noopener nofollow" + }, + "children": ["Good Friday"] + }, + ". After five years of silence, on May 13, 2022, Kendrick released his fifth studio album, ", + { + "tag": "a", + "attributes": { + "href": "https://genius.com/albums/Kendrick-lamar/Mr-morale-the-big-steppers", + "rel": "noopener" + }, + "data": { "api_path": "/albums/657430" }, + "children": [{ "tag": "em", "children": ["Mr. Morale & The Big Steppers"] }] + }, + "." + ] + }, + "", + { + "tag": "p", + "children": [ + "Known for his storytelling, imagery, wordplay, passion and varied song structures, Kendrick brings hard-hitting lyricism with narratives to the West Coast, not traditionally known for its lyricists." + ] + }, + "", + { + "tag": "p", + "children": [ + "Kendrick Lamar’s position within the rap game is held incredibly high. Lamar was ranked at No. 2 on Billboard’s ", + { + "tag": "a", + "attributes": { + "href": "https://www.billboard.com/lists/best-rappers-all-time/2-kendrick-lamar/", + "rel": "noopener nofollow" + }, + "children": [{ "tag": "em", "children": ["10 Best Rappers of All Time"] }] + }, + " list, alongside artists like ", + { + "tag": "a", + "attributes": { "href": "https://genius.com/artists/Jay-z", "rel": "noopener" }, + "data": { "api_path": "/artists/2" }, + "children": ["Jay-Z"] + }, + ", ", + { + "tag": "a", + "attributes": { "href": "https://genius.com/artists/Nas", "rel": "noopener" }, + "data": { "api_path": "/artists/56" }, + "children": ["Nas"] + }, + ", ", + { + "tag": "a", + "attributes": { "href": "https://genius.com/artists/The-notorious-big", "rel": "noopener" }, + "data": { "api_path": "/artists/22" }, + "children": ["Notorious B.I.G."] + }, + " and more. To-date, he has also been ", + { + "tag": "a", + "attributes": { + "href": "https://www.grammy.com/artists/kendrick-lamar/17949", + "rel": "noopener nofollow" + }, + "children": ["nominated for 57 Grammy Awards"] + }, + " and has won 22 of them; with three for Best Rap Album. He is also the first rapper to win all of the Grammy Awards in the rap categories at the same ceremony; doing so in 2016 and 2018. This feat wouldn’t be accomplished again until 2024 when Atlanta veteran rapper, ", + { + "tag": "a", + "attributes": { "href": "https://genius.com/artists/Killer-mike", "rel": "noopener" }, + "data": { "api_path": "/artists/547" }, + "children": ["Killer Mike"] + }, + ", ", + { + "tag": "a", + "attributes": { "href": "https://genius.com/5047179", "rel": "noopener" }, + "data": { "api_path": "/referents/5047179" }, + "children": ["already mentioned"] + }, + " on Kendrick Lamar’s “Hood Politics” swept the three Rap categories for ", + { + "tag": "a", + "attributes": { "href": "https://genius.com/albums/Killer-mike/Michael", "rel": "noopener" }, + "data": { "api_path": "/albums/964374" }, + "children": ["MICHAEL"] + }, + ". During the 67th Grammy Awards Ceremony, Kendrick Lamar would extend his historic wins by sweeping all five categories he was nominated for, including; Best Music Video, Best Rap Performance, Best Rap Song, Song of The Year, and Record of The Year. The latter two wins, marks only ", + { + "tag": "a", + "attributes": { + "href": "https://www.billboard.com/music/awards/childish-gambino-this-is-america-wins-record-of-the-year-grammys-8497638/", + "rel": "noopener nofollow" + }, + "children": ["the second-time a rapper has accomplished this"] + }, + "." + ] + }, + "", + { + "tag": "p", + "children": [ + "Lamar is a member of the hip-hop collective ", + { + "tag": "a", + "attributes": { "href": "https://genius.com/artists/Black-hippy", "rel": "noopener" }, + "data": { "api_path": "/artists/17985" }, + "children": ["Black Hippy"] + }, + ", along with ", + { + "tag": "a", + "attributes": { "href": "https://genius.com/artists/Jay-rock", "rel": "noopener" }, + "data": { "api_path": "/artists/1403" }, + "children": ["Jay Rock"] + }, + ", ", + { + "tag": "a", + "attributes": { "href": "https://genius.com/artists/Schoolboy-q", "rel": "noopener" }, + "data": { "api_path": "/artists/11353" }, + "children": ["ScHoolboy Q"] + }, + " and ", + { + "tag": "a", + "attributes": { "href": "https://genius.com/artists/Ab-soul", "rel": "noopener" }, + "data": { "api_path": "/artists/2049" }, + "children": ["Ab-Soul"] + }, + "—all of whom came up together as a part of ", + { + "tag": "a", + "attributes": { + "href": "https://genius.com/artists/Top-dawg-entertainment", + "rel": "noopener" + }, + "data": { "api_path": "/artists/1108010" }, + "children": ["Top Dawg Entertainment"] + }, + "; however, in 2022, it was ", + { + "tag": "a", + "attributes": { "href": "https://oklama.com/nuthoughts", "rel": "noopener nofollow" }, + "children": ["announced"] + }, + " that Kendrick would be departing TDE following the release of his fifth studio album. He is also signed to ", + { + "tag": "a", + "attributes": { "href": "https://genius.com/artists/Dr-dre", "rel": "noopener" }, + "data": { "api_path": "/artists/123" }, + "children": ["Dr. Dre"] + }, + "’s ", + { + "tag": "a", + "attributes": { + "href": "https://genius.com/artists/Aftermath-entertainment/bio", + "rel": "noopener" + }, + "data": { "api_path": "/artists/1136259" }, + "children": ["Aftermath Entertainment"] + }, + " imprint, under ", + { + "tag": "a", + "attributes": { "href": "https://genius.com/artists/Interscope-records", "rel": "noopener" }, + "data": { "api_path": "/artists/143490" }, + "children": ["Interscope Records"] + }, + "." + ] + }, + "", + { + "tag": "p", + "children": [ + "In February of 2018, Kendrick and TDE released ", + { + "tag": "a", + "attributes": { + "href": "https://genius.com/albums/Kendrick-lamar-the-weeknd-and-sza/Black-panther-the-album-music-from-and-inspired-by", + "rel": "noopener" + }, + "data": { "api_path": "/albums/363114" }, + "children": [ + { "tag": "em", "children": ["Black Panther: The Album (Music from and Inspired by)"] } + ] + }, + ". It debuted at No. 1 on the ", + { + "tag": "a", + "attributes": { + "href": "https://www.billboard.com/charts/billboard-200", + "rel": "noopener nofollow" + }, + "children": ["Billboard 200"] + }, + ". In April, later the same year, he won the ", + { + "tag": "a", + "attributes": { "href": "http://www.pulitzer.org/", "rel": "noopener nofollow" }, + "children": ["Pulitzer Prize"] + }, + " in music for his album, ", + { "tag": "em", "children": ["DAMN."] } + ] + }, + "", + { + "tag": "p", + "children": [ + "Several years of relative inactivity followed, with Kendrick only resurfacing for features or collaborative efforts. In March of 2020, Lamar and ", + { + "tag": "a", + "attributes": { "href": "https://genius.com/artists/Dave-free", "rel": "noopener" }, + "data": { "api_path": "/artists/27862" }, + "children": ["Dave Free"] + }, + " launched ", + { + "tag": "a", + "attributes": { "href": "https://genius.com/artists/Pglang", "rel": "noopener" }, + "data": { "api_path": "/artists/2135881" }, + "children": ["PgLang"] + }, + ", a production company whose name stands for “program language.” In August 2021, Kendrick launched a ", + { + "tag": "a", + "attributes": { "href": "http://oklama.com/", "rel": "noopener nofollow" }, + "children": ["new website"] + }, + ", where he proceeded to announce the release date for his next project in April of 2022. ", + { "tag": "em", "children": ["Mr. Morale & The Big Steppers"] }, + " appeared on Friday, May 13, as promised—a double album five years in the making." + ] + }, + "", + { + "tag": "p", + "children": [ + "Kendrick would finally surface again in 2024 with a surprise feature on ", + { + "tag": "a", + "attributes": { "href": "https://genius.com/artists/Future", "rel": "noopener" }, + "data": { "api_path": "/artists/2197" }, + "children": ["Future"] + }, + " and ", + { + "tag": "a", + "attributes": { "href": "https://genius.com/artists/Metro-boomin", "rel": "noopener" }, + "data": { "api_path": "/artists/33010" }, + "children": ["Metro Boomin"] + }, + "’s March collaboration, ", + { + "tag": "a", + "attributes": { + "href": "https://genius.com/Future-metro-boomin-and-kendrick-lamar-like-that-lyrics", + "rel": "noopener" + }, + "data": { "api_path": "/songs/10125497" }, + "children": ["“Like That.”"] + }, + " This verse kicked off Kendrick’s ", + { + "tag": "a", + "attributes": { + "href": "https://www.nytimes.com/2024/05/06/arts/music/kendrick-lamar-drake-explainer.html", + "rel": "noopener nofollow" + }, + "children": ["well-documented battle"] + }, + " against ", + { + "tag": "a", + "attributes": { "href": "https://genius.com/artists/Drake", "rel": "noopener" }, + "data": { "api_path": "/artists/130" }, + "children": ["Drake"] + }, + " which saw the Compton MC release four diss tracks. The most popular of which, ", + { + "tag": "a", + "attributes": { + "href": "https://genius.com/Kendrick-lamar-not-like-us-lyrics", + "rel": "noopener" + }, + "data": { "api_path": "/songs/10359264" }, + "children": ["“Not Like Us,”"] + }, + " would become Kendrick’s second solo ", + { + "tag": "a", + "attributes": { + "href": "https://www.billboard.com/lists/kendrick-lamar-not-like-us-hot-100-number-one-debut/", + "rel": "noopener nofollow" + }, + "children": ["number one single"] + }, + ". The track’s ", + { + "tag": "a", + "attributes": { + "href": "https://www.youtube.com/watch?v=H58vbez_m4E", + "rel": "noopener nofollow" + }, + "children": ["music video"] + }, + " would release on ", + { + "tag": "a", + "attributes": { + "href": "https://www.britannica.com/topic/Independence-Day-United-States-holiday", + "rel": "noopener nofollow" + }, + "children": ["July 4/Independence Day"] + }, + ", two months after its initial release." + ] + }, + "", + { + "tag": "p", + "children": [ + "Coming off the heel of the battle, Kendrick would announce ", + { + "tag": "a", + "attributes": { + "href": "https://www.youtube.com/watch?v=oIEKK_j0fss&feature=youtu.be", + "rel": "noopener nofollow" + }, + "children": ["his Superbowl Half Time performance"] + }, + " via ", + { + "tag": "a", + "attributes": { + "href": "https://x.com/kendricklamar/status/1832804013894689232", + "rel": "noopener nofollow" + }, + "children": ["his own social media accounts"] + }, + " on September 8, 2024. On November 22, 2024, K-Dot released his much-anticipated sixth studio album, ", + { + "tag": "a", + "attributes": { "href": "https://genius.com/albums/Kendrick-lamar/Gnx", "rel": "noopener" }, + "data": { "api_path": "/albums/1209251" }, + "children": [{ "tag": "em", "children": ["GNX"] }] + }, + ", after ", + { + "tag": "a", + "attributes": { + "href": "https://www.youtube.com/watch?v=D7liwdjvhWc", + "rel": "noopener nofollow" + }, + "children": ["teasing the project"] + }, + " only thirty minutes beforehand." + ] + } + ] + } + }, + "comment_count": 5, + "community": true, + "custom_preview": null, + "has_voters": true, + "id": 6927681, + "pinned": false, + "share_url": "https://genius.com/6927681", + "source": null, + "state": "accepted", + "url": "https://genius.com/6927681/Kendrick-lamar/Kendrick-lamar", + "verified": false, + "votes_total": 1785, + "current_user_metadata": { + "permissions": ["vote", "propose_edit_to", "report_as_abusive", "create_comment"], + "excluded_permissions": [ + "edit", + "cosign", + "uncosign", + "destroy", + "accept", + "reject", + "see_unreviewed", + "clear_votes", + "pin_to_profile", + "unpin_from_profile", + "update_source", + "edit_custom_preview" + ], + "interactions": { "cosign": false, "pyong": false, "vote": null }, + "iq_by_action": { + "accept": { "primary": { "multiplier": 1, "base": 10.0, "applicable": true } }, + "reject": { "primary": { "multiplier": 1, "base": 2.0, "applicable": true } }, + "delete": { "primary": { "multiplier": 1, "base": 5.0, "applicable": true } } + } + }, + "authors": [ + { + "attribution": 0.1695402298850575, + "pinned_role": null, + "user": { + "api_path": "/users/1603328", + "avatar": { + "tiny": { + "url": "https://images.genius.com/avatars/tiny/773f9640b0b2e0ad1c6f7fedffb70a1d", + "bounding_box": { "width": 16, "height": 16 } + }, + "thumb": { + "url": "https://images.genius.com/avatars/thumb/773f9640b0b2e0ad1c6f7fedffb70a1d", + "bounding_box": { "width": 32, "height": 32 } + }, + "small": { + "url": "https://images.genius.com/avatars/small/773f9640b0b2e0ad1c6f7fedffb70a1d", + "bounding_box": { "width": 100, "height": 100 } + }, + "medium": { + "url": "https://images.genius.com/avatars/medium/773f9640b0b2e0ad1c6f7fedffb70a1d", + "bounding_box": { "width": 300, "height": 400 } + } + }, + "header_image_url": "https://images.genius.com/e372f40ee0a6d090ffd11b4c5518a5a9.1000x370x1.jpg", + "human_readable_role_for_display": "Moderator", + "id": 1603328, + "iq": 459911, + "login": "kingkillmonger", + "name": "ʞ|ace|woe|k", + "role_for_display": "moderator", + "url": "https://genius.com/kingkillmonger", + "current_user_metadata": { + "permissions": ["follow"], + "excluded_permissions": [], + "interactions": { "following": false } + } + } + }, + { + "attribution": 0.1235632183908046, + "pinned_role": null, + "user": { + "api_path": "/users/8365583", + "avatar": { + "tiny": { + "url": "https://images.genius.com/avatars/tiny/908e5e61944cbd2d062211d345a50693", + "bounding_box": { "width": 16, "height": 16 } + }, + "thumb": { + "url": "https://images.genius.com/avatars/thumb/908e5e61944cbd2d062211d345a50693", + "bounding_box": { "width": 32, "height": 32 } + }, + "small": { + "url": "https://images.genius.com/avatars/small/908e5e61944cbd2d062211d345a50693", + "bounding_box": { "width": 100, "height": 100 } + }, + "medium": { + "url": "https://images.genius.com/avatars/medium/908e5e61944cbd2d062211d345a50693", + "bounding_box": { "width": 300, "height": 400 } + } + }, + "header_image_url": "https://images.genius.com/74d4dae12f8165c5a11572bd2479cfdb.728x228x1.jpg", + "human_readable_role_for_display": "Editor", + "id": 8365583, + "iq": 91517, + "login": "LGF", + "name": "LGF", + "role_for_display": "editor", + "url": "https://genius.com/LGF", + "current_user_metadata": { + "permissions": ["follow"], + "excluded_permissions": [], + "interactions": { "following": false } + } + } + }, + { + "attribution": 0.11494252873563218, + "pinned_role": null, + "user": { + "api_path": "/users/1057", + "avatar": { + "tiny": { + "url": "https://s3.amazonaws.com/rapgenius/avatars/tiny/1057_ae_universe.jpg", + "bounding_box": { "width": 16, "height": 16 } + }, + "thumb": { + "url": "https://s3.amazonaws.com/rapgenius/avatars/thumb/1358288265_1057_ae_universe.jpg", + "bounding_box": { "width": 32, "height": 32 } + }, + "small": { + "url": "https://s3.amazonaws.com/rapgenius/avatars/small/1358288265_1057_ae_universe.jpg", + "bounding_box": { "width": 100, "height": 100 } + }, + "medium": { + "url": "https://s3.amazonaws.com/rapgenius/avatars/medium/1358288265_1057_ae_universe.jpg", + "bounding_box": { "width": 300, "height": 400 } + } + }, + "header_image_url": "https://assets.genius.com/images/default_banner.png?1778095399", + "human_readable_role_for_display": "Contributor", + "id": 1057, + "iq": 2334, + "login": "dragon191", + "name": "dragon191", + "role_for_display": "contributor", + "url": "https://genius.com/dragon191", + "current_user_metadata": { + "permissions": ["follow"], + "excluded_permissions": [], + "interactions": { "following": false } + } + } + }, + { + "attribution": 0.07758620689655173, + "pinned_role": null, + "user": { + "api_path": "/users/21720218", + "avatar": { + "tiny": { + "url": "https://images.genius.com/avatars/tiny/0e78497a508fb4960ac2a25d9c4cf906", + "bounding_box": { "width": 16, "height": 16 } + }, + "thumb": { + "url": "https://images.genius.com/avatars/thumb/0e78497a508fb4960ac2a25d9c4cf906", + "bounding_box": { "width": 32, "height": 32 } + }, + "small": { + "url": "https://images.genius.com/avatars/small/0e78497a508fb4960ac2a25d9c4cf906", + "bounding_box": { "width": 100, "height": 100 } + }, + "medium": { + "url": "https://images.genius.com/avatars/medium/0e78497a508fb4960ac2a25d9c4cf906", + "bounding_box": { "width": 300, "height": 400 } + } + }, + "header_image_url": "https://assets.genius.com/images/default_banner.png?1778095399", + "human_readable_role_for_display": "Contributor", + "id": 21720218, + "iq": 744, + "login": "CrownedxKay", + "name": "CrownedxKay", + "role_for_display": "contributor", + "url": "https://genius.com/CrownedxKay", + "current_user_metadata": { + "permissions": ["follow"], + "excluded_permissions": [], + "interactions": { "following": false } + } + } + }, + { + "attribution": 0.0617816091954023, + "pinned_role": null, + "user": { + "api_path": "/users/46981", + "avatar": { + "tiny": { + "url": "https://images.rapgenius.com/avatars/tiny/a2e3c022d0b2b4b87a17acec38db0d95", + "bounding_box": { "width": 16, "height": 16 } + }, + "thumb": { + "url": "https://images.rapgenius.com/avatars/thumb/a2e3c022d0b2b4b87a17acec38db0d95", + "bounding_box": { "width": 32, "height": 32 } + }, + "small": { + "url": "https://images.rapgenius.com/avatars/small/a2e3c022d0b2b4b87a17acec38db0d95", + "bounding_box": { "width": 100, "height": 100 } + }, + "medium": { + "url": "https://images.rapgenius.com/avatars/medium/a2e3c022d0b2b4b87a17acec38db0d95", + "bounding_box": { "width": 300, "height": 400 } + } + }, + "header_image_url": "https://assets.genius.com/images/default_banner.png?1778095399", + "human_readable_role_for_display": "Contributor", + "id": 46981, + "iq": 156755, + "login": "BennySwans", + "name": "BennySwoons", + "role_for_display": "contributor", + "url": "https://genius.com/BennySwans", + "current_user_metadata": { + "permissions": ["follow"], + "excluded_permissions": [], + "interactions": { "following": false } + } + } + }, + { + "attribution": 0.04166666666666667, + "pinned_role": null, + "user": { + "api_path": "/users/4256751", + "avatar": { + "tiny": { + "url": "https://filepicker-images.genius.com/d48ytvIiQS65JTlfrSU2_352fd7954b2a08321132d80e2cb3531a.354x240x6.gif", + "bounding_box": { "width": 16, "height": 16 } + }, + "thumb": { + "url": "https://filepicker-images.genius.com/d48ytvIiQS65JTlfrSU2_352fd7954b2a08321132d80e2cb3531a.354x240x6.gif", + "bounding_box": { "width": 32, "height": 32 } + }, + "small": { + "url": "https://filepicker-images.genius.com/d48ytvIiQS65JTlfrSU2_352fd7954b2a08321132d80e2cb3531a.354x240x6.gif", + "bounding_box": { "width": 100, "height": 100 } + }, + "medium": { + "url": "https://filepicker-images.genius.com/d48ytvIiQS65JTlfrSU2_352fd7954b2a08321132d80e2cb3531a.354x240x6.gif", + "bounding_box": { "width": 300, "height": 400 } + } + }, + "header_image_url": "https://filepicker-images.genius.com/ywcq538ti4", + "human_readable_role_for_display": "Contributor", + "id": 4256751, + "iq": 623, + "login": "BluntLotion", + "name": "BluntLotion", + "role_for_display": "contributor", + "url": "https://genius.com/BluntLotion", + "current_user_metadata": { + "permissions": ["follow"], + "excluded_permissions": [], + "interactions": { "following": false } + } + } + }, + { + "attribution": 0.040229885057471264, + "pinned_role": null, + "user": { + "api_path": "/users/8092777", + "avatar": { + "tiny": { + "url": "https://images.genius.com/avatars/tiny/03f31b0214bb9e62e774ace0d1cd3eee", + "bounding_box": { "width": 16, "height": 16 } + }, + "thumb": { + "url": "https://images.genius.com/avatars/thumb/03f31b0214bb9e62e774ace0d1cd3eee", + "bounding_box": { "width": 32, "height": 32 } + }, + "small": { + "url": "https://images.genius.com/avatars/small/03f31b0214bb9e62e774ace0d1cd3eee", + "bounding_box": { "width": 100, "height": 100 } + }, + "medium": { + "url": "https://images.genius.com/avatars/medium/03f31b0214bb9e62e774ace0d1cd3eee", + "bounding_box": { "width": 300, "height": 400 } + } + }, + "header_image_url": "https://images.genius.com/760c0a8e1037cd845860db2a45f7c86a.1000x1000x1.png", + "human_readable_role_for_display": "Editor", + "id": 8092777, + "iq": 467299, + "login": "thedevilwalksamongstus", + "name": "THEDEVILWALKSAMONGSTUS", + "role_for_display": "editor", + "url": "https://genius.com/thedevilwalksamongstus", + "current_user_metadata": { + "permissions": ["follow"], + "excluded_permissions": [], + "interactions": { "following": false } + } + } + }, + { + "attribution": 0.034482758620689655, + "pinned_role": null, + "user": { + "api_path": "/users/33985", + "avatar": { + "tiny": { + "url": "https://images.genius.com/avatars/tiny/74331624454cc69ca53c07ce6f2533f8", + "bounding_box": { "width": 16, "height": 16 } + }, + "thumb": { + "url": "https://images.genius.com/avatars/thumb/74331624454cc69ca53c07ce6f2533f8", + "bounding_box": { "width": 32, "height": 32 } + }, + "small": { + "url": "https://images.genius.com/avatars/small/74331624454cc69ca53c07ce6f2533f8", + "bounding_box": { "width": 100, "height": 100 } + }, + "medium": { + "url": "https://images.genius.com/avatars/medium/74331624454cc69ca53c07ce6f2533f8", + "bounding_box": { "width": 300, "height": 400 } + } + }, + "header_image_url": "https://assets.genius.com/images/default_banner.png?1778095399", + "human_readable_role_for_display": "Editor", + "id": 33985, + "iq": 130704, + "login": "Haifisch", + "name": "Haifisch", + "role_for_display": "editor", + "url": "https://genius.com/Haifisch", + "current_user_metadata": { + "permissions": ["follow"], + "excluded_permissions": [], + "interactions": { "following": false } + } + } + }, + { + "attribution": 0.027298850574712645, + "pinned_role": null, + "user": { + "api_path": "/users/143147", + "avatar": { + "tiny": { + "url": "https://images.genius.com/avatars/tiny/720cefbaf38d10f0d4e25ab4eb93bfc8", + "bounding_box": { "width": 16, "height": 16 } + }, + "thumb": { + "url": "https://images.genius.com/avatars/thumb/720cefbaf38d10f0d4e25ab4eb93bfc8", + "bounding_box": { "width": 32, "height": 32 } + }, + "small": { + "url": "https://images.genius.com/avatars/small/720cefbaf38d10f0d4e25ab4eb93bfc8", + "bounding_box": { "width": 100, "height": 100 } + }, + "medium": { + "url": "https://images.genius.com/avatars/medium/720cefbaf38d10f0d4e25ab4eb93bfc8", + "bounding_box": { "width": 300, "height": 400 } + } + }, + "header_image_url": "https://assets.genius.com/images/default_banner.png?1778095399", + "human_readable_role_for_display": "Contributor", + "id": 143147, + "iq": 12054, + "login": "NSLRB", + "name": "NSLRB", + "role_for_display": "contributor", + "url": "https://genius.com/NSLRB", + "current_user_metadata": { + "permissions": ["follow"], + "excluded_permissions": [], + "interactions": { "following": false } + } + } + }, + { + "attribution": 0.02586206896551724, + "pinned_role": null, + "user": { + "api_path": "/users/6072426", + "avatar": { + "tiny": { + "url": "https://images.genius.com/avatars/tiny/00d604d742fd777130247c94034ec9cb", + "bounding_box": { "width": 16, "height": 16 } + }, + "thumb": { + "url": "https://images.genius.com/avatars/thumb/00d604d742fd777130247c94034ec9cb", + "bounding_box": { "width": 32, "height": 32 } + }, + "small": { + "url": "https://images.genius.com/avatars/small/00d604d742fd777130247c94034ec9cb", + "bounding_box": { "width": 100, "height": 100 } + }, + "medium": { + "url": "https://images.genius.com/avatars/medium/00d604d742fd777130247c94034ec9cb", + "bounding_box": { "width": 300, "height": 400 } + } + }, + "header_image_url": "https://assets.genius.com/images/default_banner.png?1778095399", + "human_readable_role_for_display": "Contributor", + "id": 6072426, + "iq": 474, + "login": "LilMash", + "name": "LilMash", + "role_for_display": "contributor", + "url": "https://genius.com/LilMash", + "current_user_metadata": { + "permissions": ["follow"], + "excluded_permissions": [], + "interactions": { "following": false } + } + } + }, + { + "attribution": 0.024425287356321837, + "pinned_role": null, + "user": { + "api_path": "/users/1272178", + "avatar": { + "tiny": { + "url": "https://images.rapgenius.com/avatars/tiny/c6e6d17c35b4d49b1a2768cdb87c1c32", + "bounding_box": { "width": 16, "height": 16 } + }, + "thumb": { + "url": "https://images.rapgenius.com/avatars/thumb/c6e6d17c35b4d49b1a2768cdb87c1c32", + "bounding_box": { "width": 32, "height": 32 } + }, + "small": { + "url": "https://images.rapgenius.com/avatars/small/c6e6d17c35b4d49b1a2768cdb87c1c32", + "bounding_box": { "width": 100, "height": 100 } + }, + "medium": { + "url": "https://images.rapgenius.com/avatars/medium/c6e6d17c35b4d49b1a2768cdb87c1c32", + "bounding_box": { "width": 300, "height": 400 } + } + }, + "header_image_url": "https://assets.genius.com/images/default_banner.png?1778095399", + "human_readable_role_for_display": "Contributor", + "id": 1272178, + "iq": 542, + "login": "INFINITY--GEM", + "name": "INFINITY--GEM", + "role_for_display": "contributor", + "url": "https://genius.com/INFINITY--GEM", + "current_user_metadata": { + "permissions": ["follow"], + "excluded_permissions": [], + "interactions": { "following": false } + } + } + }, + { + "attribution": 0.01867816091954023, + "pinned_role": null, + "user": { + "api_path": "/users/133552", + "avatar": { + "tiny": { + "url": "https://s3.amazonaws.com/rapgenius/avatars/tiny/133552_converse.png", + "bounding_box": { "width": 16, "height": 16 } + }, + "thumb": { + "url": "https://s3.amazonaws.com/rapgenius/avatars/thumb/1358291197_133552_converse.png", + "bounding_box": { "width": 32, "height": 32 } + }, + "small": { + "url": "https://s3.amazonaws.com/rapgenius/avatars/small/1358291197_133552_converse.png", + "bounding_box": { "width": 100, "height": 100 } + }, + "medium": { + "url": "https://s3.amazonaws.com/rapgenius/avatars/medium/1358291197_133552_converse.png", + "bounding_box": { "width": 300, "height": 400 } + } + }, + "header_image_url": "https://assets.genius.com/images/default_banner.png?1778095399", + "human_readable_role_for_display": "Contributor", + "id": 133552, + "iq": 853, + "login": "TheNotoriousJIV", + "name": "TheNotoriousJIV", + "role_for_display": "contributor", + "url": "https://genius.com/TheNotoriousJIV", + "current_user_metadata": { + "permissions": ["follow"], + "excluded_permissions": [], + "interactions": { "following": false } + } + } + }, + { + "attribution": 0.01867816091954023, + "pinned_role": null, + "user": { + "api_path": "/users/2582485", + "avatar": { + "tiny": { + "url": "https://images.rapgenius.com/avatars/tiny/e45567bb06ff6bad8d48adf1d4937a8c", + "bounding_box": { "width": 16, "height": 16 } + }, + "thumb": { + "url": "https://images.rapgenius.com/avatars/thumb/e45567bb06ff6bad8d48adf1d4937a8c", + "bounding_box": { "width": 32, "height": 32 } + }, + "small": { + "url": "https://images.rapgenius.com/avatars/small/e45567bb06ff6bad8d48adf1d4937a8c", + "bounding_box": { "width": 100, "height": 100 } + }, + "medium": { + "url": "https://images.rapgenius.com/avatars/medium/e45567bb06ff6bad8d48adf1d4937a8c", + "bounding_box": { "width": 300, "height": 400 } + } + }, + "header_image_url": "https://assets.genius.com/images/default_banner.png?1778095399", + "human_readable_role_for_display": "Contributor", + "id": 2582485, + "iq": 1232, + "login": "CNolan75", + "name": "CNolan75", + "role_for_display": "contributor", + "url": "https://genius.com/CNolan75", + "current_user_metadata": { + "permissions": ["follow"], + "excluded_permissions": [], + "interactions": { "following": false } + } + } + }, + { + "attribution": 0.017241379310344827, + "pinned_role": null, + "user": { + "api_path": "/users/265732", + "avatar": { + "tiny": { + "url": "https://images.rapgenius.com/avatars/tiny/c9afb3ba2c2704fa76ff242f1eadcd03", + "bounding_box": { "width": 16, "height": 16 } + }, + "thumb": { + "url": "https://images.rapgenius.com/avatars/thumb/c9afb3ba2c2704fa76ff242f1eadcd03", + "bounding_box": { "width": 32, "height": 32 } + }, + "small": { + "url": "https://images.rapgenius.com/avatars/small/c9afb3ba2c2704fa76ff242f1eadcd03", + "bounding_box": { "width": 100, "height": 100 } + }, + "medium": { + "url": "https://images.rapgenius.com/avatars/medium/c9afb3ba2c2704fa76ff242f1eadcd03", + "bounding_box": { "width": 300, "height": 400 } + } + }, + "header_image_url": "https://assets.genius.com/images/default_banner.png?1778095399", + "human_readable_role_for_display": "Editor", + "id": 265732, + "iq": 263070, + "login": "Vesuvius", + "name": "Vesuvius", + "role_for_display": "editor", + "url": "https://genius.com/Vesuvius", + "current_user_metadata": { + "permissions": ["follow"], + "excluded_permissions": [], + "interactions": { "following": false } + } + } + }, + { + "attribution": 0.017241379310344827, + "pinned_role": null, + "user": { + "api_path": "/users/2797923", + "avatar": { + "tiny": { + "url": "https://filepicker-images.genius.com/sjzb34wbwff", + "bounding_box": { "width": 16, "height": 16 } + }, + "thumb": { + "url": "https://filepicker-images.genius.com/sjzb34wbwff", + "bounding_box": { "width": 32, "height": 32 } + }, + "small": { + "url": "https://filepicker-images.genius.com/sjzb34wbwff", + "bounding_box": { "width": 100, "height": 100 } + }, + "medium": { + "url": "https://filepicker-images.genius.com/sjzb34wbwff", + "bounding_box": { "width": 300, "height": 400 } + } + }, + "header_image_url": "https://filepicker-images.genius.com/dx7250a8mc8", + "human_readable_role_for_display": "Contributor", + "id": 2797923, + "iq": 519, + "login": "escobadmon", + "name": "escobadmon", + "role_for_display": "contributor", + "url": "https://genius.com/escobadmon", + "current_user_metadata": { + "permissions": ["follow"], + "excluded_permissions": [], + "interactions": { "following": false } + } + } + }, + { + "attribution": 0.015804597701149427, + "pinned_role": null, + "user": { + "api_path": "/users/336394", + "avatar": { + "tiny": { + "url": "https://images.rapgenius.com/avatars/tiny/Fy086iwPSEW3Z3JNXhGN", + "bounding_box": { "width": 16, "height": 16 } + }, + "thumb": { + "url": "https://images.rapgenius.com/avatars/thumb/Fy086iwPSEW3Z3JNXhGN", + "bounding_box": { "width": 32, "height": 32 } + }, + "small": { + "url": "https://images.rapgenius.com/avatars/small/Fy086iwPSEW3Z3JNXhGN", + "bounding_box": { "width": 100, "height": 100 } + }, + "medium": { + "url": "https://images.rapgenius.com/avatars/medium/Fy086iwPSEW3Z3JNXhGN", + "bounding_box": { "width": 300, "height": 400 } + } + }, + "header_image_url": "https://assets.genius.com/images/default_banner.png?1778095399", + "human_readable_role_for_display": null, + "id": 336394, + "iq": 221, + "login": "Pat_Riot", + "name": "Pat_Riot", + "role_for_display": null, + "url": "https://genius.com/Pat_Riot", + "current_user_metadata": { + "permissions": ["follow"], + "excluded_permissions": [], + "interactions": { "following": false } + } + } + }, + { + "attribution": 0.015804597701149427, + "pinned_role": null, + "user": { + "api_path": "/users/993805", + "avatar": { + "tiny": { + "url": "https://filepicker-images.genius.com/ruar8gm48qe", + "bounding_box": { "width": 16, "height": 16 } + }, + "thumb": { + "url": "https://filepicker-images.genius.com/ruar8gm48qe", + "bounding_box": { "width": 32, "height": 32 } + }, + "small": { + "url": "https://filepicker-images.genius.com/ruar8gm48qe", + "bounding_box": { "width": 100, "height": 100 } + }, + "medium": { + "url": "https://filepicker-images.genius.com/ruar8gm48qe", + "bounding_box": { "width": 300, "height": 400 } + } + }, + "header_image_url": "https://filepicker-images.genius.com/73c9ellj2f7", + "human_readable_role_for_display": "Contributor", + "id": 993805, + "iq": 85759, + "login": "StayInTheHouse", + "name": "StayInTheHouse", + "role_for_display": "contributor", + "url": "https://genius.com/StayInTheHouse", + "current_user_metadata": { + "permissions": ["follow"], + "excluded_permissions": [], + "interactions": { "following": false } + } + } + }, + { + "attribution": 0.015804597701149427, + "pinned_role": null, + "user": { + "api_path": "/users/4512480", + "avatar": { + "tiny": { + "url": "https://lh4.googleusercontent.com/-AGd8J2m9hl4/AAAAAAAAAAI/AAAAAAAAADM/ZsTG9EONkHs/photo.jpg", + "bounding_box": { "width": 16, "height": 16 } + }, + "thumb": { + "url": "https://lh4.googleusercontent.com/-AGd8J2m9hl4/AAAAAAAAAAI/AAAAAAAAADM/ZsTG9EONkHs/photo.jpg", + "bounding_box": { "width": 32, "height": 32 } + }, + "small": { + "url": "https://lh4.googleusercontent.com/-AGd8J2m9hl4/AAAAAAAAAAI/AAAAAAAAADM/ZsTG9EONkHs/photo.jpg", + "bounding_box": { "width": 100, "height": 100 } + }, + "medium": { + "url": "https://lh4.googleusercontent.com/-AGd8J2m9hl4/AAAAAAAAAAI/AAAAAAAAADM/ZsTG9EONkHs/photo.jpg", + "bounding_box": { "width": 300, "height": 400 } + } + }, + "header_image_url": "https://filepicker-images.genius.com/jlbxh6h1brs", + "human_readable_role_for_display": "Editor", + "id": 4512480, + "iq": 7811, + "login": "SeventhDimension", + "name": "SeventhDimension", + "role_for_display": "editor", + "url": "https://genius.com/SeventhDimension", + "current_user_metadata": { + "permissions": ["follow"], + "excluded_permissions": [], + "interactions": { "following": false } + } + } + }, + { + "attribution": 0.014367816091954023, + "pinned_role": null, + "user": { + "api_path": "/users/94414", + "avatar": { + "tiny": { + "url": "https://images.rapgenius.com/avatars/tiny/44c07903206ea93d4502404cf6170171", + "bounding_box": { "width": 16, "height": 16 } + }, + "thumb": { + "url": "https://images.rapgenius.com/avatars/thumb/44c07903206ea93d4502404cf6170171", + "bounding_box": { "width": 32, "height": 32 } + }, + "small": { + "url": "https://images.rapgenius.com/avatars/small/44c07903206ea93d4502404cf6170171", + "bounding_box": { "width": 100, "height": 100 } + }, + "medium": { + "url": "https://images.rapgenius.com/avatars/medium/44c07903206ea93d4502404cf6170171", + "bounding_box": { "width": 300, "height": 400 } + } + }, + "header_image_url": "https://assets.genius.com/images/default_banner.png?1778095399", + "human_readable_role_for_display": null, + "id": 94414, + "iq": 217, + "login": "nolanick504", + "name": "nolanick504", + "role_for_display": null, + "url": "https://genius.com/nolanick504", + "current_user_metadata": { + "permissions": ["follow"], + "excluded_permissions": [], + "interactions": { "following": false } + } + } + }, + { + "attribution": 0.011494252873563218, + "pinned_role": null, + "user": { + "api_path": "/users/14187", + "avatar": { + "tiny": { + "url": "https://s3.amazonaws.com/rapgenius/avatars/original/14187_3ibKg.jpg?1333323077", + "bounding_box": { "width": 16, "height": 16 } + }, + "thumb": { + "url": "https://s3.amazonaws.com/rapgenius/avatars/original/14187_3ibKg.jpg?1333323077", + "bounding_box": { "width": 32, "height": 32 } + }, + "small": { + "url": "https://s3.amazonaws.com/rapgenius/avatars/original/14187_3ibKg.jpg?1333323077", + "bounding_box": { "width": 100, "height": 100 } + }, + "medium": { + "url": "https://s3.amazonaws.com/rapgenius/avatars/original/14187_3ibKg.jpg?1333323077", + "bounding_box": { "width": 300, "height": 400 } + } + }, + "header_image_url": "https://filepicker-images.genius.com/yglf64lqvzc", + "human_readable_role_for_display": "Contributor", + "id": 14187, + "iq": 36321, + "login": "TwistedMental", + "name": "TwistedMental", + "role_for_display": "contributor", + "url": "https://genius.com/TwistedMental", + "current_user_metadata": { + "permissions": ["follow"], + "excluded_permissions": [], + "interactions": { "following": false } + } + } + }, + { + "attribution": 0.011494252873563218, + "pinned_role": null, + "user": { + "api_path": "/users/11524", + "avatar": { + "tiny": { + "url": "https://images.rapgenius.com/avatars/tiny/e7b84a26140d5becfc5614929303367f", + "bounding_box": { "width": 16, "height": 16 } + }, + "thumb": { + "url": "https://images.rapgenius.com/avatars/thumb/e7b84a26140d5becfc5614929303367f", + "bounding_box": { "width": 32, "height": 32 } + }, + "small": { + "url": "https://images.rapgenius.com/avatars/small/e7b84a26140d5becfc5614929303367f", + "bounding_box": { "width": 100, "height": 100 } + }, + "medium": { + "url": "https://images.rapgenius.com/avatars/medium/e7b84a26140d5becfc5614929303367f", + "bounding_box": { "width": 300, "height": 400 } + } + }, + "header_image_url": "https://assets.genius.com/images/default_banner.png?1778095399", + "human_readable_role_for_display": "Editor", + "id": 11524, + "iq": 327638, + "login": "tomi", + "name": "Tomi Fischer", + "role_for_display": "editor", + "url": "https://genius.com/tomi", + "current_user_metadata": { + "permissions": ["follow"], + "excluded_permissions": [], + "interactions": { "following": false } + } + } + }, + { + "attribution": 0.011494252873563218, + "pinned_role": null, + "user": { + "api_path": "/users/1237897", + "avatar": { + "tiny": { + "url": "https://assets.genius.com/images/default_cover_image.png?1778095399", + "bounding_box": { "width": 16, "height": 16 } + }, + "thumb": { + "url": "https://assets.genius.com/images/default_cover_image.png?1778095399", + "bounding_box": { "width": 32, "height": 32 } + }, + "small": { + "url": "https://assets.genius.com/images/default_cover_image.png?1778095399", + "bounding_box": { "width": 100, "height": 100 } + }, + "medium": { + "url": "https://assets.genius.com/images/default_cover_image.png?1778095399", + "bounding_box": { "width": 300, "height": 400 } + } + }, + "header_image_url": "https://assets.genius.com/images/default_banner.png?1778095399", + "human_readable_role_for_display": null, + "id": 1237897, + "iq": 82, + "login": "dr_dre23", + "name": "dr_dre23", + "role_for_display": null, + "url": "https://genius.com/dr_dre23", + "current_user_metadata": { + "permissions": ["follow"], + "excluded_permissions": [], + "interactions": { "following": false } + } + } + }, + { + "attribution": 0.011494252873563218, + "pinned_role": null, + "user": { + "api_path": "/users/316149", + "avatar": { + "tiny": { + "url": "https://images.rapgenius.com/avatars/tiny/WpBNgaRyR76L7XJad60a", + "bounding_box": { "width": 16, "height": 16 } + }, + "thumb": { + "url": "https://images.rapgenius.com/avatars/thumb/WpBNgaRyR76L7XJad60a", + "bounding_box": { "width": 32, "height": 32 } + }, + "small": { + "url": "https://images.rapgenius.com/avatars/small/WpBNgaRyR76L7XJad60a", + "bounding_box": { "width": 100, "height": 100 } + }, + "medium": { + "url": "https://images.rapgenius.com/avatars/medium/WpBNgaRyR76L7XJad60a", + "bounding_box": { "width": 300, "height": 400 } + } + }, + "header_image_url": "https://assets.genius.com/images/default_banner.png?1778095399", + "human_readable_role_for_display": "Contributor", + "id": 316149, + "iq": 863, + "login": "RGHOST", + "name": "RGHOST", + "role_for_display": "contributor", + "url": "https://genius.com/RGHOST", + "current_user_metadata": { + "permissions": ["follow"], + "excluded_permissions": [], + "interactions": { "following": false } + } + } + }, + { + "attribution": 0.011494252873563218, + "pinned_role": null, + "user": { + "api_path": "/users/312329", + "avatar": { + "tiny": { + "url": "https://images.genius.com/avatars/tiny/92d93001f24a7c355040c34124518b00", + "bounding_box": { "width": 16, "height": 16 } + }, + "thumb": { + "url": "https://images.genius.com/avatars/thumb/92d93001f24a7c355040c34124518b00", + "bounding_box": { "width": 32, "height": 32 } + }, + "small": { + "url": "https://images.genius.com/avatars/small/92d93001f24a7c355040c34124518b00", + "bounding_box": { "width": 100, "height": 100 } + }, + "medium": { + "url": "https://images.genius.com/avatars/medium/92d93001f24a7c355040c34124518b00", + "bounding_box": { "width": 300, "height": 400 } + } + }, + "header_image_url": "https://images.genius.com/5c3c91a6060df690301d93aeab39e25c.351x356x1.jpg", + "human_readable_role_for_display": "Contributor", + "id": 312329, + "iq": 25667, + "login": "whenigetfree", + "name": "Whenigetfree", + "role_for_display": "contributor", + "url": "https://genius.com/whenigetfree", + "current_user_metadata": { + "permissions": ["follow"], + "excluded_permissions": [], + "interactions": { "following": false } + } + } + }, + { + "attribution": 0.011494252873563218, + "pinned_role": null, + "user": { + "api_path": "/users/481008", + "avatar": { + "tiny": { + "url": "https://images.rapgenius.com/avatars/tiny/29c2eaddc6461b2d8a54b11241eb6e0d", + "bounding_box": { "width": 16, "height": 16 } + }, + "thumb": { + "url": "https://images.rapgenius.com/avatars/thumb/29c2eaddc6461b2d8a54b11241eb6e0d", + "bounding_box": { "width": 32, "height": 32 } + }, + "small": { + "url": "https://images.rapgenius.com/avatars/small/29c2eaddc6461b2d8a54b11241eb6e0d", + "bounding_box": { "width": 100, "height": 100 } + }, + "medium": { + "url": "https://images.rapgenius.com/avatars/medium/29c2eaddc6461b2d8a54b11241eb6e0d", + "bounding_box": { "width": 300, "height": 400 } + } + }, + "header_image_url": "https://assets.genius.com/images/default_banner.png?1778095399", + "human_readable_role_for_display": "Contributor", + "id": 481008, + "iq": 4890, + "login": "meehaww", + "name": "meehaww", + "role_for_display": "contributor", + "url": "https://genius.com/meehaww", + "current_user_metadata": { + "permissions": ["follow"], + "excluded_permissions": [], + "interactions": { "following": false } + } + } + }, + { + "attribution": 0.008620689655172414, + "pinned_role": null, + "user": { + "api_path": "/users/3355118", + "avatar": { + "tiny": { + "url": "https://images.genius.com/avatars/tiny/0ca5fd8b17872345d7d0318c0ce737b7", + "bounding_box": { "width": 16, "height": 16 } + }, + "thumb": { + "url": "https://images.genius.com/avatars/thumb/0ca5fd8b17872345d7d0318c0ce737b7", + "bounding_box": { "width": 32, "height": 32 } + }, + "small": { + "url": "https://images.genius.com/avatars/small/0ca5fd8b17872345d7d0318c0ce737b7", + "bounding_box": { "width": 100, "height": 100 } + }, + "medium": { + "url": "https://images.genius.com/avatars/medium/0ca5fd8b17872345d7d0318c0ce737b7", + "bounding_box": { "width": 300, "height": 400 } + } + }, + "header_image_url": "https://images.genius.com/9980d4ad7fef159fb09f8f4920adc9b2.1000x714x1.jpg", + "human_readable_role_for_display": "Editor", + "id": 3355118, + "iq": 322198, + "login": "chanhmatt", + "name": "Matthew Huynh", + "role_for_display": "editor", + "url": "https://genius.com/chanhmatt", + "current_user_metadata": { + "permissions": ["follow"], + "excluded_permissions": [], + "interactions": { "following": false } + } + } + }, + { + "attribution": 0.008620689655172414, + "pinned_role": null, + "user": { + "api_path": "/users/16697104", + "avatar": { + "tiny": { + "url": "https://images.genius.com/avatars/tiny/9c6548ea5180eaab0004beca230fca2f", + "bounding_box": { "width": 16, "height": 16 } + }, + "thumb": { + "url": "https://images.genius.com/avatars/thumb/9c6548ea5180eaab0004beca230fca2f", + "bounding_box": { "width": 32, "height": 32 } + }, + "small": { + "url": "https://images.genius.com/avatars/small/9c6548ea5180eaab0004beca230fca2f", + "bounding_box": { "width": 100, "height": 100 } + }, + "medium": { + "url": "https://images.genius.com/avatars/medium/9c6548ea5180eaab0004beca230fca2f", + "bounding_box": { "width": 300, "height": 400 } + } + }, + "header_image_url": "https://assets.genius.com/images/default_banner.png?1778095399", + "human_readable_role_for_display": "Contributor", + "id": 16697104, + "iq": 1474, + "login": "muhsee6", + "name": "muhsee6", + "role_for_display": "contributor", + "url": "https://genius.com/muhsee6", + "current_user_metadata": { + "permissions": ["follow"], + "excluded_permissions": [], + "interactions": { "following": false } + } + } + }, + { + "attribution": 0.007183908045977011, + "pinned_role": null, + "user": { + "api_path": "/users/923739", + "avatar": { + "tiny": { + "url": "https://images.genius.com/avatars/tiny/ea9b6b625c739d23c95760ce89a3b2d8", + "bounding_box": { "width": 16, "height": 16 } + }, + "thumb": { + "url": "https://images.genius.com/avatars/thumb/ea9b6b625c739d23c95760ce89a3b2d8", + "bounding_box": { "width": 32, "height": 32 } + }, + "small": { + "url": "https://images.genius.com/avatars/small/ea9b6b625c739d23c95760ce89a3b2d8", + "bounding_box": { "width": 100, "height": 100 } + }, + "medium": { + "url": "https://images.genius.com/avatars/medium/ea9b6b625c739d23c95760ce89a3b2d8", + "bounding_box": { "width": 300, "height": 400 } + } + }, + "header_image_url": "https://assets.genius.com/images/default_banner.png?1778095399", + "human_readable_role_for_display": "Editor", + "id": 923739, + "iq": 113467, + "login": "theKuzG", + "name": "The Kuz Giacometti", + "role_for_display": "editor", + "url": "https://genius.com/theKuzG", + "current_user_metadata": { + "permissions": ["follow"], + "excluded_permissions": [], + "interactions": { "following": false } + } + } + }, + { + "attribution": 0.005747126436781609, + "pinned_role": null, + "user": { + "api_path": "/users/5749685", + "avatar": { + "tiny": { + "url": "https://images.genius.com/avatars/tiny/daea91c933d27b98f2361446237603dd", + "bounding_box": { "width": 16, "height": 16 } + }, + "thumb": { + "url": "https://images.genius.com/avatars/thumb/daea91c933d27b98f2361446237603dd", + "bounding_box": { "width": 32, "height": 32 } + }, + "small": { + "url": "https://images.genius.com/avatars/small/daea91c933d27b98f2361446237603dd", + "bounding_box": { "width": 100, "height": 100 } + }, + "medium": { + "url": "https://images.genius.com/avatars/medium/daea91c933d27b98f2361446237603dd", + "bounding_box": { "width": 300, "height": 400 } + } + }, + "header_image_url": "https://assets.genius.com/images/default_banner.png?1778095399", + "human_readable_role_for_display": null, + "id": 5749685, + "iq": 209, + "login": "Insffrbl", + "name": "Insffrbl", + "role_for_display": null, + "url": "https://genius.com/Insffrbl", + "current_user_metadata": { + "permissions": ["follow"], + "excluded_permissions": [], + "interactions": { "following": false } + } + } + }, + { + "attribution": 0.005747126436781609, + "pinned_role": null, + "user": { + "api_path": "/users/21762091", + "avatar": { + "tiny": { + "url": "https://images.genius.com/avatars/tiny/98921f0f7c45bbd1fc4014792b66d6fd", + "bounding_box": { "width": 16, "height": 16 } + }, + "thumb": { + "url": "https://images.genius.com/avatars/thumb/98921f0f7c45bbd1fc4014792b66d6fd", + "bounding_box": { "width": 32, "height": 32 } + }, + "small": { + "url": "https://images.genius.com/avatars/small/98921f0f7c45bbd1fc4014792b66d6fd", + "bounding_box": { "width": 100, "height": 100 } + }, + "medium": { + "url": "https://images.genius.com/avatars/medium/98921f0f7c45bbd1fc4014792b66d6fd", + "bounding_box": { "width": 300, "height": 400 } + } + }, + "header_image_url": "https://filepicker-images.genius.com/6473b08570993c9497f9876c3f90645b7f2ab8546b47c8d0d411c8eef0373480%2Fs1cjh3p0m2", + "human_readable_role_for_display": "Contributor", + "id": 21762091, + "iq": 15944, + "login": "camzvium", + "name": "camzvium", + "role_for_display": "contributor", + "url": "https://genius.com/camzvium", + "current_user_metadata": { + "permissions": ["follow"], + "excluded_permissions": [], + "interactions": { "following": false } + } + } + }, + { + "attribution": 0.004310344827586207, + "pinned_role": null, + "user": { + "api_path": "/users/2996174", + "avatar": { + "tiny": { + "url": "https://images.genius.com/avatars/tiny/41e4aecf2b22be564e51d5b77e4d3b22", + "bounding_box": { "width": 16, "height": 16 } + }, + "thumb": { + "url": "https://images.genius.com/avatars/thumb/41e4aecf2b22be564e51d5b77e4d3b22", + "bounding_box": { "width": 32, "height": 32 } + }, + "small": { + "url": "https://images.genius.com/avatars/small/41e4aecf2b22be564e51d5b77e4d3b22", + "bounding_box": { "width": 100, "height": 100 } + }, + "medium": { + "url": "https://images.genius.com/avatars/medium/41e4aecf2b22be564e51d5b77e4d3b22", + "bounding_box": { "width": 300, "height": 400 } + } + }, + "header_image_url": "https://images.genius.com/d411654e6e45d9ce1a5178548892d340.562x1000x1.png", + "human_readable_role_for_display": "Editor", + "id": 2996174, + "iq": 48534, + "login": "UnannotatedUnmastered", + "name": "Corban", + "role_for_display": "editor", + "url": "https://genius.com/UnannotatedUnmastered", + "current_user_metadata": { + "permissions": ["follow"], + "excluded_permissions": [], + "interactions": { "following": false } + } + } + }, + { + "attribution": 0.0028735632183908046, + "pinned_role": null, + "user": { + "api_path": "/users/3280867", + "avatar": { + "tiny": { + "url": "https://images.genius.com/avatars/tiny/e0ac494f0dee814616b695fae91ab287", + "bounding_box": { "width": 16, "height": 16 } + }, + "thumb": { + "url": "https://images.genius.com/avatars/thumb/e0ac494f0dee814616b695fae91ab287", + "bounding_box": { "width": 32, "height": 32 } + }, + "small": { + "url": "https://images.genius.com/avatars/small/e0ac494f0dee814616b695fae91ab287", + "bounding_box": { "width": 100, "height": 100 } + }, + "medium": { + "url": "https://images.genius.com/avatars/medium/e0ac494f0dee814616b695fae91ab287", + "bounding_box": { "width": 300, "height": 400 } + } + }, + "header_image_url": "https://filepicker-images.genius.com/tnEL0bhURqSh2IWuDAkT_tumblr_o13n2leEUa1u6fq9ao1_500.gif", + "human_readable_role_for_display": "Editor", + "id": 3280867, + "iq": 4851, + "login": "ACRP", + "name": "ACRP", + "role_for_display": "editor", + "url": "https://genius.com/ACRP", + "current_user_metadata": { + "permissions": ["follow"], + "excluded_permissions": [], + "interactions": { "following": false } + } + } + }, + { + "attribution": 0.0028735632183908046, + "pinned_role": null, + "user": { + "api_path": "/users/50988", + "avatar": { + "tiny": { + "url": "https://images.rapgenius.com/avatars/tiny/8bccae9a677b2659c31cc151b5e4bfd8", + "bounding_box": { "width": 16, "height": 16 } + }, + "thumb": { + "url": "https://images.rapgenius.com/avatars/thumb/8bccae9a677b2659c31cc151b5e4bfd8", + "bounding_box": { "width": 32, "height": 32 } + }, + "small": { + "url": "https://images.rapgenius.com/avatars/small/8bccae9a677b2659c31cc151b5e4bfd8", + "bounding_box": { "width": 100, "height": 100 } + }, + "medium": { + "url": "https://images.rapgenius.com/avatars/medium/8bccae9a677b2659c31cc151b5e4bfd8", + "bounding_box": { "width": 300, "height": 400 } + } + }, + "header_image_url": "https://assets.genius.com/images/default_banner.png?1778095399", + "human_readable_role_for_display": "Editor", + "id": 50988, + "iq": 182516, + "login": "nietzsche", + "name": "Briansusername", + "role_for_display": "editor", + "url": "https://genius.com/nietzsche", + "current_user_metadata": { + "permissions": ["follow"], + "excluded_permissions": [], + "interactions": { "following": false } + } + } + }, + { + "attribution": 0.0028735632183908046, + "pinned_role": null, + "user": { + "api_path": "/users/141291", + "avatar": { + "tiny": { + "url": "https://images.rapgenius.com/avatars/tiny/845fd01203157969bce194cbc8065f03", + "bounding_box": { "width": 16, "height": 16 } + }, + "thumb": { + "url": "https://images.rapgenius.com/avatars/thumb/845fd01203157969bce194cbc8065f03", + "bounding_box": { "width": 32, "height": 32 } + }, + "small": { + "url": "https://images.rapgenius.com/avatars/small/845fd01203157969bce194cbc8065f03", + "bounding_box": { "width": 100, "height": 100 } + }, + "medium": { + "url": "https://images.rapgenius.com/avatars/medium/845fd01203157969bce194cbc8065f03", + "bounding_box": { "width": 300, "height": 400 } + } + }, + "header_image_url": "https://assets.genius.com/images/default_banner.png?1778095399", + "human_readable_role_for_display": "Contributor", + "id": 141291, + "iq": 91311, + "login": "123andtotha4", + "name": "123andtotha4", + "role_for_display": "contributor", + "url": "https://genius.com/123andtotha4", + "current_user_metadata": { + "permissions": ["follow"], + "excluded_permissions": [], + "interactions": { "following": false } + } + } + }, + { + "attribution": 0.0028735632183908046, + "pinned_role": null, + "user": { + "api_path": "/users/127469", + "avatar": { + "tiny": { + "url": "https://images.rapgenius.com/avatars/tiny/bec6b4e5e1c79992ef430e06dd831f44", + "bounding_box": { "width": 16, "height": 16 } + }, + "thumb": { + "url": "https://images.rapgenius.com/avatars/thumb/bec6b4e5e1c79992ef430e06dd831f44", + "bounding_box": { "width": 32, "height": 32 } + }, + "small": { + "url": "https://images.rapgenius.com/avatars/small/bec6b4e5e1c79992ef430e06dd831f44", + "bounding_box": { "width": 100, "height": 100 } + }, + "medium": { + "url": "https://images.rapgenius.com/avatars/medium/bec6b4e5e1c79992ef430e06dd831f44", + "bounding_box": { "width": 300, "height": 400 } + } + }, + "header_image_url": "https://assets.genius.com/images/default_banner.png?1778095399", + "human_readable_role_for_display": "Contributor", + "id": 127469, + "iq": 20148, + "login": "Turkebaconsandwhich", + "name": "Turkebaconsandwhich", + "role_for_display": "contributor", + "url": "https://genius.com/Turkebaconsandwhich", + "current_user_metadata": { + "permissions": ["follow"], + "excluded_permissions": [], + "interactions": { "following": false } + } + } + }, + { + "attribution": 0.0014367816091954023, + "pinned_role": null, + "user": { + "api_path": "/users/14985074", + "avatar": { + "tiny": { + "url": "https://images.genius.com/9ea93d60f90abfdfb72f017cec03c90d.719x719x1.jpg", + "bounding_box": { "width": 16, "height": 16 } + }, + "thumb": { + "url": "https://images.genius.com/9ea93d60f90abfdfb72f017cec03c90d.719x719x1.jpg", + "bounding_box": { "width": 32, "height": 32 } + }, + "small": { + "url": "https://images.genius.com/9ea93d60f90abfdfb72f017cec03c90d.719x719x1.jpg", + "bounding_box": { "width": 100, "height": 100 } + }, + "medium": { + "url": "https://images.genius.com/9ea93d60f90abfdfb72f017cec03c90d.719x719x1.jpg", + "bounding_box": { "width": 300, "height": 400 } + } + }, + "header_image_url": "https://images.genius.com/08019dd7988e1f2091e25c26d4b541af.1000x602x1.jpg", + "human_readable_role_for_display": "Contributor", + "id": 14985074, + "iq": 13583, + "login": "miketysonblowtotheface", + "name": "miketysonblowtotheface", + "role_for_display": "contributor", + "url": "https://genius.com/miketysonblowtotheface", + "current_user_metadata": { + "permissions": ["follow"], + "excluded_permissions": [], + "interactions": { "following": false } + } + } + }, + { + "attribution": 0.0014367816091954023, + "pinned_role": null, + "user": { + "api_path": "/users/12657641", + "avatar": { + "tiny": { + "url": "https://images.genius.com/avatars/tiny/73e90badf9e35a8388b779fcd29b2543", + "bounding_box": { "width": 16, "height": 16 } + }, + "thumb": { + "url": "https://images.genius.com/avatars/thumb/73e90badf9e35a8388b779fcd29b2543", + "bounding_box": { "width": 32, "height": 32 } + }, + "small": { + "url": "https://images.genius.com/avatars/small/73e90badf9e35a8388b779fcd29b2543", + "bounding_box": { "width": 100, "height": 100 } + }, + "medium": { + "url": "https://images.genius.com/avatars/medium/73e90badf9e35a8388b779fcd29b2543", + "bounding_box": { "width": 300, "height": 400 } + } + }, + "header_image_url": "https://assets.genius.com/images/default_banner.png?1778095399", + "human_readable_role_for_display": "Contributor", + "id": 12657641, + "iq": 4926, + "login": "0gflo", + "name": "0gflo", + "role_for_display": "contributor", + "url": "https://genius.com/0gflo", + "current_user_metadata": { + "permissions": ["follow"], + "excluded_permissions": [], + "interactions": { "following": false } + } + } + }, + { + "attribution": 0.0014367816091954023, + "pinned_role": null, + "user": { + "api_path": "/users/845202", + "avatar": { + "tiny": { + "url": "https://images.genius.com/avatars/tiny/c8f629b872e29850b952a1df6d7c962a", + "bounding_box": { "width": 16, "height": 16 } + }, + "thumb": { + "url": "https://images.genius.com/avatars/thumb/c8f629b872e29850b952a1df6d7c962a", + "bounding_box": { "width": 32, "height": 32 } + }, + "small": { + "url": "https://images.genius.com/avatars/small/c8f629b872e29850b952a1df6d7c962a", + "bounding_box": { "width": 100, "height": 100 } + }, + "medium": { + "url": "https://images.genius.com/avatars/medium/c8f629b872e29850b952a1df6d7c962a", + "bounding_box": { "width": 300, "height": 400 } + } + }, + "header_image_url": "https://assets.genius.com/images/default_banner.png?1778095399", + "human_readable_role_for_display": "Editor", + "id": 845202, + "iq": 71430, + "login": "Zenameless", + "name": "Zenameless", + "role_for_display": "editor", + "url": "https://genius.com/Zenameless", + "current_user_metadata": { + "permissions": ["follow"], + "excluded_permissions": [], + "interactions": { "following": false } + } + } + } + ], + "cosigned_by": [], + "rejection_comment": null, + "verified_by": null + } + ] + }, + "user": { + "api_path": "/users/117985", + "avatar": { + "tiny": { + "url": "https://images.genius.com/avatars/tiny/ccabbdc0aa0d50012e879f86f717a82d", + "bounding_box": { "width": 16, "height": 16 } + }, + "thumb": { + "url": "https://images.genius.com/avatars/thumb/ccabbdc0aa0d50012e879f86f717a82d", + "bounding_box": { "width": 32, "height": 32 } + }, + "small": { + "url": "https://images.genius.com/avatars/small/ccabbdc0aa0d50012e879f86f717a82d", + "bounding_box": { "width": 100, "height": 100 } + }, + "medium": { + "url": "https://images.genius.com/avatars/medium/ccabbdc0aa0d50012e879f86f717a82d", + "bounding_box": { "width": 300, "height": 400 } + } + }, + "header_image_url": "https://images.genius.com/1d39f4a8c2906db0e696e5cc4427fa92.300x300x1.png", + "human_readable_role_for_display": "Verified Artist", + "id": 117985, + "iq": 69426, + "login": "KendrickLamar", + "name": "Kendrick Lamar", + "role_for_display": "verified_artist", + "url": "https://genius.com/KendrickLamar", + "current_user_metadata": { + "permissions": ["follow"], + "excluded_permissions": [], + "interactions": { "following": false } + } + } + } + } +} diff --git a/examples/search.json b/examples/search.json new file mode 100644 index 0000000..e646a99 --- /dev/null +++ b/examples/search.json @@ -0,0 +1,621 @@ +{ + "meta": { "status": 200 }, + "response": { + "hits": [ + { + "highlights": [], + "index": "song", + "matched_words": 2, + "nb_exact_words": 2, + "nb_typos": 0, + "type": "song", + "result": { + "annotation_count": 61, + "api_path": "/songs/10359264", + "artist_names": "Kendrick Lamar", + "full_title": "Not Like Us by Kendrick Lamar", + "header_image_thumbnail_url": "https://images.genius.com/95cfea0187b37c7731e11d54b07d2415.300x300x1.png", + "header_image_url": "https://images.genius.com/95cfea0187b37c7731e11d54b07d2415.1000x1000x1.png", + "id": 10359264, + "lyrics_owner_id": 6877117, + "lyrics_state": "complete", + "path": "/Kendrick-lamar-not-like-us-lyrics", + "pending_lyrics_edits_count": 4, + "primary_artist_names": "Kendrick Lamar", + "pyongs_count": 186, + "relationships_index_url": "https://genius.com/Kendrick-lamar-not-like-us-sample", + "release_date_components": { "year": 2024, "month": 5, "day": 4 }, + "release_date_for_display": "May 4, 2024", + "release_date_with_abbreviated_month_for_display": "May 4, 2024", + "song_art_image_thumbnail_url": "https://images.genius.com/95cfea0187b37c7731e11d54b07d2415.300x300x1.png", + "song_art_image_url": "https://images.genius.com/95cfea0187b37c7731e11d54b07d2415.1000x1000x1.png", + "stats": { "unreviewed_annotations": 0, "concurrents": 5, "hot": false, "pageviews": 17580870 }, + "title": "Not Like Us", + "title_with_featured": "Not Like Us", + "url": "https://genius.com/Kendrick-lamar-not-like-us-lyrics", + "featured_artists": [], + "primary_artist": { + "api_path": "/artists/1421", + "header_image_url": "https://images.genius.com/1d39f4a8c2906db0e696e5cc4427fa92.300x300x1.png", + "id": 1421, + "image_url": "https://images.genius.com/43c7fc30a6d9fd31b239bb47cf1533f4.1000x1000x1.png", + "is_meme_verified": true, + "is_verified": true, + "name": "Kendrick Lamar", + "url": "https://genius.com/artists/Kendrick-lamar", + "iq": 69426 + }, + "primary_artists": [ + { + "api_path": "/artists/1421", + "header_image_url": "https://images.genius.com/1d39f4a8c2906db0e696e5cc4427fa92.300x300x1.png", + "id": 1421, + "image_url": "https://images.genius.com/43c7fc30a6d9fd31b239bb47cf1533f4.1000x1000x1.png", + "is_meme_verified": true, + "is_verified": true, + "name": "Kendrick Lamar", + "url": "https://genius.com/artists/Kendrick-lamar", + "iq": 69426 + } + ] + } + }, + { + "highlights": [], + "index": "song", + "matched_words": 2, + "nb_exact_words": 2, + "nb_typos": 0, + "type": "song", + "result": { + "annotation_count": 21, + "api_path": "/songs/3039923", + "artist_names": "Kendrick Lamar", + "full_title": "HUMBLE. by Kendrick Lamar", + "header_image_thumbnail_url": "https://images.genius.com/483306c535608c27f9e3781b854dc91d.300x300x1.png", + "header_image_url": "https://images.genius.com/483306c535608c27f9e3781b854dc91d.1000x1000x1.png", + "id": 3039923, + "lyrics_owner_id": 104344, + "lyrics_state": "complete", + "path": "/Kendrick-lamar-humble-lyrics", + "pending_lyrics_edits_count": 0, + "primary_artist_names": "Kendrick Lamar", + "pyongs_count": 1212, + "relationships_index_url": "https://genius.com/Kendrick-lamar-humble-sample", + "release_date_components": { "year": 2017, "month": 3, "day": 30 }, + "release_date_for_display": "March 30, 2017", + "release_date_with_abbreviated_month_for_display": "Mar. 30, 2017", + "song_art_image_thumbnail_url": "https://images.genius.com/483306c535608c27f9e3781b854dc91d.300x300x1.png", + "song_art_image_url": "https://images.genius.com/483306c535608c27f9e3781b854dc91d.1000x1000x1.png", + "stats": { "unreviewed_annotations": 1, "hot": false, "pageviews": 12281568 }, + "title": "HUMBLE.", + "title_with_featured": "HUMBLE.", + "url": "https://genius.com/Kendrick-lamar-humble-lyrics", + "featured_artists": [], + "primary_artist": { + "api_path": "/artists/1421", + "header_image_url": "https://images.genius.com/1d39f4a8c2906db0e696e5cc4427fa92.300x300x1.png", + "id": 1421, + "image_url": "https://images.genius.com/43c7fc30a6d9fd31b239bb47cf1533f4.1000x1000x1.png", + "is_meme_verified": true, + "is_verified": true, + "name": "Kendrick Lamar", + "url": "https://genius.com/artists/Kendrick-lamar", + "iq": 69426 + }, + "primary_artists": [ + { + "api_path": "/artists/1421", + "header_image_url": "https://images.genius.com/1d39f4a8c2906db0e696e5cc4427fa92.300x300x1.png", + "id": 1421, + "image_url": "https://images.genius.com/43c7fc30a6d9fd31b239bb47cf1533f4.1000x1000x1.png", + "is_meme_verified": true, + "is_verified": true, + "name": "Kendrick Lamar", + "url": "https://genius.com/artists/Kendrick-lamar", + "iq": 69426 + } + ] + } + }, + { + "highlights": [], + "index": "song", + "matched_words": 2, + "nb_exact_words": 2, + "nb_typos": 0, + "type": "song", + "result": { + "annotation_count": 93, + "api_path": "/songs/10341021", + "artist_names": "Kendrick Lamar", + "full_title": "euphoria by Kendrick Lamar", + "header_image_thumbnail_url": "https://images.genius.com/3e497e7f4219c60d8e2497fc1a4a5f68.300x300x1.png", + "header_image_url": "https://images.genius.com/3e497e7f4219c60d8e2497fc1a4a5f68.1000x1000x1.png", + "id": 10341021, + "lyrics_owner_id": 5748418, + "lyrics_state": "complete", + "path": "/Kendrick-lamar-euphoria-lyrics", + "pending_lyrics_edits_count": 0, + "primary_artist_names": "Kendrick Lamar", + "pyongs_count": 155, + "relationships_index_url": "https://genius.com/Kendrick-lamar-euphoria-sample", + "release_date_components": { "year": 2024, "month": 4, "day": 30 }, + "release_date_for_display": "April 30, 2024", + "release_date_with_abbreviated_month_for_display": "Apr. 30, 2024", + "song_art_image_thumbnail_url": "https://images.genius.com/3e497e7f4219c60d8e2497fc1a4a5f68.300x300x1.png", + "song_art_image_url": "https://images.genius.com/3e497e7f4219c60d8e2497fc1a4a5f68.1000x1000x1.png", + "stats": { "unreviewed_annotations": 3, "concurrents": 5, "hot": false, "pageviews": 11174847 }, + "title": "euphoria", + "title_with_featured": "euphoria", + "url": "https://genius.com/Kendrick-lamar-euphoria-lyrics", + "featured_artists": [], + "primary_artist": { + "api_path": "/artists/1421", + "header_image_url": "https://images.genius.com/1d39f4a8c2906db0e696e5cc4427fa92.300x300x1.png", + "id": 1421, + "image_url": "https://images.genius.com/43c7fc30a6d9fd31b239bb47cf1533f4.1000x1000x1.png", + "is_meme_verified": true, + "is_verified": true, + "name": "Kendrick Lamar", + "url": "https://genius.com/artists/Kendrick-lamar", + "iq": 69426 + }, + "primary_artists": [ + { + "api_path": "/artists/1421", + "header_image_url": "https://images.genius.com/1d39f4a8c2906db0e696e5cc4427fa92.300x300x1.png", + "id": 1421, + "image_url": "https://images.genius.com/43c7fc30a6d9fd31b239bb47cf1533f4.1000x1000x1.png", + "is_meme_verified": true, + "is_verified": true, + "name": "Kendrick Lamar", + "url": "https://genius.com/artists/Kendrick-lamar", + "iq": 69426 + } + ] + } + }, + { + "highlights": [], + "index": "song", + "matched_words": 2, + "nb_exact_words": 2, + "nb_typos": 0, + "type": "song", + "result": { + "annotation_count": 82, + "api_path": "/songs/90478", + "artist_names": "Kendrick Lamar (Ft. MC Eiht)", + "full_title": "m.A.A.d city by Kendrick Lamar (Ft. MC Eiht)", + "header_image_thumbnail_url": "https://images.genius.com/b4d6d87f080c362200ce55ed35ec65bb.300x300x1.png", + "header_image_url": "https://images.genius.com/b4d6d87f080c362200ce55ed35ec65bb.1000x1000x1.png", + "id": 90478, + "lyrics_owner_id": 103971, + "lyrics_state": "complete", + "path": "/Kendrick-lamar-maad-city-lyrics", + "pending_lyrics_edits_count": 1, + "primary_artist_names": "Kendrick Lamar", + "pyongs_count": 2240, + "relationships_index_url": "https://genius.com/Kendrick-lamar-maad-city-sample", + "release_date_components": { "year": 2012, "month": 10, "day": 22 }, + "release_date_for_display": "October 22, 2012", + "release_date_with_abbreviated_month_for_display": "Oct. 22, 2012", + "song_art_image_thumbnail_url": "https://images.genius.com/b4d6d87f080c362200ce55ed35ec65bb.300x300x1.png", + "song_art_image_url": "https://images.genius.com/b4d6d87f080c362200ce55ed35ec65bb.1000x1000x1.png", + "stats": { "unreviewed_annotations": 0, "hot": false, "pageviews": 7797017 }, + "title": "m.A.A.d city", + "title_with_featured": "m.A.A.d city (Ft. MC Eiht)", + "url": "https://genius.com/Kendrick-lamar-maad-city-lyrics", + "featured_artists": [ + { + "api_path": "/artists/4637", + "header_image_url": "https://images.genius.com/5f7c5b37dd412d8dcfe5318a0f05d167.396x297x1.jpg", + "id": 4637, + "image_url": "https://images.genius.com/5f7c5b37dd412d8dcfe5318a0f05d167.396x297x1.jpg", + "is_meme_verified": false, + "is_verified": false, + "name": "MC Eiht", + "url": "https://genius.com/artists/Mc-eiht" + } + ], + "primary_artist": { + "api_path": "/artists/1421", + "header_image_url": "https://images.genius.com/1d39f4a8c2906db0e696e5cc4427fa92.300x300x1.png", + "id": 1421, + "image_url": "https://images.genius.com/43c7fc30a6d9fd31b239bb47cf1533f4.1000x1000x1.png", + "is_meme_verified": true, + "is_verified": true, + "name": "Kendrick Lamar", + "url": "https://genius.com/artists/Kendrick-lamar", + "iq": 69426 + }, + "primary_artists": [ + { + "api_path": "/artists/1421", + "header_image_url": "https://images.genius.com/1d39f4a8c2906db0e696e5cc4427fa92.300x300x1.png", + "id": 1421, + "image_url": "https://images.genius.com/43c7fc30a6d9fd31b239bb47cf1533f4.1000x1000x1.png", + "is_meme_verified": true, + "is_verified": true, + "name": "Kendrick Lamar", + "url": "https://genius.com/artists/Kendrick-lamar", + "iq": 69426 + } + ] + } + }, + { + "highlights": [], + "index": "song", + "matched_words": 2, + "nb_exact_words": 2, + "nb_typos": 0, + "type": "song", + "result": { + "annotation_count": 54, + "api_path": "/songs/90475", + "artist_names": "Kendrick Lamar (Ft. Jay Rock)", + "full_title": "Money Trees by Kendrick Lamar (Ft. Jay Rock)", + "header_image_thumbnail_url": "https://images.genius.com/b4d6d87f080c362200ce55ed35ec65bb.300x300x1.png", + "header_image_url": "https://images.genius.com/b4d6d87f080c362200ce55ed35ec65bb.1000x1000x1.png", + "id": 90475, + "lyrics_owner_id": 1328, + "lyrics_state": "complete", + "path": "/Kendrick-lamar-money-trees-lyrics", + "pending_lyrics_edits_count": 5, + "primary_artist_names": "Kendrick Lamar", + "pyongs_count": 1001, + "relationships_index_url": "https://genius.com/Kendrick-lamar-money-trees-sample", + "release_date_components": { "year": 2012, "month": 10, "day": 22 }, + "release_date_for_display": "October 22, 2012", + "release_date_with_abbreviated_month_for_display": "Oct. 22, 2012", + "song_art_image_thumbnail_url": "https://images.genius.com/b4d6d87f080c362200ce55ed35ec65bb.300x300x1.png", + "song_art_image_url": "https://images.genius.com/b4d6d87f080c362200ce55ed35ec65bb.1000x1000x1.png", + "stats": { "unreviewed_annotations": 5, "hot": false, "pageviews": 7054337 }, + "title": "Money Trees", + "title_with_featured": "Money Trees (Ft. Jay Rock)", + "url": "https://genius.com/Kendrick-lamar-money-trees-lyrics", + "featured_artists": [ + { + "api_path": "/artists/1403", + "header_image_url": "https://images.genius.com/342a36ab4005da9cfd3b0292f7a748a1.1000x600x1.jpg", + "id": 1403, + "image_url": "https://images.genius.com/e1cbef603f6c11cee182adcd55a78a87.421x421x1.jpg", + "is_meme_verified": false, + "is_verified": true, + "name": "Jay Rock", + "url": "https://genius.com/artists/Jay-rock", + "iq": 15102 + } + ], + "primary_artist": { + "api_path": "/artists/1421", + "header_image_url": "https://images.genius.com/1d39f4a8c2906db0e696e5cc4427fa92.300x300x1.png", + "id": 1421, + "image_url": "https://images.genius.com/43c7fc30a6d9fd31b239bb47cf1533f4.1000x1000x1.png", + "is_meme_verified": true, + "is_verified": true, + "name": "Kendrick Lamar", + "url": "https://genius.com/artists/Kendrick-lamar", + "iq": 69426 + }, + "primary_artists": [ + { + "api_path": "/artists/1421", + "header_image_url": "https://images.genius.com/1d39f4a8c2906db0e696e5cc4427fa92.300x300x1.png", + "id": 1421, + "image_url": "https://images.genius.com/43c7fc30a6d9fd31b239bb47cf1533f4.1000x1000x1.png", + "is_meme_verified": true, + "is_verified": true, + "name": "Kendrick Lamar", + "url": "https://genius.com/artists/Kendrick-lamar", + "iq": 69426 + } + ] + } + }, + { + "highlights": [], + "index": "song", + "matched_words": 2, + "nb_exact_words": 2, + "nb_typos": 0, + "type": "song", + "result": { + "annotation_count": 47, + "api_path": "/songs/81159", + "artist_names": "Kendrick Lamar", + "full_title": "Swimming Pools (Drank) by Kendrick Lamar", + "header_image_thumbnail_url": "https://images.genius.com/31be6d410838e0668609868bf0a78e5e.300x300x1.png", + "header_image_url": "https://images.genius.com/31be6d410838e0668609868bf0a78e5e.1000x1000x1.png", + "id": 81159, + "lyrics_owner_id": 11524, + "lyrics_state": "complete", + "path": "/Kendrick-lamar-swimming-pools-drank-lyrics", + "pending_lyrics_edits_count": 1, + "primary_artist_names": "Kendrick Lamar", + "pyongs_count": 989, + "relationships_index_url": "https://genius.com/Kendrick-lamar-swimming-pools-drank-sample", + "release_date_components": { "year": 2012, "month": 7, "day": 31 }, + "release_date_for_display": "July 31, 2012", + "release_date_with_abbreviated_month_for_display": "Jul. 31, 2012", + "song_art_image_thumbnail_url": "https://images.genius.com/31be6d410838e0668609868bf0a78e5e.300x300x1.png", + "song_art_image_url": "https://images.genius.com/31be6d410838e0668609868bf0a78e5e.1000x1000x1.png", + "stats": { "unreviewed_annotations": 1, "concurrents": 3, "hot": false, "pageviews": 7059626 }, + "title": "Swimming Pools (Drank)", + "title_with_featured": "Swimming Pools (Drank)", + "url": "https://genius.com/Kendrick-lamar-swimming-pools-drank-lyrics", + "featured_artists": [], + "primary_artist": { + "api_path": "/artists/1421", + "header_image_url": "https://images.genius.com/1d39f4a8c2906db0e696e5cc4427fa92.300x300x1.png", + "id": 1421, + "image_url": "https://images.genius.com/43c7fc30a6d9fd31b239bb47cf1533f4.1000x1000x1.png", + "is_meme_verified": true, + "is_verified": true, + "name": "Kendrick Lamar", + "url": "https://genius.com/artists/Kendrick-lamar", + "iq": 69426 + }, + "primary_artists": [ + { + "api_path": "/artists/1421", + "header_image_url": "https://images.genius.com/1d39f4a8c2906db0e696e5cc4427fa92.300x300x1.png", + "id": 1421, + "image_url": "https://images.genius.com/43c7fc30a6d9fd31b239bb47cf1533f4.1000x1000x1.png", + "is_meme_verified": true, + "is_verified": true, + "name": "Kendrick Lamar", + "url": "https://genius.com/artists/Kendrick-lamar", + "iq": 69426 + } + ] + } + }, + { + "highlights": [], + "index": "song", + "matched_words": 2, + "nb_exact_words": 2, + "nb_typos": 0, + "type": "song", + "result": { + "annotation_count": 38, + "api_path": "/songs/3035222", + "artist_names": "Kendrick Lamar", + "full_title": "DNA. by Kendrick Lamar", + "header_image_thumbnail_url": "https://images.genius.com/f3f77222e1b615e0a10354ea6282ff22.300x300x1.png", + "header_image_url": "https://images.genius.com/f3f77222e1b615e0a10354ea6282ff22.1000x1000x1.png", + "id": 3035222, + "lyrics_owner_id": 104344, + "lyrics_state": "complete", + "path": "/Kendrick-lamar-dna-lyrics", + "pending_lyrics_edits_count": 1, + "primary_artist_names": "Kendrick Lamar", + "pyongs_count": 695, + "relationships_index_url": "https://genius.com/Kendrick-lamar-dna-sample", + "release_date_components": { "year": 2017, "month": 4, "day": 14 }, + "release_date_for_display": "April 14, 2017", + "release_date_with_abbreviated_month_for_display": "Apr. 14, 2017", + "song_art_image_thumbnail_url": "https://images.genius.com/f3f77222e1b615e0a10354ea6282ff22.300x300x1.png", + "song_art_image_url": "https://images.genius.com/f3f77222e1b615e0a10354ea6282ff22.1000x1000x1.png", + "stats": { "unreviewed_annotations": 0, "concurrents": 2, "hot": false, "pageviews": 6672872 }, + "title": "DNA.", + "title_with_featured": "DNA.", + "url": "https://genius.com/Kendrick-lamar-dna-lyrics", + "featured_artists": [], + "primary_artist": { + "api_path": "/artists/1421", + "header_image_url": "https://images.genius.com/1d39f4a8c2906db0e696e5cc4427fa92.300x300x1.png", + "id": 1421, + "image_url": "https://images.genius.com/43c7fc30a6d9fd31b239bb47cf1533f4.1000x1000x1.png", + "is_meme_verified": true, + "is_verified": true, + "name": "Kendrick Lamar", + "url": "https://genius.com/artists/Kendrick-lamar", + "iq": 69426 + }, + "primary_artists": [ + { + "api_path": "/artists/1421", + "header_image_url": "https://images.genius.com/1d39f4a8c2906db0e696e5cc4427fa92.300x300x1.png", + "id": 1421, + "image_url": "https://images.genius.com/43c7fc30a6d9fd31b239bb47cf1533f4.1000x1000x1.png", + "is_meme_verified": true, + "is_verified": true, + "name": "Kendrick Lamar", + "url": "https://genius.com/artists/Kendrick-lamar", + "iq": 69426 + } + ] + } + }, + { + "highlights": [], + "index": "song", + "matched_words": 2, + "nb_exact_words": 2, + "nb_typos": 0, + "type": "song", + "result": { + "annotation_count": 74, + "api_path": "/songs/10356410", + "artist_names": "Kendrick Lamar", + "full_title": "meet the grahams by Kendrick Lamar", + "header_image_thumbnail_url": "https://images.genius.com/b4b1a76b307b6d969a60dc6e93ce9d58.300x300x1.png", + "header_image_url": "https://images.genius.com/b4b1a76b307b6d969a60dc6e93ce9d58.1000x1000x1.png", + "id": 10356410, + "lyrics_owner_id": 1599419, + "lyrics_state": "complete", + "path": "/Kendrick-lamar-meet-the-grahams-lyrics", + "pending_lyrics_edits_count": 2, + "primary_artist_names": "Kendrick Lamar", + "pyongs_count": 120, + "relationships_index_url": "https://genius.com/Kendrick-lamar-meet-the-grahams-sample", + "release_date_components": { "year": 2024, "month": 5, "day": 3 }, + "release_date_for_display": "May 3, 2024", + "release_date_with_abbreviated_month_for_display": "May 3, 2024", + "song_art_image_thumbnail_url": "https://images.genius.com/b4b1a76b307b6d969a60dc6e93ce9d58.300x300x1.png", + "song_art_image_url": "https://images.genius.com/b4b1a76b307b6d969a60dc6e93ce9d58.1000x1000x1.png", + "stats": { "unreviewed_annotations": 0, "concurrents": 3, "hot": false, "pageviews": 6137490 }, + "title": "meet the grahams", + "title_with_featured": "meet the grahams", + "url": "https://genius.com/Kendrick-lamar-meet-the-grahams-lyrics", + "featured_artists": [], + "primary_artist": { + "api_path": "/artists/1421", + "header_image_url": "https://images.genius.com/1d39f4a8c2906db0e696e5cc4427fa92.300x300x1.png", + "id": 1421, + "image_url": "https://images.genius.com/43c7fc30a6d9fd31b239bb47cf1533f4.1000x1000x1.png", + "is_meme_verified": true, + "is_verified": true, + "name": "Kendrick Lamar", + "url": "https://genius.com/artists/Kendrick-lamar", + "iq": 69426 + }, + "primary_artists": [ + { + "api_path": "/artists/1421", + "header_image_url": "https://images.genius.com/1d39f4a8c2906db0e696e5cc4427fa92.300x300x1.png", + "id": 1421, + "image_url": "https://images.genius.com/43c7fc30a6d9fd31b239bb47cf1533f4.1000x1000x1.png", + "is_meme_verified": true, + "is_verified": true, + "name": "Kendrick Lamar", + "url": "https://genius.com/artists/Kendrick-lamar", + "iq": 69426 + } + ] + } + }, + { + "highlights": [], + "index": "song", + "matched_words": 2, + "nb_exact_words": 2, + "nb_typos": 0, + "type": "song", + "result": { + "annotation_count": 31, + "api_path": "/songs/3047142", + "artist_names": "Kendrick Lamar (Ft. U2)", + "full_title": "XXX. by Kendrick Lamar (Ft. U2)", + "header_image_thumbnail_url": "https://images.genius.com/f3f77222e1b615e0a10354ea6282ff22.300x300x1.png", + "header_image_url": "https://images.genius.com/f3f77222e1b615e0a10354ea6282ff22.1000x1000x1.png", + "id": 3047142, + "lyrics_owner_id": 599242, + "lyrics_state": "complete", + "path": "/Kendrick-lamar-xxx-lyrics", + "pending_lyrics_edits_count": 1, + "primary_artist_names": "Kendrick Lamar", + "pyongs_count": 248, + "relationships_index_url": "https://genius.com/Kendrick-lamar-xxx-sample", + "release_date_components": { "year": 2017, "month": 4, "day": 14 }, + "release_date_for_display": "April 14, 2017", + "release_date_with_abbreviated_month_for_display": "Apr. 14, 2017", + "song_art_image_thumbnail_url": "https://images.genius.com/f3f77222e1b615e0a10354ea6282ff22.300x300x1.png", + "song_art_image_url": "https://images.genius.com/f3f77222e1b615e0a10354ea6282ff22.1000x1000x1.png", + "stats": { "unreviewed_annotations": 2, "hot": false, "pageviews": 6131976 }, + "title": "XXX.", + "title_with_featured": "XXX. (Ft. U2)", + "url": "https://genius.com/Kendrick-lamar-xxx-lyrics", + "featured_artists": [ + { + "api_path": "/artists/23895", + "header_image_url": "https://images.genius.com/66ee6f8a6abd56e7dffb7f5eb993e1d6.1000x667x1.jpg", + "id": 23895, + "image_url": "https://images.genius.com/09825f1b03c944f9a89fa391fcbc717f.480x480x1.jpg", + "is_meme_verified": false, + "is_verified": false, + "name": "U2", + "url": "https://genius.com/artists/U2" + } + ], + "primary_artist": { + "api_path": "/artists/1421", + "header_image_url": "https://images.genius.com/1d39f4a8c2906db0e696e5cc4427fa92.300x300x1.png", + "id": 1421, + "image_url": "https://images.genius.com/43c7fc30a6d9fd31b239bb47cf1533f4.1000x1000x1.png", + "is_meme_verified": true, + "is_verified": true, + "name": "Kendrick Lamar", + "url": "https://genius.com/artists/Kendrick-lamar", + "iq": 69426 + }, + "primary_artists": [ + { + "api_path": "/artists/1421", + "header_image_url": "https://images.genius.com/1d39f4a8c2906db0e696e5cc4427fa92.300x300x1.png", + "id": 1421, + "image_url": "https://images.genius.com/43c7fc30a6d9fd31b239bb47cf1533f4.1000x1000x1.png", + "is_meme_verified": true, + "is_verified": true, + "name": "Kendrick Lamar", + "url": "https://genius.com/artists/Kendrick-lamar", + "iq": 69426 + } + ] + } + }, + { + "highlights": [], + "index": "song", + "matched_words": 2, + "nb_exact_words": 2, + "nb_typos": 0, + "type": "song", + "result": { + "annotation_count": 36, + "api_path": "/songs/90473", + "artist_names": "Kendrick Lamar", + "full_title": "Bitch, Don't Kill My Vibe by Kendrick Lamar", + "header_image_thumbnail_url": "https://images.genius.com/c7ad3b5dceb9f4fe50e744f796badffa.300x300x1.png", + "header_image_url": "https://images.genius.com/c7ad3b5dceb9f4fe50e744f796badffa.1000x1000x1.png", + "id": 90473, + "lyrics_owner_id": 83406, + "lyrics_state": "complete", + "path": "/Kendrick-lamar-bitch-dont-kill-my-vibe-lyrics", + "pending_lyrics_edits_count": 0, + "primary_artist_names": "Kendrick Lamar", + "pyongs_count": 708, + "relationships_index_url": "https://genius.com/Kendrick-lamar-bitch-dont-kill-my-vibe-sample", + "release_date_components": { "year": 2012, "month": 10, "day": 22 }, + "release_date_for_display": "October 22, 2012", + "release_date_with_abbreviated_month_for_display": "Oct. 22, 2012", + "song_art_image_thumbnail_url": "https://images.genius.com/c7ad3b5dceb9f4fe50e744f796badffa.300x300x1.png", + "song_art_image_url": "https://images.genius.com/c7ad3b5dceb9f4fe50e744f796badffa.1000x1000x1.png", + "stats": { "unreviewed_annotations": 1, "concurrents": 2, "hot": false, "pageviews": 5398446 }, + "title": "Bitch, Don’t Kill My Vibe", + "title_with_featured": "Bitch, Don't Kill My Vibe", + "url": "https://genius.com/Kendrick-lamar-bitch-dont-kill-my-vibe-lyrics", + "featured_artists": [], + "primary_artist": { + "api_path": "/artists/1421", + "header_image_url": "https://images.genius.com/1d39f4a8c2906db0e696e5cc4427fa92.300x300x1.png", + "id": 1421, + "image_url": "https://images.genius.com/43c7fc30a6d9fd31b239bb47cf1533f4.1000x1000x1.png", + "is_meme_verified": true, + "is_verified": true, + "name": "Kendrick Lamar", + "url": "https://genius.com/artists/Kendrick-lamar", + "iq": 69426 + }, + "primary_artists": [ + { + "api_path": "/artists/1421", + "header_image_url": "https://images.genius.com/1d39f4a8c2906db0e696e5cc4427fa92.300x300x1.png", + "id": 1421, + "image_url": "https://images.genius.com/43c7fc30a6d9fd31b239bb47cf1533f4.1000x1000x1.png", + "is_meme_verified": true, + "is_verified": true, + "name": "Kendrick Lamar", + "url": "https://genius.com/artists/Kendrick-lamar", + "iq": 69426 + } + ] + } + } + ] + } +} diff --git a/renderer/src/components/artist/ArtistPanel.tsx b/renderer/src/components/artist/ArtistPanel.tsx index eeefbd2..ed46d0e 100644 --- a/renderer/src/components/artist/ArtistPanel.tsx +++ b/renderer/src/components/artist/ArtistPanel.tsx @@ -12,6 +12,23 @@ import { ArtistAlbumCard } from './ArtistAlbumCard'; import type { SonosItem } from '../../types/sonos'; import styles from '../../styles/ArtistPanel.module.css'; +function domToText(node: GeniusDomNode): string { + if (typeof node === 'string') return node; + return (node.children ?? []).map(domToText).join(''); +} + +function firstBlurb(description: GeniusDomNode | null, maxLen = 220): string { + if (!description || typeof description === 'string') return ''; + const root = description as { tag: string; children?: GeniusDomNode[] }; + const paras = (root.children ?? []).filter(c => typeof c !== 'string' && (c as { tag: string }).tag === 'p'); + for (const p of paras) { + const text = domToText(p as GeniusDomNode).trim(); + if (!text) continue; + return text.length > maxLen ? text.slice(0, maxLen).trimEnd() + '…' : text; + } + return ''; +} + interface Props { onAddToQueue: (item: SonosItem) => void; } @@ -99,7 +116,25 @@ export function ArtistPanel({ onAddToQueue }: Props) {
{name}
+ {data?.genius && (() => { + const blurb = firstBlurb(data.genius.description); + return blurb ?

{blurb}

: null; + })()}
+ {data?.genius && (data.genius.instagram || data.genius.twitter) && ( +
+ {data.genius.instagram && ( + + )} + {data.genius.twitter && ( + + )} +
+ )} diff --git a/renderer/src/hooks/useArtistBrowse.ts b/renderer/src/hooks/useArtistBrowse.ts index 70f4c5d..bca3ecb 100644 --- a/renderer/src/hooks/useArtistBrowse.ts +++ b/renderer/src/hooks/useArtistBrowse.ts @@ -11,9 +11,10 @@ export interface ArtistData { albums: SonosItem[]; playlists: SonosItem[]; // Artist Shuffle, Artist Radio (no Top Songs) topSongs: AlbumTrack[]; + genius: GeniusArtistInfo | null; } -function parseArtist(data: ArtistResponse): { parsed: Omit; topSongsItem: SonosItem | null } { +function parseArtist(data: ArtistResponse): { parsed: Omit; topSongsItem: SonosItem | null } { const name = data.title ?? ''; const imageUrl = data.images?.tile1x1 ?? null; const allItems = (data.sections?.items?.[0]?.items ?? []) as unknown as SonosItem[]; @@ -42,21 +43,25 @@ export function artistQueryOptions( const { parsed, topSongsItem } = parseArtist(r.data as ArtistResponse); - let topSongs: AlbumTrack[] = []; - if (topSongsItem) { + const fetchTopSongs = async (): Promise => { + if (!topSongsItem) return []; const rid = topSongsItem.resource?.id as SonosItemId | undefined; - if (rid?.objectId && rid?.serviceId && rid?.accountId) { - const pr = await api.browse.playlist(rid.objectId, { - serviceId: rid.serviceId, - accountId: rid.accountId, - defaults: topSongsItem.resource?.defaults as string | undefined, - muse2: true, - }); - if (!pr.error) topSongs = parsePlaylistTracks(pr.data); - } - } + if (!rid?.objectId || !rid?.serviceId || !rid?.accountId) return []; + const pr = await api.browse.playlist(rid.objectId, { + serviceId: rid.serviceId, + accountId: rid.accountId, + defaults: topSongsItem.resource?.defaults as string | undefined, + muse2: true, + }); + return pr.error ? [] : parsePlaylistTracks(pr.data); + }; - return { ...parsed, topSongs }; + const [topSongs, genius] = await Promise.all([ + fetchTopSongs(), + window.sonos.geniusArtist(parsed.name), + ]); + + return { ...parsed, topSongs, genius }; }, staleTime: Infinity, gcTime: 60 * 60 * 1000, diff --git a/renderer/src/styles/ArtistPanel.module.css b/renderer/src/styles/ArtistPanel.module.css index 76118a8..bdcd836 100644 --- a/renderer/src/styles/ArtistPanel.module.css +++ b/renderer/src/styles/ArtistPanel.module.css @@ -69,12 +69,21 @@ display: flex; align-items: center; justify-content: center; + background: none; + border: 1px solid var(--border); + border-radius: var(--r-sm); + padding: 4px 8px; + font-size: 11px; + font-weight: 700; + letter-spacing: 0.3px; color: var(--text-3); - transition: color 0.15s; + cursor: pointer; + transition: color 0.15s, border-color 0.15s; text-decoration: none; } .socialLink:hover { color: var(--text); + border-color: var(--border-2); } .artistLabel { diff --git a/renderer/src/test/setup.ts b/renderer/src/test/setup.ts index 1aff391..4bd396b 100644 --- a/renderer/src/test/setup.ts +++ b/renderer/src/test/setup.ts @@ -62,6 +62,7 @@ Object.defineProperty(window, 'sonos', { isNewVersion: vi.fn(() => Promise.resolve(false)), openExternal: vi.fn(() => Promise.resolve()), geniusDescription: vi.fn(() => Promise.resolve(null)), + geniusArtist: vi.fn(() => Promise.resolve(null)), trackEvent: vi.fn(() => Promise.resolve()), minimizeWindow: vi.fn(() => Promise.resolve()), maximizeWindow: vi.fn(() => Promise.resolve()), diff --git a/renderer/src/types/globals.d.ts b/renderer/src/types/globals.d.ts index 688513b..9395a5a 100644 --- a/renderer/src/types/globals.d.ts +++ b/renderer/src/types/globals.d.ts @@ -2,6 +2,15 @@ type GeniusDomNode = string | { tag: string; children?: GeniusDomNode[]; attributes?: Record }; +interface GeniusArtistInfo { + description: GeniusDomNode | null; + alternateNames: string[]; + imageUrl: string | null; + headerImageUrl: string | null; + instagram: string | null; + twitter: string | null; +} + interface AttributionEntry { user: string; timestamp: number; @@ -245,6 +254,7 @@ interface SonosPreload { onAttributionMap: (cb: (map: AttributionMap) => void) => Unsubscribe; onAttributionEvent: (cb: (event: AttributionEvent) => void) => Unsubscribe; geniusDescription: (trackName: string, artistName: string) => Promise; + geniusArtist: (artistName: string, trackHint?: string) => Promise; /** Fire-and-forget telemetry event routed through the main process. No-op when App Insights is not configured. */ trackEvent: (name: string, properties?: Record) => Promise; minimizeWindow: () => Promise; diff --git a/src/main.ts b/src/main.ts index bae8c2c..32794ce 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1695,6 +1695,74 @@ ipcMain.handle('genius:description', async (_: IpcMainInvokeEvent, trackName: st } }); +ipcMain.handle('genius:artist', async (_: IpcMainInvokeEvent, artistName: string, trackHint?: string) => { + const key = process.env.GENIUS_ACCESS_TOKEN; + if (!key) { + log('[genius] GENIUS_ACCESS_TOKEN not set — skipping artist lookup'); + return null; + } + + const debugReq = (id: string, url: string, ts: number) => + httpDebugWin?.webContents.send('http:req', { id, ts, operationId: 'genius:artist', method: 'GET', url, headers: { Authorization: 'Bearer ***' } }); + const debugRes = (id: string, status: number, body: string, ts: number) => + httpDebugWin?.webContents.send('http:res', { id, status, statusText: String(status), headers: {}, body, durationMs: Date.now() - ts }); + + try { + const q = trackHint ? `${trackHint} ${artistName}` : artistName; + const searchUrl = `https://api.genius.com/search?q=${encodeURIComponent(q)}`; + const searchId = randomUUID(); const searchTs = Date.now(); + debugReq(searchId, searchUrl, searchTs); + const searchRes = await fetch(searchUrl, { headers: { Authorization: `Bearer ${key}` } }); + const searchBody = await searchRes.text(); + debugRes(searchId, searchRes.status, searchBody, searchTs); + if (!searchRes.ok) return null; + + type SearchHit = { result: { primary_artist: { id: number; name: string } } }; + const searchData = JSON.parse(searchBody) as { response: { hits: SearchHit[] } }; + const hits = searchData.response?.hits ?? []; + const artistNameLower = artistName.toLowerCase(); + const hit = hits.find((h) => h.result.primary_artist.name.toLowerCase().includes(artistNameLower)) ?? hits[0]; + const artistId = hit?.result?.primary_artist?.id; + if (!artistId) return null; + + const artistUrl = `https://api.genius.com/artists/${artistId}`; + const artistReqId = randomUUID(); const artistTs = Date.now(); + debugReq(artistReqId, artistUrl, artistTs); + const artistRes = await fetch(artistUrl, { headers: { Authorization: `Bearer ${key}` } }); + const artistBody = await artistRes.text(); + debugRes(artistReqId, artistRes.status, artistBody, artistTs); + if (!artistRes.ok) return null; + + type ArtistPayload = { + response: { + artist: { + description: { dom: unknown }; + alternate_names: string[]; + image_url: string | null; + header_image_url: string | null; + instagram_name: string | null; + twitter_name: string | null; + }; + }; + }; + const artistData = JSON.parse(artistBody) as ArtistPayload; + const a = artistData.response?.artist; + if (!a) return null; + + return { + description: a.description?.dom ?? null, + alternateNames: a.alternate_names ?? [], + imageUrl: a.image_url ?? null, + headerImageUrl: a.header_image_url ?? null, + instagram: a.instagram_name ?? null, + twitter: a.twitter_name ?? null, + }; + } catch (err) { + log(`[genius] artist error: ${err}`); + return null; + } +}); + // ─── Application menu ──────────────────────────────────────────────────────── function buildMenu(): void { diff --git a/src/preload.ts b/src/preload.ts index 6b93357..f102e61 100644 --- a/src/preload.ts +++ b/src/preload.ts @@ -58,6 +58,7 @@ export interface SonosAPI { fetchMyScore: (gameId: string, userName: string) => Promise; fetchGameStats: (date?: string) => Promise; geniusDescription: (trackName: string, artistName: string) => Promise; + geniusArtist: (artistName: string, trackHint?: string) => Promise; trackEvent: (name: string, properties?: Record) => Promise; minimizeWindow: () => Promise; maximizeWindow: () => Promise; @@ -174,6 +175,8 @@ contextBridge.exposeInMainWorld('sonos', { }, geniusDescription: (trackName: string, artistName: string) => ipcRenderer.invoke('genius:description', trackName, artistName), + geniusArtist: (artistName: string, trackHint?: string) => + ipcRenderer.invoke('genius:artist', artistName, trackHint), trackEvent: (name: string, properties?: Record) => ipcRenderer.invoke('telemetry:event', name, properties), minimizeWindow: () => ipcRenderer.invoke('win:minimize'), From e91b32c0f3143e82d45f7bf99a779b0848f468aa Mon Sep 17 00:00:00 2001 From: Joe Pitts Date: Thu, 7 May 2026 15:51:33 +0100 Subject: [PATCH 2/7] feat: premium artist bio section with scrollable bio, icon-only socials, alt names MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Replaced truncated first-paragraph blurb with full scrollable bio (all paragraphs) - Moved bio from header to right column (About → Socials → Latest Release stack) - Replaced IG/𝕏 pill buttons with inline SVG icon-only buttons - Added alternate names display below artist name in header - Removed Artist Radio card - Tightened sideCol gap for better column height balance Co-Authored-By: Claude Sonnet 4.6 --- .../src/components/artist/ArtistPanel.tsx | 105 +++++++++++------ renderer/src/styles/ArtistPanel.module.css | 108 +++++++++++++++++- 2 files changed, 179 insertions(+), 34 deletions(-) diff --git a/renderer/src/components/artist/ArtistPanel.tsx b/renderer/src/components/artist/ArtistPanel.tsx index ed46d0e..589c7ec 100644 --- a/renderer/src/components/artist/ArtistPanel.tsx +++ b/renderer/src/components/artist/ArtistPanel.tsx @@ -17,16 +17,16 @@ function domToText(node: GeniusDomNode): string { return (node.children ?? []).map(domToText).join(''); } -function firstBlurb(description: GeniusDomNode | null, maxLen = 220): string { +function extractBio(description: GeniusDomNode | null): string { if (!description || typeof description === 'string') return ''; const root = description as { tag: string; children?: GeniusDomNode[] }; - const paras = (root.children ?? []).filter(c => typeof c !== 'string' && (c as { tag: string }).tag === 'p'); - for (const p of paras) { - const text = domToText(p as GeniusDomNode).trim(); - if (!text) continue; - return text.length > maxLen ? text.slice(0, maxLen).trimEnd() + '…' : text; - } - return ''; + const paras = (root.children ?? []).filter( + c => typeof c !== 'string' && (c as { tag: string }).tag === 'p', + ); + return paras + .map(p => domToText(p as GeniusDomNode).trim()) + .filter(Boolean) + .join('\n\n'); } interface Props { @@ -39,7 +39,9 @@ export function ArtistPanel({ onAddToQueue }: Props) { const openItem = useOpenItem(); const { artistId, serviceId, accountId, defaults, name: fallbackName } = - item ? resolveArtistParams(item) : { artistId: undefined, serviceId: undefined, accountId: undefined, defaults: undefined, name: undefined }; + item + ? resolveArtistParams(item) + : { artistId: undefined, serviceId: undefined, accountId: undefined, defaults: undefined, name: undefined }; const { data, isLoading } = useArtistBrowse(artistId, serviceId, accountId, defaults); @@ -61,13 +63,27 @@ export function ArtistPanel({ onAddToQueue }: Props) { if (e.shiftKey && lastSelected.current !== null) { const lo = Math.min(lastSelected.current, index); const hi = Math.max(lastSelected.current, index); - setSelected(prev => { const next = new Set(prev); for (let i = lo; i <= hi; i++) next.add(i); return next; }); + setSelected(prev => { + const next = new Set(prev); + for (let i = lo; i <= hi; i++) next.add(i); + return next; + }); } else if (e.ctrlKey || e.metaKey) { - setSelected(prev => { const next = new Set(prev); if (next.has(index)) next.delete(index); else next.add(index); return next; }); + setSelected(prev => { + const next = new Set(prev); + if (next.has(index)) next.delete(index); + else next.add(index); + return next; + }); lastSelected.current = index; } else { - if (selected.size === 1 && selected.has(index)) { setSelected(new Set()); lastSelected.current = null; } - else { setSelected(new Set([index])); lastSelected.current = index; } + if (selected.size === 1 && selected.has(index)) { + setSelected(new Set()); + lastSelected.current = null; + } else { + setSelected(new Set([index])); + lastSelected.current = index; + } } } @@ -95,6 +111,11 @@ export function ArtistPanel({ onAddToQueue }: Props) { const artistRadio = data?.playlists.find(p => (p.title as string)?.toLowerCase().includes('radio')); const latestAlbum = data?.albums[0] ?? null; + const genius = data?.genius ?? null; + const blurb = genius ? extractBio(genius.description) : ''; + const altNames = genius?.alternateNames?.filter(Boolean).slice(0, 4) ?? []; + const hasAbout = !!(blurb || genius?.instagram || genius?.twitter); + if (!item) return null; return ( @@ -116,25 +137,10 @@ export function ArtistPanel({ onAddToQueue }: Props) {
{name}
- {data?.genius && (() => { - const blurb = firstBlurb(data.genius.description); - return blurb ?

{blurb}

: null; - })()} + {altNames.length > 0 && ( +
{altNames.join(' · ')}
+ )}
- {data?.genius && (data.genius.instagram || data.genius.twitter) && ( -
- {data.genius.instagram && ( - - )} - {data.genius.twitter && ( - - )} -
- )} @@ -154,7 +160,10 @@ export function ArtistPanel({ onAddToQueue }: Props) {
{data && data.topSongs.length > 0 && ( <> - {visibleSongs.map((track, i) => ( @@ -171,9 +180,39 @@ export function ArtistPanel({ onAddToQueue }: Props) { )}
+
+ {blurb && ( +
+
About
+ {blurb.split('\n\n').map((para, i) => ( +

{para}

+ ))} +
+ )} + {(genius?.instagram || genius?.twitter) && ( +
+
+ {genius.instagram && ( + + )} + {genius.twitter && ( + + )} +
+
+ )} {latestAlbum && } - {artistRadio && }
)} diff --git a/renderer/src/styles/ArtistPanel.module.css b/renderer/src/styles/ArtistPanel.module.css index bdcd836..79334cb 100644 --- a/renderer/src/styles/ArtistPanel.module.css +++ b/renderer/src/styles/ArtistPanel.module.css @@ -110,6 +110,112 @@ max-width: 460px; } +/* ── Alternate names ── */ +.altNames { + font-size: 10px; + font-weight: 500; + letter-spacing: 1.2px; + text-transform: uppercase; + color: rgba(255, 255, 255, 0.28); + margin-top: 10px; +} + +/* ── About / Genius bio ── */ +.aboutSection { + padding-bottom: 22px; + margin-bottom: 18px; + border-bottom: 1px solid rgba(255, 255, 255, 0.07); + max-height: 210px; + overflow-y: auto; +} + +.aboutEyebrow { + font-size: 9px; + font-weight: 800; + letter-spacing: 2px; + text-transform: uppercase; + color: rgba(255, 255, 255, 0.25); + margin-bottom: 10px; +} + +.aboutText { + font-size: 14.5px; + line-height: 1.75; + color: rgba(255, 255, 255, 0.68); + margin: 0 0 16px; + font-style: italic; + letter-spacing: 0.1px; +} + +.socialSection { + margin-bottom: 16px; + border-bottom: 1px solid rgba(255, 255, 255, 0.07); +} + +.socialIcons { + display: flex; + gap: 10px; + justify-content: flex-start; + padding-bottom: 10px; +} + +.socialIconBtn { + background: none; + border: none; + padding: 0; + display: flex; + align-items: center; + justify-content: center; + color: var(--text-3); + cursor: pointer; + transition: color 0.15s; +} +.socialIconBtn:hover { + color: var(--text); +} + +.aboutSocials { + display: flex; + gap: 28px; +} + +.aboutSocialBtn { + background: none; + border: none; + padding: 0; + cursor: pointer; + text-align: left; + display: flex; + flex-direction: column; + gap: 4px; +} + +.aboutSocialPlatform { + font-size: 13px; + font-weight: 700; + letter-spacing: -0.1px; + color: var(--text-3); + line-height: 1; + margin-bottom: 4px; + transition: color 0.15s; +} + +.aboutSocialHandle { + font-size: 12px; + font-weight: 500; + color: rgba(255, 255, 255, 0.5); + line-height: 1; + transition: color 0.15s; +} + +.aboutSocialBtn:hover .aboutSocialHandle { + color: rgba(255, 255, 255, 0.92); +} + +.aboutSocialBtn:hover .aboutSocialPlatform { + color: rgba(255, 255, 255, 0.45); +} + .headerActions { display: flex; gap: 10px; @@ -286,7 +392,7 @@ .sideCol { display: flex; flex-direction: column; - gap: 24px; + gap: 12px; } /* Latest Release */ From 28889b474fad5e0403f3d21b124fe31c38f54020 Mon Sep 17 00:00:00 2001 From: Joe Pitts Date: Thu, 7 May 2026 16:00:43 +0100 Subject: [PATCH 3/7] =?UTF-8?q?feat:=20artist=20panel=20=E2=80=94=20Genius?= =?UTF-8?q?=20header=20image=20texture=20+=20now-playing=20waveform?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Use genius.headerImageUrl as a blurred/dimmed background texture in the artist header for depth and atmosphere (brightness 0.18, blur 28px) - Animate a 3-bar waveform in place of the track number when a top song is currently playing; pauses animation when playback is paused - Highlight active track name at full opacity - Thread currentObjectId/isPlaybackActive from App playback state into ArtistPanel rather than calling usePlayback a second time - Fix ArtistPanel tests to supply new required props Co-Authored-By: Claude Sonnet 4.6 --- renderer/src/App.tsx | 2 +- .../src/components/artist/ArtistPanel.tsx | 19 ++++--- renderer/src/components/artist/TopSongRow.tsx | 16 ++++-- .../artist/__tests__/ArtistPanel.test.tsx | 18 +++---- renderer/src/styles/ArtistPanel.module.css | 52 +++++++++++++++++++ 5 files changed, 88 insertions(+), 19 deletions(-) diff --git a/renderer/src/App.tsx b/renderer/src/App.tsx index aac7365..8d8e8a2 100644 --- a/renderer/src/App.tsx +++ b/renderer/src/App.tsx @@ -471,7 +471,7 @@ useEffect(() => { } /> } /> - } /> + } /> } /> } /> } /> diff --git a/renderer/src/components/artist/ArtistPanel.tsx b/renderer/src/components/artist/ArtistPanel.tsx index 589c7ec..7fff6f4 100644 --- a/renderer/src/components/artist/ArtistPanel.tsx +++ b/renderer/src/components/artist/ArtistPanel.tsx @@ -31,9 +31,11 @@ function extractBio(description: GeniusDomNode | null): string { interface Props { onAddToQueue: (item: SonosItem) => void; + currentObjectId: string | null; + isPlaybackActive: boolean; } -export function ArtistPanel({ onAddToQueue }: Props) { +export function ArtistPanel({ onAddToQueue, currentObjectId, isPlaybackActive }: Props) { const { state } = useLocation(); const item = (state as { item?: SonosItem } | null)?.item; const openItem = useOpenItem(); @@ -108,13 +110,13 @@ export function ArtistPanel({ onAddToQueue }: Props) { const cachedArt = useImage(imageUrl); const dominantColor = useDominantColor(cachedArt, { setGlobal: true }); - const artistRadio = data?.playlists.find(p => (p.title as string)?.toLowerCase().includes('radio')); const latestAlbum = data?.albums[0] ?? null; - const genius = data?.genius ?? null; - const blurb = genius ? extractBio(genius.description) : ''; - const altNames = genius?.alternateNames?.filter(Boolean).slice(0, 4) ?? []; - const hasAbout = !!(blurb || genius?.instagram || genius?.twitter); + const genius = data?.genius ?? null; + const blurb = genius ? extractBio(genius.description) : ''; + const altNames = genius?.alternateNames?.filter(Boolean).slice(0, 4) ?? []; + const geniusHeaderImg = useImage(genius?.headerImageUrl ?? null); + if (!item) return null; @@ -129,6 +131,9 @@ export function ArtistPanel({ onAddToQueue }: Props) { : undefined } > + {geniusHeaderImg && ( + + )}
{cachedArt @@ -172,6 +177,8 @@ export function ArtistPanel({ onAddToQueue }: Props) { track={track} index={i} isSelected={selected.has(i)} + isCurrentTrack={track.id.objectId === currentObjectId} + isPlaybackActive={isPlaybackActive} onAdd={onAddToQueue} onClick={handleTrackClick} onDragStart={handleDragStart} diff --git a/renderer/src/components/artist/TopSongRow.tsx b/renderer/src/components/artist/TopSongRow.tsx index d639d7c..ecd92c8 100644 --- a/renderer/src/components/artist/TopSongRow.tsx +++ b/renderer/src/components/artist/TopSongRow.tsx @@ -9,12 +9,14 @@ interface Props { track: AlbumTrack; index: number; isSelected: boolean; + isCurrentTrack?: boolean; + isPlaybackActive?: boolean; onAdd: (item: SonosItem) => void; onClick: (index: number, e: React.MouseEvent) => void; onDragStart: (index: number, e: React.DragEvent) => void; } -export function TopSongRow({ track, index, isSelected, onAdd, onClick, onDragStart }: Props) { +export function TopSongRow({ track, index, isSelected, isCurrentTrack, isPlaybackActive, onAdd, onClick, onDragStart }: Props) { const art = useImage(track.artUrl); const subtitle = (track.raw as Record)?.['subtitle'] as string | undefined; return ( @@ -24,12 +26,20 @@ export function TopSongRow({ track, index, isSelected, onAdd, onClick, onDragSta onClick={e => onClick(index, e)} onDragStart={e => onDragStart(index, e)} > - {index + 1} + {isCurrentTrack ? ( +
+
+
+
+
+ ) : ( + {index + 1} + )}
{art ? :
}
- + {track.title} {track.explicit && } diff --git a/renderer/src/components/artist/__tests__/ArtistPanel.test.tsx b/renderer/src/components/artist/__tests__/ArtistPanel.test.tsx index 87205ac..8fc388e 100644 --- a/renderer/src/components/artist/__tests__/ArtistPanel.test.tsx +++ b/renderer/src/components/artist/__tests__/ArtistPanel.test.tsx @@ -48,6 +48,8 @@ function makeData(overrides = {}) { }; } +const defaultProps = { onAddToQueue: vi.fn(), currentObjectId: null, isPlaybackActive: false }; + beforeEach(() => { vi.clearAllMocks(); mockUseLocation.mockReturnValue({ state: { item: artistItem } }); @@ -57,18 +59,18 @@ beforeEach(() => { describe('ArtistPanel', () => { it('returns nothing when no item in state', () => { mockUseLocation.mockReturnValue({ state: null }); - const { container } = render(); + const { container } = render(); expect(container.firstChild).toBeNull(); }); it('shows artist name from data', () => { - render(); + render(); expect(screen.getByText('The Beatles')).toBeInTheDocument(); }); it('shows loading skeletons while loading', () => { mockUseArtistBrowse.mockReturnValue({ data: undefined, isLoading: true }); - const { container } = render(); + const { container } = render(); expect(container.querySelectorAll('[class*="skeletonRow"]').length).toBeGreaterThan(0); }); @@ -78,7 +80,7 @@ describe('ArtistPanel', () => { { name: 'Let It Be', id: { objectId: 'trk-2' } }, ]; mockUseArtistBrowse.mockReturnValue({ data: makeData({ topSongs }), isLoading: false }); - render(); + render(); expect(screen.getByText('Come Together')).toBeInTheDocument(); expect(screen.getByText('Let It Be')).toBeInTheDocument(); }); @@ -90,11 +92,9 @@ describe('ArtistPanel', () => { })); mockUseArtistBrowse.mockReturnValue({ data: makeData({ topSongs }), isLoading: false }); const user = userEvent.setup(); - render(); - // Initially shows first 10 + render(); expect(screen.queryByText('Song 11')).not.toBeInTheDocument(); await user.click(screen.getByText(/Top Songs/)); - // After click shows all 12 expect(screen.getByText('Song 11')).toBeInTheDocument(); }); @@ -104,7 +104,7 @@ describe('ArtistPanel', () => { { title: 'Album Two', id: { objectId: 'alb-2' } }, ]; mockUseArtistBrowse.mockReturnValue({ data: makeData({ albums }), isLoading: false }); - render(); + render(); expect(screen.getByText('Albums')).toBeInTheDocument(); expect(screen.getAllByText('Album Two').length).toBeGreaterThan(0); }); @@ -112,7 +112,7 @@ describe('ArtistPanel', () => { it('does not render albums section when only one album', () => { const albums = [{ title: 'Abbey Road', id: { objectId: 'alb-1' } }]; mockUseArtistBrowse.mockReturnValue({ data: makeData({ albums }), isLoading: false }); - render(); + render(); expect(screen.queryByText('Albums')).not.toBeInTheDocument(); }); }); diff --git a/renderer/src/styles/ArtistPanel.module.css b/renderer/src/styles/ArtistPanel.module.css index 79334cb..4f2b78c 100644 --- a/renderer/src/styles/ArtistPanel.module.css +++ b/renderer/src/styles/ArtistPanel.module.css @@ -12,11 +12,27 @@ /* background gradient applied via inline style from dominant colour */ } +.headerBgImg { + position: absolute; + inset: 0; + width: 100%; + height: 100%; + object-fit: cover; + object-position: center top; + filter: blur(28px) brightness(0.18) saturate(1.6); + transform: scale(1.08); + z-index: 0; + pointer-events: none; + clip-path: inset(0); +} + /* flex row: circle + name, vertically centred together */ .headerRow { display: flex; align-items: center; gap: 24px; + position: relative; + z-index: 1; } /* Circle: in flow, negative margin-bottom makes bottom half bleed into body */ @@ -311,6 +327,42 @@ color: var(--text-3); } +/* ── Now-playing waveform ── */ +.waveform { + width: 18px; + flex-shrink: 0; + display: flex; + align-items: flex-end; + justify-content: flex-end; + gap: 2px; + height: 14px; +} + +@keyframes waveformBounce { + 0% { transform: scaleY(0.2); } + 100% { transform: scaleY(1); } +} + +.waveformBar { + width: 3px; + border-radius: 2px; + background: rgba(255, 255, 255, 0.8); + transform-origin: bottom; + animation: waveformBounce 0.9s ease-in-out infinite alternate; +} +.waveformBar:nth-child(1) { height: 55%; animation-delay: 0s; } +.waveformBar:nth-child(2) { height: 100%; animation-delay: -0.35s; } +.waveformBar:nth-child(3) { height: 70%; animation-delay: -0.18s; } + +.waveformPaused .waveformBar { + animation-play-state: paused; + transform: scaleY(0.5); +} + +.topSongNameActive { + color: rgba(255, 255, 255, 0.95); +} + .topSongArt { width: 36px; height: 36px; From 3babc4736b5f9b6f93515749081f26c8e2d4a9c6 Mon Sep 17 00:00:00 2001 From: Joe Pitts Date: Thu, 7 May 2026 16:01:47 +0100 Subject: [PATCH 4/7] revert: remove Genius header image background texture Co-Authored-By: Claude Sonnet 4.6 --- renderer/src/components/artist/ArtistPanel.tsx | 6 ------ renderer/src/styles/ArtistPanel.module.css | 16 ---------------- 2 files changed, 22 deletions(-) diff --git a/renderer/src/components/artist/ArtistPanel.tsx b/renderer/src/components/artist/ArtistPanel.tsx index 7fff6f4..d178f6a 100644 --- a/renderer/src/components/artist/ArtistPanel.tsx +++ b/renderer/src/components/artist/ArtistPanel.tsx @@ -115,9 +115,6 @@ export function ArtistPanel({ onAddToQueue, currentObjectId, isPlaybackActive }: const genius = data?.genius ?? null; const blurb = genius ? extractBio(genius.description) : ''; const altNames = genius?.alternateNames?.filter(Boolean).slice(0, 4) ?? []; - const geniusHeaderImg = useImage(genius?.headerImageUrl ?? null); - - if (!item) return null; return ( @@ -131,9 +128,6 @@ export function ArtistPanel({ onAddToQueue, currentObjectId, isPlaybackActive }: : undefined } > - {geniusHeaderImg && ( - - )}
{cachedArt diff --git a/renderer/src/styles/ArtistPanel.module.css b/renderer/src/styles/ArtistPanel.module.css index 4f2b78c..3154320 100644 --- a/renderer/src/styles/ArtistPanel.module.css +++ b/renderer/src/styles/ArtistPanel.module.css @@ -12,27 +12,11 @@ /* background gradient applied via inline style from dominant colour */ } -.headerBgImg { - position: absolute; - inset: 0; - width: 100%; - height: 100%; - object-fit: cover; - object-position: center top; - filter: blur(28px) brightness(0.18) saturate(1.6); - transform: scale(1.08); - z-index: 0; - pointer-events: none; - clip-path: inset(0); -} - /* flex row: circle + name, vertically centred together */ .headerRow { display: flex; align-items: center; gap: 24px; - position: relative; - z-index: 1; } /* Circle: in flow, negative margin-bottom makes bottom half bleed into body */ From 0f39094f71786ef6c112cfc401984152bbe75392 Mon Sep 17 00:00:00 2001 From: Joe Pitts Date: Thu, 7 May 2026 16:06:53 +0100 Subject: [PATCH 5/7] fix: match now-playing waveform by track name instead of objectId MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Top songs use playlist-track objectIds which differ in format from the playback state's currentObjectId — they never matched. Switch to comparing track title against playback.trackName which is reliable. Co-Authored-By: Claude Sonnet 4.6 --- renderer/src/App.tsx | 2 +- renderer/src/components/artist/ArtistPanel.tsx | 6 +++--- .../src/components/artist/__tests__/ArtistPanel.test.tsx | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/renderer/src/App.tsx b/renderer/src/App.tsx index 8d8e8a2..9cc2c28 100644 --- a/renderer/src/App.tsx +++ b/renderer/src/App.tsx @@ -471,7 +471,7 @@ useEffect(() => { } /> } /> - } /> + } /> } /> } /> } /> diff --git a/renderer/src/components/artist/ArtistPanel.tsx b/renderer/src/components/artist/ArtistPanel.tsx index d178f6a..a4aa365 100644 --- a/renderer/src/components/artist/ArtistPanel.tsx +++ b/renderer/src/components/artist/ArtistPanel.tsx @@ -31,11 +31,11 @@ function extractBio(description: GeniusDomNode | null): string { interface Props { onAddToQueue: (item: SonosItem) => void; - currentObjectId: string | null; + currentTrackName: string; isPlaybackActive: boolean; } -export function ArtistPanel({ onAddToQueue, currentObjectId, isPlaybackActive }: Props) { +export function ArtistPanel({ onAddToQueue, currentTrackName, isPlaybackActive }: Props) { const { state } = useLocation(); const item = (state as { item?: SonosItem } | null)?.item; const openItem = useOpenItem(); @@ -171,7 +171,7 @@ export function ArtistPanel({ onAddToQueue, currentObjectId, isPlaybackActive }: track={track} index={i} isSelected={selected.has(i)} - isCurrentTrack={track.id.objectId === currentObjectId} + isCurrentTrack={track.title === currentTrackName} isPlaybackActive={isPlaybackActive} onAdd={onAddToQueue} onClick={handleTrackClick} diff --git a/renderer/src/components/artist/__tests__/ArtistPanel.test.tsx b/renderer/src/components/artist/__tests__/ArtistPanel.test.tsx index 8fc388e..4cf6d44 100644 --- a/renderer/src/components/artist/__tests__/ArtistPanel.test.tsx +++ b/renderer/src/components/artist/__tests__/ArtistPanel.test.tsx @@ -48,7 +48,7 @@ function makeData(overrides = {}) { }; } -const defaultProps = { onAddToQueue: vi.fn(), currentObjectId: null, isPlaybackActive: false }; +const defaultProps = { onAddToQueue: vi.fn(), currentTrackName: '', isPlaybackActive: false }; beforeEach(() => { vi.clearAllMocks(); From a93f99bd4a96a8ba14cef1f95e2e77bb9b5353b7 Mon Sep 17 00:00:00 2001 From: Joe Pitts Date: Thu, 7 May 2026 16:08:06 +0100 Subject: [PATCH 6/7] style: make artist alt names brighter and slightly larger 11.5px up from 10px, opacity 0.48 up from 0.28. Co-Authored-By: Claude Sonnet 4.6 --- renderer/src/styles/ArtistPanel.module.css | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/renderer/src/styles/ArtistPanel.module.css b/renderer/src/styles/ArtistPanel.module.css index 3154320..b40944a 100644 --- a/renderer/src/styles/ArtistPanel.module.css +++ b/renderer/src/styles/ArtistPanel.module.css @@ -112,11 +112,11 @@ /* ── Alternate names ── */ .altNames { - font-size: 10px; + font-size: 11.5px; font-weight: 500; letter-spacing: 1.2px; text-transform: uppercase; - color: rgba(255, 255, 255, 0.28); + color: rgba(255, 255, 255, 0.48); margin-top: 10px; } From 8c150a4a094cfba56e12a822637ad7921553612b Mon Sep 17 00:00:00 2001 From: Joe Pitts Date: Fri, 8 May 2026 10:02:40 +0100 Subject: [PATCH 7/7] fix: remove unused RadioCard import Co-Authored-By: Claude Sonnet 4.6 --- renderer/src/components/artist/ArtistPanel.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/renderer/src/components/artist/ArtistPanel.tsx b/renderer/src/components/artist/ArtistPanel.tsx index a4aa365..87a7109 100644 --- a/renderer/src/components/artist/ArtistPanel.tsx +++ b/renderer/src/components/artist/ArtistPanel.tsx @@ -7,7 +7,6 @@ import { useOpenItem } from '../../hooks/useOpenItem'; import { resolveArtistParams } from '../../lib/itemHelpers'; import { TopSongRow } from './TopSongRow'; import { LatestReleaseCard } from './LatestReleaseCard'; -import { RadioCard } from './RadioCard'; import { ArtistAlbumCard } from './ArtistAlbumCard'; import type { SonosItem } from '../../types/sonos'; import styles from '../../styles/ArtistPanel.module.css';