Ejemplo n.º 1
0
        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);
        }
Ejemplo n.º 2
0
        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();
            });
        }
Ejemplo n.º 3
0
        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);
        }
Ejemplo n.º 4
0
        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";
        }
Ejemplo n.º 5
0
        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);
        }
Ejemplo n.º 6
0
        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);
        }