added volume and device change event

This commit is contained in:
andy 2021-09-28 21:14:52 +01:00
parent 823c1368e7
commit 6f482f14d3
6 changed files with 180 additions and 87 deletions

View File

@ -80,6 +80,17 @@ namespace Selector.Tests
};
}
public static CurrentlyPlayingContext CurrentPlayback(FullTrack track, Device device = null, bool isPlaying = true, string context = null)
{
return new CurrentlyPlayingContext()
{
Context = Context(context ?? track.Uri),
Device = device ?? Device("device"),
IsPlaying = isPlaying,
Item = track
};
}
public static CurrentlyPlaying CurrentlyPlaying(FullEpisode episode, bool isPlaying = true, string context = null)
{
return new CurrentlyPlaying()
@ -90,6 +101,17 @@ namespace Selector.Tests
};
}
public static CurrentlyPlayingContext CurrentPlayback(FullEpisode episode, Device device = null, bool isPlaying = true, string context = null)
{
return new CurrentlyPlayingContext()
{
Context = Context(context ?? episode.Uri),
Device = device ?? Device("device"),
IsPlaying = isPlaying,
Item = episode
};
}
public static Context Context(string uri)
{
return new Context()
@ -97,5 +119,16 @@ namespace Selector.Tests
Uri = uri
};
}
public static Device Device(string name, string id = null, int volume = 50)
{
return new Device()
{
Name = name,
Id = id ?? name,
Type = "computer",
VolumePercent = volume
};
}
}
}

View File

@ -14,24 +14,24 @@ namespace Selector.Tests
public static IEnumerable<object[]> NowPlayingData =>
new List<object[]>
{
new object[] { new List<CurrentlyPlaying>(){
Helper.CurrentlyPlaying(Helper.FullTrack("track1", "album1", "artist1")),
Helper.CurrentlyPlaying(Helper.FullTrack("track2", "album2", "artist2")),
Helper.CurrentlyPlaying(Helper.FullTrack("track3", "album3", "artist3")),
new object[] { new List<CurrentlyPlayingContext>(){
Helper.CurrentPlayback(Helper.FullTrack("track1", "album1", "artist1")),
Helper.CurrentPlayback(Helper.FullTrack("track2", "album2", "artist2")),
Helper.CurrentPlayback(Helper.FullTrack("track3", "album3", "artist3")),
}
}
};
[Theory]
[MemberData(nameof(NowPlayingData))]
public async void NowPlaying(List<CurrentlyPlaying> playing)
public async void NowPlaying(List<CurrentlyPlayingContext> playing)
{
var playingQueue = new Queue<CurrentlyPlaying>(playing);
var playingQueue = new Queue<CurrentlyPlayingContext>(playing);
var spotMock = new Mock<IPlayerClient>();
var eq = new UriEquality();
spotMock.Setup(s => s.GetCurrentlyPlaying(It.IsAny<PlayerCurrentlyPlayingRequest>()).Result).Returns(playingQueue.Dequeue);
spotMock.Setup(s => s.GetCurrentPlayback().Result).Returns(playingQueue.Dequeue);
var watcher = new PlayerWatcher(spotMock.Object, eq);
@ -47,108 +47,150 @@ namespace Selector.Tests
new List<object[]>
{
// NO CHANGING
new object[] { new List<CurrentlyPlaying>(){
Helper.CurrentlyPlaying(Helper.FullTrack("track1", "album1", "artist1"), isPlaying: true, context: "context1"),
Helper.CurrentlyPlaying(Helper.FullTrack("track1", "album1", "artist1"), isPlaying: true, context: "context1"),
Helper.CurrentlyPlaying(Helper.FullTrack("track1", "album1", "artist1"), isPlaying: true, context: "context1"),
new object[] { new List<CurrentlyPlayingContext>(){
Helper.CurrentPlayback(Helper.FullTrack("track1", "album1", "artist1"), isPlaying: true, context: "context1"),
Helper.CurrentPlayback(Helper.FullTrack("track1", "album1", "artist1"), isPlaying: true, context: "context1"),
Helper.CurrentPlayback(Helper.FullTrack("track1", "album1", "artist1"), isPlaying: true, context: "context1"),
},
// to raise
new List<string>(){ },
// to not raise
new List<string>(){ "ItemChange", "AlbumChange", "ArtistChange", "ContextChange", "PlayingChange" }
new List<string>(){ "ItemChange", "AlbumChange", "ArtistChange", "ContextChange", "PlayingChange", "DeviceChange", "VolumeChange" }
},
// TRACK CHANGE
new object[] { new List<CurrentlyPlaying>(){
Helper.CurrentlyPlaying(Helper.FullTrack("track1", "album1", "artist1")),
Helper.CurrentlyPlaying(Helper.FullTrack("track2", "album1", "artist1"))
new object[] { new List<CurrentlyPlayingContext>(){
Helper.CurrentPlayback(Helper.FullTrack("track1", "album1", "artist1")),
Helper.CurrentPlayback(Helper.FullTrack("track2", "album1", "artist1"))
},
// to raise
new List<string>(){ "ItemChange" },
// to not raise
new List<string>(){ "AlbumChange", "ArtistChange" }
new List<string>(){ "AlbumChange", "ArtistChange", "DeviceChange", "VolumeChange" }
},
// ALBUM CHANGE
new object[] { new List<CurrentlyPlaying>(){
Helper.CurrentlyPlaying(Helper.FullTrack("track1", "album1", "artist1")),
Helper.CurrentlyPlaying(Helper.FullTrack("track1", "album2", "artist1"))
new object[] { new List<CurrentlyPlayingContext>(){
Helper.CurrentPlayback(Helper.FullTrack("track1", "album1", "artist1")),
Helper.CurrentPlayback(Helper.FullTrack("track1", "album2", "artist1"))
},
// to raise
new List<string>(){ "ItemChange", "AlbumChange" },
// to not raise
new List<string>(){ "ArtistChange" }
new List<string>(){ "ArtistChange", "DeviceChange", "VolumeChange" }
},
// ARTIST CHANGE
new object[] { new List<CurrentlyPlaying>(){
Helper.CurrentlyPlaying(Helper.FullTrack("track1", "album1", "artist1")),
Helper.CurrentlyPlaying(Helper.FullTrack("track1", "album1", "artist2"))
new object[] { new List<CurrentlyPlayingContext>(){
Helper.CurrentPlayback(Helper.FullTrack("track1", "album1", "artist1")),
Helper.CurrentPlayback(Helper.FullTrack("track1", "album1", "artist2"))
},
// to raise
new List<string>(){ "ItemChange", "AlbumChange", "ArtistChange" },
// to not raise
new List<string>(){ }
new List<string>(){ "DeviceChange", "VolumeChange" }
},
// CONTEXT CHANGE
new object[] { new List<CurrentlyPlaying>(){
Helper.CurrentlyPlaying(Helper.FullTrack("track1", "album1", "artist1"), context: "context1"),
Helper.CurrentlyPlaying(Helper.FullTrack("track1", "album1", "artist1"), context: "context2")
new object[] { new List<CurrentlyPlayingContext>(){
Helper.CurrentPlayback(Helper.FullTrack("track1", "album1", "artist1"), context: "context1"),
Helper.CurrentPlayback(Helper.FullTrack("track1", "album1", "artist1"), context: "context2")
},
// to raise
new List<string>(){ "ContextChange" },
// to not raise
new List<string>(){ "ItemChange", "AlbumChange", "ArtistChange" }
new List<string>(){ "ItemChange", "AlbumChange", "ArtistChange", "DeviceChange", "VolumeChange" }
},
// PLAYING CHANGE
new object[] { new List<CurrentlyPlaying>(){
Helper.CurrentlyPlaying(Helper.FullTrack("track1", "album1", "artist1"), isPlaying: true, context: "context1"),
Helper.CurrentlyPlaying(Helper.FullTrack("track1", "album1", "artist1"), isPlaying: false, context: "context1")
new object[] { new List<CurrentlyPlayingContext>(){
Helper.CurrentPlayback(Helper.FullTrack("track1", "album1", "artist1"), isPlaying: true, context: "context1"),
Helper.CurrentPlayback(Helper.FullTrack("track1", "album1", "artist1"), isPlaying: false, context: "context1")
},
// to raise
new List<string>(){ "PlayingChange" },
// to not raise
new List<string>(){ "ItemChange", "AlbumChange", "ArtistChange", "ContextChange" }
new List<string>(){ "ItemChange", "AlbumChange", "ArtistChange", "ContextChange", "DeviceChange", "VolumeChange" }
},
// PLAYING CHANGE
new object[] { new List<CurrentlyPlaying>(){
Helper.CurrentlyPlaying(Helper.FullTrack("track1", "album1", "artist1"), isPlaying: false, context: "context1"),
Helper.CurrentlyPlaying(Helper.FullTrack("track1", "album1", "artist1"), isPlaying: true, context: "context1")
new object[] { new List<CurrentlyPlayingContext>(){
Helper.CurrentPlayback(Helper.FullTrack("track1", "album1", "artist1"), isPlaying: false, context: "context1"),
Helper.CurrentPlayback(Helper.FullTrack("track1", "album1", "artist1"), isPlaying: true, context: "context1")
},
// to raise
new List<string>(){ "PlayingChange" },
// to not raise
new List<string>(){ "ItemChange", "AlbumChange", "ArtistChange", "ContextChange" }
new List<string>(){ "ItemChange", "AlbumChange", "ArtistChange", "ContextChange", "DeviceChange", "VolumeChange" }
},
// CONTENT CHANGE
new object[] { new List<CurrentlyPlaying>(){
Helper.CurrentlyPlaying(Helper.FullTrack("track1", "album1", "artist1"), isPlaying: true, context: "context1"),
Helper.CurrentlyPlaying(Helper.FullEpisode("ep1", "show1", "pub1"), isPlaying: true, context: "context2")
new object[] { new List<CurrentlyPlayingContext>(){
Helper.CurrentPlayback(Helper.FullTrack("track1", "album1", "artist1"), isPlaying: true, context: "context1"),
Helper.CurrentPlayback(Helper.FullEpisode("ep1", "show1", "pub1"), isPlaying: true, context: "context2")
},
// to raise
new List<string>(){ "ContentChange", "ContextChange", "ItemChange" },
// to not raise
new List<string>(){ "AlbumChange", "ArtistChange", "PlayingChange" }
new List<string>(){ "AlbumChange", "ArtistChange", "PlayingChange", "DeviceChange", "VolumeChange" }
},
// CONTENT CHANGE
new object[] { new List<CurrentlyPlaying>(){
Helper.CurrentlyPlaying(Helper.FullEpisode("ep1", "show1", "pub1"), isPlaying: true, context: "context2"),
Helper.CurrentlyPlaying(Helper.FullTrack("track1", "album1", "artist1"), isPlaying: true, context: "context1")
new object[] { new List<CurrentlyPlayingContext>(){
Helper.CurrentPlayback(Helper.FullEpisode("ep1", "show1", "pub1"), isPlaying: true, context: "context2"),
Helper.CurrentPlayback(Helper.FullTrack("track1", "album1", "artist1"), isPlaying: true, context: "context1")
},
// to raise
new List<string>(){ "ContentChange", "ContextChange", "ItemChange" },
// to not raise
new List<string>(){ "AlbumChange", "ArtistChange", "PlayingChange" }
}
new List<string>(){ "AlbumChange", "ArtistChange", "PlayingChange", "DeviceChange", "VolumeChange" }
},
// DEVICE CHANGE
new object[] { new List<CurrentlyPlayingContext>(){
Helper.CurrentPlayback(Helper.FullTrack("track1", "album1", "artist1"), device: Helper.Device("dev1")),
Helper.CurrentPlayback(Helper.FullTrack("track1", "album1", "artist1"), device: Helper.Device("dev2"))
},
// to raise
new List<string>(){ "DeviceChange" },
// to not raise
new List<string>(){ "AlbumChange", "ArtistChange", "PlayingChange", "ContentChange", "ContextChange", "ItemChange", "VolumeChange" }
},
// VOLUME CHANGE
new object[] { new List<CurrentlyPlayingContext>(){
Helper.CurrentPlayback(Helper.FullTrack("track1", "album1", "artist1"), device: Helper.Device("dev1", volume: 50)),
Helper.CurrentPlayback(Helper.FullTrack("track1", "album1", "artist1"), device: Helper.Device("dev1", volume: 60))
},
// to raise
new List<string>(){ "VolumeChange" },
// to not raise
new List<string>(){ "AlbumChange", "ArtistChange", "PlayingChange", "ContentChange", "ContextChange", "ItemChange", "DeviceChange" }
},
// // STARTED PLAYBACK
// new object[] { new List<CurrentlyPlayingContext>(){
// null,
// Helper.CurrentPlayback(Helper.FullTrack("track1", "album1", "artist1"), isPlaying: true, context: "context1")
// },
// // to raise
// new List<string>(){ "PlayingChange" },
// // to not raise
// new List<string>(){ "AlbumChange", "ArtistChange", "ContentChange", "ContextChange", "ItemChange" }
// },
// // STARTED PLAYBACK
// new object[] { new List<CurrentlyPlayingContext>(){
// Helper.CurrentPlayback(Helper.FullTrack("track1", "album1", "artist1"), isPlaying: true, context: "context1"),
// null
// },
// // to raise
// new List<string>(){ "PlayingChange" },
// // to not raise
// new List<string>(){ "AlbumChange", "ArtistChange", "ContentChange", "ContextChange", "ItemChange" }
// }
};
[Theory]
[MemberData(nameof(EventsData))]
public async void Events(List<CurrentlyPlaying> playing, List<string> toRaise, List<string> toNotRaise)
public async void Events(List<CurrentlyPlayingContext> playing, List<string> toRaise, List<string> toNotRaise)
{
var playingQueue = new Queue<CurrentlyPlaying>(playing);
var playingQueue = new Queue<CurrentlyPlayingContext>(playing);
var spotMock = new Mock<IPlayerClient>();
var eq = new UriEquality();
spotMock.Setup(s => s.GetCurrentlyPlaying(It.IsAny<PlayerCurrentlyPlayingRequest>()).Result).Returns(playingQueue.Dequeue);
spotMock.Setup(
s => s.GetCurrentPlayback().Result
).Returns(playingQueue.Dequeue);
var watcher = new PlayerWatcher(spotMock.Object, eq);
using var monitoredWatcher = watcher.Monitor();
@ -158,12 +200,8 @@ namespace Selector.Tests
await watcher.WatchOne();
}
foreach(var raise in toRaise){
monitoredWatcher.Should().Raise(raise).WithSender(watcher);
}
foreach(var notRraise in toNotRaise){
monitoredWatcher.Should().NotRaise(notRraise);
}
toRaise.ForEach(r => monitoredWatcher.Should().Raise(r).WithSender(watcher));
toNotRaise.ForEach(r => monitoredWatcher.Should().NotRaise(r));
}
// [Fact]

View File

@ -63,12 +63,12 @@ namespace Selector {
public bool Context(Context context1, Context context2)
{
return context1.Uri == context2.Uri;
return context1?.Uri == context2?.Uri;
}
public bool Device(Device device1, Device device2)
{
return device1.Id == device2.Id;
return device1?.Id == device2?.Id;
}
}
}

View File

@ -4,7 +4,7 @@ using SpotifyAPI.Web;
namespace Selector
{
public class ListeningChangeEventArgs: EventArgs {
public CurrentlyPlaying Previous;
public CurrentlyPlaying Current;
public CurrentlyPlayingContext Previous;
public CurrentlyPlayingContext Current;
}
}

View File

@ -12,11 +12,11 @@ namespace Selector
public event EventHandler<ListeningChangeEventArgs> ContextChange;
public event EventHandler<ListeningChangeEventArgs> ContentChange;
// public event EventHandler<ListeningChangeEventArgs> VolumeChange;
// public event EventHandler<ListeningChangeEventArgs> DeviceChange;
public event EventHandler<ListeningChangeEventArgs> VolumeChange;
public event EventHandler<ListeningChangeEventArgs> DeviceChange;
public event EventHandler<ListeningChangeEventArgs> PlayingChange;
public CurrentlyPlaying NowPlaying();
public CurrentlyPlayingContext NowPlaying();
// recently playing
}
}

View File

@ -17,12 +17,12 @@ namespace Selector
public event EventHandler<ListeningChangeEventArgs> ContextChange;
public event EventHandler<ListeningChangeEventArgs> ContentChange;
// public event EventHandler<ListeningChangeEventArgs> VolumeChange;
// public event EventHandler<ListeningChangeEventArgs> DeviceChange;
public event EventHandler<ListeningChangeEventArgs> VolumeChange;
public event EventHandler<ListeningChangeEventArgs> DeviceChange;
public event EventHandler<ListeningChangeEventArgs> PlayingChange;
private CurrentlyPlaying live { get; set; }
private List<List<CurrentlyPlaying>> lastPlays { get; set; }
private CurrentlyPlayingContext live { get; set; }
private List<List<CurrentlyPlayingContext>> lastPlays { get; set; }
private int _pollPeriod;
public int PollPeriod {
@ -38,17 +38,17 @@ namespace Selector
this.equalityChecker = equalityChecker;
this.PollPeriod = pollPeriod;
lastPlays = new List<List<CurrentlyPlaying>>();
lastPlays = new List<List<CurrentlyPlayingContext>>();
}
public async Task WatchOne()
{
try{
var polledCurrent = await spotifyClient.GetCurrentlyPlaying(new PlayerCurrentlyPlayingRequest());
var polledCurrent = await spotifyClient.GetCurrentPlayback();
if (polledCurrent != null) StoreCurrentPlaying(polledCurrent);
if (polledCurrent != null) StoreCurrentPlaying(live, polledCurrent);
CurrentlyPlaying previous;
CurrentlyPlayingContext previous;
if(live is null) {
live = polledCurrent;
previous = polledCurrent;
@ -69,13 +69,19 @@ namespace Selector
if(previous is null && (live.Item is FullTrack || live.Item is FullEpisode))
{
// Console.WriteLine("started playing");
OnPlayingChange(new ListeningChangeEventArgs(){
Previous = previous,
Current = live
});
}
// STOPPED PLAYBACK
else if((previous.Item is FullTrack || previous.Item is FullEpisode) && live is null)
{
// Console.WriteLine("stopped playing");
OnPlayingChange(new ListeningChangeEventArgs(){
Previous = previous,
Current = live
});
}
else {
@ -144,6 +150,14 @@ namespace Selector
});
}
// DEVICE
if(!equalityChecker.Device(previous?.Device, live?.Device)) {
OnDeviceChange(new ListeningChangeEventArgs(){
Previous = previous,
Current = live
});
}
// IS PLAYING
if(previous.IsPlaying != live.IsPlaying) {
OnPlayingChange(new ListeningChangeEventArgs(){
@ -151,6 +165,14 @@ namespace Selector
Current = live
});
}
// VOLUME
if(previous.Device.VolumePercent != live.Device.VolumePercent) {
OnVolumeChange(new ListeningChangeEventArgs(){
Previous = previous,
Current = live
});
}
}
}
}
@ -177,7 +199,7 @@ namespace Selector
}
}
public CurrentlyPlaying NowPlaying()
public CurrentlyPlayingContext NowPlaying()
{
return live;
}
@ -186,7 +208,7 @@ namespace Selector
/// Store currently playing in last plays. Determine whether new list or appending required
/// </summary>
/// <param name="current">New currently playing to store</param>
private void StoreCurrentPlaying(CurrentlyPlaying current)
private void StoreCurrentPlaying(CurrentlyPlayingContext previous, CurrentlyPlayingContext current)
{
if(lastPlays.Count > 0)
{
@ -212,11 +234,11 @@ namespace Selector
}
else
{
StoreNewTrack(current);
StoreNewTrack(previous, current);
}
}
else {
StoreNewTrack(current);
StoreNewTrack(previous, current);
}
}
@ -224,11 +246,11 @@ namespace Selector
/// Store currently playing at front of last plays list. Pushes new list to hold same track
/// </summary>
/// <param name="current">New currently playing to store</param>
private void StoreNewTrack(CurrentlyPlaying current)
private void StoreNewTrack(CurrentlyPlayingContext previous, CurrentlyPlayingContext current)
{
if (live != null) {
var newPlayingList = new List<CurrentlyPlaying>();
newPlayingList.Add(live);
if (previous != null) {
var newPlayingList = new List<CurrentlyPlayingContext>();
newPlayingList.Add(previous);
lastPlays.Insert(0, newPlayingList);
}
}
@ -258,15 +280,15 @@ namespace Selector
ContentChange?.Invoke(this, args);
}
// protected virtual void OnVolumeChange(ListeningChangeEventArgs args)
// {
// ArtistChange?.Invoke(this, args);
// }
protected virtual void OnVolumeChange(ListeningChangeEventArgs args)
{
VolumeChange?.Invoke(this, args);
}
// protected virtual void OnDeviceChange(ListeningChangeEventArgs args)
// {
// ContextChange?.Invoke(this, args);
// }
protected virtual void OnDeviceChange(ListeningChangeEventArgs args)
{
DeviceChange?.Invoke(this, args);
}
protected virtual void OnPlayingChange(ListeningChangeEventArgs args)
{