adding signalr project
This commit is contained in:
parent
b9cc6d5d45
commit
562c119e18
@ -19,6 +19,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Selector.Event", "Selector.
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Selector.Data", "Selector.Data\Selector.Data.csproj", "{CB62ACCB-94F1-4B78-A195-8B108B9E800D}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Selector.Data", "Selector.Data\Selector.Data.csproj", "{CB62ACCB-94F1-4B78-A195-8B108B9E800D}"
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Selector.SignalR", "Selector.SignalR\Selector.SignalR.csproj", "{089C9DE8-2B73-4341-BA17-572CD6BAD14D}"
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
Debug|Any CPU = Debug|Any CPU
|
||||||
@ -57,6 +59,10 @@ Global
|
|||||||
{CB62ACCB-94F1-4B78-A195-8B108B9E800D}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{CB62ACCB-94F1-4B78-A195-8B108B9E800D}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{CB62ACCB-94F1-4B78-A195-8B108B9E800D}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{CB62ACCB-94F1-4B78-A195-8B108B9E800D}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{CB62ACCB-94F1-4B78-A195-8B108B9E800D}.Release|Any CPU.Build.0 = Release|Any CPU
|
{CB62ACCB-94F1-4B78-A195-8B108B9E800D}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{089C9DE8-2B73-4341-BA17-572CD6BAD14D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{089C9DE8-2B73-4341-BA17-572CD6BAD14D}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{089C9DE8-2B73-4341-BA17-572CD6BAD14D}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{089C9DE8-2B73-4341-BA17-572CD6BAD14D}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
40
Selector.SignalR/BaseSignalRClient.cs
Normal file
40
Selector.SignalR/BaseSignalRClient.cs
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
using System;
|
||||||
|
using Microsoft.AspNetCore.SignalR.Client;
|
||||||
|
|
||||||
|
namespace Selector.SignalR;
|
||||||
|
|
||||||
|
public abstract class BaseSignalRClient: IAsyncDisposable
|
||||||
|
{
|
||||||
|
private readonly string _baseUrl;
|
||||||
|
protected HubConnection hubConnection;
|
||||||
|
|
||||||
|
public BaseSignalRClient(string path)
|
||||||
|
{
|
||||||
|
var baseOverride = Environment.GetEnvironmentVariable("SELECTOR_BASE_URL");
|
||||||
|
|
||||||
|
if (!string.IsNullOrWhiteSpace(baseOverride))
|
||||||
|
{
|
||||||
|
_baseUrl = baseOverride;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_baseUrl = "https://selector.sarsoo.xyz";
|
||||||
|
}
|
||||||
|
|
||||||
|
hubConnection = new HubConnectionBuilder()
|
||||||
|
.WithUrl(_baseUrl + "/" + path)
|
||||||
|
.WithAutomaticReconnect()
|
||||||
|
.Build();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ValueTask DisposeAsync()
|
||||||
|
{
|
||||||
|
return ((IAsyncDisposable)hubConnection).DisposeAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task StartAsync()
|
||||||
|
{
|
||||||
|
await hubConnection.StartAsync();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
24
Selector.SignalR/INow.cs
Normal file
24
Selector.SignalR/INow.cs
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
using System;
|
||||||
|
using SpotifyAPI.Web;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Selector.SignalR;
|
||||||
|
|
||||||
|
public interface INowPlayingHubClient
|
||||||
|
{
|
||||||
|
public Task OnNewPlaying(CurrentlyPlayingDTO context);
|
||||||
|
public Task OnNewAudioFeature(TrackAudioFeatures features);
|
||||||
|
public Task OnNewPlayCount(PlayCount playCount);
|
||||||
|
public Task OnNewCard(ICard card);
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface INowPlayingHub
|
||||||
|
{
|
||||||
|
Task OnConnected();
|
||||||
|
Task PlayDensityFacts(string track, string artist, string album, string albumArtist);
|
||||||
|
Task SendAudioFeatures(string trackId);
|
||||||
|
Task SendFacts(string track, string artist, string album, string albumArtist);
|
||||||
|
Task SendNewPlaying();
|
||||||
|
Task SendPlayCount(string track, string artist, string album, string albumArtist);
|
||||||
|
}
|
||||||
|
|
14
Selector.SignalR/IPast.cs
Normal file
14
Selector.SignalR/IPast.cs
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Selector.SignalR;
|
||||||
|
|
||||||
|
public interface IPastHub
|
||||||
|
{
|
||||||
|
Task OnConnected();
|
||||||
|
Task OnSubmitted(IPastParams param);
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface IPastHubClient
|
||||||
|
{
|
||||||
|
public Task OnRankResult(IRankResult result);
|
||||||
|
}
|
6
Selector.SignalR/Models/ICard.cs
Normal file
6
Selector.SignalR/Models/ICard.cs
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
namespace Selector.SignalR;
|
||||||
|
|
||||||
|
public interface ICard
|
||||||
|
{
|
||||||
|
string Content { get; set; }
|
||||||
|
}
|
7
Selector.SignalR/Models/IChartEntry.cs
Normal file
7
Selector.SignalR/Models/IChartEntry.cs
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
namespace Selector.SignalR;
|
||||||
|
|
||||||
|
public interface IChartEntry
|
||||||
|
{
|
||||||
|
string Name { get; set; }
|
||||||
|
int Value { get; set; }
|
||||||
|
}
|
10
Selector.SignalR/Models/IPastParams.cs
Normal file
10
Selector.SignalR/Models/IPastParams.cs
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
namespace Selector.SignalR;
|
||||||
|
|
||||||
|
public interface IPastParams
|
||||||
|
{
|
||||||
|
string Track { get; set; }
|
||||||
|
string Album { get; set; }
|
||||||
|
string Artist { get; set; }
|
||||||
|
string From { get; set; }
|
||||||
|
string To { get; set; }
|
||||||
|
}
|
12
Selector.SignalR/Models/IRankResult.cs
Normal file
12
Selector.SignalR/Models/IRankResult.cs
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace Selector.SignalR;
|
||||||
|
|
||||||
|
public interface IRankResult
|
||||||
|
{
|
||||||
|
IEnumerable<IChartEntry> TrackEntries { get; set; }
|
||||||
|
IEnumerable<IChartEntry> AlbumEntries { get; set; }
|
||||||
|
IEnumerable<IChartEntry> ArtistEntries { get; set; }
|
||||||
|
IEnumerable<CountSample> ResampledSeries { get; set; }
|
||||||
|
int TotalCount { get; set; }
|
||||||
|
}
|
98
Selector.SignalR/NowHubClient.cs
Normal file
98
Selector.SignalR/NowHubClient.cs
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
using System;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.AspNetCore.SignalR.Client;
|
||||||
|
using SpotifyAPI.Web;
|
||||||
|
|
||||||
|
namespace Selector.SignalR;
|
||||||
|
|
||||||
|
public class NowHubClient: BaseSignalRClient, INowPlayingHub, IDisposable
|
||||||
|
{
|
||||||
|
private List<IDisposable> NewPlayingCallbacks = new();
|
||||||
|
private List<IDisposable> NewAudioFeatureCallbacks = new();
|
||||||
|
private List<IDisposable> NewPlayCountCallbacks = new();
|
||||||
|
private List<IDisposable> NewCardCallbacks = new();
|
||||||
|
private bool disposedValue;
|
||||||
|
|
||||||
|
public NowHubClient(): base("nowhub")
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnNewPlaying(Action<CurrentlyPlayingDTO> action)
|
||||||
|
{
|
||||||
|
NewPlayingCallbacks.Add(hubConnection.On(nameof(OnNewPlaying), action));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnNewAudioFeature(Action<TrackAudioFeatures> action)
|
||||||
|
{
|
||||||
|
NewAudioFeatureCallbacks.Add(hubConnection.On(nameof(OnNewAudioFeature), action));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnNewPlayCount(Action<PlayCount> action)
|
||||||
|
{
|
||||||
|
NewPlayCountCallbacks.Add(hubConnection.On(nameof(OnNewPlayCount), action));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnNewCard(Action<ICard> action)
|
||||||
|
{
|
||||||
|
NewCardCallbacks.Add(hubConnection.On(nameof(OnNewCard), action));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task OnConnected()
|
||||||
|
{
|
||||||
|
return hubConnection.InvokeAsync(nameof(OnConnected));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task PlayDensityFacts(string track, string artist, string album, string albumArtist)
|
||||||
|
{
|
||||||
|
return hubConnection.InvokeAsync(nameof(PlayDensityFacts), track, artist, album, albumArtist);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task SendAudioFeatures(string trackId)
|
||||||
|
{
|
||||||
|
return hubConnection.InvokeAsync(nameof(SendAudioFeatures), trackId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task SendFacts(string track, string artist, string album, string albumArtist)
|
||||||
|
{
|
||||||
|
return hubConnection.InvokeAsync(nameof(SendFacts), track, artist, album, albumArtist);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task SendNewPlaying()
|
||||||
|
{
|
||||||
|
return hubConnection.InvokeAsync(nameof(SendNewPlaying));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task SendPlayCount(string track, string artist, string album, string albumArtist)
|
||||||
|
{
|
||||||
|
return hubConnection.InvokeAsync(nameof(SendPlayCount), track, artist, album, albumArtist);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual void Dispose(bool disposing)
|
||||||
|
{
|
||||||
|
if (!disposedValue)
|
||||||
|
{
|
||||||
|
if (disposing)
|
||||||
|
{
|
||||||
|
foreach(var callback in NewPlayingCallbacks
|
||||||
|
.Concat(NewAudioFeatureCallbacks)
|
||||||
|
.Concat(NewPlayCountCallbacks)
|
||||||
|
.Concat(NewCardCallbacks))
|
||||||
|
{
|
||||||
|
callback.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
base.DisposeAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
disposedValue = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
// Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
|
||||||
|
Dispose(disposing: true);
|
||||||
|
GC.SuppressFinalize(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
25
Selector.SignalR/Selector.SignalR.csproj
Normal file
25
Selector.SignalR/Selector.SignalR.csproj
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net7.0</TargetFramework>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\Selector\Selector.csproj" />
|
||||||
|
<!-- <ProjectReference Include="..\Selector.Model\Selector.Model.csproj" /> -->
|
||||||
|
</ItemGroup>
|
||||||
|
<!-- <ItemGroup>
|
||||||
|
<None Remove="Microsoft.AspNetCore.SignalR.Client" />
|
||||||
|
</ItemGroup> -->
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Microsoft.AspNetCore.SignalR.Client" Version="7.0.2" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<None Remove="Models\" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Folder Include="Models\" />
|
||||||
|
</ItemGroup>
|
||||||
|
</Project>
|
@ -1,6 +1,7 @@
|
|||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Selector.Web.Service;
|
using Selector.Web.Service;
|
||||||
using Selector.Web.Hubs;
|
using Selector.Web.Hubs;
|
||||||
|
using Selector.SignalR;
|
||||||
|
|
||||||
namespace Selector.Web.Extensions
|
namespace Selector.Web.Extensions
|
||||||
{
|
{
|
||||||
|
@ -11,21 +11,14 @@ using Microsoft.Extensions.Options;
|
|||||||
using Selector.Cache;
|
using Selector.Cache;
|
||||||
using Selector.Model;
|
using Selector.Model;
|
||||||
using Selector.Model.Extensions;
|
using Selector.Model.Extensions;
|
||||||
|
using Selector.SignalR;
|
||||||
using Selector.Web.NowPlaying;
|
using Selector.Web.NowPlaying;
|
||||||
using SpotifyAPI.Web;
|
using SpotifyAPI.Web;
|
||||||
using StackExchange.Redis;
|
using StackExchange.Redis;
|
||||||
|
|
||||||
namespace Selector.Web.Hubs
|
namespace Selector.Web.Hubs
|
||||||
{
|
{
|
||||||
public interface INowPlayingHubClient
|
public class NowPlayingHub : Hub<INowPlayingHubClient>, INowPlayingHub
|
||||||
{
|
|
||||||
public Task OnNewPlaying(CurrentlyPlayingDTO context);
|
|
||||||
public Task OnNewAudioFeature(TrackAudioFeatures features);
|
|
||||||
public Task OnNewPlayCount(PlayCount playCount);
|
|
||||||
public Task OnNewCard(Card card);
|
|
||||||
}
|
|
||||||
|
|
||||||
public class NowPlayingHub: Hub<INowPlayingHubClient>
|
|
||||||
{
|
{
|
||||||
private readonly IDatabaseAsync Cache;
|
private readonly IDatabaseAsync Cache;
|
||||||
private readonly AudioFeaturePuller AudioFeaturePuller;
|
private readonly AudioFeaturePuller AudioFeaturePuller;
|
||||||
@ -96,7 +89,7 @@ namespace Selector.Web.Hubs
|
|||||||
|
|
||||||
public async Task SendPlayCount(string track, string artist, string album, string albumArtist)
|
public async Task SendPlayCount(string track, string artist, string album, string albumArtist)
|
||||||
{
|
{
|
||||||
if(PlayCountPuller is not null)
|
if (PlayCountPuller is not null)
|
||||||
{
|
{
|
||||||
var user = Db.Users
|
var user = Db.Users
|
||||||
.AsNoTracking()
|
.AsNoTracking()
|
||||||
@ -124,17 +117,13 @@ namespace Selector.Web.Hubs
|
|||||||
|
|
||||||
public async Task SendFacts(string track, string artist, string album, string albumArtist)
|
public async Task SendFacts(string track, string artist, string album, string albumArtist)
|
||||||
{
|
{
|
||||||
var user = Db.Users
|
await PlayDensityFacts(track, artist, album, albumArtist);
|
||||||
.AsNoTracking()
|
|
||||||
.Where(u => u.Id == Context.UserIdentifier)
|
|
||||||
.SingleOrDefault()
|
|
||||||
?? throw new SqlNullValueException("No user returned");
|
|
||||||
|
|
||||||
await PlayDensityFacts(user, track, artist, album, albumArtist);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task PlayDensityFacts(ApplicationUser user, string track, string artist, string album, string albumArtist)
|
public async Task PlayDensityFacts(string track, string artist, string album, string albumArtist)
|
||||||
{
|
{
|
||||||
|
var user = await Db.Users.AsNoTracking().FirstOrDefaultAsync(u => u.Id == Context.UserIdentifier);
|
||||||
|
|
||||||
if (user.ScrobbleSavingEnabled())
|
if (user.ScrobbleSavingEnabled())
|
||||||
{
|
{
|
||||||
var artistScrobbles = ScrobbleRepository.GetAll(userId: user.Id, artistName: artist, from: GetMaximumWindow()).ToArray();
|
var artistScrobbles = ScrobbleRepository.GetAll(userId: user.Id, artistName: artist, from: GetMaximumWindow()).ToArray();
|
||||||
@ -144,7 +133,7 @@ namespace Selector.Web.Hubs
|
|||||||
|
|
||||||
if (artistDensity > nowOptions.Value.ArtistDensityThreshold)
|
if (artistDensity > nowOptions.Value.ArtistDensityThreshold)
|
||||||
{
|
{
|
||||||
tasks.Add(Clients.Caller.OnNewCard(new()
|
tasks.Add(Clients.Caller.OnNewCard(new Card()
|
||||||
{
|
{
|
||||||
Content = $"You're on a {artist} binge! {artistDensity} plays/day recently"
|
Content = $"You're on a {artist} binge! {artistDensity} plays/day recently"
|
||||||
}));
|
}));
|
||||||
@ -154,7 +143,7 @@ namespace Selector.Web.Hubs
|
|||||||
|
|
||||||
if (albumDensity > nowOptions.Value.AlbumDensityThreshold)
|
if (albumDensity > nowOptions.Value.AlbumDensityThreshold)
|
||||||
{
|
{
|
||||||
tasks.Add(Clients.Caller.OnNewCard(new()
|
tasks.Add(Clients.Caller.OnNewCard(new Card()
|
||||||
{
|
{
|
||||||
Content = $"You're on a {album} binge! {albumDensity} plays/day recently"
|
Content = $"You're on a {album} binge! {albumDensity} plays/day recently"
|
||||||
}));
|
}));
|
||||||
@ -164,13 +153,13 @@ namespace Selector.Web.Hubs
|
|||||||
|
|
||||||
if (albumDensity > nowOptions.Value.TrackDensityThreshold)
|
if (albumDensity > nowOptions.Value.TrackDensityThreshold)
|
||||||
{
|
{
|
||||||
tasks.Add(Clients.Caller.OnNewCard(new()
|
tasks.Add(Clients.Caller.OnNewCard(new Card()
|
||||||
{
|
{
|
||||||
Content = $"You're on a {track} binge! {trackDensity} plays/day recently"
|
Content = $"You're on a {track} binge! {trackDensity} plays/day recently"
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
if(tasks.Any())
|
if (tasks.Any())
|
||||||
{
|
{
|
||||||
await Task.WhenAll(tasks);
|
await Task.WhenAll(tasks);
|
||||||
}
|
}
|
||||||
|
@ -7,16 +7,12 @@ using Microsoft.AspNetCore.SignalR;
|
|||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
using Selector.Cache;
|
using Selector.Cache;
|
||||||
using Selector.Model;
|
using Selector.Model;
|
||||||
|
using Selector.SignalR;
|
||||||
using StackExchange.Redis;
|
using StackExchange.Redis;
|
||||||
|
|
||||||
namespace Selector.Web.Hubs
|
namespace Selector.Web.Hubs
|
||||||
{
|
{
|
||||||
public interface IPastHubClient
|
public class PastHub : Hub<IPastHubClient>, IPastHub
|
||||||
{
|
|
||||||
public Task OnRankResult(RankResult result);
|
|
||||||
}
|
|
||||||
|
|
||||||
public class PastHub: Hub<IPastHubClient>
|
|
||||||
{
|
{
|
||||||
private readonly IDatabaseAsync Cache;
|
private readonly IDatabaseAsync Cache;
|
||||||
private readonly AudioFeaturePuller AudioFeaturePuller;
|
private readonly AudioFeaturePuller AudioFeaturePuller;
|
||||||
@ -61,7 +57,7 @@ namespace Selector.Web.Hubs
|
|||||||
" (Expanded Edition)",
|
" (Expanded Edition)",
|
||||||
};
|
};
|
||||||
|
|
||||||
public async Task OnSubmitted(PastParams param)
|
public async Task OnSubmitted(IPastParams param)
|
||||||
{
|
{
|
||||||
param.Track = string.IsNullOrWhiteSpace(param.Track) ? null : param.Track;
|
param.Track = string.IsNullOrWhiteSpace(param.Track) ? null : param.Track;
|
||||||
param.Album = string.IsNullOrWhiteSpace(param.Album) ? null : param.Album;
|
param.Album = string.IsNullOrWhiteSpace(param.Album) ? null : param.Album;
|
||||||
@ -111,7 +107,7 @@ namespace Selector.Web.Hubs
|
|||||||
.Take(pastOptions.Value.RankingCount)
|
.Take(pastOptions.Value.RankingCount)
|
||||||
.ToArray();
|
.ToArray();
|
||||||
|
|
||||||
await Clients.Caller.OnRankResult(new()
|
await Clients.Caller.OnRankResult(new RankResult()
|
||||||
{
|
{
|
||||||
TrackEntries = trackGrouped.Select(x => new ChartEntry()
|
TrackEntries = trackGrouped.Select(x => new ChartEntry()
|
||||||
{
|
{
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
using System;
|
using System;
|
||||||
namespace Selector.Web.NowPlaying
|
using Selector.SignalR;
|
||||||
|
|
||||||
|
namespace Selector.Web.NowPlaying;
|
||||||
|
|
||||||
|
public class Card : ICard
|
||||||
{
|
{
|
||||||
public class Card
|
|
||||||
{
|
|
||||||
public string Content { get; set; }
|
public string Content { get; set; }
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using Selector.SignalR;
|
||||||
|
|
||||||
namespace Selector.Web;
|
namespace Selector.Web;
|
||||||
|
|
||||||
public class ChartEntry
|
public class ChartEntry : IChartEntry
|
||||||
{
|
{
|
||||||
public string Name { get; set; }
|
public string Name { get; set; }
|
||||||
public int Value { get; set; }
|
public int Value { get; set; }
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using Selector.SignalR;
|
||||||
|
|
||||||
namespace Selector.Web;
|
namespace Selector.Web;
|
||||||
|
|
||||||
public class PastParams
|
public class PastParams : IPastParams
|
||||||
{
|
{
|
||||||
public string Track { get; set; }
|
public string Track { get; set; }
|
||||||
public string Album { get; set; }
|
public string Album { get; set; }
|
||||||
|
@ -1,13 +1,14 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using Selector.SignalR;
|
||||||
|
|
||||||
namespace Selector.Web;
|
namespace Selector.Web;
|
||||||
|
|
||||||
public class RankResult
|
public class RankResult : IRankResult
|
||||||
{
|
{
|
||||||
public IEnumerable<ChartEntry> TrackEntries { get; set; }
|
public IEnumerable<IChartEntry> TrackEntries { get; set; }
|
||||||
public IEnumerable<ChartEntry> AlbumEntries { get; set; }
|
public IEnumerable<IChartEntry> AlbumEntries { get; set; }
|
||||||
public IEnumerable<ChartEntry> ArtistEntries { get; set; }
|
public IEnumerable<IChartEntry> ArtistEntries { get; set; }
|
||||||
|
|
||||||
public IEnumerable<CountSample> ResampledSeries { get; set; }
|
public IEnumerable<CountSample> ResampledSeries { get; set; }
|
||||||
|
|
||||||
|
@ -11,6 +11,9 @@
|
|||||||
<ProjectReference Include="..\Selector.Model\Selector.Model.csproj" />
|
<ProjectReference Include="..\Selector.Model\Selector.Model.csproj" />
|
||||||
<ProjectReference Include="..\Selector.Cache\Selector.Cache.csproj" />
|
<ProjectReference Include="..\Selector.Cache\Selector.Cache.csproj" />
|
||||||
<ProjectReference Include="..\Selector.Event\Selector.Event.csproj" />
|
<ProjectReference Include="..\Selector.Event\Selector.Event.csproj" />
|
||||||
|
<ProjectReference Include="..\Selector.SignalR\Selector.SignalR.csproj">
|
||||||
|
<GlobalPropertiesToRemove></GlobalPropertiesToRemove>
|
||||||
|
</ProjectReference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
@ -4,6 +4,7 @@ using Microsoft.Extensions.Logging;
|
|||||||
|
|
||||||
using Selector.Web.Hubs;
|
using Selector.Web.Hubs;
|
||||||
using Selector.Events;
|
using Selector.Events;
|
||||||
|
using Selector.SignalR;
|
||||||
|
|
||||||
namespace Selector.Web.Service
|
namespace Selector.Web.Service
|
||||||
{
|
{
|
||||||
|
@ -21,6 +21,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Selector.Data", "Selector.D
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Selector.MAUI", "Selector.MAUI\Selector.MAUI.csproj", "{090ADE89-4119-43D7-B108-3357B7D676FC}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Selector.MAUI", "Selector.MAUI\Selector.MAUI.csproj", "{090ADE89-4119-43D7-B108-3357B7D676FC}"
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Selector.SignalR", "Selector.SignalR\Selector.SignalR.csproj", "{F41D98F2-7684-4786-969C-BFC8DF7FB489}"
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
Debug|Any CPU = Debug|Any CPU
|
||||||
@ -63,6 +65,10 @@ Global
|
|||||||
{090ADE89-4119-43D7-B108-3357B7D676FC}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{090ADE89-4119-43D7-B108-3357B7D676FC}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{090ADE89-4119-43D7-B108-3357B7D676FC}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{090ADE89-4119-43D7-B108-3357B7D676FC}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{090ADE89-4119-43D7-B108-3357B7D676FC}.Release|Any CPU.Build.0 = Release|Any CPU
|
{090ADE89-4119-43D7-B108-3357B7D676FC}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{F41D98F2-7684-4786-969C-BFC8DF7FB489}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{F41D98F2-7684-4786-969C-BFC8DF7FB489}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{F41D98F2-7684-4786-969C-BFC8DF7FB489}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{F41D98F2-7684-4786-969C-BFC8DF7FB489}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
Loading…
Reference in New Issue
Block a user