added last.fm logo, last.fm links for play counts, spotify popularity to progress bar
This commit is contained in:
parent
ab058c769f
commit
fa75eedf31
@ -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,
|
||||||
|
@ -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;
|
||||||
|
}
|
@ -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>
|
||||||
|
@ -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>
|
||||||
|
`
|
||||||
|
}
|
@ -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>
|
||||||
`
|
`
|
||||||
|
@ -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');
|
BIN
Selector.Web/wwwroot/last-fm.png
Normal file
BIN
Selector.Web/wwwroot/last-fm.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 687 B |
Loading…
Reference in New Issue
Block a user