diff --git a/VDownload.Core/VDownload.Core.Strings/VDownload.Core.Strings.csproj b/VDownload.Core/VDownload.Core.Strings/VDownload.Core.Strings.csproj index 0b0aa2a..7a200cb 100644 --- a/VDownload.Core/VDownload.Core.Strings/VDownload.Core.Strings.csproj +++ b/VDownload.Core/VDownload.Core.Strings/VDownload.Core.Strings.csproj @@ -10,8 +10,8 @@ - - + + diff --git a/VDownload.Core/VDownload.Core.Tasks/DownloadTask.cs b/VDownload.Core/VDownload.Core.Tasks/DownloadTask.cs index 2503af5..da21750 100644 --- a/VDownload.Core/VDownload.Core.Tasks/DownloadTask.cs +++ b/VDownload.Core/VDownload.Core.Tasks/DownloadTask.cs @@ -21,6 +21,19 @@ namespace VDownload.Core.Tasks { public partial class DownloadTask : ObservableObject { + #region ENUMS + + private enum TaskResult + { + Success, + Cancellation, + Error + } + + #endregion + + + #region SERVICES protected readonly IConfigurationService _configurationService; @@ -156,6 +169,8 @@ namespace VDownload.Core.Tasks $"{_stringResourcesService.NotificationsResources.Get("Author")}: {Video.Author}" }; + string errorMessage = null; + TaskResult? endingStatus = null; try { IProgress onProgressDownloading = new Progress((value) => @@ -194,16 +209,12 @@ namespace VDownload.Core.Tasks await Finalizing(outputFile); UpdateStatusWithDispatcher(DownloadTaskStatus.EndedSuccessfully); - - if (_settingsService.Data.Common.Notifications.OnSuccessful) - { - string title = _stringResourcesService.NotificationsResources.Get("OnSuccessfulTitle"); - _notificationsService.SendNotification(title, content); - } + endingStatus = TaskResult.Success; } catch (OperationCanceledException) { UpdateStatusWithDispatcher(DownloadTaskStatus.EndedCancelled); + endingStatus = TaskResult.Cancellation; } catch (Exception ex) { @@ -226,18 +237,32 @@ namespace VDownload.Core.Tasks message = ex.Message; } - UpdateErrorWithDispatcher(message); + UpdateErrorWithDispatcher(message); UpdateStatusWithDispatcher(DownloadTaskStatus.EndedUnsuccessfully); - - if (_settingsService.Data.Common.Notifications.OnUnsuccessful) - { - string title = _stringResourcesService.NotificationsResources.Get("OnSuccessfulTitle"); - content.Add($"{_stringResourcesService.NotificationsResources.Get("Message")}: {ex.Message}"); - _notificationsService.SendNotification(title, content); - } + endingStatus = TaskResult.Error; + errorMessage = message; } finally { + switch (endingStatus) + { + case TaskResult.Error: + if (_settingsService.Data.Common.Notifications.OnUnsuccessful) + { + string title = _stringResourcesService.NotificationsResources.Get("OnUnsuccessfulTitle"); + content.Add($"{_stringResourcesService.NotificationsResources.Get("Message")}: {errorMessage}"); + _notificationsService.SendNotification(title, content); + } + break; + case TaskResult.Success: + if (_settingsService.Data.Common.Notifications.OnSuccessful) + { + string title = _stringResourcesService.NotificationsResources.Get("OnSuccessfulTitle"); + _notificationsService.SendNotification(title, content); + } + break; + } + if (Status != DownloadTaskStatus.EndedUnsuccessfully || _settingsService.Data.Common.Temp.DeleteOnError) { Directory.Delete(tempDirectory, true); diff --git a/VDownload.Core/VDownload.Core.ViewModels/VDownload.Core.ViewModels.csproj b/VDownload.Core/VDownload.Core.ViewModels/VDownload.Core.ViewModels.csproj index 723fff0..e493bd7 100644 --- a/VDownload.Core/VDownload.Core.ViewModels/VDownload.Core.ViewModels.csproj +++ b/VDownload.Core/VDownload.Core.ViewModels/VDownload.Core.ViewModels.csproj @@ -11,8 +11,8 @@ - - + + diff --git a/VDownload.Core/VDownload.Core.Views/VDownload.Core.Views.csproj b/VDownload.Core/VDownload.Core.Views/VDownload.Core.Views.csproj index cb2d07a..7f6d8a0 100644 --- a/VDownload.Core/VDownload.Core.Views/VDownload.Core.Views.csproj +++ b/VDownload.Core/VDownload.Core.Views/VDownload.Core.Views.csproj @@ -20,8 +20,8 @@ - - + + diff --git a/VDownload.Services/VDownload.Services.UI/VDownload.Services.UI.Dialogs/VDownload.Services.UI.Dialogs.csproj b/VDownload.Services/VDownload.Services.UI/VDownload.Services.UI.Dialogs/VDownload.Services.UI.Dialogs.csproj index 73dc57e..8744244 100644 --- a/VDownload.Services/VDownload.Services.UI/VDownload.Services.UI.Dialogs/VDownload.Services.UI.Dialogs.csproj +++ b/VDownload.Services/VDownload.Services.UI/VDownload.Services.UI.Dialogs/VDownload.Services.UI.Dialogs.csproj @@ -10,8 +10,8 @@ - - + + diff --git a/VDownload.Services/VDownload.Services.UI/VDownload.Services.UI.DictionaryResources/VDownload.Services.UI.DictionaryResources.csproj b/VDownload.Services/VDownload.Services.UI/VDownload.Services.UI.DictionaryResources/VDownload.Services.UI.DictionaryResources.csproj index 86ac367..0404798 100644 --- a/VDownload.Services/VDownload.Services.UI/VDownload.Services.UI.DictionaryResources/VDownload.Services.UI.DictionaryResources.csproj +++ b/VDownload.Services/VDownload.Services.UI/VDownload.Services.UI.DictionaryResources/VDownload.Services.UI.DictionaryResources.csproj @@ -10,8 +10,8 @@ - - + + diff --git a/VDownload.Services/VDownload.Services.UI/VDownload.Services.UI.Notifications/NotificationsService.cs b/VDownload.Services/VDownload.Services.UI/VDownload.Services.UI.Notifications/NotificationsService.cs index 778aa50..653760b 100644 --- a/VDownload.Services/VDownload.Services.UI/VDownload.Services.UI.Notifications/NotificationsService.cs +++ b/VDownload.Services/VDownload.Services.UI/VDownload.Services.UI.Notifications/NotificationsService.cs @@ -1,4 +1,5 @@ -using Microsoft.Windows.AppNotifications; +using Microsoft.Toolkit.Uwp.Notifications; +using Microsoft.Windows.AppNotifications; using Microsoft.Windows.AppNotifications.Builder; using System; using System.Collections.Generic; @@ -10,6 +11,7 @@ namespace VDownload.Services.UI.Notifications { public interface INotificationsService { + void Initialize(Action notificationInvoked); void SendNotification(string title, IEnumerable message); } @@ -17,8 +19,26 @@ namespace VDownload.Services.UI.Notifications public class NotificationsService : INotificationsService { + #region CONSTRCUTORS + + ~NotificationsService() + { + AppNotificationManager.Default.Unregister(); + } + + #endregion + + + #region PUBLIC METHODS + public void Initialize(Action notificationInvoked) + { + AppNotificationManager.Default.NotificationInvoked += (obj, args) => notificationInvoked.Invoke(); + + AppNotificationManager.Default.Register(); + } + public void SendNotification(string title, IEnumerable message) { AppNotificationBuilder builder = new AppNotificationBuilder(); @@ -27,7 +47,9 @@ namespace VDownload.Services.UI.Notifications { builder.AddText(text); } + AppNotification notification = builder.BuildNotification(); + AppNotificationManager.Default.Show(notification); } diff --git a/VDownload.Services/VDownload.Services.UI/VDownload.Services.UI.Notifications/VDownload.Services.UI.Notifications.csproj b/VDownload.Services/VDownload.Services.UI/VDownload.Services.UI.Notifications/VDownload.Services.UI.Notifications.csproj index 72ceb84..8d89a91 100644 --- a/VDownload.Services/VDownload.Services.UI/VDownload.Services.UI.Notifications/VDownload.Services.UI.Notifications.csproj +++ b/VDownload.Services/VDownload.Services.UI/VDownload.Services.UI.Notifications/VDownload.Services.UI.Notifications.csproj @@ -10,7 +10,8 @@ - - + + + diff --git a/VDownload.Services/VDownload.Services.UI/VDownload.Services.UI.StoragePicker/VDownload.Services.UI.StoragePicker.csproj b/VDownload.Services/VDownload.Services.UI/VDownload.Services.UI.StoragePicker/VDownload.Services.UI.StoragePicker.csproj index 34ac897..6ea7798 100644 --- a/VDownload.Services/VDownload.Services.UI/VDownload.Services.UI.StoragePicker/VDownload.Services.UI.StoragePicker.csproj +++ b/VDownload.Services/VDownload.Services.UI/VDownload.Services.UI.StoragePicker/VDownload.Services.UI.StoragePicker.csproj @@ -10,7 +10,7 @@ - - + + diff --git a/VDownload.Services/VDownload.Services.UI/VDownload.Services.UI.StringResources/VDownload.Services.UI.StringResources.csproj b/VDownload.Services/VDownload.Services.UI/VDownload.Services.UI.StringResources/VDownload.Services.UI.StringResources.csproj index c15f245..50e13b6 100644 --- a/VDownload.Services/VDownload.Services.UI/VDownload.Services.UI.StringResources/VDownload.Services.UI.StringResources.csproj +++ b/VDownload.Services/VDownload.Services.UI/VDownload.Services.UI.StringResources/VDownload.Services.UI.StringResources.csproj @@ -10,8 +10,8 @@ - - + + diff --git a/VDownload.Services/VDownload.Services.UI/VDownload.Services.UI.WebView/VDownload.Services.UI.WebView.csproj b/VDownload.Services/VDownload.Services.UI/VDownload.Services.UI.WebView/VDownload.Services.UI.WebView.csproj index 9c8dbdc..aa294dd 100644 --- a/VDownload.Services/VDownload.Services.UI/VDownload.Services.UI.WebView/VDownload.Services.UI.WebView.csproj +++ b/VDownload.Services/VDownload.Services.UI/VDownload.Services.UI.WebView/VDownload.Services.UI.WebView.csproj @@ -13,8 +13,8 @@ - - + + diff --git a/VDownload/App.xaml.cs b/VDownload/App.xaml.cs index af9ab08..fc2d7c1 100644 --- a/VDownload/App.xaml.cs +++ b/VDownload/App.xaml.cs @@ -1,7 +1,9 @@ using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration.Json; using Microsoft.Extensions.DependencyInjection; +using Microsoft.Toolkit.Uwp.Notifications; using Microsoft.UI.Xaml; +using Microsoft.Windows.AppNotifications; using System; using System.Net.Http; using System.Threading.Tasks; @@ -39,6 +41,7 @@ using VDownload.Sources.Twitch; using VDownload.Sources.Twitch.Api; using VDownload.Sources.Twitch.Authentication; using Windows.Graphics.Printing; +using Windows.UI.Notifications; namespace VDownload { @@ -175,32 +178,34 @@ namespace VDownload services.AddTransient(); } - protected override async void OnLaunched(LaunchActivatedEventArgs args) - { - await InitData(); - - _window = _serviceProvider.GetService(); - _window.RootLoaded += Window_RootLoaded; - _window.Activate(); - - AssignStaticProperties(); - } - - protected async Task InitData() + protected async Task InitializeServices() { IApplicationDataService applicationDataService = _serviceProvider.GetService(); ISettingsService settingsService = _serviceProvider.GetService(); IAuthenticationDataService authenticationDataService = _serviceProvider.GetService(); ISubscriptionsDataService subscriptionsDataService = _serviceProvider.GetService(); - await Task.WhenAll(applicationDataService.Load(), settingsService.Load(), authenticationDataService.Load(), subscriptionsDataService.Load()); + Task initViewModelToViewConverterTask = Task.Run(() => ViewModelToViewConverter.ServiceProvider = _serviceProvider); + Task initStoragePickerServiceTask = Task.Run(() => _serviceProvider.GetService().DefaultRoot = _window); + Task initNotificationsServiceTask = Task.Run(() => _serviceProvider.GetService().Initialize(() => WindowHelper.ShowWindow(_window))); + + await Task.WhenAll( + applicationDataService.Load(), + settingsService.Load(), + authenticationDataService.Load(), + subscriptionsDataService.Load(), + initStoragePickerServiceTask, + initViewModelToViewConverterTask, + initNotificationsServiceTask + ); } - protected void AssignStaticProperties() + protected override async void OnLaunched(LaunchActivatedEventArgs args) { - IStoragePickerService storagePickerService = _serviceProvider.GetService(); - storagePickerService.DefaultRoot = _window; + _window = _serviceProvider.GetService(); + _window.RootLoaded += Window_RootLoaded; + _window.Activate(); - ViewModelToViewConverter.ServiceProvider = _serviceProvider; + await InitializeServices(); } protected void Window_RootLoaded(object sender, EventArgs e) diff --git a/VDownload/Package.appxmanifest b/VDownload/Package.appxmanifest index 858c5db..a07c131 100644 --- a/VDownload/Package.appxmanifest +++ b/VDownload/Package.appxmanifest @@ -5,7 +5,9 @@ xmlns:mp="http://schemas.microsoft.com/appx/2014/phone/manifest" xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10" xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities" - IgnorableNamespaces="uap rescap"> + xmlns:com="http://schemas.microsoft.com/appx/manifest/com/windows10" + xmlns:desktop="http://schemas.microsoft.com/appx/manifest/desktop/windows10" + IgnorableNamespaces="uap rescap com desktop"> + + + + + + + + + + + + + diff --git a/VDownload/VDownload.csproj b/VDownload/VDownload.csproj index 589ff2a..f25b174 100644 --- a/VDownload/VDownload.csproj +++ b/VDownload/VDownload.csproj @@ -18,6 +18,7 @@ True 0.0.0 false + true @@ -167,8 +168,9 @@ - - + + + diff --git a/VDownload/WindowHelper.cs b/VDownload/WindowHelper.cs new file mode 100644 index 0000000..e63b411 --- /dev/null +++ b/VDownload/WindowHelper.cs @@ -0,0 +1,43 @@ +using Microsoft.UI.Xaml; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.InteropServices; +using System.Text; +using System.Threading.Tasks; + +namespace VDownload +{ + public static partial class WindowHelper + { + #region PUBLIC METHODS + + public static void ShowWindow(Window window) + { + // Bring the window to the foreground... first get the window handle... + var hwnd = WinRT.Interop.WindowNative.GetWindowHandle(window); + + // Restore window if minimized... requires DLL import above + ShowWindow(hwnd, 0x00000009); + + // And call SetForegroundWindow... requires DLL import above + SetForegroundWindow(hwnd); + } + + #endregion + + + + #region PRIVATE METHODS + + [LibraryImport("user32.dll")] + [return: MarshalAs(UnmanagedType.Bool)] + private static partial bool ShowWindow(IntPtr hWnd, int nCmdShow); + + [LibraryImport("user32.dll")] + [return: MarshalAs(UnmanagedType.Bool)] + private static partial bool SetForegroundWindow(IntPtr hWnd); + + #endregion + } +}