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) public static CurrentlyPlaying CurrentlyPlaying(FullEpisode episode, bool isPlaying = true, string context = null)
{ {
return new CurrentlyPlaying() 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) public static Context Context(string uri)
{ {
return new Context() return new Context()
@ -97,5 +119,16 @@ namespace Selector.Tests
Uri = uri 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 => public static IEnumerable<object[]> NowPlayingData =>
new List<object[]> new List<object[]>
{ {
new object[] { new List<CurrentlyPlaying>(){ new object[] { new List<CurrentlyPlayingContext>(){
Helper.CurrentlyPlaying(Helper.FullTrack("track1", "album1", "artist1")), Helper.CurrentPlayback(Helper.FullTrack("track1", "album1", "artist1")),
Helper.CurrentlyPlaying(Helper.FullTrack("track2", "album2", "artist2")), Helper.CurrentPlayback(Helper.FullTrack("track2", "album2", "artist2")),
Helper.CurrentlyPlaying(Helper.FullTrack("track3", "album3", "artist3")), Helper.CurrentPlayback(Helper.FullTrack("track3", "album3", "artist3")),
} }
} }
}; };
[Theory] [Theory]
[MemberData(nameof(NowPlayingData))] [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 spotMock = new Mock<IPlayerClient>();
var eq = new UriEquality(); 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); var watcher = new PlayerWatcher(spotMock.Object, eq);
@ -47,108 +47,150 @@ namespace Selector.Tests
new List<object[]> new List<object[]>
{ {
// NO CHANGING // NO CHANGING
new object[] { new List<CurrentlyPlaying>(){ new object[] { new List<CurrentlyPlayingContext>(){
Helper.CurrentlyPlaying(Helper.FullTrack("track1", "album1", "artist1"), isPlaying: true, context: "context1"), Helper.CurrentPlayback(Helper.FullTrack("track1", "album1", "artist1"), isPlaying: true, context: "context1"),
Helper.CurrentlyPlaying(Helper.FullTrack("track1", "album1", "artist1"), isPlaying: true, context: "context1"), Helper.CurrentPlayback(Helper.FullTrack("track1", "album1", "artist1"), isPlaying: true, context: "context1"),
Helper.CurrentlyPlaying(Helper.FullTrack("track1", "album1", "artist1"), isPlaying: true, context: "context1"), Helper.CurrentPlayback(Helper.FullTrack("track1", "album1", "artist1"), isPlaying: true, context: "context1"),
}, },
// to raise // to raise
new List<string>(){ }, new List<string>(){ },
// to not raise // to not raise
new List<string>(){ "ItemChange", "AlbumChange", "ArtistChange", "ContextChange", "PlayingChange" } new List<string>(){ "ItemChange", "AlbumChange", "ArtistChange", "ContextChange", "PlayingChange", "DeviceChange", "VolumeChange" }
}, },
// TRACK CHANGE // TRACK CHANGE
new object[] { new List<CurrentlyPlaying>(){ new object[] { new List<CurrentlyPlayingContext>(){
Helper.CurrentlyPlaying(Helper.FullTrack("track1", "album1", "artist1")), Helper.CurrentPlayback(Helper.FullTrack("track1", "album1", "artist1")),
Helper.CurrentlyPlaying(Helper.FullTrack("track2", "album1", "artist1")) Helper.CurrentPlayback(Helper.FullTrack("track2", "album1", "artist1"))
}, },
// to raise // to raise
new List<string>(){ "ItemChange" }, new List<string>(){ "ItemChange" },
// to not raise // to not raise
new List<string>(){ "AlbumChange", "ArtistChange" } new List<string>(){ "AlbumChange", "ArtistChange", "DeviceChange", "VolumeChange" }
}, },
// ALBUM CHANGE // ALBUM CHANGE
new object[] { new List<CurrentlyPlaying>(){ new object[] { new List<CurrentlyPlayingContext>(){
Helper.CurrentlyPlaying(Helper.FullTrack("track1", "album1", "artist1")), Helper.CurrentPlayback(Helper.FullTrack("track1", "album1", "artist1")),
Helper.CurrentlyPlaying(Helper.FullTrack("track1", "album2", "artist1")) Helper.CurrentPlayback(Helper.FullTrack("track1", "album2", "artist1"))
}, },
// to raise // to raise
new List<string>(){ "ItemChange", "AlbumChange" }, new List<string>(){ "ItemChange", "AlbumChange" },
// to not raise // to not raise
new List<string>(){ "ArtistChange" } new List<string>(){ "ArtistChange", "DeviceChange", "VolumeChange" }
}, },
// ARTIST CHANGE // ARTIST CHANGE
new object[] { new List<CurrentlyPlaying>(){ new object[] { new List<CurrentlyPlayingContext>(){
Helper.CurrentlyPlaying(Helper.FullTrack("track1", "album1", "artist1")), Helper.CurrentPlayback(Helper.FullTrack("track1", "album1", "artist1")),
Helper.CurrentlyPlaying(Helper.FullTrack("track1", "album1", "artist2")) Helper.CurrentPlayback(Helper.FullTrack("track1", "album1", "artist2"))
}, },
// to raise // to raise
new List<string>(){ "ItemChange", "AlbumChange", "ArtistChange" }, new List<string>(){ "ItemChange", "AlbumChange", "ArtistChange" },
// to not raise // to not raise
new List<string>(){ } new List<string>(){ "DeviceChange", "VolumeChange" }
}, },
// CONTEXT CHANGE // CONTEXT CHANGE
new object[] { new List<CurrentlyPlaying>(){ new object[] { new List<CurrentlyPlayingContext>(){
Helper.CurrentlyPlaying(Helper.FullTrack("track1", "album1", "artist1"), context: "context1"), Helper.CurrentPlayback(Helper.FullTrack("track1", "album1", "artist1"), context: "context1"),
Helper.CurrentlyPlaying(Helper.FullTrack("track1", "album1", "artist1"), context: "context2") Helper.CurrentPlayback(Helper.FullTrack("track1", "album1", "artist1"), context: "context2")
}, },
// to raise // to raise
new List<string>(){ "ContextChange" }, new List<string>(){ "ContextChange" },
// to not raise // to not raise
new List<string>(){ "ItemChange", "AlbumChange", "ArtistChange" } new List<string>(){ "ItemChange", "AlbumChange", "ArtistChange", "DeviceChange", "VolumeChange" }
}, },
// PLAYING CHANGE // PLAYING CHANGE
new object[] { new List<CurrentlyPlaying>(){ new object[] { new List<CurrentlyPlayingContext>(){
Helper.CurrentlyPlaying(Helper.FullTrack("track1", "album1", "artist1"), isPlaying: true, context: "context1"), Helper.CurrentPlayback(Helper.FullTrack("track1", "album1", "artist1"), isPlaying: true, context: "context1"),
Helper.CurrentlyPlaying(Helper.FullTrack("track1", "album1", "artist1"), isPlaying: false, context: "context1") Helper.CurrentPlayback(Helper.FullTrack("track1", "album1", "artist1"), isPlaying: false, context: "context1")
}, },
// to raise // to raise
new List<string>(){ "PlayingChange" }, new List<string>(){ "PlayingChange" },
// to not raise // to not raise
new List<string>(){ "ItemChange", "AlbumChange", "ArtistChange", "ContextChange" } new List<string>(){ "ItemChange", "AlbumChange", "ArtistChange", "ContextChange", "DeviceChange", "VolumeChange" }
}, },
// PLAYING CHANGE // PLAYING CHANGE
new object[] { new List<CurrentlyPlaying>(){ new object[] { new List<CurrentlyPlayingContext>(){
Helper.CurrentlyPlaying(Helper.FullTrack("track1", "album1", "artist1"), isPlaying: false, context: "context1"), Helper.CurrentPlayback(Helper.FullTrack("track1", "album1", "artist1"), isPlaying: false, context: "context1"),
Helper.CurrentlyPlaying(Helper.FullTrack("track1", "album1", "artist1"), isPlaying: true, context: "context1") Helper.CurrentPlayback(Helper.FullTrack("track1", "album1", "artist1"), isPlaying: true, context: "context1")
}, },
// to raise // to raise
new List<string>(){ "PlayingChange" }, new List<string>(){ "PlayingChange" },
// to not raise // to not raise
new List<string>(){ "ItemChange", "AlbumChange", "ArtistChange", "ContextChange" } new List<string>(){ "ItemChange", "AlbumChange", "ArtistChange", "ContextChange", "DeviceChange", "VolumeChange" }
}, },
// CONTENT CHANGE // CONTENT CHANGE
new object[] { new List<CurrentlyPlaying>(){ new object[] { new List<CurrentlyPlayingContext>(){
Helper.CurrentlyPlaying(Helper.FullTrack("track1", "album1", "artist1"), isPlaying: true, context: "context1"), Helper.CurrentPlayback(Helper.FullTrack("track1", "album1", "artist1"), isPlaying: true, context: "context1"),
Helper.CurrentlyPlaying(Helper.FullEpisode("ep1", "show1", "pub1"), isPlaying: true, context: "context2") Helper.CurrentPlayback(Helper.FullEpisode("ep1", "show1", "pub1"), isPlaying: true, context: "context2")
}, },
// to raise // to raise
new List<string>(){ "ContentChange", "ContextChange", "ItemChange" }, new List<string>(){ "ContentChange", "ContextChange", "ItemChange" },
// to not raise // to not raise
new List<string>(){ "AlbumChange", "ArtistChange", "PlayingChange" } new List<string>(){ "AlbumChange", "ArtistChange", "PlayingChange", "DeviceChange", "VolumeChange" }
}, },
// CONTENT CHANGE // CONTENT CHANGE
new object[] { new List<CurrentlyPlaying>(){ new object[] { new List<CurrentlyPlayingContext>(){
Helper.CurrentlyPlaying(Helper.FullEpisode("ep1", "show1", "pub1"), isPlaying: true, context: "context2"), Helper.CurrentPlayback(Helper.FullEpisode("ep1", "show1", "pub1"), isPlaying: true, context: "context2"),
Helper.CurrentlyPlaying(Helper.FullTrack("track1", "album1", "artist1"), isPlaying: true, context: "context1") Helper.CurrentPlayback(Helper.FullTrack("track1", "album1", "artist1"), isPlaying: true, context: "context1")
}, },
// to raise // to raise
new List<string>(){ "ContentChange", "ContextChange", "ItemChange" }, new List<string>(){ "ContentChange", "ContextChange", "ItemChange" },
// to not raise // 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] [Theory]
[MemberData(nameof(EventsData))] [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 spotMock = new Mock<IPlayerClient>();
var eq = new UriEquality(); 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); var watcher = new PlayerWatcher(spotMock.Object, eq);
using var monitoredWatcher = watcher.Monitor(); using var monitoredWatcher = watcher.Monitor();
@ -158,12 +200,8 @@ namespace Selector.Tests
await watcher.WatchOne(); await watcher.WatchOne();
} }
foreach(var raise in toRaise){ toRaise.ForEach(r => monitoredWatcher.Should().Raise(r).WithSender(watcher));
monitoredWatcher.Should().Raise(raise).WithSender(watcher); toNotRaise.ForEach(r => monitoredWatcher.Should().NotRaise(r));
}
foreach(var notRraise in toNotRaise){
monitoredWatcher.Should().NotRaise(notRraise);
}
} }
// [Fact] // [Fact]

View File

@ -63,12 +63,12 @@ namespace Selector {
public bool Context(Context context1, Context context2) public bool Context(Context context1, Context context2)
{ {
return context1.Uri == context2.Uri; return context1?.Uri == context2?.Uri;
} }
public bool Device(Device device1, Device device2) 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 namespace Selector
{ {
public class ListeningChangeEventArgs: EventArgs { public class ListeningChangeEventArgs: EventArgs {
public CurrentlyPlaying Previous; public CurrentlyPlayingContext Previous;
public CurrentlyPlaying Current; public CurrentlyPlayingContext Current;
} }
} }

View File

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

View File

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