A decentralized music tracking and discovery platform built on AT Protocol 🎵

Show artist genres as hashtags

Add --color-genre CSS variable for light and dark themes
Map artistResult.data.genres (previously tags) into the artist object
and render genres as hashtag spans using the new --color-genre color.
Remove Group's bottom margin and adjust the avatar/info wrapper layout.

+90 -70
+2
apps/web/src/index.css
··· 91 --color-button-text: #fff; 92 --color-skeleton-background: #f3f3f3; 93 --color-skeleton-foreground: #ecebeb; 94 } 95 96 .dark { ··· 113 --color-button-text: #000; 114 --color-skeleton-background: #221538; 115 --color-skeleton-foreground: #2b1a4c; 116 } 117 118 ::placeholder {
··· 91 --color-button-text: #fff; 92 --color-skeleton-background: #f3f3f3; 93 --color-skeleton-foreground: #ecebeb; 94 + --color-genre: #3f03fb; 95 } 96 97 .dark { ··· 114 --color-button-text: #000; 115 --color-skeleton-background: #221538; 116 --color-skeleton-foreground: #2b1a4c; 117 + --color-genre: #00f1f3; 118 } 119 120 ::placeholder {
+88 -70
apps/web/src/pages/artist/Artist.tsx
··· 24 display: flex; 25 flex-direction: row; 26 margin-top: 20px; 27 - margin-bottom: 50px; 28 `; 29 30 const Artist = () => { ··· 80 listeners: artistResult.data.uniqueListeners, 81 scrobbles: artistResult.data.playCount, 82 picture: artistResult.data.picture, 83 - tags: artistResult.data.tags, 84 uri: artistResult.data.uri, 85 spotifyLink: artistResult.data.spotifyLink, 86 }); ··· 130 artistResult.isLoading || 131 artistTracksResult.isLoading || 132 artistAlbumsResult.isLoading; 133 return ( 134 <Main> 135 <div className="pb-[100px] pt-[50px]"> 136 - <Group> 137 - <div className="mr-[20px]"> 138 - {artist?.picture && !loading && ( 139 - <Avatar name={artist?.name} src={artist?.picture} size="150px" /> 140 - )} 141 - {!artist?.picture && !loading && ( 142 - <div className="w-[150px] h-[150px] rounded-[80px] bg-[rgba(243, 243, 243, 0.725)] flex items-center justify-center"> 143 - <div 144 - style={{ 145 - height: 60, 146 - width: 60, 147 - }} 148 - > 149 - <ArtistIcon color="rgba(66, 87, 108, 0.65)" /> 150 - </div> 151 - </div> 152 - )} 153 - </div> 154 - {artist && !loading && ( 155 - <div style={{ flex: 1 }}> 156 - <HeadingMedium 157 - marginTop={"20px"} 158 - marginBottom={0} 159 - className="!text-[var(--color-text)]" 160 - > 161 - {artist?.name} 162 - </HeadingMedium> 163 - <div className="mt-[20px] flex flex-row"> 164 - <div className="mr-[20px]"> 165 - <LabelMedium 166 - margin={0} 167 - className="!text-[var(--color-text-muted)]" 168 > 169 - Listeners 170 - </LabelMedium> 171 - <HeadingXSmall 172 - margin={0} 173 - className="!text-[var(--color-text)]" 174 - > 175 - {numeral(artist?.listeners).format("0,0")} 176 - </HeadingXSmall> 177 </div> 178 - <div> 179 - <LabelMedium 180 - margin={0} 181 - className="!text-[var(--color-text-muted)]" 182 - > 183 - Scrobbles 184 - </LabelMedium> 185 - <HeadingXSmall 186 - margin={0} 187 - className="!text-[var(--color-text)]" 188 - > 189 - {numeral(artist?.scrobbles).format("0,0")} 190 - </HeadingXSmall> 191 - </div> 192 - <div className="flex items-center justify-end flex-1 mr-[10px]"> 193 - <a 194 - href={`https://pdsls.dev/at/${uri.replace("at://", "")}`} 195 - target="_blank" 196 - className="text-[var(--color-text)] no-underline bg-[var(--color-default-button)] rounded-[10px] p-[16px] pl-[25px] pr-[25px]" 197 - > 198 - <ExternalLink 199 - size={24} 200 - className="mr-[10px] text-[var(--color-text)]" 201 - /> 202 - View on PDSls 203 - </a> 204 </div> 205 </div> 206 </div> 207 )} 208 - </Group> 209 - 210 <PopularSongs topTracks={topTracks} /> 211 <Albums topAlbums={topAlbums} /> 212 <ArtistListeners listeners={artistListenersResult.data} />
··· 24 display: flex; 25 flex-direction: row; 26 margin-top: 20px; 27 `; 28 29 const Artist = () => { ··· 79 listeners: artistResult.data.uniqueListeners, 80 scrobbles: artistResult.data.playCount, 81 picture: artistResult.data.picture, 82 + tags: artistResult.data.genres, 83 uri: artistResult.data.uri, 84 spotifyLink: artistResult.data.spotifyLink, 85 }); ··· 129 artistResult.isLoading || 130 artistTracksResult.isLoading || 131 artistAlbumsResult.isLoading; 132 + 133 return ( 134 <Main> 135 <div className="pb-[100px] pt-[50px]"> 136 + <div className="mb-[50px]"> 137 + <Group> 138 + <div className="mr-[20px]"> 139 + {artist?.picture && !loading && ( 140 + <Avatar 141 + name={artist?.name} 142 + src={artist?.picture} 143 + size="150px" 144 + /> 145 + )} 146 + {!artist?.picture && !loading && ( 147 + <div className="w-[150px] h-[150px] rounded-[80px] bg-[rgba(243, 243, 243, 0.725)] flex items-center justify-center"> 148 + <div 149 + style={{ 150 + height: 60, 151 + width: 60, 152 + }} 153 > 154 + <ArtistIcon color="rgba(66, 87, 108, 0.65)" /> 155 + </div> 156 </div> 157 + )} 158 + </div> 159 + {artist && !loading && ( 160 + <div style={{ flex: 1 }}> 161 + <HeadingMedium 162 + marginTop={"20px"} 163 + marginBottom={0} 164 + className="!text-[var(--color-text)]" 165 + > 166 + {artist?.name} 167 + </HeadingMedium> 168 + <div className="mt-[20px] flex flex-row"> 169 + <div className="mr-[20px]"> 170 + <LabelMedium 171 + margin={0} 172 + className="!text-[var(--color-text-muted)]" 173 + > 174 + Listeners 175 + </LabelMedium> 176 + <HeadingXSmall 177 + margin={0} 178 + className="!text-[var(--color-text)]" 179 + > 180 + {numeral(artist?.listeners).format("0,0")} 181 + </HeadingXSmall> 182 + </div> 183 + <div> 184 + <LabelMedium 185 + margin={0} 186 + className="!text-[var(--color-text-muted)]" 187 + > 188 + Scrobbles 189 + </LabelMedium> 190 + <HeadingXSmall 191 + margin={0} 192 + className="!text-[var(--color-text)]" 193 + > 194 + {numeral(artist?.scrobbles).format("0,0")} 195 + </HeadingXSmall> 196 + </div> 197 + <div className="flex items-center justify-end flex-1 mr-[10px]"> 198 + <a 199 + href={`https://pdsls.dev/at/${uri.replace("at://", "")}`} 200 + target="_blank" 201 + className="text-[var(--color-text)] no-underline bg-[var(--color-default-button)] rounded-[10px] p-[16px] pl-[25px] pr-[25px]" 202 + > 203 + <ExternalLink 204 + size={24} 205 + className="mr-[10px] text-[var(--color-text)]" 206 + /> 207 + View on PDSls 208 + </a> 209 + </div> 210 </div> 211 </div> 212 + )} 213 + </Group> 214 + 215 + {artist && ( 216 + <div className="mt-[30px]"> 217 + {(artist?.tags || []).map((genre) => ( 218 + <span 219 + className="mr-[15px] text-[var(--color-genre)] text-[13px]" 220 + style={{ fontFamily: "RockfordSansRegular" }} 221 + > 222 + # {genre} 223 + </span> 224 + ))} 225 </div> 226 )} 227 + </div> 228 <PopularSongs topTracks={topTracks} /> 229 <Albums topAlbums={topAlbums} /> 230 <ArtistListeners listeners={artistListenersResult.data} />