public MediaBrowserViewModel(IMediaLibraryBrowser mediaLibraryBrowser, Settings settings, LoginFormViewModel loginFormViewModel, IMixViewModelFactory mixViewModelFactory) { this.settings = settings; this.mixViewModelFactory = mixViewModelFactory; this.mediaLibraryBrowser = mediaLibraryBrowser; GetRecentlyMadeMixes = new ReactiveAsyncCommand(null, 1); GetRecentlyMadeMixes.RegisterAsyncFunction( _ => mediaLibraryBrowser.GetRecentlyMadeMixes(CreateMixFilter(Filter))) .Subscribe(SetBrowsedMixes); GetHotMixes = new ReactiveAsyncCommand(null, 1); GetHotMixes.RegisterAsyncFunction(_ => mediaLibraryBrowser.GetHotMixes(CreateMixFilter(Filter))).Subscribe( SetBrowsedMixes); GetPopularMixes = new ReactiveAsyncCommand(null, 1); GetPopularMixes.RegisterAsyncFunction(_ => mediaLibraryBrowser.GetPopularMixes(CreateMixFilter(Filter))) .Subscribe(SetBrowsedMixes); // command is enabled only if the user is logged in GetLikedMixes = new ReactiveAsyncCommand(loginFormViewModel.UserLoggedInObservable, 1); GetLikedMixes.RegisterAsyncFunction(_ => { var mixFilter = CreateMixFilter(Filter); string userSlug = loginFormViewModel.UserData.UserSlug; return(mediaLibraryBrowser.GetLikedMixes(mixFilter, userSlug)); }).Subscribe(SetBrowsedMixes); // command is enabled only if the user is logged in GetFeedMixes = new ReactiveAsyncCommand(loginFormViewModel.UserLoggedInObservable, 1); GetFeedMixes.RegisterAsyncFunction(_ => { var mixFilter = CreateMixFilter(Filter); string userSlug = loginFormViewModel.UserData.UserSlug; return(mediaLibraryBrowser.GetFeedMixes(mixFilter, userSlug)); }).Subscribe(SetBrowsedMixes); GetRecommendedMixes = new ReactiveAsyncCommand(loginFormViewModel.UserLoggedInObservable, 1); GetRecommendedMixes.RegisterAsyncFunction(_ => { var mixFilter = CreateMixFilter(Filter); string userSlug = loginFormViewModel.UserData.UserSlug; return(mediaLibraryBrowser.GetRecommendedMixes(mixFilter, userSlug)); }).Subscribe(SetBrowsedMixes); GetHistoryMixes = new ReactiveAsyncCommand(loginFormViewModel.UserLoggedInObservable, 1); GetHistoryMixes.RegisterAsyncFunction(_ => { var mixFilter = CreateMixFilter(Filter); string userSlug = loginFormViewModel.UserData.UserSlug; return(mediaLibraryBrowser.GetHistoryMixes(mixFilter, userSlug)); }).Subscribe(SetBrowsedMixes); BrowsedMixes = new DispatchedReactiveCollection <MixViewModel>(); ReplaySubject <bool> browsedMixesExistObservable = new ReplaySubject <bool>(1); BrowsedMixes.CollectionCountChanged.Select(count => count > 0).Subscribe(browsedMixesExistObservable.OnNext); browsedMixesExistObservable.OnNext(false); GetMoreMixes = new ReactiveAsyncCommand(browsedMixesExistObservable, 1); GetMoreMixes.RegisterAsyncFunction(_ => mediaLibraryBrowser.GetMoreMixes()) .Subscribe(AddBrowsedMixes); // set can execute only if there is something in the list SetMixDisplayMode = new ReactiveCommand(browsedMixesExistObservable); SetMixDisplayMode.Subscribe(mode => MixDisplayMode = (MixDisplayMode)mode); ApplyFilter = new ReactiveCommand(); ApplyFilter.Where(_ => Filter.Length > 0) .Subscribe(_ => { // if we only started up the application, by search for Hot mixes if (mediaLibraryBrowser.SessionData.IsEmpty) { GetHotMixes.Execute(null); return; } // otherwise, take the same type of mixes as they were before switch (mediaLibraryBrowser.SessionData.LastMixesRequest.ViewType) { case MixesViewType.Hot: GetHotMixes.Execute(null); break; case MixesViewType.Popular: GetPopularMixes.Execute(null); break; case MixesViewType.Recent: GetRecentlyMadeMixes.Execute(null); break; case MixesViewType.Liked: GetLikedMixes.Execute(null); break; case MixesViewType.Feed: GetFeedMixes.Execute(null); break; case MixesViewType.Listened: GetHistoryMixes.Execute(null); break; case MixesViewType.Recommended: GetRecommendedMixes.Execute(null); break; default: // throw new ArgumentOutOfRangeException(); break; } }); MixDisplayMode mixDisplayMode; string storedMixDisplayModeString = (string)settings[mixdisplayModeKey]; Enum.TryParse <MixDisplayMode>(storedMixDisplayModeString, out mixDisplayMode); MixDisplayMode = mixDisplayMode; MixesViewTypeAsString = String.Empty; Filter = String.Empty; MixBrowsingMessage = String.Empty; }
public PlaybackViewModel(IPlaybackController playbackController, Settings settings, IMixViewModelFactory mixViewModelFactory) { this.playbackController = playbackController; this.settings = settings; var volumeString = (string)settings[volumeKey] ?? "50"; Volume = Double.Parse(volumeString); _CurrentPosition = playbackController.CurrentPositionObservable .ToProperty(this, x => x.CurrentPosition); _CurrentPositionAsString = playbackController.CurrentPositionObservable .Select(TimeSpan.FromSeconds) .Select(DurationToString) .ToProperty(this, x => x.CurrentPositionAsString); // connecting current mix being played to the viewmodel IObservable <MixViewModel> currentMixViewModelObservable = playbackController.CurrentMixObservable.Select(mixViewModelFactory.CreateMixViewModel); _CurrentMixViewModel = currentMixViewModelObservable .ToProperty(this, x => x.CurrentMixViewModel); IObservable <bool> _CurrentMixViewModelPresent = this.WhenAny( x => x.CurrentMixViewModel, mixViewModel => mixViewModel.Value != null && mixViewModel.Value.Model != Mix.NoMixAvailable); _CurrentTrackDurationAsString = playbackController.CurrentDurationObservable .Select(duration => DurationToString(TimeSpan.FromSeconds(duration))) .ToProperty(this, x => x.CurrentTrackDurationAsString); _CurrentTrackDuration = playbackController.CurrentDurationObservable .ToProperty(this, x => x.CurrentTrackDuration); // commands // going to the next song only if there is a mix currently loaded _NextSong = currentMixViewModelObservable .Select(x => x.NextSong) .ToProperty(this, x => x.NextSong); var audioPlayerState = playbackController.PlayerStateObservable; // both having a current mix and not running var audioPlayerNotRunning = audioPlayerState.Select(status => status == MediaStatus.Stopped || status == MediaStatus.Paused).CombineLatest( _CurrentMixViewModelPresent, (x, y) => x && y); Continue = new ReactiveAsyncCommand(audioPlayerNotRunning, 1); Continue.Subscribe(_ => playbackController.Continue()); var audioPlayerRunning = audioPlayerState.Select(status => status == MediaStatus.Running); Pause = new ReactiveAsyncCommand(audioPlayerRunning, 1); Pause.Subscribe(_ => playbackController.Pause()); var audioPlayerRunningOrPaused = audioPlayerState.Select(status => status == MediaStatus.Running || status == MediaStatus.Paused); Stop = new ReactiveAsyncCommand(audioPlayerRunningOrPaused, 1); Stop.Subscribe(_ => playbackController.Stop()); NextMix = new ReactiveAsyncCommand(_CurrentMixViewModelPresent, 1); NextMix.RegisterAsyncAction(_ => { try { playbackController.NextMix(); } catch (Exception e) { log.Error("Unable to go to the next mix", e); } } ); bool debugModeOn = ConfigurationManager.AppSettings["AudioPlayer"] != null && ConfigurationManager.AppSettings["AudioPlayer"].Equals("DirectX WMI 3.14169"); _IsPositionSliderEnabled = audioPlayerRunningOrPaused .Select(a => a && debugModeOn) .ToProperty(this, x => x.IsPositionSliderEnabled); GoToTrack = new ReactiveAsyncCommand(_CurrentMixViewModelPresent, 1); GoToTrack.Subscribe(_ => { if (debugModeOn) { try { playbackController.GoToTrack(SelectedTrackIndex); } catch (Exception e) { log.Error("Unable to go to track " + SelectedTrackIndex, e); } } }); Skip = new ReactiveAsyncCommand(audioPlayerRunningOrPaused, 1); Skip.Subscribe(step => { double newPosition = CurrentPosition + Double.Parse((string)step); if (newPosition >= 0 && newPosition <= CurrentTrackDuration) { CurrentPosition = newPosition; } }); ChangeVolume = new ReactiveAsyncCommand(null, 1); ChangeVolume.Subscribe(step => { double newVolume = Volume + Double.Parse((string)step); if (newVolume >= 0 && newVolume <= 100) { Volume = newVolume; } }); }
public MediaBrowserViewModel(LoginFormViewModel loginFormViewModel, IMixViewModelFactory mixViewModelFactory) : this(new MediaLibraryBrowser(), new Settings(), loginFormViewModel, mixViewModelFactory) { }