added last.fm logo, last.fm links for play counts, spotify popularity to progress bar

This commit is contained in:
andy 2021-12-01 23:34:30 +00:00
parent ab058c769f
commit fa75eedf31
7 changed files with 114 additions and 12 deletions

View File

@ -16,7 +16,7 @@ namespace Selector.Cache
public class PlayCounterCaching: PlayCounter public class PlayCounterCaching: PlayCounter
{ {
private readonly IDatabaseAsync Db; private readonly IDatabaseAsync Db;
public TimeSpan CacheExpiry { get; set; } = TimeSpan.FromDays(14); public TimeSpan CacheExpiry { get; set; } = TimeSpan.FromDays(1);
public PlayCounterCaching( public PlayCounterCaching(
IPlayerWatcher watcher, IPlayerWatcher watcher,

View File

@ -2,12 +2,13 @@
display: block; display: block;
} }
$text-color: white;
.card { .card {
background-color: grey; background-color: grey;
color: white; color: $text-color;
margin: 5px; margin: 5px;
padding: 15px; padding: 15px;
box-shadow: 4px 4px 2px #5e5e5e; box-shadow: 4px 4px 2px #5e5e5e;
transition: box-shadow 0.5s; transition: box-shadow 0.5s;
@ -45,6 +46,7 @@
.app { .app {
display: flex; display: flex;
align-items: flex-start; align-items: flex-start;
flex-wrap: wrap;
} }
.now-playing-card { .now-playing-card {
@ -59,7 +61,8 @@
@media only screen and (min-width: 768px) { @media only screen and (min-width: 768px) {
.info-card { .info-card {
max-width: 300px; min-width: 200px;
max-width: 500px;
} }
} }
@ -70,3 +73,21 @@
width: 21px; width: 21px;
} }
} }
.lastfm-logo {
width: 24px;
img {
width: 24px;
}
}
.popularity-progress {
margin-top: 20px;
margin-bottom: 20px;
}
.subtle-link {
color: $text-color;
text-decoration: none;
}

View File

@ -13,7 +13,7 @@
<popularity :track="currentlyPlaying.track" v-if="currentlyPlaying !== null && currentlyPlaying !== undefined && currentlyPlaying.track != null && currentlyPlaying.track != undefined" ></popularity> <popularity :track="currentlyPlaying.track" v-if="currentlyPlaying !== null && currentlyPlaying !== undefined && currentlyPlaying.track != null && currentlyPlaying.track != undefined" ></popularity>
<audio-feature-card :feature="trackFeatures" v-if="trackFeatures !== null && trackFeatures !== undefined" /></audio-feature-card> <audio-feature-card :feature="trackFeatures" v-if="trackFeatures !== null && trackFeatures !== undefined" /></audio-feature-card>
<audio-feature-chart-card :feature="trackFeatures" v-if="trackFeatures !== null && trackFeatures !== undefined" /></audio-feature-chart-card> <audio-feature-chart-card :feature="trackFeatures" v-if="trackFeatures !== null && trackFeatures !== undefined" /></audio-feature-chart-card>
<play-count-card :count="playCount" v-if="playCount !== null && playCount !== undefined" /></play-count-card> <play-count-card :count="playCount" :track="lastfmTrack" :username="playCount.username" v-if="playCount !== null && playCount !== undefined" /></play-count-card>
<info-card v-for="card in cards" :html="card.html"></info-card> <info-card v-for="card in cards" :html="card.html"></info-card>
</div> </div>
</div> </div>

View File

@ -1,14 +1,77 @@
import * as Vue from "vue"; import * as Vue from "vue";
const root_url = "https://www.last.fm/user/username/library/music/artist/album";
export let PlayCountCard: Vue.Component = { export let PlayCountCard: Vue.Component = {
props: ['count'], props: ['count', 'track', 'username'],
computed: {
TrackLink(): string {
return `https://www.last.fm/user/${this.username}/library/music/${this.track.artist}/_/${this.track.name}`;
},
AlbumLink(): string {
return `https://www.last.fm/user/${this.username}/library/music/${this.track.album_artist}/${this.track.album}`;
},
ArtistLink(): string {
return `https://www.last.fm/user/${this.username}/library/music/${this.track.artist}`;
},
UserLink(): string {
return `https://www.last.fm/user/${this.username}`;
},
TrackPercent(): number {
return ((this.count.track * 100) / this.count.user);
},
AlbumPercent(): number {
return ((this.count.album * 100) / this.count.user);
},
ArtistPercent(): number {
return ((this.count.artist * 100) / this.count.user);
},
TrackPercentStr(): string {
return this.TrackPercent.toFixed(2);
},
AlbumPercentStr(): string {
return this.AlbumPercent.toFixed(2);
},
ArtistPercentStr(): string {
return this.ArtistPercent.toFixed(1);
}
},
template: template:
` `
<div class="card info-card"> <div class="card info-card">
<h5 v-if="count.track != null && count.track != undefined" >Track: {{ count.track.toLocaleString() }}</h5> <h5 v-if="count.track != null && count.track != undefined" >
<h5 v-if="count.album != null && count.album != undefined" >Album: {{ count.album.toLocaleString() }}</h5> <a :href="TrackLink" class="subtle-link">
<h5 v-if="count.artist != null && count.artist != undefined" >Artist: {{ count.artist.toLocaleString() }}</h5> Track: {{ count.track.toLocaleString() }} <small v-if="TrackPercent >= 0.01">({{ this.TrackPercentStr }}%)</small>
<h5 v-if="count.user != null && count.user != undefined" >User: {{ count.user.toLocaleString() }}</h5> </a>
</h5>
<h5 v-if="count.album != null && count.album != undefined" >
<a :href="AlbumLink" class="subtle-link">
Album: {{ count.album.toLocaleString() }} <small v-if="AlbumPercent >= 0.01">({{ this.AlbumPercentStr }}%)</small>
</a>
</h5>
<h5 v-if="count.artist != null && count.artist != undefined" >
<a :href="ArtistLink" class="subtle-link">
Artist: {{ count.artist.toLocaleString() }} <small v-if="ArtistPercent >= 0.1">({{ this.ArtistPercentStr }}%)</small>
</a>
</h5>
<h5 v-if="count.user != null && count.user != undefined" >
<a :href="UserLink" class="subtle-link">
User: {{ count.user.toLocaleString() }}
</a>
</h5>
<lastfm-logo :link="UserLink" />
</div> </div>
` `
} }
export let LastFmLogoLink: Vue.Component = {
props: ['link'],
template:
`
<a :href="link" target="_blank" class="lastfm-logo" v-if="link != null && link != undefined">
<img src="/last-fm.png" >
</a>
<img src="/last-fm.png" class="lastfm-logo" v-else>
`
}

View File

@ -6,11 +6,18 @@ Chart.register(RadarController, RadialLinearScale, PointElement, LineElement);
export let PopularityCard: Vue.Component = { export let PopularityCard: Vue.Component = {
props: ['track'], props: ['track'],
computed: {
progressBarWidth() {
return `width: ${this.track.popularity}%`;
}
},
template: template:
` `
<div class="card info-card"> <div class="card info-card">
<h3>Popularity</h3> <h3>Popularity</h3>
<h1>{{ track.popularity }}%</h1> <div class="progress popularity-progress">
<div class="progress-bar progress-bar-striped progress-bar-animated" role="progressbar" :style="progressBarWidth" :aria-valuenow="track.popularity" aria-valuemin="0" aria-valuemax="100">{{ track.popularity }}%</div>
</div>
<spotify-logo :link="track.externalUrls.spotify" /> <spotify-logo :link="track.externalUrls.spotify" />
</div> </div>
` `

View File

@ -3,7 +3,7 @@ import * as Vue from "vue";
import { TrackAudioFeatures, PlayCount, CurrentlyPlayingDTO } from "./HubInterfaces"; import { TrackAudioFeatures, PlayCount, CurrentlyPlayingDTO } from "./HubInterfaces";
import NowPlayingCard from "./Now/NowPlayingCard"; import NowPlayingCard from "./Now/NowPlayingCard";
import { AudioFeatureCard, AudioFeatureChartCard, PopularityCard, SpotifyLogoLink } from "./Now/Spotify"; import { AudioFeatureCard, AudioFeatureChartCard, PopularityCard, SpotifyLogoLink } from "./Now/Spotify";
import { PlayCountCard } from "./Now/LastFm"; import { PlayCountCard, LastFmLogoLink } from "./Now/LastFm";
import BaseInfoCard from "./Now/BaseInfoCard"; import BaseInfoCard from "./Now/BaseInfoCard";
const connection = new signalR.HubConnectionBuilder() const connection = new signalR.HubConnectionBuilder()
@ -36,6 +36,16 @@ const app = Vue.createApp({
cards: [] cards: []
} as NowPlaying } as NowPlaying
}, },
computed: {
lastfmTrack() {
return {
name: this.currentlyPlaying.track.name,
artist: this.currentlyPlaying.track.artists[0].name,
album: this.currentlyPlaying.track.album.name,
album_artist: this.currentlyPlaying.track.album.artists[0].name,
};
}
},
created() { created() {
connection.on("OnNewPlaying", (context: CurrentlyPlayingDTO) => connection.on("OnNewPlaying", (context: CurrentlyPlayingDTO) =>
{ {
@ -77,5 +87,6 @@ app.component("audio-feature-chart-card", AudioFeatureChartCard);
app.component("info-card", BaseInfoCard); app.component("info-card", BaseInfoCard);
app.component("popularity", PopularityCard); app.component("popularity", PopularityCard);
app.component("spotify-logo", SpotifyLogoLink); app.component("spotify-logo", SpotifyLogoLink);
app.component("lastfm-logo", LastFmLogoLink);
app.component("play-count-card", PlayCountCard); app.component("play-count-card", PlayCountCard);
const vm = app.mount('#app'); const vm = app.mount('#app');

Binary file not shown.

After

Width:  |  Height:  |  Size: 687 B