From 0102273f5151f163f777c98f39e236d53cd736df Mon Sep 17 00:00:00 2001 From: Omar Plata Salas Date: Thu, 3 Mar 2022 17:33:07 -0500 Subject: [PATCH 1/7] made repository a singleton --- Rise Media Player Dev/App.xaml.cs | 19 +++----- Rise Media Player Dev/Rise.App.csproj | 44 +++++++++---------- .../ViewModels/AlbumViewModel.cs | 7 +-- .../ViewModels/ArtistViewModel.cs | 7 +-- .../ViewModels/GenreViewModel.cs | 3 +- .../ViewModels/MainViewModel.cs | 33 +++++++------- .../ViewModels/SongViewModel.cs | 9 ++-- .../ViewModels/VideoViewModel.cs | 3 +- .../Views/Artists/ArtistsPage.xaml.cs | 3 +- Rise.Repository/SQL/SQLRepository.cs | 25 ++++++++++- 10 files changed, 87 insertions(+), 66 deletions(-) diff --git a/Rise Media Player Dev/App.xaml.cs b/Rise Media Player Dev/App.xaml.cs index e929f254..bb86ea2e 100644 --- a/Rise Media Player Dev/App.xaml.cs +++ b/Rise Media Player Dev/App.xaml.cs @@ -94,11 +94,6 @@ public static TimeSpan IndexingInterval /// public static LastFMViewModel LMViewModel { get; private set; } - /// - /// Pipeline for interacting with backend service or database. - /// - public static IRepository Repository { get; private set; } - /// /// Gets the music library. /// @@ -183,6 +178,7 @@ protected async override void OnActivated(IActivatedEventArgs e) Window.Current.Activate(); break; + case ActivationKind.ToastNotification: if (e is ToastNotificationActivatedEventArgs toastActivationArgs) { @@ -206,22 +202,19 @@ protected async override void OnActivated(IActivatedEventArgs e) } /// - /// Initializes the app's database and ViewModels. + /// Initializes the app's ViewModels. /// - private async Task InitDatabase() + private async Task InitDataSourcesAsync() { + // We still have to make sure the file's there _ = await ApplicationData.Current.LocalCacheFolder.CreateFileAsync("Files.db", CreationCollisionOption.OpenIfExists); - string dbPath = Path.Combine(ApplicationData.Current.LocalCacheFolder.Path, "Files.db"); - DbContextOptionsBuilder dbOptions = new DbContextOptionsBuilder().UseSqlite( - "Data Source=" + dbPath); - - Repository = new SQLRepository(dbOptions); MusicLibrary = await StorageLibrary.GetLibraryAsync(KnownLibraryId.Music); VideoLibrary = await StorageLibrary.GetLibraryAsync(KnownLibraryId.Videos); PBackendController = new PlaylistsBackendController(); NBackendController = new NotificationsBackendController(); + MViewModel = new MainViewModel(); LMViewModel = new LastFMViewModel(); PViewModel = new PlaybackViewModel(); @@ -351,7 +344,7 @@ private async Task InitializeWindowAsync(dynamic args) // just ensure that the window is active if (Window.Current.Content is not Frame rootFrame) { - await InitDatabase(); + await InitDataSourcesAsync(); await MViewModel.GetListsAsync(); StartIndexingTimer(); diff --git a/Rise Media Player Dev/Rise.App.csproj b/Rise Media Player Dev/Rise.App.csproj index ab84b90b..e7b04eda 100644 --- a/Rise Media Player Dev/Rise.App.csproj +++ b/Rise Media Player Dev/Rise.App.csproj @@ -568,9 +568,9 @@ - - - + + + @@ -940,14 +940,14 @@ - - - - - - - - + + + + + + + + @@ -961,13 +961,13 @@ - + - + - + @@ -1097,14 +1097,14 @@ - - - - - - - - + + + + + + + + diff --git a/Rise Media Player Dev/ViewModels/AlbumViewModel.cs b/Rise Media Player Dev/ViewModels/AlbumViewModel.cs index 0035083e..4bd083bb 100644 --- a/Rise Media Player Dev/ViewModels/AlbumViewModel.cs +++ b/Rise Media Player Dev/ViewModels/AlbumViewModel.cs @@ -1,5 +1,6 @@ using Rise.App.Common; using Rise.Models; +using Rise.Repository.SQL; using System; using System.Linq; using System.Threading.Tasks; @@ -274,7 +275,7 @@ public async Task SaveAsync() App.MViewModel.Albums.Add(this); } - await App.Repository.Albums.QueueUpsertAsync(Model); + await SQLRepository.Repository.Albums.QueueUpsertAsync(Model); } /// @@ -298,7 +299,7 @@ public async Task DeleteAsync() IsModified = true; App.MViewModel.Albums.Remove(this); - await App.Repository.Albums.QueueDeletionAsync(Model); + await SQLRepository.Repository.Albums.QueueDeletionAsync(Model); ArtistViewModel artist = App.MViewModel.Artists. FirstOrDefault(a => a.Model.Name == Model.Artist); @@ -347,7 +348,7 @@ public async Task RevertChangesAsync() /// public async Task RefreshAlbumsAsync() { - Model = await App.Repository.Albums.GetAsync(Model.Id); + Model = await SQLRepository.Repository.Albums.GetAsync(Model.Id); } } } diff --git a/Rise Media Player Dev/ViewModels/ArtistViewModel.cs b/Rise Media Player Dev/ViewModels/ArtistViewModel.cs index ebca6331..808201e8 100644 --- a/Rise Media Player Dev/ViewModels/ArtistViewModel.cs +++ b/Rise Media Player Dev/ViewModels/ArtistViewModel.cs @@ -3,6 +3,7 @@ using System; using System.Linq; using System.Threading.Tasks; +using Rise.Repository.SQL; namespace Rise.App.ViewModels { @@ -120,7 +121,7 @@ public async Task SaveAsync() App.MViewModel.Artists.Add(this); } - await App.Repository.Artists.QueueUpsertAsync(Model); + await SQLRepository.Repository.Artists.QueueUpsertAsync(Model); } /// @@ -144,7 +145,7 @@ public async Task DeleteAsync() IsModified = true; App.MViewModel.Artists.Remove(this); - await App.Repository.Artists.QueueDeletionAsync(Model); + await SQLRepository.Repository.Artists.QueueDeletionAsync(Model); } /// @@ -190,7 +191,7 @@ public async Task RevertChangesAsync() /// public async Task RefreshArtistsAsync() { - Model = await App.Repository.Artists.GetAsync(Model.Id); + Model = await SQLRepository.Repository.Artists.GetAsync(Model.Id); } } } diff --git a/Rise Media Player Dev/ViewModels/GenreViewModel.cs b/Rise Media Player Dev/ViewModels/GenreViewModel.cs index 840a02d3..9eacd178 100644 --- a/Rise Media Player Dev/ViewModels/GenreViewModel.cs +++ b/Rise Media Player Dev/ViewModels/GenreViewModel.cs @@ -1,5 +1,6 @@ using Rise.App.Common; using Rise.Models; +using Rise.Repository.SQL; using System.Threading.Tasks; namespace Rise.App.ViewModels @@ -62,7 +63,7 @@ public async Task SaveAsync() App.MViewModel.Genres.Add(this); } - await App.Repository.Genres.QueueUpsertAsync(Model); + await SQLRepository.Repository.Genres.QueueUpsertAsync(Model); } } } diff --git a/Rise Media Player Dev/ViewModels/MainViewModel.cs b/Rise Media Player Dev/ViewModels/MainViewModel.cs index 78f7736d..4549b620 100644 --- a/Rise Media Player Dev/ViewModels/MainViewModel.cs +++ b/Rise Media Player Dev/ViewModels/MainViewModel.cs @@ -5,6 +5,7 @@ using Rise.App.Props; using Rise.App.Views; using Rise.Models; +using Rise.Repository.SQL; using System; using System.Collections.Generic; using System.Collections.ObjectModel; @@ -156,14 +157,14 @@ public VideoViewModel SelectedVideo public async Task GetListsAsync() { LoadingStarted?.Invoke(this, EventArgs.Empty); - IEnumerable songs = (await App.Repository.Songs.GetAsync()).Distinct(); + IEnumerable songs = (await SQLRepository.Repository.Songs.GetAsync()).Distinct(); if (songs != null) { - IEnumerable albums = (await App.Repository.Albums.GetAsync()).Distinct(); - IEnumerable artists = (await App.Repository.Artists.GetAsync()).Distinct(); - IEnumerable genres = (await App.Repository.Genres.GetAsync()).Distinct(); - IEnumerable public async Task UpdateItemsAsync() { - await App.Repository.Songs.UpsertQueuedAsync(); - await App.Repository.Albums.UpsertQueuedAsync(); - await App.Repository.Artists.UpsertQueuedAsync(); - await App.Repository.Genres.UpsertQueuedAsync(); - await App.Repository.Videos.UpsertQueuedAsync(); - - await App.Repository.Songs.DeleteQueuedAsync(); - await App.Repository.Albums.DeleteQueuedAsync(); - await App.Repository.Artists.DeleteQueuedAsync(); - await App.Repository.Genres.DeleteQueuedAsync(); - await App.Repository.Videos.DeleteQueuedAsync(); + await SQLRepository.Repository.Songs.UpsertQueuedAsync(); + await SQLRepository.Repository.Albums.UpsertQueuedAsync(); + await SQLRepository.Repository.Artists.UpsertQueuedAsync(); + await SQLRepository.Repository.Genres.UpsertQueuedAsync(); + await SQLRepository.Repository.Videos.UpsertQueuedAsync(); + + await SQLRepository.Repository.Songs.DeleteQueuedAsync(); + await SQLRepository.Repository.Albums.DeleteQueuedAsync(); + await SQLRepository.Repository.Artists.DeleteQueuedAsync(); + await SQLRepository.Repository.Genres.DeleteQueuedAsync(); + await SQLRepository.Repository.Videos.DeleteQueuedAsync(); } /// diff --git a/Rise Media Player Dev/ViewModels/SongViewModel.cs b/Rise Media Player Dev/ViewModels/SongViewModel.cs index 290e1e2c..8b796c29 100644 --- a/Rise Media Player Dev/ViewModels/SongViewModel.cs +++ b/Rise Media Player Dev/ViewModels/SongViewModel.cs @@ -1,6 +1,7 @@ using Rise.App.Common; using Rise.App.Views; using Rise.Models; +using Rise.Repository.SQL; using System; using System.Collections.Generic; using System.IO; @@ -367,9 +368,9 @@ public async Task SaveAsync() OnPropertyChanged(nameof(ArtistViewModel.SongCount)); } - if (await App.Repository.Songs.GetAsync(Model.Id) == null) + if (await SQLRepository.Repository.Songs.GetAsync(Model.Id) == null) { - await App.Repository.Songs.QueueUpsertAsync(Model); + await SQLRepository.Repository.Songs.QueueUpsertAsync(Model); } } @@ -386,7 +387,7 @@ public async Task DeleteAsync() App.MViewModel.Songs.Remove(this); } - await App.Repository.Songs.QueueUpsertAsync(Model); + await SQLRepository.Repository.Songs.QueueUpsertAsync(Model); AlbumViewModel album = App.MViewModel.Albums. FirstOrDefault(a => a.Model.Title == Model.Album && a.Model.Artist == Model.AlbumArtist); @@ -463,7 +464,7 @@ public async Task StartEdit() /// public async Task RefreshSongsAsync() { - Model = await App.Repository.Songs.GetAsync(Model.Id); + Model = await SQLRepository.Repository.Songs.GetAsync(Model.Id); } /// diff --git a/Rise Media Player Dev/ViewModels/VideoViewModel.cs b/Rise Media Player Dev/ViewModels/VideoViewModel.cs index c6496742..fffcb692 100644 --- a/Rise Media Player Dev/ViewModels/VideoViewModel.cs +++ b/Rise Media Player Dev/ViewModels/VideoViewModel.cs @@ -1,4 +1,5 @@ using Rise.Models; +using Rise.Repository.SQL; using System; using System.Threading.Tasks; using Windows.Media; @@ -164,7 +165,7 @@ public async Task SaveAsync() App.MViewModel.Videos.Add(this); } - await App.Repository.Videos.QueueUpsertAsync(Model); + await SQLRepository.Repository.Videos.QueueUpsertAsync(Model); } /// diff --git a/Rise Media Player Dev/Views/Artists/ArtistsPage.xaml.cs b/Rise Media Player Dev/Views/Artists/ArtistsPage.xaml.cs index b28aaaee..438e5699 100644 --- a/Rise Media Player Dev/Views/Artists/ArtistsPage.xaml.cs +++ b/Rise Media Player Dev/Views/Artists/ArtistsPage.xaml.cs @@ -3,6 +3,7 @@ using Rise.App.Helpers; using Rise.App.ViewModels; using Rise.Models; +using Rise.Repository.SQL; using System; using System.Collections.Generic; using System.Linq; @@ -168,7 +169,7 @@ private async Task SetArtistPictures() foreach (ArtistViewModel artist in Artists) { // Get images from database - IEnumerable artists = await App.Repository.Artists.GetAsync(); + IEnumerable artists = await SQLRepository.Repository.Artists.GetAsync(); StorageFile file = null; try diff --git a/Rise.Repository/SQL/SQLRepository.cs b/Rise.Repository/SQL/SQLRepository.cs index b10a8d3a..8d8fa9f7 100644 --- a/Rise.Repository/SQL/SQLRepository.cs +++ b/Rise.Repository/SQL/SQLRepository.cs @@ -1,5 +1,7 @@ using Microsoft.EntityFrameworkCore; using Rise.Models; +using System.IO; +using Windows.Storage; namespace Rise.Repository.SQL { @@ -7,7 +9,26 @@ public class SQLRepository : IRepository { private readonly DbContextOptions _dbOptions; - public SQLRepository(DbContextOptionsBuilder + private static SQLRepository _repository; + public static SQLRepository Repository + { + get + { + if (_repository == null) + { + string dbPath = Path.Combine(ApplicationData.Current.LocalCacheFolder.Path, "Files.db"); + + DbContextOptionsBuilder dbOptions = new DbContextOptionsBuilder().UseSqlite( + "Data Source=" + dbPath); + + _repository = new SQLRepository(dbOptions); + } + + return _repository; + } + } + + private SQLRepository(DbContextOptionsBuilder dbOptionsBuilder) { _dbOptions = dbOptionsBuilder.Options; @@ -29,4 +50,4 @@ public SQLRepository(DbContextOptionsBuilder public ISQLRepository Genres { get; set; } public ISQLRepository Task GetAsync(Guid id); + /// + /// Directly upserts an item. + /// + Task UpsertAsync(T item); + /// /// Queues an item for upserting. /// + /// If a high amount of items are queued, call + /// to prevent excessive + /// RAM usage. Task QueueUpsertAsync(T item); /// @@ -31,9 +40,17 @@ public interface ISQLRepository where T : class /// Task UpsertQueuedAsync(); + /// + /// Directly deletes an item. + /// + Task DeleteAsync(T item); + /// /// Queues an item for deletion. /// + /// If a high amount of items are queued, call + /// to prevent excessive + /// RAM usage. Task QueueDeletionAsync(T item); /// diff --git a/Rise.Repository/SQL/SQLAlbumRepository.cs b/Rise.Repository/SQL/SQLAlbumRepository.cs index 3ea00427..eb2ffb77 100644 --- a/Rise.Repository/SQL/SQLAlbumRepository.cs +++ b/Rise.Repository/SQL/SQLAlbumRepository.cs @@ -62,10 +62,22 @@ public async Task> GetAsync(string search) } } + public async Task UpsertAsync(Album item) + { + using (_db = new Context(_dbOptions)) + { + await _db.Albums.AddAsync(item); + await _db.SaveChangesAsync(); + } + } + public async Task QueueUpsertAsync(Album item) { _upsertQueue.Add(item); - await UpsertQueuedAsync(); + if (_upsertQueue.Count >= 250) + { + await UpsertQueuedAsync(); + } } public async Task UpsertQueuedAsync() @@ -77,10 +89,22 @@ public async Task UpsertQueuedAsync() } } + public async Task DeleteAsync(Album item) + { + using (_db = new Context(_dbOptions)) + { + _db.Albums.Remove(item); + await _db.SaveChangesAsync(); + } + } + public async Task QueueDeletionAsync(Album item) { _removalQueue.Add(item); - await DeleteQueuedAsync(); + if (_removalQueue.Count >= 250) + { + await DeleteQueuedAsync(); + } } public async Task DeleteQueuedAsync() diff --git a/Rise.Repository/SQL/SQLArtistRepository.cs b/Rise.Repository/SQL/SQLArtistRepository.cs index d5d14ee2..098aa871 100644 --- a/Rise.Repository/SQL/SQLArtistRepository.cs +++ b/Rise.Repository/SQL/SQLArtistRepository.cs @@ -60,10 +60,22 @@ public async Task> GetAsync(string search) } } + public async Task UpsertAsync(Artist item) + { + using (_db = new Context(_dbOptions)) + { + await _db.Artists.AddAsync(item); + await _db.SaveChangesAsync(); + } + } + public async Task QueueUpsertAsync(Artist item) { _upsertQueue.Add(item); - await UpsertQueuedAsync(); + if (_upsertQueue.Count >= 250) + { + await UpsertQueuedAsync(); + } } public async Task UpsertQueuedAsync() @@ -75,10 +87,22 @@ public async Task UpsertQueuedAsync() } } + public async Task DeleteAsync(Artist item) + { + using (_db = new Context(_dbOptions)) + { + _db.Artists.Remove(item); + await _db.SaveChangesAsync(); + } + } + public async Task QueueDeletionAsync(Artist item) { _removalQueue.Add(item); - await DeleteQueuedAsync(); + if (_removalQueue.Count >= 250) + { + await DeleteQueuedAsync(); + } } public async Task DeleteQueuedAsync() diff --git a/Rise.Repository/SQL/SQLGenreRepository.cs b/Rise.Repository/SQL/SQLGenreRepository.cs index 0fec9ebb..a457a66a 100644 --- a/Rise.Repository/SQL/SQLGenreRepository.cs +++ b/Rise.Repository/SQL/SQLGenreRepository.cs @@ -60,10 +60,22 @@ public async Task> GetAsync(string search) } } + public async Task UpsertAsync(Genre item) + { + using (_db = new Context(_dbOptions)) + { + await _db.Genres.AddAsync(item); + await _db.SaveChangesAsync(); + } + } + public async Task QueueUpsertAsync(Genre item) { _upsertQueue.Add(item); - await UpsertQueuedAsync(); + if (_upsertQueue.Count >= 250) + { + await UpsertQueuedAsync(); + } } public async Task UpsertQueuedAsync() @@ -75,10 +87,22 @@ public async Task UpsertQueuedAsync() } } + public async Task DeleteAsync(Genre item) + { + using (_db = new Context(_dbOptions)) + { + _db.Genres.Remove(item); + await _db.SaveChangesAsync(); + } + } + public async Task QueueDeletionAsync(Genre item) { _removalQueue.Add(item); - await DeleteQueuedAsync(); + if (_removalQueue.Count >= 250) + { + await DeleteQueuedAsync(); + } } public async Task DeleteQueuedAsync() diff --git a/Rise.Repository/SQL/SQLSongRepository.cs b/Rise.Repository/SQL/SQLSongRepository.cs index 1c3b43d8..6a7ad85e 100644 --- a/Rise.Repository/SQL/SQLSongRepository.cs +++ b/Rise.Repository/SQL/SQLSongRepository.cs @@ -64,10 +64,22 @@ public async Task> GetAsync(string search) } } + public async Task UpsertAsync(Song item) + { + using (_db = new Context(_dbOptions)) + { + await _db.Songs.AddAsync(item); + await _db.SaveChangesAsync(); + } + } + public async Task QueueUpsertAsync(Song item) { _upsertQueue.Add(item); - await UpsertQueuedAsync(); + if (_upsertQueue.Count >= 250) + { + await UpsertQueuedAsync(); + } } public async Task UpsertQueuedAsync() @@ -79,10 +91,22 @@ public async Task UpsertQueuedAsync() } } + public async Task DeleteAsync(Song item) + { + using (_db = new Context(_dbOptions)) + { + _db.Songs.Remove(item); + await _db.SaveChangesAsync(); + } + } + public async Task QueueDeletionAsync(Song item) { _removalQueue.Add(item); - await DeleteQueuedAsync(); + if (_removalQueue.Count >= 250) + { + await DeleteQueuedAsync(); + } } public async Task DeleteQueuedAsync() diff --git a/Rise.Repository/SQL/SQLVideoRepository.cs b/Rise.Repository/SQL/SQLVideoRepository.cs index 695d31d4..99a7c259 100644 --- a/Rise.Repository/SQL/SQLVideoRepository.cs +++ b/Rise.Repository/SQL/SQLVideoRepository.cs @@ -60,10 +60,22 @@ public async Task> GetAsync(string search) } } + public async Task UpsertAsync(Video item) + { + using (_db = new Context(_dbOptions)) + { + await _db.Videos.AddAsync(item); + await _db.SaveChangesAsync(); + } + } + public async Task QueueUpsertAsync(Video item) { _upsertQueue.Add(item); - await UpsertQueuedAsync(); + if (_upsertQueue.Count >= 250) + { + await UpsertQueuedAsync(); + } } public async Task UpsertQueuedAsync() @@ -78,7 +90,19 @@ public async Task UpsertQueuedAsync() public async Task QueueDeletionAsync(Video item) { _removalQueue.Add(item); - await DeleteQueuedAsync(); + if (_removalQueue.Count >= 250) + { + await DeleteQueuedAsync(); + } + } + + public async Task DeleteAsync(Video item) + { + using (_db = new Context(_dbOptions)) + { + _db.Videos.Remove(item); + await _db.SaveChangesAsync(); + } } public async Task DeleteQueuedAsync() From 5ca42ba75b7c95214d82c676575d9f078aa157c0 Mon Sep 17 00:00:00 2001 From: Omar Plata Salas Date: Thu, 3 Mar 2022 20:40:54 -0500 Subject: [PATCH 5/7] organized viewmodels, added update functions --- .../UserControls/NowPlayingBar.xaml.cs | 2 +- .../ViewModels/AlbumViewModel.cs | 122 ++++---------- .../ViewModels/ArtistViewModel.cs | 102 ++++-------- .../ViewModels/GenreViewModel.cs | 18 +- .../ViewModels/PlaybackViewModel.cs | 4 +- .../ViewModels/PlaylistViewModel.cs | 77 +++++---- .../ViewModels/SongPropertiesViewModel.cs | 5 +- .../ViewModels/SongViewModel.cs | 154 ++++-------------- .../ViewModels/VideoViewModel.cs | 10 +- .../Views/Albums/AlbumSongsPage.xaml.cs | 4 +- .../Views/Artists/ArtistSongsPage.xaml.cs | 4 +- .../Views/Genres/GenreSongsPage.xaml.cs | 4 +- .../Views/NPBarQueuePage.xaml.cs | 2 +- Rise Media Player Dev/Views/QueuePage.xaml.cs | 2 +- Rise Media Player Dev/Views/SongsPage.xaml.cs | 4 +- .../Windows/PlaylistPropertiesPage.xaml.cs | 4 +- Rise.Repository/ISQLRepository.cs | 5 + Rise.Repository/SQL/SQLAlbumRepository.cs | 9 + Rise.Repository/SQL/SQLArtistRepository.cs | 9 + Rise.Repository/SQL/SQLGenreRepository.cs | 9 + Rise.Repository/SQL/SQLSongRepository.cs | 9 + Rise.Repository/SQL/SQLVideoRepository.cs | 9 + 22 files changed, 226 insertions(+), 342 deletions(-) diff --git a/Rise Media Player Dev/UserControls/NowPlayingBar.xaml.cs b/Rise Media Player Dev/UserControls/NowPlayingBar.xaml.cs index 23b5f034..c989961b 100644 --- a/Rise Media Player Dev/UserControls/NowPlayingBar.xaml.cs +++ b/Rise Media Player Dev/UserControls/NowPlayingBar.xaml.cs @@ -746,7 +746,7 @@ private async void Props_Click(object sender, RoutedEventArgs e) if (!App.PViewModel.CurrentSong.IsOnline) { SelectedSong = App.PViewModel.CurrentSong; - await App.PViewModel.CurrentSong.StartEdit(); + await App.PViewModel.CurrentSong.StartEditAsync(); } } diff --git a/Rise Media Player Dev/ViewModels/AlbumViewModel.cs b/Rise Media Player Dev/ViewModels/AlbumViewModel.cs index 4bd083bb..9795121d 100644 --- a/Rise Media Player Dev/ViewModels/AlbumViewModel.cs +++ b/Rise Media Player Dev/ViewModels/AlbumViewModel.cs @@ -9,8 +9,7 @@ namespace Rise.App.ViewModels { public class AlbumViewModel : ViewModel { - // private readonly DispatcherQueue dispatcherQueue = DispatcherQueue.GetForCurrentThread(); - + #region Constructor /// /// Initializes a new instance of the AlbumViewModel class that wraps an Album object. /// @@ -28,7 +27,9 @@ public AlbumViewModel(Album model = null) OnPropertyChanged(nameof(ArtistViewModel.AlbumCount)); } + #endregion + #region Properties /// /// Gets or sets the album title. /// @@ -48,8 +49,7 @@ public string Title if (value != Model.Title) { Model.Title = value; - IsModified = true; - OnPropertyChanged(nameof(Title)); + OnPropertyChanged(); } } } @@ -73,8 +73,7 @@ public string Artist if (value != Model.Artist) { Model.Artist = value; - IsModified = true; - OnPropertyChanged(nameof(Artist)); + OnPropertyChanged(); } } } @@ -109,8 +108,7 @@ public string Genres if (value != Model.Genres) { Model.Genres = value; - IsModified = true; - OnPropertyChanged(nameof(Genres)); + OnPropertyChanged(); } } } @@ -132,8 +130,7 @@ public string Thumbnail if (value != Model.Thumbnail) { Model.Thumbnail = value; - IsModified = true; - OnPropertyChanged(nameof(Thumbnail)); + OnPropertyChanged(); } } } @@ -149,31 +146,11 @@ public uint Year if (value != Model.Year) { Model.Year = value; - IsModified = true; - OnPropertyChanged(nameof(Year)); + OnPropertyChanged(); } } } - /// - /// Gets or sets a value that indicates whether the underlying model has been modified. - /// - /// - /// Used to reduce load and only upsert the models that have changed. - /// - public bool IsModified { get; set; } - - private bool _isLoading; - - /// - /// Gets or sets a value that indicates whether to show a progress bar. - /// - public bool IsLoading - { - get => _isLoading; - set => Set(ref _isLoading, value); - } - private bool _isNew; /// /// Gets or sets a value that indicates whether this is a new item. @@ -184,19 +161,7 @@ public bool IsNew set => Set(ref _isNew, value); } - private bool _isInEdit = false; - - /// - /// Gets or sets a value that indicates whether the album data is being edited. - /// - public bool IsInEdit - { - get => _isInEdit; - set => Set(ref _isInEdit, value); - } - private bool _isArtistVisible = true; - /// /// Gets or sets a value that indicates whether the album title is displayed or not. /// @@ -207,7 +172,6 @@ public bool IsArtistVisible } private bool _isThumbnailVisible = true; - /// /// Gets or sets a value that indicates whether the album art is displayed or not. /// @@ -218,7 +182,6 @@ public bool IsThumbnailVisible } private bool _isGenresVisible = false; - /// /// Gets or sets a value that indicates whether the album genre is displayed or not. /// @@ -229,7 +192,6 @@ public bool IsGenresVisible } private bool _isTitleVisible = true; - /// /// Gets or sets a value that indicates whether the album title is displayed or not. /// @@ -240,7 +202,6 @@ public bool IsTitleVisible } private bool _hasRoundedAlbumArt = true; - /// /// Gets or sets a value that indicates whether the album art is rounded or not. /// @@ -251,7 +212,6 @@ public bool HasRoundedAlbumArt } private bool _isReleaseYearVisible = false; - /// /// Gets or sets a value that indicates whether the album release year is rounded or not. /// @@ -260,15 +220,14 @@ public bool IsReleaseYearVisible get => _isReleaseYearVisible; set => Set(ref _isReleaseYearVisible, value); } + #endregion + #region Backend /// /// Saves album data that has been edited. /// public async Task SaveAsync() { - IsInEdit = false; - IsModified = false; - if (IsNew) { IsNew = false; @@ -278,26 +237,11 @@ public async Task SaveAsync() await SQLRepository.Repository.Albums.QueueUpsertAsync(Model); } - /// - /// Checks whether or not the album is available. If it's not, - /// delete it. - /// - public async Task CheckAvailabilityAsync() - { - if (TrackCount == 0) - { - await DeleteAsync(); - return; - } - } - /// /// Delete album from repository and MViewModel. /// public async Task DeleteAsync() { - IsModified = true; - App.MViewModel.Albums.Remove(this); await SQLRepository.Repository.Albums.QueueDeletionAsync(Model); @@ -311,44 +255,44 @@ public async Task DeleteAsync() } /// - /// Raised when the user cancels the changes they've made to the album data. - /// - public event EventHandler AddNewAlbumCanceled; - - /// - /// Cancels any in progress edits. + /// Checks whether or not the album is available. If it's not, + /// delete it. /// - public async Task CancelEditsAsync() + public async Task CheckAvailabilityAsync() { - if (IsNew) - { - AddNewAlbumCanceled?.Invoke(this, EventArgs.Empty); - } - else + if (TrackCount == 0) { - await RevertChangesAsync(); + await DeleteAsync(); + return; } } + #endregion + #region Editing /// - /// Discards any edits that have been made, restoring the original values. + /// Enables edit mode. /// - public async Task RevertChangesAsync() + /*public async Task StartEditAsync() { - IsInEdit = false; - if (IsModified) - { - await RefreshAlbumsAsync(); - IsModified = false; - } + _ = await typeof(PropertiesPage). + PlaceInWindowAsync(ApplicationViewMode.Default, 380, 550, true, props); + }*/ + + /// + /// Saves any edits that have been made. + /// + public async Task SaveEditAsync() + { + await SQLRepository.Repository.Albums.UpdateAsync(Model); } /// - /// Reloads all of the album data. + /// Discards any edits that have been made, restoring the original values. /// - public async Task RefreshAlbumsAsync() + public async Task CancelEditAsync() { Model = await SQLRepository.Repository.Albums.GetAsync(Model.Id); } + #endregion } } diff --git a/Rise Media Player Dev/ViewModels/ArtistViewModel.cs b/Rise Media Player Dev/ViewModels/ArtistViewModel.cs index 808201e8..55bf1aed 100644 --- a/Rise Media Player Dev/ViewModels/ArtistViewModel.cs +++ b/Rise Media Player Dev/ViewModels/ArtistViewModel.cs @@ -1,16 +1,15 @@ -using Rise.Models; -using Rise.App.Common; +using Rise.App.Common; +using Rise.Models; +using Rise.Repository.SQL; using System; using System.Linq; using System.Threading.Tasks; -using Rise.Repository.SQL; namespace Rise.App.ViewModels { public class ArtistViewModel : ViewModel { - // private readonly DispatcherQueue dispatcherQueue = DispatcherQueue.GetForCurrentThread(); - + #region Constructor /// /// Initializes a new instance of the ArtistViewModel class that wraps an Artist object. /// @@ -19,7 +18,9 @@ public ArtistViewModel(Artist model = null) Model = model ?? new Artist(); IsNew = true; } + #endregion + #region Properties /// /// Gets or sets the artist name. /// @@ -39,8 +40,7 @@ public string Name if (value != Model.Name) { Model.Name = value; - IsModified = true; - OnPropertyChanged(nameof(Name)); + OnPropertyChanged(); } } } @@ -56,8 +56,7 @@ public string Picture if (value != Model.Picture) { Model.Picture = value; - IsModified = true; - OnPropertyChanged(nameof(Picture)); + OnPropertyChanged(); } } } @@ -79,14 +78,6 @@ public string Picture /// public string SongsNAlbums => Albums + ", " + Songs; - /// - /// Gets or sets a value that indicates whether the underlying model has been modified. - /// - /// - /// Used to reduce load and only upsert the models that have changed. - /// - public bool IsModified { get; set; } - private bool _isNew; /// /// Gets or sets a value that indicates whether this is a new item. @@ -96,25 +87,14 @@ public bool IsNew get => _isNew; set => Set(ref _isNew, value); } + #endregion - private bool _isInEdit = false; - /// - /// Gets or sets a value that indicates whether the artist data is being edited. - /// - public bool IsInEdit - { - get => _isInEdit; - set => Set(ref _isInEdit, value); - } - + #region Backend /// /// Saves artist data that has been edited. /// public async Task SaveAsync() { - IsInEdit = false; - IsModified = false; - if (IsNew) { IsNew = false; @@ -124,74 +104,54 @@ public async Task SaveAsync() await SQLRepository.Repository.Artists.QueueUpsertAsync(Model); } - /// - /// Checks whether or not the artist is available. If it's not, - /// delete it. - /// - public async Task CheckAvailabilityAsync() - { - if (SongCount == 0 && AlbumCount == 0) - { - await DeleteAsync(); - return; - } - } - /// /// Delete artist from repository and MViewModel. /// public async Task DeleteAsync() { - IsModified = true; - App.MViewModel.Artists.Remove(this); await SQLRepository.Repository.Artists.QueueDeletionAsync(Model); } /// - /// Raised when the user cancels the changes they've made to the artist data. - /// - public event EventHandler AddNewArtistCanceled; - - /// - /// Cancels any in progress edits. + /// Checks whether or not the artist is available. If it's not, + /// delete it. /// - public async Task CancelEditsAsync() + public async Task CheckAvailabilityAsync() { - if (IsNew) - { - AddNewArtistCanceled?.Invoke(this, EventArgs.Empty); - } - else + if (SongCount == 0 && AlbumCount == 0) { - await RevertChangesAsync(); + await DeleteAsync(); + return; } } + #endregion + #region Editing /// - /// Discards any edits that have been made, restoring the original values. + /// Enables edit mode. /// - public async Task RevertChangesAsync() + /*public async Task StartEditAsync() { - IsInEdit = false; - if (IsModified) - { - await RefreshArtistsAsync(); - IsModified = false; - } - } + _ = await typeof(PropertiesPage). + PlaceInWindowAsync(ApplicationViewMode.Default, 380, 550, true, props); + }*/ /// - /// Enables edit mode. + /// Saves any edits that have been made. /// - public void StartEdit() => IsInEdit = true; + public async Task SaveEditAsync() + { + await SQLRepository.Repository.Artists.UpdateAsync(Model); + } /// - /// Reloads all of the artist data. + /// Discards any edits that have been made, restoring the original values. /// - public async Task RefreshArtistsAsync() + public async Task CancelEditAsync() { Model = await SQLRepository.Repository.Artists.GetAsync(Model.Id); } + #endregion } } diff --git a/Rise Media Player Dev/ViewModels/GenreViewModel.cs b/Rise Media Player Dev/ViewModels/GenreViewModel.cs index 9eacd178..43751d1a 100644 --- a/Rise Media Player Dev/ViewModels/GenreViewModel.cs +++ b/Rise Media Player Dev/ViewModels/GenreViewModel.cs @@ -7,6 +7,7 @@ namespace Rise.App.ViewModels { public class GenreViewModel : ViewModel { + #region Constructor /// /// Initializes a new instance of the AlbumViewModel class that wraps an Album object. /// @@ -15,7 +16,9 @@ public GenreViewModel(Genre model = null) Model = model ?? new Genre(); IsNew = true; } + #endregion + #region Properties /// /// Gets or sets the genre name. /// @@ -27,20 +30,11 @@ public string Name if (value != Model.Name) { Model.Name = value; - IsModified = true; - OnPropertyChanged(nameof(Name)); + OnPropertyChanged(); } } } - /// - /// Gets or sets a value that indicates whether the underlying model has been modified. - /// - /// - /// Used to reduce load and only upsert the models that have changed. - /// - public bool IsModified { get; set; } - private bool _isNew; /// /// Gets or sets a value that indicates whether this is a new item. @@ -50,13 +44,14 @@ public bool IsNew get => _isNew; set => Set(ref _isNew, value); } + #endregion + #region Backend /// /// Saves genre data that has been edited. /// public async Task SaveAsync() { - IsModified = false; if (IsNew) { IsNew = false; @@ -65,5 +60,6 @@ public async Task SaveAsync() await SQLRepository.Repository.Genres.QueueUpsertAsync(Model); } + #endregion } } diff --git a/Rise Media Player Dev/ViewModels/PlaybackViewModel.cs b/Rise Media Player Dev/ViewModels/PlaybackViewModel.cs index a7299031..b89c87ef 100644 --- a/Rise Media Player Dev/ViewModels/PlaybackViewModel.cs +++ b/Rise Media Player Dev/ViewModels/PlaybackViewModel.cs @@ -124,7 +124,7 @@ public async Task PlaySongFromUrlAsync(SongViewModel song) ClearLists(); PlaybackList.ShuffleEnabled = false; - PlaybackList.Items.Add(await song.AsPlaybackItemAsync(new Uri(song.Location))); + PlaybackList.Items.Add(song.AsPlaybackItem(new Uri(song.Location))); CurrentSong = song; @@ -167,7 +167,7 @@ public async Task PlayVideoFromUrlAsync(VideoViewModel video) ClearLists(); PlaybackList.ShuffleEnabled = false; - PlaybackList.Items.Add(await video.AsPlaybackItemAsync(new Uri(video.Location))); + PlaybackList.Items.Add(video.AsPlaybackItem(new Uri(video.Location))); CurrentVideo = video; diff --git a/Rise Media Player Dev/ViewModels/PlaylistViewModel.cs b/Rise Media Player Dev/ViewModels/PlaylistViewModel.cs index b289349f..eba8446f 100644 --- a/Rise Media Player Dev/ViewModels/PlaylistViewModel.cs +++ b/Rise Media Player Dev/ViewModels/PlaylistViewModel.cs @@ -10,6 +10,7 @@ namespace Rise.App.ViewModels { public class PlaylistViewModel : ViewModel { + #region Constructor /// /// Initializes a new instance of the PlaylistViewModel class that wraps a Playlist object. /// @@ -25,7 +26,9 @@ public PlaylistViewModel(Playlist model = null) IsNew = true; } } + #endregion + #region Properties /// /// Gets or sets the playlist title. /// @@ -128,7 +131,9 @@ public bool IsNew get => _isNew; set => Set(ref _isNew, value); } + #endregion + #region Backend /// /// Saves playlist to the backend. /// @@ -147,6 +152,30 @@ public async Task SaveAsync() } } + /// + /// Deletes playlist from the backend. + /// + public async Task DeleteAsync() + { + App.MViewModel.Playlists.Remove(this); + await App.PBackendController.DeleteAsync(this); + } + + /// + /// Checks whether or not the playlist is available. If it's not, + /// delete it. + /// + /*public async Task CheckAvailabilityAsync() + { + if (TrackCount == 0) + { + await DeleteAsync(); + return; + } + }*/ + #endregion + + #region Item management /// /// Adds a song to the playlist. /// @@ -184,27 +213,25 @@ public async Task AddSongsAsync(IEnumerable songs) } /// - /// Checks whether or not the playlist is available. If it's not, - /// delete it. + /// Removes multiple songs from the playlist. /// - /*public async Task CheckAvailabilityAsync() + public async Task RemoveSongsAsync(List songs) { - if (TrackCount == 0) + try { - await DeleteAsync(); - return; + foreach (SongViewModel song in songs) + { + Songs.Remove(song); + } + } + finally + { + await SaveAsync(); } - }*/ - - /// - /// Delete playlist from repository and MViewModel. - /// - public async Task DeleteAsync() - { - App.MViewModel.Playlists.Remove(this); - await App.PBackendController.DeleteAsync(this); } + #endregion + #region Editing public async Task StartEditAsync() { _ = await typeof(PlaylistPropertiesPage). @@ -214,7 +241,7 @@ public async Task StartEditAsync() /// /// Saves any edits that have been made. /// - public async Task EndEditAsync() + public async Task SaveEditAsync() { await App.PBackendController.DeleteAsync(this); await App.PBackendController.UpsertAsync(this); @@ -223,24 +250,10 @@ public async Task EndEditAsync() /// /// Discards any edits that have been made, restoring the original values. /// - public async Task RevertChangesAsync() + public async Task CancelEditAsync() { Model = (await App.PBackendController.GetAsync(Model.Id)).Model; } - - public async Task RemoveSongsAsync(List songs) - { - try - { - foreach (SongViewModel song in songs) - { - Songs.Remove(song); - } - } - finally - { - await SaveAsync(); - } - } + #endregion } } diff --git a/Rise Media Player Dev/ViewModels/SongPropertiesViewModel.cs b/Rise Media Player Dev/ViewModels/SongPropertiesViewModel.cs index b15cf5d3..566cc96f 100644 --- a/Rise Media Player Dev/ViewModels/SongPropertiesViewModel.cs +++ b/Rise Media Player Dev/ViewModels/SongPropertiesViewModel.cs @@ -140,16 +140,15 @@ public async Task SaveChangesAsync() { // await songFile.Properties.SavePropertiesAsync(props); await musicProps.SavePropertiesAsync(); + await Model.SaveAsync(); result = true; } catch (Exception ex) { - await Model.CancelEditsAsync(); + await Model.CancelEditAsync(); Debug.WriteLine(ex.Message); result = false; } - - await Model.SaveAsync(); } return result; diff --git a/Rise Media Player Dev/ViewModels/SongViewModel.cs b/Rise Media Player Dev/ViewModels/SongViewModel.cs index 8b796c29..0f7b9f87 100644 --- a/Rise Media Player Dev/ViewModels/SongViewModel.cs +++ b/Rise Media Player Dev/ViewModels/SongViewModel.cs @@ -3,7 +3,6 @@ using Rise.Models; using Rise.Repository.SQL; using System; -using System.Collections.Generic; using System.IO; using System.Linq; using System.Threading.Tasks; @@ -18,8 +17,7 @@ namespace Rise.App.ViewModels { public class SongViewModel : ViewModel { - // private readonly DispatcherQueue dispatcherQueue = DispatcherQueue.GetForCurrentThread(); - + #region Constructor /// /// Initializes a new instance of the SongViewModel class that wraps a Song object. /// @@ -31,7 +29,9 @@ public SongViewModel(Song model = null) OnPropertyChanged(nameof(AlbumViewModel.TrackCount)); OnPropertyChanged(nameof(ArtistViewModel.SongCount)); } + #endregion + #region Properties /// /// Checks if the song is played from an online stream, playlist or song. /// @@ -48,8 +48,7 @@ public string Title if (value != Model.Title) { Model.Title = value; - IsModified = true; - OnPropertyChanged(nameof(Title)); + OnPropertyChanged(); } } } @@ -73,8 +72,7 @@ public string Artist if (value != Model.Artist) { Model.Artist = value; - IsModified = true; - OnPropertyChanged(nameof(Artist)); + OnPropertyChanged(); } } } @@ -90,8 +88,7 @@ public uint Track if (value != Model.Track) { Model.Track = value; - IsModified = true; - OnPropertyChanged(nameof(Track)); + OnPropertyChanged(); } } } @@ -107,8 +104,7 @@ public int Disc if (value != Model.Disc) { Model.Disc = value; - IsModified = true; - OnPropertyChanged(nameof(Disc)); + OnPropertyChanged(); } } } @@ -132,8 +128,7 @@ public string Album if (value != Model.Album) { Model.Album = value; - IsModified = true; - OnPropertyChanged(nameof(Album)); + OnPropertyChanged(); } } } @@ -157,8 +152,7 @@ public string AlbumArtist if (value != Model.AlbumArtist) { Model.AlbumArtist = value; - IsModified = true; - OnPropertyChanged(nameof(AlbumArtist)); + OnPropertyChanged(); } } } @@ -182,8 +176,7 @@ public string Genres if (value != Model.Genres) { Model.Genres = value; - IsModified = true; - OnPropertyChanged(nameof(Genres)); + OnPropertyChanged(); } } } @@ -199,8 +192,7 @@ public TimeSpan Length if (value != Model.Length) { Model.Length = value; - IsModified = true; - OnPropertyChanged(nameof(Length)); + OnPropertyChanged(); } } } @@ -216,8 +208,7 @@ public uint Year if (value != Model.Year) { Model.Year = value; - IsModified = true; - OnPropertyChanged(nameof(Year)); + OnPropertyChanged(); } } } @@ -233,8 +224,7 @@ public string Location if (value != Model.Location) { Model.Location = value; - IsModified = true; - OnPropertyChanged(nameof(Location)); + OnPropertyChanged(); } } } @@ -260,8 +250,7 @@ public uint Rating if (value != Model.Rating) { Model.Rating = value; - IsModified = true; - OnPropertyChanged(nameof(Rating)); + OnPropertyChanged(); } } } @@ -277,30 +266,11 @@ public string Thumbnail if (value != Model.Thumbnail) { Model.Thumbnail = value; - IsModified = true; - OnPropertyChanged(nameof(Thumbnail)); + OnPropertyChanged(); } } } - /// - /// Gets or sets a value that indicates whether the underlying model has been modified. - /// - /// - /// Used to reduce load and only upsert the models that have changed. - /// - public bool IsModified { get; set; } - - private bool _isLoading; - /// - /// Gets or sets a value that indicates whether to show a progress bar. - /// - public bool IsLoading - { - get => _isLoading; - set => Set(ref _isLoading, value); - } - private bool _isNew; /// /// Gets or sets a value that indicates whether this is a new item. @@ -311,16 +281,6 @@ public bool IsNew set => Set(ref _isNew, value); } - private bool _isInEdit; - /// - /// Gets or sets a value that indicates whether the item data is being edited. - /// - public bool IsInEdit - { - get => _isInEdit; - set => Set(ref _isInEdit, value); - } - private bool _isFocused; /// /// Gets or sets a value that indicates whether the item is focused. @@ -350,15 +310,14 @@ public bool IsDurationVisible get => _isDurationVisible; set => Set(ref _isDurationVisible, value); } + #endregion + #region Backend /// /// Saves song data that has been edited. /// public async Task SaveAsync() { - IsInEdit = false; - IsModified = false; - if (IsNew) { IsNew = false; @@ -379,9 +338,6 @@ public async Task SaveAsync() /// public async Task DeleteAsync() { - await CancelEditsAsync(); - IsModified = true; - if (!IsNew) { App.MViewModel.Songs.Remove(this); @@ -405,46 +361,14 @@ public async Task DeleteAsync() await artist.CheckAvailabilityAsync(); } } + #endregion - /// - /// Raised when the user cancels the changes they've made to the song data. - /// - public event EventHandler AddNewSongCanceled; - - /// - /// Cancels any in progress edits. - /// - public async Task CancelEditsAsync() - { - if (IsNew) - { - AddNewSongCanceled?.Invoke(this, EventArgs.Empty); - } - else - { - await RevertChangesAsync(); - } - } - - /// - /// Discards any edits that have been made, restoring the original values. - /// - public async Task RevertChangesAsync() - { - IsInEdit = false; - if (IsModified) - { - await RefreshSongsAsync(); - IsModified = false; - } - } - + #region Editing /// /// Enables edit mode. /// - public async Task StartEdit() + public async Task StartEditAsync() { - IsInEdit = true; StorageFile file = await StorageFile.GetFileFromPathAsync(Location); if (file != null) @@ -460,13 +384,23 @@ public async Task StartEdit() } /// - /// Reloads all of the song data. + /// Saves any edits that have been made. + /// + public async Task SaveEditAsync() + { + await SQLRepository.Repository.Songs.UpdateAsync(Model); + } + + /// + /// Discards any edits that have been made, restoring the original values. /// - public async Task RefreshSongsAsync() + public async Task CancelEditAsync() { Model = await SQLRepository.Repository.Songs.GetAsync(Model.Id); } + #endregion + #region Playback /// /// Creates a from this . /// @@ -501,7 +435,7 @@ public async Task AsPlaybackItemAsync() /// Creates a from this . /// /// A based on the song. - public async Task AsPlaybackItemAsync(Uri url) + public MediaPlaybackItem AsPlaybackItem(Uri url) { MediaSource source = MediaSource.CreateFromUri(url); MediaPlaybackItem media = new(source); @@ -524,26 +458,6 @@ public async Task AsPlaybackItemAsync(Uri url) media.ApplyDisplayProperties(props); return media; } - - public readonly static RelayCommand _beginPlayback = new RelayCommand(async () => - { - int index = 0; - if (App.MViewModel.SelectedSong != null) - { - index = App.MViewModel.FilteredSongs.IndexOf(App.MViewModel.SelectedSong); - App.MViewModel.SelectedSong = null; - } - - IEnumerator enumerator = App.MViewModel.FilteredSongs.GetEnumerator(); - List songs = new List(); - - while (enumerator.MoveNext()) - { - songs.Add(enumerator.Current as SongViewModel); - } - - enumerator.Dispose(); - await App.PViewModel.StartMusicPlaybackAsync(songs.GetEnumerator(), index, songs.Count); - }); + #endregion } } diff --git a/Rise Media Player Dev/ViewModels/VideoViewModel.cs b/Rise Media Player Dev/ViewModels/VideoViewModel.cs index fffcb692..9f5e64c0 100644 --- a/Rise Media Player Dev/ViewModels/VideoViewModel.cs +++ b/Rise Media Player Dev/ViewModels/VideoViewModel.cs @@ -12,6 +12,7 @@ namespace Rise.App.ViewModels { public class VideoViewModel : ViewModel