public SimplePlaylistViewModel( IAudioPlaybackEngine audioPlaybackEngine, IWriteLibraryService writeLibraryService, IDialogService dialogService, TracksSubsetViewModel parentTracksSubsetViewModel, IObservable <IChangeSet <TrackViewModel, uint> > sourceTrackViewModelsChangesFlow, SimplePlaylist playlist) : base(audioPlaybackEngine, writeLibraryService, dialogService, parentTracksSubsetViewModel, sourceTrackViewModelsChangesFlow, playlist) { this.RemoveTrackFromSubset = ReactiveCommand.CreateFromTask( async(TrackViewModel trackViewModel) => { var selectedItem = this.SelectedTrackViewModel; if (this.SelectedTrackViewModel == trackViewModel) { // TODO: use dynamicdata watch overload to expose selected item as filter by id this.SelectedTrackViewModel = null; } try { // TODO: handle null? should not happen await this.Playlist?.Remove(trackViewModel.Id); } catch { this.SelectedTrackViewModel = selectedItem; } }) .DisposeWith(this._disposables); this.RemoveTrackFromSubset.ThrownExceptions .Subscribe(ex => Debug.WriteLine(ex)) .DisposeWith(this._disposables); }
public AllTracksViewModel( IAudioPlaybackEngine audioPlaybackEngine, IWriteLibraryService writeLibraryService, IDialogService dialogService, TracksSubsetViewModel parentTracksSubsetViewModel, IObservable <IChangeSet <TrackViewModel, uint> > sourceTrackViewModelsChanges) : base(audioPlaybackEngine, writeLibraryService, dialogService, parentTracksSubsetViewModel, sourceTrackViewModelsChanges) { }
public PlaylistBaseViewModel( IAudioPlaybackEngine audioPlaybackEngine, IWriteLibraryService writeLibraryService, IDialogService dialogService, TracksSubsetViewModel parentTracksSubsetViewModel, IObservable <IChangeSet <TrackViewModel, uint> > sourceTrackViewModelsChangesFlow, PlaylistBase playlist) : base(audioPlaybackEngine, writeLibraryService, dialogService, parentTracksSubsetViewModel, sourceTrackViewModelsChangesFlow) { this._playlist = playlist ?? throw new ArgumentNullException(nameof(playlist)); }
public FolderPlaylistViewModel( IAudioPlaybackEngine audioPlaybackEngine, IWriteLibraryService writeLibraryService, IDialogService dialogService, TracksSubsetViewModel parentTracksSubsetViewModel, IObservable <IChangeSet <TrackViewModel, uint> > sourceTrackViewModelsChangesFlow, FolderPlaylist playlistFolder, Func <PlaylistBase, FolderPlaylistViewModel, PlaylistBaseViewModel> playlistViewModelFactoryMethod) : base(audioPlaybackEngine, writeLibraryService, dialogService, parentTracksSubsetViewModel, sourceTrackViewModelsChangesFlow, playlistFolder) { this._playlistViewModelFactoryMethod = playlistViewModelFactoryMethod ?? throw new ArgumentNullException(nameof(playlistViewModelFactoryMethod)); this._childrenSubscription = new SerialDisposable().DisposeWith(this._disposables); }
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 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 LibraryViewModel( IAudioFileInfoProvider audioFileInfoProvider, //IReadLibraryService readLibraryService, IWriteLibraryService writeLibraryService, IAudioPlaybackEngine audioPlaybackEngine, IDialogService dialogService, Services.LocalLibraryService libraryViewModelsProxy //Func<Track, EditTrackTagsViewModel> editTrackViewModelFactoryMethod, //Func<PlaylistBase, PlaylistBaseViewModel> playlistBaseViewModelFactoryMethod ) { this._audioFileInfoProvider = audioFileInfoProvider ?? throw new ArgumentNullException(nameof(audioFileInfoProvider)); //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._libraryViewModelsProxy = libraryViewModelsProxy ?? throw new ArgumentNullException(nameof(libraryViewModelsProxy)); //this._editTrackTagsViewModelFactoryMethod = editTrackViewModelFactoryMethod ?? throw new ArgumentNullException(nameof(editTrackViewModelFactoryMethod)); //this._playlistBaseViewModelFactoryMethod = playlistBaseViewModelFactoryMethod ?? throw new ArgumentNullException(nameof(playlistBaseViewModelFactoryMethod)); this._serialViewModelsChangesSubscription = new SerialDisposable().DisposeWith(this._disposables); this.ShowFilePicker = ReactiveCommand.CreateFromTask( async() => { var openFileDialogResult = await this._dialogService.OpenFileDialogAsync( "Add files to library ...", Environment.GetFolderPath(Environment.SpecialFolder.MyMusic), true, new Dictionary <string, IReadOnlyCollection <string> > { { "Audio files", this._audioPlaybackEngine.SupportedExtensions } }); if (openFileDialogResult.IsConfirmed != true) { return; } IList <AddTrackCommand> atc = new List <AddTrackCommand>(); foreach (var filePath in openFileDialogResult.Content) { var audioFileInfo = await this._audioFileInfoProvider.ExtractAudioFileInfo(new Uri(filePath)); if (audioFileInfo == null) { // TODO: handle exceptions // TODO: log } atc.Add(new AddTrackCommand( audioFileInfo.Location, audioFileInfo.Duration, audioFileInfo.LastModifiedDateTime, audioFileInfo.SizeBytes, audioFileInfo.Tags.Title, audioFileInfo.Tags.PerformersNames, audioFileInfo.Tags.ComposersNames, audioFileInfo.Tags.Year, new TrackAlbumAssociation( new Album( audioFileInfo.Tags.AlbumTitle, audioFileInfo.Tags.AlbumAuthors, audioFileInfo.Tags.AlbumTracksCount, audioFileInfo.Tags.AlbumDiscsCount), audioFileInfo.Tags.AlbumTrackNumber, audioFileInfo.Tags.AlbumDiscNumber))); } //var addedTracks = await this._writeLibraryService.AddTracksAsync(atc); }) .DisposeWith(this._disposables); this.ShowFilePicker.ThrownExceptions .Subscribe(ex => Debug.WriteLine(ex)) .DisposeWith(this._disposables); this.AllTracksViewModel = this._libraryViewModelsProxy.AllTracksViewModel; //this._libraryViewModelsProxy.PlaylistViewModelsChanges.Bind(out var playlists).Subscribe(_ => this.PlaylistViewModelsROOC = playlists).DisposeWith(this._disposables); //this._libraryViewModelsProxy.PlaylistViewModels // .Cast<IChangeSet<TracksSubsetViewModel, uint>>() // .StartWithItem(this.AllTracksViewModel, 0u) // .Bind(out var subsets).Subscribe(_ => this.PlaylistViewModelsROOC = playlists).DisposeWith(this._disposables); }
public TracksSubsetViewModel( IAudioPlaybackEngine audioPlaybackEngine, IWriteLibraryService writeLibraryService, IDialogService dialogService, TracksSubsetViewModel parentTracksSubsetViewModel, IObservable <IChangeSet <TrackViewModel, uint> > sourceTrackViewModelsChanges) { this._audioPlaybackEngine = audioPlaybackEngine ?? throw new ArgumentNullException(nameof(audioPlaybackEngine)); this._writeLibraryService = writeLibraryService ?? throw new ArgumentNullException(nameof(writeLibraryService)); this._dialogService = dialogService ?? throw new ArgumentNullException(nameof(dialogService)); this._sourceTrackViewModelsChanges = sourceTrackViewModelsChanges ?? throw new ArgumentNullException(nameof(sourceTrackViewModelsChanges)); this.ParentTracksSubsetViewModel = parentTracksSubsetViewModel; this._serialViewModelsChangesSubscription = new SerialDisposable().DisposeWith(this._disposables); this._areTracksLoaded = this .WhenAnyValue(x => x.SortedFilteredTrackViewModelsROOC) .Select(x => x != null) .StartWith(this.SortedFilteredTrackViewModelsROOC != null) .ToProperty(this, nameof(this.AreTracksLoaded), deferSubscription: true) .DisposeWith(this._disposables); //this._tracksCount_OAPH = this // .WhenAnyObservable( // x => x.WhenPropertyChanged(e => e.SortedFilteredTrackViewModelsROOC, true, null) // ) // .Select(p => p?.Value?.Count) // .ToProperty(this, nameof(this.TracksCount)) // .DisposeWith(this._disposables); 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(t => t.SelectedTrackViewModel), this._audioPlaybackEngine.WhenCanLoadChanged, this._audioPlaybackEngine.WhenCanPlayChanged, this._audioPlaybackEngine.WhenCanStopChanged, (selectedTrackViewModel, canLoad, canPlay, canStop) => selectedTrackViewModel != null && (canLoad || canPlay || canStop))) .DisposeWith(this._disposables); this.PlayTrack.ThrownExceptions .ObserveOn(RxApp.MainThreadScheduler) .Subscribe(ex => Debug.WriteLine(ex)) .DisposeWith(this._disposables); this.RemoveTrackFromLibrary = ReactiveCommand.CreateFromTask( async(TrackViewModel trackViewModel) => { if (this.SelectedTrackViewModel == trackViewModel) { this.SelectedTrackViewModel = null; } await this._writeLibraryService.RemoveTrackAsync(new RemoveTrackCommand(trackViewModel.Id)); }) .DisposeWith(this._disposables); this.RemoveTrackFromLibrary.ThrownExceptions .Subscribe(ex => Debug.WriteLine(ex)) .DisposeWith(this._disposables); }