diff --git a/src/AudioBand.Test/CustomLabelsViewModelTests.cs b/src/AudioBand.Test/CustomLabelsViewModelTests.cs index 89ed0528..502b65b1 100644 --- a/src/AudioBand.Test/CustomLabelsViewModelTests.cs +++ b/src/AudioBand.Test/CustomLabelsViewModelTests.cs @@ -2,6 +2,7 @@ using System.Text; using System.Collections.Generic; using System.Threading.Tasks; +using AudioBand.AudioSource; using Microsoft.VisualStudio.TestTools.UnitTesting; using AudioBand.ViewModels; using AudioBand.Models; @@ -108,16 +109,35 @@ public void AddRemoveLabel_ThenCancel() Assert.AreEqual(0, _viewModel.CustomLabels.Count); } - [TestMethod, Ignore("Issue with verifying invocation")] + [TestMethod, Ignore("Unable to setup sequence")] public void ProfileChangeRemovesAllLabelsAndAddsNewOnes() { - var settingsMock = new Mock(); - settingsMock.SetupGet(m => m.CustomLabels).Returns(new List {new CustomLabel()}); + settingsMock.SetupSequence(m => m.CustomLabels) + .Returns(new List { new CustomLabel { Name = "test" } }) + .Returns(new List { new CustomLabel { Name = "second" } }); var vm = new CustomLabelsViewModel(settingsMock.Object, new Mock().Object); Assert.AreEqual(1, vm.CustomLabels.Count); - _appSettingsMock.Raise(m => m.ProfileChanged += null, EventArgs.Empty); + Assert.AreEqual("test", vm.CustomLabels[0].Name); + _appSettingsMock.Raise(m => m.ProfileChanged += null, null, EventArgs.Empty); + Assert.AreEqual("second", vm.CustomLabels[0].Name); + } + + [TestMethod] + public void ProfileChangeUpdateAudioSources() + { + var settingsMock = new Mock(); + settingsMock.SetupSequence(m => m.CustomLabels) + .Returns(new List {new CustomLabel()}); + var audioSourceMock = new Mock(); + audioSourceMock.SetupGet(m => m.LastTrackInfo).Returns(new TrackInfoChangedEventArgs()); + + var vm = new CustomLabelsViewModel(settingsMock.Object, new Mock().Object); + vm.AudioSource = audioSourceMock.Object; + _appSettingsMock.Raise(m => m.ProfileChanged += null, null, EventArgs.Empty); + audioSourceMock.Raise(m => m.IsPlayingChanged += null, null, true); + Assert.IsTrue(vm.CustomLabels[0].IsPlaying); } } } diff --git a/src/AudioBand/AudioSource/AudioSourceProxy.cs b/src/AudioBand/AudioSource/AudioSourceProxy.cs index cd5ff705..4f8760be 100644 --- a/src/AudioBand/AudioSource/AudioSourceProxy.cs +++ b/src/AudioBand/AudioSource/AudioSourceProxy.cs @@ -87,6 +87,21 @@ public string Name /// public IAudioSourceLogger Logger { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + /// + /// Gets a value indicating whether the audio source is currently playing. + /// + public bool IsPlaying { get; private set; } + + /// + /// Gets the current progress. + /// + public TimeSpan CurrentProgress { get; private set; } + + /// + /// Gets the last track info. + /// + public TrackInfoChangedEventArgs LastTrackInfo { get; private set; } = new TrackInfoChangedEventArgs(); + /// /// Gets the settings that the audio source has. /// @@ -321,9 +336,21 @@ private void CreateWrapper() } _wrapper.SettingChanged += new MarshaledEventHandler(e => SettingChanged?.Invoke(this, e)).Handler; - _wrapper.TrackInfoChanged += new MarshaledEventHandler(e => TrackInfoChanged?.Invoke(this, e)).Handler; - _wrapper.IsPlayingChanged += new MarshaledEventHandler(e => IsPlayingChanged?.Invoke(this, e)).Handler; - _wrapper.TrackProgressChanged += new MarshaledEventHandler(e => TrackProgressChanged?.Invoke(this, e)).Handler; + _wrapper.TrackInfoChanged += new MarshaledEventHandler(e => + { + TrackInfoChanged?.Invoke(this, e); + LastTrackInfo = e; + }).Handler; + _wrapper.IsPlayingChanged += new MarshaledEventHandler(e => + { + IsPlayingChanged?.Invoke(this, e); + IsPlaying = e; + }).Handler; + _wrapper.TrackProgressChanged += new MarshaledEventHandler(e => + { + TrackProgressChanged?.Invoke(this, e); + CurrentProgress = e; + }).Handler; _wrapper.VolumeChanged += new MarshaledEventHandler(e => VolumeChanged?.Invoke(this, e)).Handler; _wrapper.ShuffleChanged += new MarshaledEventHandler(e => ShuffleChanged?.Invoke(this, e)).Handler; _wrapper.RepeatModeChanged += new MarshaledEventHandler(e => RepeatModeChanged?.Invoke(this, e)).Handler; diff --git a/src/AudioBand/AudioSource/IInternalAudioSource.cs b/src/AudioBand/AudioSource/IInternalAudioSource.cs index 319713f8..24217b80 100644 --- a/src/AudioBand/AudioSource/IInternalAudioSource.cs +++ b/src/AudioBand/AudioSource/IInternalAudioSource.cs @@ -8,6 +8,21 @@ namespace AudioBand.AudioSource /// public interface IInternalAudioSource : IAudioSource { + /// + /// Gets a value indicating whether the audio source is currently playing. + /// + bool IsPlaying { get; } + + /// + /// Gets the current progress. + /// + TimeSpan CurrentProgress { get; } + + /// + /// Gets the last track info. + /// + TrackInfoChangedEventArgs LastTrackInfo { get; } + /// /// Gets the settings that the audio source exposes. /// diff --git a/src/AudioBand/Resources/ComboBoxStyles.xaml b/src/AudioBand/Resources/ComboBoxStyles.xaml index a355f219..6a7ae951 100644 --- a/src/AudioBand/Resources/ComboBoxStyles.xaml +++ b/src/AudioBand/Resources/ComboBoxStyles.xaml @@ -72,7 +72,7 @@ (LoadCommandOnExecute); - SelectAudioSourceCommand = new AsyncRelayCommand(SelectAudioSourceCommandOnExecute); + SelectAudioSourceCommand = new AsyncRelayCommand(SelectAudioSourceCommandOnExecute); } /// @@ -112,7 +112,7 @@ private async Task LoadCommandOnExecute(object arg) Logger.Debug("Audio sources loaded. Loaded {num} sources", AudioSources.Count); } - private async Task SelectAudioSourceCommandOnExecute(IAudioSource audioSource) + private async Task SelectAudioSourceCommandOnExecute(IInternalAudioSource audioSource) { if (SelectedAudioSource != null) { @@ -153,7 +153,7 @@ private async Task SelectAudioSourceCommandOnExecute(IAudioSource audioSource) } } - private void UpdateViewModels(IAudioSource audioSource) + private void UpdateViewModels(IInternalAudioSource audioSource) { ViewModels.AlbumArtViewModel.AudioSource = audioSource; ViewModels.NextButtonViewModel.AudioSource = audioSource; @@ -162,10 +162,7 @@ private void UpdateViewModels(IAudioSource audioSource) ViewModels.ProgressBarViewModel.AudioSource = audioSource; ViewModels.RepeatModeButtonViewModel.AudioSource = audioSource; ViewModels.ShuffleModeButtonViewModel.AudioSource = audioSource; - foreach (var customLabelVm in ViewModels.CustomLabelsViewModel.CustomLabels) - { - customLabelVm.AudioSource = audioSource; - } + ViewModels.CustomLabelsViewModel.AudioSource = audioSource; } } } diff --git a/src/AudioBand/ViewModels/CustomLabelViewModel.cs b/src/AudioBand/ViewModels/CustomLabelViewModel.cs index b759bf80..fb3d6fb8 100644 --- a/src/AudioBand/ViewModels/CustomLabelViewModel.cs +++ b/src/AudioBand/ViewModels/CustomLabelViewModel.cs @@ -16,7 +16,7 @@ namespace AudioBand.ViewModels public class CustomLabelViewModel : LayoutViewModelBase { private readonly FormattedTextParser _parser; - private IAudioSource _audioSource; + private IInternalAudioSource _audioSource; private bool _isPlaying; /// @@ -185,7 +185,7 @@ public double RightFadeOffset /// /// Sets the audio source. /// - public IAudioSource AudioSource + public IInternalAudioSource AudioSource { set => UpdateAudioSource(value); } @@ -214,7 +214,7 @@ protected override void OnModelPropertyChanged(string propertyName) } } - private void UpdateAudioSource(IAudioSource audioSource) + private void UpdateAudioSource(IInternalAudioSource audioSource) { if (_audioSource != null) { @@ -231,6 +231,11 @@ private void UpdateAudioSource(IAudioSource audioSource) return; } + // Sync current information in the case the profiles change, otherwise we won't receive information until the next time the event is activated. + AudioSourceOnTrackInfoChanged(null, _audioSource.LastTrackInfo); + AudioSourceOnIsPlayingChanged(null, _audioSource.IsPlaying); + AudioSourceOnTrackProgressChanged(null, _audioSource.CurrentProgress); + _audioSource.TrackInfoChanged += AudioSourceOnTrackInfoChanged; _audioSource.TrackProgressChanged += AudioSourceOnTrackProgressChanged; _audioSource.IsPlayingChanged += AudioSourceOnIsPlayingChanged; diff --git a/src/AudioBand/ViewModels/CustomLabelsViewModel.cs b/src/AudioBand/ViewModels/CustomLabelsViewModel.cs index d6c9dab0..8ff20537 100644 --- a/src/AudioBand/ViewModels/CustomLabelsViewModel.cs +++ b/src/AudioBand/ViewModels/CustomLabelsViewModel.cs @@ -3,6 +3,7 @@ using System.Collections.ObjectModel; using System.Diagnostics; using System.Linq; +using AudioBand.AudioSource; using AudioBand.Commands; using AudioBand.Models; using AudioBand.Settings; @@ -18,6 +19,7 @@ public class CustomLabelsViewModel : ViewModelBase private readonly HashSet _removed = new HashSet(); private readonly IAppSettings _appsettings; private readonly IDialogService _dialogService; + private IInternalAudioSource _audioSource; /// /// Initializes a new instance of the class @@ -51,6 +53,14 @@ public CustomLabelsViewModel(IAppSettings appsettings, IDialogService dialogServ /// public RelayCommand RemoveLabelCommand { get; } + /// + /// Sets the audio source. + /// + public IInternalAudioSource AudioSource + { + set => UpdateAudioSource(value); + } + /// protected override void OnBeginEdit() { @@ -130,10 +140,22 @@ private void AppsettingsOnProfileChanged(object sender, EventArgs e) { Debug.Assert(IsEditing == false, "Should not be editing while profile is changing"); - CustomLabels.Clear(); - // Add labels for new profile SetupLabels(); + + foreach (var customLabelViewModel in CustomLabels) + { + customLabelViewModel.AudioSource = _audioSource; + } + } + + private void UpdateAudioSource(IInternalAudioSource audioSource) + { + _audioSource = audioSource; + foreach (var customLabelViewModel in CustomLabels) + { + customLabelViewModel.AudioSource = audioSource; + } } } }