diff --git a/VDownload.Core/Services/Config.cs b/VDownload.Core/Services/Config.cs index 338449f..ee7bfdd 100644 --- a/VDownload.Core/Services/Config.cs +++ b/VDownload.Core/Services/Config.cs @@ -35,7 +35,9 @@ namespace VDownload.Core.Services { "remove_task_when_successfully_ended", false }, { "delete_task_temp_when_ended_with_error", false }, { "show_notification_when_task_ended_successfully", false }, - { "show_notification_when_task_ended_unsuccessfully", false } + { "show_notification_when_task_ended_unsuccessfully", false }, + { "show_warning_when_task_starts_on_metered_network", true }, + { "delay_task_when_queued_task_starts_on_metered_network", true } }; #endregion diff --git a/VDownload/Assets/Images/HomeTasksListPlaceholderImage.svg b/VDownload/Assets/Images/HomeTasksListPlaceholderImage.svg new file mode 100644 index 0000000..f39f467 --- /dev/null +++ b/VDownload/Assets/Images/HomeTasksListPlaceholderImage.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/VDownload/Assets/Images/UnknownThumbnail.png b/VDownload/Assets/Images/UnknownThumbnail.png index 38ed3d5..10e53ca 100644 Binary files a/VDownload/Assets/Images/UnknownThumbnail.png and b/VDownload/Assets/Images/UnknownThumbnail.png differ diff --git a/VDownload/Resources/Colors.xaml b/VDownload/Resources/Colors.xaml index 3b5aef4..3303643 100644 --- a/VDownload/Resources/Colors.xaml +++ b/VDownload/Resources/Colors.xaml @@ -11,4 +11,5 @@ + diff --git a/VDownload/Resources/Images.xaml b/VDownload/Resources/Images.xaml index 764b264..8829843 100644 --- a/VDownload/Resources/Images.xaml +++ b/VDownload/Resources/Images.xaml @@ -2,4 +2,5 @@ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> + diff --git a/VDownload/Strings/en-US/Resources.resw b/VDownload/Strings/en-US/Resources.resw index 2126177..589ac44 100644 --- a/VDownload/Strings/en-US/Resources.resw +++ b/VDownload/Strings/en-US/Resources.resw @@ -120,6 +120,21 @@ OK + + No + + + You are on the metered connection now. You can delay tasks until the network changes. Do you want to start the tasks? + + + Yes (With delay) + + + Yes (Without delay) + + + Metered connection detected + Add playlist @@ -217,9 +232,30 @@ The number in the numberbox indicades how many videos will be got from playlist. Processing + + Scheduled + Queued + + No + + + You are on the metered connection now. You can delay task until the network changes. Do you want to start the task? + + + Yes (With delay) + + + Yes (Without delay) + + + Metered connection detected + + + Click "Add video/playlist" button to start + Downloading options diff --git a/VDownload/VDownload.csproj b/VDownload/VDownload.csproj index 6a48a5f..9206e34 100644 --- a/VDownload/VDownload.csproj +++ b/VDownload/VDownload.csproj @@ -137,6 +137,9 @@ HomeMain.xaml + + HomeTasksListPlaceholder.xaml + HomeVideoAddingPanel.xaml @@ -202,6 +205,8 @@ + + @@ -253,7 +258,6 @@ - @@ -297,6 +301,10 @@ Designer MSBuild:Compile + + Designer + MSBuild:Compile + Designer MSBuild:Compile @@ -326,6 +334,9 @@ 6.2.13 + + 7.1.2 + 7.1.2 diff --git a/VDownload/Views/Home/HomeMain.xaml b/VDownload/Views/Home/HomeMain.xaml index f4529d1..171ea56 100644 --- a/VDownload/Views/Home/HomeMain.xaml +++ b/VDownload/Views/Home/HomeMain.xaml @@ -60,7 +60,7 @@ - + @@ -69,7 +69,7 @@ - + diff --git a/VDownload/Views/Home/HomeMain.xaml.cs b/VDownload/Views/Home/HomeMain.xaml.cs index 4fdbd03..8e0b1e4 100644 --- a/VDownload/Views/Home/HomeMain.xaml.cs +++ b/VDownload/Views/Home/HomeMain.xaml.cs @@ -1,4 +1,5 @@ -using System; +using Microsoft.Toolkit.Uwp.Connectivity; +using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; @@ -40,8 +41,12 @@ namespace VDownload.Views.Home // CANCELLATON TOKEN private CancellationTokenSource SearchingCancellationToken = new CancellationTokenSource(); + // HOME TASKS LIST PLACEHOLDER + private readonly HomeTasksListPlaceholder HomeTasksListPlaceholder = new HomeTasksListPlaceholder(); + // HOME VIDEOS LIST - private static StackPanel HomeTasksListParent = null; + private static ContentControl HomeTasksListPlaceCurrent = null; + private static StackPanel HomeTasksList = null; public static List TaskPanelsList = new List(); #endregion @@ -53,9 +58,18 @@ namespace VDownload.Views.Home // ON NAVIGATED TO protected override async void OnNavigatedTo(NavigationEventArgs e) { - if (HomeTasksListParent != null) HomeTasksListParent.Children.Clear(); - HomeTasksListParent = HomeTasksList; - foreach (HomeTaskPanel homeVideoPanel in TaskPanelsList) HomeTasksList.Children.Add(homeVideoPanel); + HomeTasksListPlaceCurrent = HomeTasksListPlace; + if (HomeTasksList != null) HomeTasksList.Children.Clear(); + HomeTasksList = new StackPanel { Spacing = 10 }; + if (TaskPanelsList.Count > 0) + { + foreach (HomeTaskPanel homeVideoPanel in TaskPanelsList) HomeTasksList.Children.Add(homeVideoPanel); + HomeTasksListPlace.Content = HomeTasksList; + } + else + { + HomeTasksListPlace.Content = HomeTasksListPlaceholder; + } } // ADD VIDEO BUTTON CHECKED @@ -73,6 +87,9 @@ namespace VDownload.Views.Home // ADD VIDEO SEARCH BUTTON CLICKED private async void HomeOptionsBarAddVideoControl_SearchButtonClicked(object sender, VideoSearchEventArgs e) { + HomeOptionBarAndAddingPanelRow.Height = GridLength.Auto; + HomeTasksListRow.Height = new GridLength(1, GridUnitType.Star); + HomeAddingPanel.Content = null; // Cancel previous operations @@ -166,6 +183,9 @@ namespace VDownload.Views.Home private void HomeVideoAddingPanel_VideoAddRequest(object sender, VideoAddEventArgs e) { + // Replace placeholder + HomeTasksListPlace.Content = HomeTasksList; + // Uncheck video button HomeOptionsBarAddVideoButton.IsChecked = false; @@ -177,6 +197,7 @@ namespace VDownload.Views.Home // Remove task from tasks lists TaskPanelsList.Remove(taskPanel); HomeTasksList.Children.Remove(taskPanel); + if (TaskPanelsList.Count <= 0) HomeTasksListPlace.Content = HomeTasksListPlaceholder; }; // Add task to tasks lists @@ -297,10 +318,30 @@ namespace VDownload.Views.Home // DOWNLOAD ALL BUTTON CLICKED private async void HomeOptionsBarDownloadAllButton_Click(object sender, RoutedEventArgs e) { - foreach (HomeTaskPanel videoPanel in HomeTasksList.Children.Where((object video) => ((HomeTaskPanel)video).TaskStatus == Core.Enums.TaskStatus.Idle)) + HomeTaskPanel[] idleTasks = TaskPanelsList.Where((HomeTaskPanel video) => video.TaskStatus == Core.Enums.TaskStatus.Idle).ToArray(); + if (idleTasks.Count() > 0) { - await Task.Delay(50); - videoPanel.Start(); + bool delay = (bool)Config.GetValue("delay_task_when_queued_task_starts_on_metered_network"); + ContentDialogResult dialogResult = await new ContentDialog + { + Title = ResourceLoader.GetForCurrentView().GetString("HomeDownloadAllButtonMeteredConnectionDialogTitle"), + Content = ResourceLoader.GetForCurrentView().GetString("HomeDownloadAllButtonMeteredConnectionDialogDescription"), + PrimaryButtonText = ResourceLoader.GetForCurrentView().GetString("HomeDownloadAllButtonMeteredConnectionDialogStartAndDelayText"), + SecondaryButtonText = ResourceLoader.GetForCurrentView().GetString("HomeDownloadAllButtonMeteredConnectionDialogStartWithoutDelayText"), + CloseButtonText = ResourceLoader.GetForCurrentView().GetString("HomeDownloadAllButtonMeteredConnectionDialogCancel"), + }.ShowAsync(); + switch (dialogResult) + { + case ContentDialogResult.Primary: delay = true; break; + case ContentDialogResult.Secondary: delay = false; break; + case ContentDialogResult.None: return; + } + + foreach (HomeTaskPanel videoPanel in idleTasks) + { + await Task.Delay(50); + videoPanel.Start(delay); + } } } @@ -311,11 +352,11 @@ namespace VDownload.Views.Home #region METHODS // WAIT IN QUEUE - public static async Task WaitInQueue(CancellationToken token) + public static async Task WaitInQueue(bool delayWhenOnMeteredConnection, CancellationToken token) { - while (TaskPanelsList.Where((HomeTaskPanel video) => video.TaskStatus == Core.Enums.TaskStatus.InProgress).Count() >= (int)Config.GetValue("max_active_video_task") && !token.IsCancellationRequested) + while ((TaskPanelsList.Where((HomeTaskPanel video) => video.TaskStatus == Core.Enums.TaskStatus.InProgress).Count() >= (int)Config.GetValue("max_active_video_task") || (delayWhenOnMeteredConnection && NetworkHelper.Instance.ConnectionInformation.IsInternetOnMeteredConnection)) && !token.IsCancellationRequested) { - await Task.Delay(50); + await Task.Delay(100); } } diff --git a/VDownload/Views/Home/HomeTaskPanel.xaml.cs b/VDownload/Views/Home/HomeTaskPanel.xaml.cs index d086272..0895a6d 100644 --- a/VDownload/Views/Home/HomeTaskPanel.xaml.cs +++ b/VDownload/Views/Home/HomeTaskPanel.xaml.cs @@ -1,6 +1,7 @@ using Microsoft.Toolkit.Uwp.Notifications; using System; using System.Diagnostics; +using System.Globalization; using System.Linq; using System.Net; using System.Threading; @@ -113,7 +114,7 @@ namespace VDownload.Views.Home #region METHODS - public async Task Start() + public async Task Start(bool delayWhenOnMeteredConnection) { // Change icon HomeTaskPanelStartStopButton.Icon = new SymbolIcon(Symbol.Stop); @@ -121,6 +122,22 @@ namespace VDownload.Views.Home // Create cancellation token CancellationTokenSource = new CancellationTokenSource(); + // Scheduling + if (Schedule > 0) + { + DateTime ScheduledDateTime = DateTime.Now.AddMinutes(Schedule); + + // Set task status + TaskStatus = Core.Enums.TaskStatus.Scheduled; + + // Set state controls + HomeTaskPanelStateIcon.Source = (SvgImageSource)IconsRes["StateScheduledIcon"]; + HomeTaskPanelStateText.Text = $"{ResourceLoader.GetForCurrentView().GetString("HomeTaskPanelStateTextScheduled")} ({ScheduledDateTime.ToString(CultureInfo.InstalledUICulture.DateTimeFormat.ShortDatePattern)} {ScheduledDateTime.ToString(CultureInfo.InstalledUICulture.DateTimeFormat.ShortTimePattern)})"; + HomeTaskPanelStateProgressBar.Visibility = Visibility.Collapsed; + + while (DateTime.Now < ScheduledDateTime && !CancellationTokenSource.IsCancellationRequested) await Task.Delay(100); + } + // Set task status TaskStatus = Core.Enums.TaskStatus.Waiting; @@ -131,7 +148,7 @@ namespace VDownload.Views.Home HomeTaskPanelStateProgressBar.IsIndeterminate = true; // Wait in queue - await HomeMain.WaitInQueue(CancellationTokenSource.Token); + await HomeMain.WaitInQueue(delayWhenOnMeteredConnection, CancellationTokenSource.Token); if (!CancellationTokenSource.IsCancellationRequested) { // Set task status @@ -280,6 +297,9 @@ namespace VDownload.Views.Home HomeTaskPanelStateIcon.Source = (SvgImageSource)IconsRes["StateCancelledIcon"]; HomeTaskPanelStateText.Text = ResourceLoader.GetForCurrentView().GetString("HomeTaskPanelStateTextCancelled"); HomeTaskPanelStateProgressBar.Visibility = Visibility.Collapsed; + + // Change icon + HomeTaskPanelStartStopButton.Icon = new SymbolIcon(Symbol.Download); } } @@ -300,7 +320,25 @@ namespace VDownload.Views.Home private async void HomeTaskPanelStartStopButton_Click(object sender, RoutedEventArgs e) { if (TaskStatus == Core.Enums.TaskStatus.InProgress || TaskStatus == Core.Enums.TaskStatus.Waiting || TaskStatus == Core.Enums.TaskStatus.Scheduled) CancellationTokenSource.Cancel(); - else await Start(); + else + { + bool delay = (bool)Config.GetValue("delay_task_when_queued_task_starts_on_metered_network"); + ContentDialogResult dialogResult = await new ContentDialog + { + Title = ResourceLoader.GetForCurrentView().GetString("HomeTaskPanelTaskStartMeteredConnectionDialogTitle"), + Content = ResourceLoader.GetForCurrentView().GetString("HomeTaskPanelTaskStartMeteredConnectionDialogDescription"), + PrimaryButtonText = ResourceLoader.GetForCurrentView().GetString("HomeTaskPanelTaskStartMeteredConnectionDialogStartAndDelayText"), + SecondaryButtonText = ResourceLoader.GetForCurrentView().GetString("HomeTaskPanelTaskStartMeteredConnectionDialogStartWithoutDelayText"), + CloseButtonText = ResourceLoader.GetForCurrentView().GetString("HomeTaskPanelTaskStartMeteredConnectionDialogCancel"), + }.ShowAsync(); + switch (dialogResult) + { + case ContentDialogResult.Primary: delay = true; break; + case ContentDialogResult.Secondary: delay = false; break; + case ContentDialogResult.None: return; + } + await Start(delay); + } } // REMOVE BUTTON CLICKED diff --git a/VDownload/Views/Home/HomeTasksListPlaceholder.xaml b/VDownload/Views/Home/HomeTasksListPlaceholder.xaml new file mode 100644 index 0000000..8d96a25 --- /dev/null +++ b/VDownload/Views/Home/HomeTasksListPlaceholder.xaml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/VDownload/Views/Home/HomeTasksListPlaceholder.xaml.cs b/VDownload/Views/Home/HomeTasksListPlaceholder.xaml.cs new file mode 100644 index 0000000..38162eb --- /dev/null +++ b/VDownload/Views/Home/HomeTasksListPlaceholder.xaml.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Runtime.InteropServices.WindowsRuntime; +using Windows.Foundation; +using Windows.Foundation.Collections; +using Windows.UI.Xaml; +using Windows.UI.Xaml.Controls; +using Windows.UI.Xaml.Controls.Primitives; +using Windows.UI.Xaml.Data; +using Windows.UI.Xaml.Input; +using Windows.UI.Xaml.Media; +using Windows.UI.Xaml.Navigation; + +// The User Control item template is documented at https://go.microsoft.com/fwlink/?LinkId=234236 + +namespace VDownload.Views.Home +{ + public sealed partial class HomeTasksListPlaceholder : UserControl + { + public HomeTasksListPlaceholder() + { + this.InitializeComponent(); + } + } +} diff --git a/VDownload/Views/Home/HomeVideoAddingPanel.xaml b/VDownload/Views/Home/HomeVideoAddingPanel.xaml index a99f53a..465609b 100644 --- a/VDownload/Views/Home/HomeVideoAddingPanel.xaml +++ b/VDownload/Views/Home/HomeVideoAddingPanel.xaml @@ -8,9 +8,7 @@ xmlns:ex="using:Microsoft.Toolkit.Uwp.UI" xmlns:cc="using:VDownload.Controls" xmlns:muxc="using:Microsoft.UI.Xaml.Controls" - mc:Ignorable="d" - d:DesignHeight="300" - d:DesignWidth="400"> + mc:Ignorable="d">