From fbbc598762788fb124a790ebe56429d5b283b13f Mon Sep 17 00:00:00 2001 From: Omar Plata Salas <49221554+YourOrdinaryCat@users.noreply.github.com> Date: Fri, 4 Mar 2022 18:39:26 -0500 Subject: [PATCH] Revert "Improve the process of inserting changes into the database" (#142) --- Rise Media Player Dev.sln | 44 ---- Rise Media Player Dev/App.xaml.cs | 19 +- .../ChangeTrackers/SongsTracker.cs | 2 +- Rise Media Player Dev/Rise.App.csproj | 44 ++-- .../UserControls/NowPlayingBar.xaml.cs | 2 +- .../ViewModels/AlbumViewModel.cs | 160 +++++++++++---- .../ViewModels/ArtistViewModel.cs | 115 ++++++++--- .../ViewModels/GenreViewModel.cs | 41 +++- .../ViewModels/MainViewModel.cs | 33 ++- .../ViewModels/PlaybackViewModel.cs | 4 +- .../ViewModels/PlaylistViewModel.cs | 116 ++++++----- .../ViewModels/SongPropertiesViewModel.cs | 3 +- .../ViewModels/SongViewModel.cs | 192 ++++++++++++++---- .../ViewModels/VideoViewModel.cs | 62 ++---- .../Views/Albums/AlbumSongsPage.xaml.cs | 4 +- .../Views/Artists/ArtistSongsPage.xaml.cs | 4 +- .../Views/Artists/ArtistsPage.xaml.cs | 5 +- .../Views/Genres/GenreSongsPage.xaml.cs | 4 +- .../Views/NPBarQueuePage.xaml.cs | 2 +- .../Playlists/PlaylistDetailsPage.xaml.cs | 3 +- Rise Media Player Dev/Views/QueuePage.xaml.cs | 2 +- Rise Media Player Dev/Views/SongsPage.xaml.cs | 4 +- .../Windows/PlaylistPropertiesPage.xaml.cs | 4 +- Rise.Data/Properties/AssemblyInfo.cs | 29 --- Rise.Data/Properties/Rise.Data.rd.xml | 33 --- Rise.Data/Rise.Data.csproj | 144 ------------- Rise.Data/Sources/MainDataSource.cs | 12 -- Rise.Data/Sources/NavViewDataSource.cs | 12 -- Rise.Repository/ISQLRepository.cs | 24 +-- Rise.Repository/SQL/SQLAlbumRepository.cs | 37 +--- Rise.Repository/SQL/SQLArtistRepository.cs | 37 +--- Rise.Repository/SQL/SQLGenreRepository.cs | 37 +--- Rise.Repository/SQL/SQLRepository.cs | 25 +-- Rise.Repository/SQL/SQLSongRepository.cs | 37 +--- Rise.Repository/SQL/SQLVideoRepository.cs | 37 +--- Rise.Tasks/MusicIndexingTask.cs | 63 ------ Rise.Tasks/Properties/AssemblyInfo.cs | 29 --- Rise.Tasks/Rise.Tasks.csproj | 143 ------------- 38 files changed, 555 insertions(+), 1013 deletions(-) delete mode 100644 Rise.Data/Properties/AssemblyInfo.cs delete mode 100644 Rise.Data/Properties/Rise.Data.rd.xml delete mode 100644 Rise.Data/Rise.Data.csproj delete mode 100644 Rise.Data/Sources/MainDataSource.cs delete mode 100644 Rise.Data/Sources/NavViewDataSource.cs delete mode 100644 Rise.Tasks/MusicIndexingTask.cs delete mode 100644 Rise.Tasks/Properties/AssemblyInfo.cs delete mode 100644 Rise.Tasks/Rise.Tasks.csproj diff --git a/Rise Media Player Dev.sln b/Rise Media Player Dev.sln index cab5e2ae..2ca19f3f 100644 --- a/Rise Media Player Dev.sln +++ b/Rise Media Player Dev.sln @@ -9,10 +9,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Rise.Models", "Rise.Models\ EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Rise.Repository", "Rise.Repository\Rise.Repository.csproj", "{C0DA58A4-4EBE-4F14-8EB2-F92E99960C52}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Rise.Tasks", "Rise.Tasks\Rise.Tasks.csproj", "{1AC2B1A4-6E0F-4849-A301-7C646A212A24}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Rise.Data", "Rise.Data\Rise.Data.csproj", "{5185BB21-8B6A-4C08-8C50-4E1B8F57B2D5}" -EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -97,46 +93,6 @@ Global {C0DA58A4-4EBE-4F14-8EB2-F92E99960C52}.Release|x64.Build.0 = Release|x64 {C0DA58A4-4EBE-4F14-8EB2-F92E99960C52}.Release|x86.ActiveCfg = Release|x86 {C0DA58A4-4EBE-4F14-8EB2-F92E99960C52}.Release|x86.Build.0 = Release|x86 - {1AC2B1A4-6E0F-4849-A301-7C646A212A24}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {1AC2B1A4-6E0F-4849-A301-7C646A212A24}.Debug|Any CPU.Build.0 = Debug|Any CPU - {1AC2B1A4-6E0F-4849-A301-7C646A212A24}.Debug|ARM.ActiveCfg = Debug|ARM - {1AC2B1A4-6E0F-4849-A301-7C646A212A24}.Debug|ARM.Build.0 = Debug|ARM - {1AC2B1A4-6E0F-4849-A301-7C646A212A24}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {1AC2B1A4-6E0F-4849-A301-7C646A212A24}.Debug|ARM64.Build.0 = Debug|ARM64 - {1AC2B1A4-6E0F-4849-A301-7C646A212A24}.Debug|x64.ActiveCfg = Debug|x64 - {1AC2B1A4-6E0F-4849-A301-7C646A212A24}.Debug|x64.Build.0 = Debug|x64 - {1AC2B1A4-6E0F-4849-A301-7C646A212A24}.Debug|x86.ActiveCfg = Debug|x86 - {1AC2B1A4-6E0F-4849-A301-7C646A212A24}.Debug|x86.Build.0 = Debug|x86 - {1AC2B1A4-6E0F-4849-A301-7C646A212A24}.Release|Any CPU.ActiveCfg = Release|Any CPU - {1AC2B1A4-6E0F-4849-A301-7C646A212A24}.Release|Any CPU.Build.0 = Release|Any CPU - {1AC2B1A4-6E0F-4849-A301-7C646A212A24}.Release|ARM.ActiveCfg = Release|ARM - {1AC2B1A4-6E0F-4849-A301-7C646A212A24}.Release|ARM.Build.0 = Release|ARM - {1AC2B1A4-6E0F-4849-A301-7C646A212A24}.Release|ARM64.ActiveCfg = Release|ARM64 - {1AC2B1A4-6E0F-4849-A301-7C646A212A24}.Release|ARM64.Build.0 = Release|ARM64 - {1AC2B1A4-6E0F-4849-A301-7C646A212A24}.Release|x64.ActiveCfg = Release|x64 - {1AC2B1A4-6E0F-4849-A301-7C646A212A24}.Release|x64.Build.0 = Release|x64 - {1AC2B1A4-6E0F-4849-A301-7C646A212A24}.Release|x86.ActiveCfg = Release|x86 - {1AC2B1A4-6E0F-4849-A301-7C646A212A24}.Release|x86.Build.0 = Release|x86 - {5185BB21-8B6A-4C08-8C50-4E1B8F57B2D5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {5185BB21-8B6A-4C08-8C50-4E1B8F57B2D5}.Debug|Any CPU.Build.0 = Debug|Any CPU - {5185BB21-8B6A-4C08-8C50-4E1B8F57B2D5}.Debug|ARM.ActiveCfg = Debug|ARM - {5185BB21-8B6A-4C08-8C50-4E1B8F57B2D5}.Debug|ARM.Build.0 = Debug|ARM - {5185BB21-8B6A-4C08-8C50-4E1B8F57B2D5}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {5185BB21-8B6A-4C08-8C50-4E1B8F57B2D5}.Debug|ARM64.Build.0 = Debug|ARM64 - {5185BB21-8B6A-4C08-8C50-4E1B8F57B2D5}.Debug|x64.ActiveCfg = Debug|x64 - {5185BB21-8B6A-4C08-8C50-4E1B8F57B2D5}.Debug|x64.Build.0 = Debug|x64 - {5185BB21-8B6A-4C08-8C50-4E1B8F57B2D5}.Debug|x86.ActiveCfg = Debug|x86 - {5185BB21-8B6A-4C08-8C50-4E1B8F57B2D5}.Debug|x86.Build.0 = Debug|x86 - {5185BB21-8B6A-4C08-8C50-4E1B8F57B2D5}.Release|Any CPU.ActiveCfg = Release|Any CPU - {5185BB21-8B6A-4C08-8C50-4E1B8F57B2D5}.Release|Any CPU.Build.0 = Release|Any CPU - {5185BB21-8B6A-4C08-8C50-4E1B8F57B2D5}.Release|ARM.ActiveCfg = Release|ARM - {5185BB21-8B6A-4C08-8C50-4E1B8F57B2D5}.Release|ARM.Build.0 = Release|ARM - {5185BB21-8B6A-4C08-8C50-4E1B8F57B2D5}.Release|ARM64.ActiveCfg = Release|ARM64 - {5185BB21-8B6A-4C08-8C50-4E1B8F57B2D5}.Release|ARM64.Build.0 = Release|ARM64 - {5185BB21-8B6A-4C08-8C50-4E1B8F57B2D5}.Release|x64.ActiveCfg = Release|x64 - {5185BB21-8B6A-4C08-8C50-4E1B8F57B2D5}.Release|x64.Build.0 = Release|x64 - {5185BB21-8B6A-4C08-8C50-4E1B8F57B2D5}.Release|x86.ActiveCfg = Release|x86 - {5185BB21-8B6A-4C08-8C50-4E1B8F57B2D5}.Release|x86.Build.0 = Release|x86 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/Rise Media Player Dev/App.xaml.cs b/Rise Media Player Dev/App.xaml.cs index 7c7f4255..88bbf18c 100644 --- a/Rise Media Player Dev/App.xaml.cs +++ b/Rise Media Player Dev/App.xaml.cs @@ -94,6 +94,11 @@ 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. /// @@ -178,7 +183,6 @@ protected async override void OnActivated(IActivatedEventArgs e) Window.Current.Activate(); break; - case ActivationKind.ToastNotification: if (e is ToastNotificationActivatedEventArgs toastActivationArgs) { @@ -202,19 +206,22 @@ protected async override void OnActivated(IActivatedEventArgs e) } /// - /// Initializes the app's ViewModels. + /// Initializes the app's database and ViewModels. /// - private async Task InitDataSourcesAsync() + private async Task InitDatabase() { - // 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(); @@ -344,7 +351,7 @@ private async Task InitializeWindowAsync(dynamic args) // just ensure that the window is active if (Window.Current.Content is not Frame rootFrame) { - await InitDataSourcesAsync(); + await InitDatabase(); await MViewModel.GetListsAsync(); StartIndexingTimer(); diff --git a/Rise Media Player Dev/ChangeTrackers/SongsTracker.cs b/Rise Media Player Dev/ChangeTrackers/SongsTracker.cs index 78e3b25f..314ac3cf 100644 --- a/Rise Media Player Dev/ChangeTrackers/SongsTracker.cs +++ b/Rise Media Player Dev/ChangeTrackers/SongsTracker.cs @@ -100,7 +100,7 @@ public static async Task ManageSongChange(StorageLibraryChange change) if (change.PreviousPath == ViewModel.Songs[i].Location) { ViewModel.Songs[i].Location = file.Path; - await ViewModel.Songs[i].SaveEditsAsync(); + await ViewModel.Songs[i].SaveAsync(); } } break; diff --git a/Rise Media Player Dev/Rise.App.csproj b/Rise Media Player Dev/Rise.App.csproj index dc82af99..ab0221bc 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 @@ - + - + - + @@ -1077,14 +1077,14 @@ - - - - - - - - + + + + + + + + diff --git a/Rise Media Player Dev/UserControls/NowPlayingBar.xaml.cs b/Rise Media Player Dev/UserControls/NowPlayingBar.xaml.cs index 0a228379..b665acc1 100644 --- a/Rise Media Player Dev/UserControls/NowPlayingBar.xaml.cs +++ b/Rise Media Player Dev/UserControls/NowPlayingBar.xaml.cs @@ -748,7 +748,7 @@ private async void Props_Click(object sender, RoutedEventArgs e) if (!App.PViewModel.CurrentSong.IsOnline) { SelectedSong = App.PViewModel.CurrentSong; - await App.PViewModel.CurrentSong.StartEditAsync(); + await App.PViewModel.CurrentSong.StartEdit(); } } diff --git a/Rise Media Player Dev/ViewModels/AlbumViewModel.cs b/Rise Media Player Dev/ViewModels/AlbumViewModel.cs index 84af4bea..0035083e 100644 --- a/Rise Media Player Dev/ViewModels/AlbumViewModel.cs +++ b/Rise Media Player Dev/ViewModels/AlbumViewModel.cs @@ -1,6 +1,5 @@ using Rise.App.Common; using Rise.Models; -using Rise.Repository.SQL; using System; using System.Linq; using System.Threading.Tasks; @@ -9,19 +8,26 @@ namespace Rise.App.ViewModels { public class AlbumViewModel : ViewModel { - #region Constructor + // private readonly DispatcherQueue dispatcherQueue = DispatcherQueue.GetForCurrentThread(); + /// /// Initializes a new instance of the AlbumViewModel class that wraps an Album object. /// public AlbumViewModel(Album model = null) { - Model = model ?? new Album(); + if (model != null) + { + Model = model; + } + else + { + Model = new Album(); + IsNew = true; + } OnPropertyChanged(nameof(ArtistViewModel.AlbumCount)); } - #endregion - #region Properties /// /// Gets or sets the album title. /// @@ -41,7 +47,8 @@ public string Title if (value != Model.Title) { Model.Title = value; - OnPropertyChanged(); + IsModified = true; + OnPropertyChanged(nameof(Title)); } } } @@ -65,7 +72,8 @@ public string Artist if (value != Model.Artist) { Model.Artist = value; - OnPropertyChanged(); + IsModified = true; + OnPropertyChanged(nameof(Artist)); } } } @@ -100,7 +108,8 @@ public string Genres if (value != Model.Genres) { Model.Genres = value; - OnPropertyChanged(); + IsModified = true; + OnPropertyChanged(nameof(Genres)); } } } @@ -122,7 +131,8 @@ public string Thumbnail if (value != Model.Thumbnail) { Model.Thumbnail = value; - OnPropertyChanged(); + IsModified = true; + OnPropertyChanged(nameof(Thumbnail)); } } } @@ -138,12 +148,54 @@ public uint Year if (value != Model.Year) { Model.Year = value; - OnPropertyChanged(); + IsModified = true; + OnPropertyChanged(nameof(Year)); } } } + /// + /// 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. + /// + public bool IsNew + { + get => _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. /// @@ -154,6 +206,7 @@ public bool IsArtistVisible } private bool _isThumbnailVisible = true; + /// /// Gets or sets a value that indicates whether the album art is displayed or not. /// @@ -164,6 +217,7 @@ public bool IsThumbnailVisible } private bool _isGenresVisible = false; + /// /// Gets or sets a value that indicates whether the album genre is displayed or not. /// @@ -174,6 +228,7 @@ public bool IsGenresVisible } private bool _isTitleVisible = true; + /// /// Gets or sets a value that indicates whether the album title is displayed or not. /// @@ -184,6 +239,7 @@ public bool IsTitleVisible } private bool _hasRoundedAlbumArt = true; + /// /// Gets or sets a value that indicates whether the album art is rounded or not. /// @@ -194,6 +250,7 @@ public bool HasRoundedAlbumArt } private bool _isReleaseYearVisible = false; + /// /// Gets or sets a value that indicates whether the album release year is rounded or not. /// @@ -202,25 +259,46 @@ public bool IsReleaseYearVisible get => _isReleaseYearVisible; set => Set(ref _isReleaseYearVisible, value); } - #endregion - #region Backend /// - /// Saves item data to the backend. + /// Saves album data that has been edited. /// public async Task SaveAsync() { - App.MViewModel.Albums.Add(this); - await SQLRepository.Repository.Albums.QueueUpsertAsync(Model); + IsInEdit = false; + IsModified = false; + + if (IsNew) + { + IsNew = false; + App.MViewModel.Albums.Add(this); + } + + await App.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; + } } /// - /// Deletes item data from the backend. + /// Delete album from repository and MViewModel. /// public async Task DeleteAsync() { + IsModified = true; + App.MViewModel.Albums.Remove(this); - await SQLRepository.Repository.Albums.QueueDeletionAsync(Model); + await App.Repository.Albums.QueueDeletionAsync(Model); ArtistViewModel artist = App.MViewModel.Artists. FirstOrDefault(a => a.Model.Name == Model.Artist); @@ -232,44 +310,44 @@ public async Task DeleteAsync() } /// - /// Checks whether or not the item is available. If it's not, - /// delete it. + /// Raised when the user cancels the changes they've made to the album data. /// - public async Task CheckAvailabilityAsync() - { - if (TrackCount == 0) - { - await DeleteAsync(); - return; - } - } - #endregion + public event EventHandler AddNewAlbumCanceled; - #region Editing /// - /// Enables edit mode. + /// Cancels any in progress edits. /// - /*public async Task StartEditAsync() + public async Task CancelEditsAsync() { - _ = await typeof(PropertiesPage). - PlaceInWindowAsync(ApplicationViewMode.Default, 380, 550, true, props); - }*/ + if (IsNew) + { + AddNewAlbumCanceled?.Invoke(this, EventArgs.Empty); + } + else + { + await RevertChangesAsync(); + } + } /// - /// Saves any edits that have been made. + /// Discards any edits that have been made, restoring the original values. /// - public async Task SaveEditsAsync() + public async Task RevertChangesAsync() { - await SQLRepository.Repository.Albums.UpdateAsync(Model); + IsInEdit = false; + if (IsModified) + { + await RefreshAlbumsAsync(); + IsModified = false; + } } /// - /// Discards any edits that have been made, restoring the original values. + /// Reloads all of the album data. /// - public async Task CancelEditsAsync() + public async Task RefreshAlbumsAsync() { - Model = await SQLRepository.Repository.Albums.GetAsync(Model.Id); + Model = await App.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 be99a6bd..ad4719da 100644 --- a/Rise Media Player Dev/ViewModels/ArtistViewModel.cs +++ b/Rise Media Player Dev/ViewModels/ArtistViewModel.cs @@ -1,6 +1,5 @@ using Rise.App.Common; using Rise.Models; -using Rise.Repository.SQL; using System; using System.Linq; using System.Threading.Tasks; @@ -9,17 +8,17 @@ namespace Rise.App.ViewModels { public class ArtistViewModel : ViewModel { - #region Constructor + // private readonly DispatcherQueue dispatcherQueue = DispatcherQueue.GetForCurrentThread(); + /// /// Initializes a new instance of the ArtistViewModel class that wraps an Artist object. /// public ArtistViewModel(Artist model = null) { Model = model ?? new Artist(); + IsNew = true; } - #endregion - #region Properties /// /// Gets or sets the artist name. /// @@ -39,7 +38,8 @@ public string Name if (value != Model.Name) { Model.Name = value; - OnPropertyChanged(); + IsModified = true; + OnPropertyChanged(nameof(Name)); } } } @@ -55,7 +55,8 @@ public string Picture if (value != Model.Picture) { Model.Picture = value; - OnPropertyChanged(); + IsModified = true; + OnPropertyChanged(nameof(Picture)); } } } @@ -76,29 +77,54 @@ public string Picture /// Combination of artist's song count and album count. /// public string SongsNAlbums => Albums + ", " + Songs; - #endregion - #region Backend /// - /// Saves item data to the backend. + /// Gets or sets a value that indicates whether the underlying model has been modified. /// - public async Task SaveAsync() + /// + /// 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. + /// + public bool IsNew { - App.MViewModel.Artists.Add(this); - await SQLRepository.Repository.Artists.QueueUpsertAsync(Model); + get => _isNew; + set => Set(ref _isNew, value); } + private bool _isInEdit = false; /// - /// Deletes item data from the backend. + /// Gets or sets a value that indicates whether the artist data is being edited. /// - public async Task DeleteAsync() + public bool IsInEdit { - App.MViewModel.Artists.Remove(this); - await SQLRepository.Repository.Artists.QueueDeletionAsync(Model); + get => _isInEdit; + set => Set(ref _isInEdit, value); } /// - /// Checks whether or not the item is available. If it's not, + /// Saves artist data that has been edited. + /// + public async Task SaveAsync() + { + IsInEdit = false; + IsModified = false; + + if (IsNew) + { + IsNew = false; + App.MViewModel.Artists.Add(this); + } + + await App.Repository.Artists.QueueUpsertAsync(Model); + } + + /// + /// Checks whether or not the artist is available. If it's not, /// delete it. /// public async Task CheckAvailabilityAsync() @@ -109,33 +135,62 @@ public async Task CheckAvailabilityAsync() return; } } - #endregion - #region Editing /// - /// Enables edit mode. + /// Delete artist from repository and MViewModel. /// - /*public async Task StartEditAsync() + public async Task DeleteAsync() { - _ = await typeof(PropertiesPage). - PlaceInWindowAsync(ApplicationViewMode.Default, 380, 550, true, props); - }*/ + IsModified = true; + + App.MViewModel.Artists.Remove(this); + await App.Repository.Artists.QueueDeletionAsync(Model); + } + + /// + /// Raised when the user cancels the changes they've made to the artist data. + /// + public event EventHandler AddNewArtistCanceled; /// - /// Saves any edits that have been made. + /// Cancels any in progress edits. /// - public async Task SaveEditsAsync() + public async Task CancelEditsAsync() { - await SQLRepository.Repository.Artists.UpdateAsync(Model); + if (IsNew) + { + AddNewArtistCanceled?.Invoke(this, EventArgs.Empty); + } + else + { + await RevertChangesAsync(); + } } /// /// Discards any edits that have been made, restoring the original values. /// - public async Task CancelEditsAsync() + public async Task RevertChangesAsync() + { + IsInEdit = false; + if (IsModified) + { + await RefreshArtistsAsync(); + IsModified = false; + } + } + + /// + /// Enables edit mode. + /// + public void StartEdit() => IsInEdit = true; + + /// + /// Reloads all of the artist data. + /// + public async Task RefreshArtistsAsync() { - Model = await SQLRepository.Repository.Artists.GetAsync(Model.Id); + Model = await App.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 5c2de94a..840a02d3 100644 --- a/Rise Media Player Dev/ViewModels/GenreViewModel.cs +++ b/Rise Media Player Dev/ViewModels/GenreViewModel.cs @@ -1,23 +1,20 @@ using Rise.App.Common; using Rise.Models; -using Rise.Repository.SQL; using System.Threading.Tasks; namespace Rise.App.ViewModels { public class GenreViewModel : ViewModel { - #region Constructor /// /// Initializes a new instance of the AlbumViewModel class that wraps an Album object. /// public GenreViewModel(Genre model = null) { Model = model ?? new Genre(); + IsNew = true; } - #endregion - #region Properties /// /// Gets or sets the genre name. /// @@ -29,21 +26,43 @@ public string Name if (value != Model.Name) { Model.Name = value; - OnPropertyChanged(); + IsModified = true; + OnPropertyChanged(nameof(Name)); } } } - #endregion - #region Backend /// - /// Saves item data to the backend. + /// 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. + /// + public bool IsNew + { + get => _isNew; + set => Set(ref _isNew, value); + } + + /// + /// Saves genre data that has been edited. /// public async Task SaveAsync() { - App.MViewModel.Genres.Add(this); - await SQLRepository.Repository.Genres.QueueUpsertAsync(Model); + IsModified = false; + if (IsNew) + { + IsNew = false; + App.MViewModel.Genres.Add(this); + } + + await App.Repository.Genres.QueueUpsertAsync(Model); } - #endregion } } diff --git a/Rise Media Player Dev/ViewModels/MainViewModel.cs b/Rise Media Player Dev/ViewModels/MainViewModel.cs index 4549b620..78f7736d 100644 --- a/Rise Media Player Dev/ViewModels/MainViewModel.cs +++ b/Rise Media Player Dev/ViewModels/MainViewModel.cs @@ -5,7 +5,6 @@ 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; @@ -157,14 +156,14 @@ public VideoViewModel SelectedVideo public async Task GetListsAsync() { LoadingStarted?.Invoke(this, EventArgs.Empty); - IEnumerable songs = (await SQLRepository.Repository.Songs.GetAsync()).Distinct(); + IEnumerable songs = (await App.Repository.Songs.GetAsync()).Distinct(); if (songs != null) { - IEnumerable albums = (await SQLRepository.Repository.Albums.GetAsync()).Distinct(); - IEnumerable artists = (await SQLRepository.Repository.Artists.GetAsync()).Distinct(); - IEnumerable genres = (await SQLRepository.Repository.Genres.GetAsync()).Distinct(); - IEnumerable