public LocalLibraryService( IReadLibraryService readLibraryService, IWriteLibraryService writeLibraryService, IAudioPlaybackEngine audioPlaybackEngine, IDialogService dialogService, Func <Track, TrackViewModel> trackViewModelFactoryMethod) { this._readLibraryService = readLibraryService ?? throw new ArgumentNullException(nameof(readLibraryService)); this._writeLibraryService = writeLibraryService ?? throw new ArgumentNullException(nameof(writeLibraryService)); this._audioPlaybackEngine = audioPlaybackEngine ?? throw new ArgumentNullException(nameof(audioPlaybackEngine)); this._dialogService = dialogService ?? throw new ArgumentNullException(nameof(dialogService)); this._trackViewModelFactoryMethod = trackViewModelFactoryMethod ?? throw new ArgumentNullException(nameof(trackViewModelFactoryMethod)); //this._readLibraryService.TracksChanges.DeferUntilLoaded().Subscribe().DisposeWith(this._disposables); //this._readLibraryService.PlaylistsChanges.DeferUntilLoaded().Subscribe().DisposeWith(this._disposables); this._tracksSubscription = new SerialDisposable().DisposeWith(this._disposables); this._playlistsSubscription = new SerialDisposable().DisposeWith(this._disposables); this.TrackViewModelsChangeSets = this._readLibraryService.TracksChanges .Transform(track => this._trackViewModelFactoryMethod.Invoke(track), new ParallelisationOptions(ParallelType.Parallelise)) .DisposeMany() // TODO: is RefCount needed with multicast+replay? .Multicast(new ReplaySubject <IChangeSet <TrackViewModel, uint> >()) .AutoConnect(1, subscription => this._tracksSubscription.Disposable = subscription); //.RefCount(); this.PlaylistViewModelsChanges = this._readLibraryService.PlaylistsChanges .Transform(playlist => this.CreatePlaylistViewModel(playlist, null), new ParallelisationOptions(ParallelType.Parallelise)) .DisposeMany() .Multicast(new ReplaySubject <IChangeSet <PlaylistBaseViewModel, uint> >()) .AutoConnect(1, subscription => this._playlistsSubscription.Disposable = subscription); //.RefCount(); //this.TrackViewModelsChangeSets.DeferUntilLoaded().Subscribe().DisposeWith(this._disposables); //this.PlaylistViewModelsChanges.DeferUntilLoaded().Subscribe().DisposeWith(this._disposables); this.AllTracksViewModel = new AllTracksViewModel( this._audioPlaybackEngine, //this._readLibraryService, this._writeLibraryService, this._dialogService, null, this.TrackViewModelsChangeSets); }
public EditTrackViewModel( IReadLibraryService readLibraryService, IWriteLibraryService writeLibraryService, Track track, Func <Track, EditTrackTagsViewModel> editTrackTagsViewModelFactoryMethod) { this._track = track ?? throw new ArgumentNullException(nameof(track)); this._readLibraryService = readLibraryService ?? throw new ArgumentNullException(nameof(readLibraryService)); this._writeLibraryService = writeLibraryService ?? throw new ArgumentNullException(nameof(writeLibraryService)); this._editTrackTagsViewModelFactoryMethod = editTrackTagsViewModelFactoryMethod ?? throw new ArgumentNullException(nameof(editTrackTagsViewModelFactoryMethod)); this.EditTrackTagsViewModel = this._editTrackTagsViewModelFactoryMethod.Invoke(this._track); this.FakeEdit = ReactiveCommand.Create( (TrackViewModel trackVM) => { throw new NotImplementedException(); }); }
public TracksViewModel( IAudioPlaybackEngine audioPlaybackEngine, IReadLibraryService readLibraryService, Func <Track, TrackViewModel> trackViewModelFactoryMethod) { this._audioPlaybackEngine = audioPlaybackEngine ?? throw new ArgumentNullException(nameof(audioPlaybackEngine)); this._readLibraryService = readLibraryService ?? throw new ArgumentNullException(nameof(readLibraryService)); this._trackViewModelFactoryMethod = trackViewModelFactoryMethod ?? throw new ArgumentNullException(nameof(trackViewModelFactoryMethod)); this._serialViewModelsChangesSubscription = new SerialDisposable().DisposeWith(this._disposables); this._tracksSubscriber = this._readLibraryService.TracksChanges //.RefCount() .Transform(track => this._trackViewModelFactoryMethod(track), new ParallelisationOptions(ParallelType.Parallelise)) .DisposeMany() //.Sort(SortExpressionComparer<TrackViewModel>.Ascending(vm => this._random.Next())) .Sort(SortExpressionComparer <TrackViewModel> .Ascending(vm => vm.Id)) .Multicast(new ReplaySubject <IChangeSet <TrackViewModel, uint> >()) .AutoConnect(1, subscription => this._serialViewModelsChangesSubscription.Disposable = subscription) .ObserveOn(RxApp.MainThreadScheduler) .SubscribeOn(RxApp.TaskpoolScheduler) .Bind(out this._trackViewModels) ; this.PlayTrack = ReactiveCommand.CreateFromTask( async(TrackViewModel trackVM) => { // TODO: add ConfigureAwait await this._audioPlaybackEngine.StopAsync() /*.ConfigureAwait(false)*/; await this._audioPlaybackEngine.LoadAndPlayAsync(trackVM.Track) /*.ConfigureAwait(false)*/; }, Observable.CombineLatest( this.WhenAnyValue(subset => subset.SelectedTrackViewModel), this._audioPlaybackEngine.WhenCanLoadChanged, this._audioPlaybackEngine.WhenCanPlayChanged, this._audioPlaybackEngine.WhenCanStopChanged, (selectedTrackViewModel, canLoad, canPlay, canStop) => selectedTrackViewModel != null && (canLoad || canPlay || canStop))); this.PlayTrack.ThrownExceptions //.ObserveOn(RxApp.MainThreadScheduler) .Subscribe(ex => Debug.WriteLine(ex.Message)) .DisposeWith(this._disposables); this.PlayTrack.DisposeWith(this._disposables); }
public EditTrackViewModel( IReadLibraryService readLibraryService, IWriteLibraryService writeLibraryService, Track track, Func <Track, EditTrackTagsViewModel> editTrackTagsViewModelFactoryMethod) { this._track = track ?? throw new ArgumentNullException(nameof(track)); this._readLibraryService = readLibraryService ?? throw new ArgumentNullException(nameof(readLibraryService)); this._writeLibraryService = writeLibraryService ?? throw new ArgumentNullException(nameof(writeLibraryService)); this._editTrackTagsViewModelFactoryMethod = editTrackTagsViewModelFactoryMethod ?? throw new ArgumentNullException(nameof(editTrackTagsViewModelFactoryMethod)); this.EditTrackTagsViewModel = this._editTrackTagsViewModelFactoryMethod.Invoke(this._track); this.CancelAndClose = ReactiveCommand.CreateFromTask(() => this.TryCloseAsync(false)).DisposeWith(this._disposables); this.CancelAndClose.ThrownExceptions.Subscribe(ex => Debug.WriteLine(ex)).DisposeWith(this._disposables); this.ConfirmAndClose = ReactiveCommand.CreateFromTask(() => this.TryCloseAsync(true)).DisposeWith(this._disposables); this.CancelAndClose.ThrownExceptions.Subscribe(ex => Debug.WriteLine(ex)).DisposeWith(this._disposables); this.DisplayName = "Edit"; }
public ShellViewModel( IAudioPlaybackEngine audioPlaybackEngine, //IWriteLibraryService writeLibraryService, IReadLibraryService readLibraryService, IDialogService dialogService, LibraryViewModel libraryViewModel, PlaybackControlsViewModel playbackControlsViewModel, //PlaybackHistoryViewModel playbackHistoryViewModel, ShellMenuViewModel shellMenuViewModel, Func <MiniPlayerViewModel> _miniplayerViewModelFactoryMethod) { this._audioPlaybackEngine = audioPlaybackEngine ?? throw new ArgumentNullException(nameof(audioPlaybackEngine)); //this._writeLibraryService = writeLibraryService ?? throw new ArgumentNullException(nameof(writeLibraryService)); this._readLibraryService = readLibraryService ?? throw new ArgumentNullException(nameof(readLibraryService)); this._dialogService = dialogService ?? throw new ArgumentNullException(nameof(dialogService)); this.LibraryViewModel = libraryViewModel ?? throw new ArgumentNullException(nameof(libraryViewModel)); this.PlaybackControlsViewModel = playbackControlsViewModel ?? throw new ArgumentNullException(nameof(playbackControlsViewModel)); //this.PlaybackHistoryViewModel = playbackHistoryViewModel ?? throw new ArgumentNullException(nameof(playbackHistoryViewModel)); this.ShellMenuViewModel = shellMenuViewModel ?? throw new ArgumentNullException(nameof(shellMenuViewModel)); this.miniplayerViewModelFactoryMethod = _miniplayerViewModelFactoryMethod ?? throw new ArgumentNullException(nameof(_miniplayerViewModelFactoryMethod)); this._isEnabled_OAPH = Observable .Return(true) .ToProperty(this, nameof(this.IsEnabled)) .DisposeWith(this._disposables); this._taskbarProgressState_OAPH = Observable.CombineLatest( this._audioPlaybackEngine.WhenStatusChanged, this._audioPlaybackEngine.WhenDurationChanged, this._audioPlaybackEngine.WhenPositionChanged, (status, duration, position) => { switch (status) { case PlaybackStatus.Loaded: case PlaybackStatus.PlayedToEnd: case PlaybackStatus.ManuallyInterrupted: case PlaybackStatus.None: return(TaskbarItemProgressState.None); case PlaybackStatus.Playing: if (duration.HasValue && position.HasValue) { return(TaskbarItemProgressState.Normal); } return(TaskbarItemProgressState.Indeterminate); case PlaybackStatus.Paused: return(TaskbarItemProgressState.Paused); case PlaybackStatus.Loading: return(TaskbarItemProgressState.Indeterminate); case PlaybackStatus.Exploded: return(TaskbarItemProgressState.Error); default: return(TaskbarItemProgressState.None); } }) .DistinctUntilChanged() .ToProperty(this, nameof(this.TaskbarProgressState)) .DisposeWith(this._disposables); this._taskbarProgressValue_OAPH = Observable.CombineLatest( this._audioPlaybackEngine.WhenDurationChanged, this._audioPlaybackEngine.WhenPositionChanged, (duration, position) => { if (duration.HasValue && position.HasValue) { return(position.Value.TotalMilliseconds / duration.Value.TotalMilliseconds); } return(Double.NaN); }) .DistinctUntilChanged() .ToProperty(this, nameof(this.TaskbarProgressValue)) .DisposeWith(this._disposables); this._audioPlaybackEngine.WhenTrackChanged //.ObserveOn(RxApp.MainThreadScheduler) .Subscribe(track => this.UpdateDisplayName(track)) .DisposeWith(this._disposables); this.HideShellAndShowMiniPlayer = ReactiveCommand.CreateFromTask( async() => { var miniPlayerVM = this.miniplayerViewModelFactoryMethod.Invoke(); this.IsVisible = false; await this._dialogService.ShowWindowAsync(miniPlayerVM); //this.IsVisible = true; }) .DisposeWith(this._disposables); this.Items.Add(this.LibraryViewModel); this.Items.Add(this.PlaybackHistoryViewModel); this.Items.Add(this.PlaybackControlsViewModel); this.Items.Add(this.ShellMenuViewModel); }
public ShellViewModel( IAudioPlaybackEngine playbackService, //IWriteLibraryService writeLibraryService, IReadLibraryService readLibraryService, IDialogService dialogService, LibraryViewModel libraryViewModel, PlaybackControlsViewModel playbackControlsViewModel, PlaybackHistoryViewModel playbackHistoryViewModel, ShellMenuViewModel shellMenuViewModel) { this._playbackService = playbackService ?? throw new ArgumentNullException(nameof(playbackService)); //this._writeLibraryService = writeLibraryService ?? throw new ArgumentNullException(nameof(writeLibraryService)); this._readLibraryService = readLibraryService ?? throw new ArgumentNullException(nameof(readLibraryService)); this._dialogService = dialogService ?? throw new ArgumentNullException(nameof(dialogService)); this.LibraryViewModel = libraryViewModel ?? throw new ArgumentNullException(nameof(libraryViewModel)); this.PlaybackControlsViewModel = playbackControlsViewModel ?? throw new ArgumentNullException(nameof(playbackControlsViewModel)); this.PlaybackHistoryViewModel = playbackHistoryViewModel ?? throw new ArgumentNullException(nameof(playbackHistoryViewModel)); this.ShellMenuViewModel = shellMenuViewModel ?? throw new ArgumentNullException(nameof(shellMenuViewModel)); this._isEnabled_OAPH = Observable .Return(true) .ToProperty(this, nameof(this.IsEnabled)) .DisposeWith(this._disposables); this._taskbarProgressState_OAPH = Observable.CombineLatest( this._playbackService.WhenStatusChanged, this._playbackService.WhenDurationChanged, this._playbackService.WhenPositionChanged, (status, duration, position) => { switch (status) { case PlaybackStatus.Loaded: case PlaybackStatus.PlayedToEnd: case PlaybackStatus.ManuallyInterrupted: case PlaybackStatus.None: return(TaskbarItemProgressState.None); case PlaybackStatus.Playing: if (duration.HasValue && position.HasValue) { return(TaskbarItemProgressState.Normal); } return(TaskbarItemProgressState.Indeterminate); case PlaybackStatus.Paused: return(TaskbarItemProgressState.Paused); case PlaybackStatus.Loading: return(TaskbarItemProgressState.Indeterminate); case PlaybackStatus.Exploded: return(TaskbarItemProgressState.Error); default: return(TaskbarItemProgressState.None); } }) .DistinctUntilChanged() .ToProperty(this, nameof(this.TaskbarProgressState)) .DisposeWith(this._disposables); this._taskbarProgressValue_OAPH = Observable.CombineLatest( this._playbackService.WhenDurationChanged, this._playbackService.WhenPositionChanged, (duration, position) => { if (duration.HasValue && position.HasValue) { return(position.Value.TotalMilliseconds / duration.Value.TotalMilliseconds); } return(Double.NaN); }) .DistinctUntilChanged() .ToProperty(this, nameof(this.TaskbarProgressValue)) .DisposeWith(this._disposables); this._playbackService.WhenTrackChanged .Subscribe(track => this.UpdateDisplayName(track)) .DisposeWith(this._disposables); this.ActivateItem(this.LibraryViewModel); this.ActivateItem(this.PlaybackControlsViewModel); this.ActivateItem(this.PlaybackHistoryViewModel); this.ActivateItem(this.ShellMenuViewModel); }