diff --git a/VDownload.Core/VDownload.Core.Strings/Strings/en-US/CommonResources.resw b/VDownload.Core/VDownload.Core.Strings/Strings/en-US/CommonResources.resw new file mode 100644 index 0000000..2deb893 --- /dev/null +++ b/VDownload.Core/VDownload.Core.Strings/Strings/en-US/CommonResources.resw @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + You are trying to download a video using a metered connection. Do you want to continue? + + + Warning + + \ No newline at end of file diff --git a/VDownload.Core/VDownload.Core.ViewModels/Home/HomeDownloadsViewModel.cs b/VDownload.Core/VDownload.Core.ViewModels/Home/HomeDownloadsViewModel.cs index 1af5186..cf82579 100644 --- a/VDownload.Core/VDownload.Core.ViewModels/Home/HomeDownloadsViewModel.cs +++ b/VDownload.Core/VDownload.Core.ViewModels/Home/HomeDownloadsViewModel.cs @@ -1,5 +1,6 @@ using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.Input; +using CommunityToolkit.WinUI.Helpers; using System; using System.Collections.Generic; using System.Collections.ObjectModel; @@ -7,6 +8,8 @@ using System.Linq; using System.Text; using System.Threading.Tasks; using VDownload.Core.Tasks; +using VDownload.Services.UI.Dialogs; +using VDownload.Services.UI.StringResources; namespace VDownload.Core.ViewModels.Home { @@ -16,6 +19,9 @@ namespace VDownload.Core.ViewModels.Home protected readonly IDownloadTaskManager _tasksManager; + protected readonly IDialogsService _dialogsService; + protected readonly IStringResourcesService _stringResourcesService; + #endregion @@ -33,11 +39,14 @@ namespace VDownload.Core.ViewModels.Home #region CONSTRUCTORS - public HomeDownloadsViewModel(IDownloadTaskManager tasksManager) + public HomeDownloadsViewModel(IDownloadTaskManager tasksManager, IDialogsService dialogsService, IStringResourcesService stringResourcesService) { _tasksManager = tasksManager; _tasksManager.TaskCollectionChanged += Tasks_CollectionChanged; + _dialogsService = dialogsService; + _stringResourcesService = stringResourcesService; + _taskListIsEmpty = _tasksManager.Tasks.Count == 0; } @@ -59,7 +68,19 @@ namespace VDownload.Core.ViewModels.Home ]; if (idleStatuses.Contains(task.Status)) { - task.Enqueue(); + bool continueEnqueue = true; + if (NetworkHelper.Instance.ConnectionInformation.IsInternetOnMeteredConnection) + { + string title = _stringResourcesService.CommonResources.Get("StartAtMeteredConnectionDialogTitle"); + string message = _stringResourcesService.CommonResources.Get("StartAtMeteredConnectionDialogMessage"); + DialogResultYesNo result = await _dialogsService.ShowYesNo(title, message); + continueEnqueue = result == DialogResultYesNo.Yes; + } + + if (continueEnqueue) + { + task.Enqueue(); + } } else { diff --git a/VDownload.Core/VDownload.Core.ViewModels/Home/HomePlaylistViewModel.cs b/VDownload.Core/VDownload.Core.ViewModels/Home/HomePlaylistViewModel.cs index f509d70..b4ed119 100644 --- a/VDownload.Core/VDownload.Core.ViewModels/Home/HomePlaylistViewModel.cs +++ b/VDownload.Core/VDownload.Core.ViewModels/Home/HomePlaylistViewModel.cs @@ -17,6 +17,9 @@ using VDownload.Sources.Twitch.Configuration.Models; using SimpleToolkit.MVVM; using System.Text.RegularExpressions; using VDownload.Services.Utility.Filename; +using VDownload.Services.UI.Dialogs; +using VDownload.Services.UI.StringResources; +using CommunityToolkit.WinUI.Helpers; namespace VDownload.Core.ViewModels.Home { @@ -29,6 +32,8 @@ namespace VDownload.Core.ViewModels.Home protected readonly ISettingsService _settingsService; protected readonly IStoragePickerService _storagePickerService; protected readonly IFilenameService _filenameService; + protected readonly IDialogsService _dialogsService; + protected readonly IStringResourcesService _stringResourcesService; #endregion @@ -174,12 +179,14 @@ namespace VDownload.Core.ViewModels.Home #region CONSTRUCTORS - public HomePlaylistViewModel(IDownloadTaskManager tasksManager, ISettingsService settingsService, IStoragePickerService storagePickerService, IFilenameService filenameService) + public HomePlaylistViewModel(IDownloadTaskManager tasksManager, ISettingsService settingsService, IStoragePickerService storagePickerService, IFilenameService filenameService, IDialogsService dialogsService, IStringResourcesService stringResourcesService) { _tasksManager = tasksManager; _settingsService = settingsService; _storagePickerService = storagePickerService; _filenameService = filenameService; + _dialogsService = dialogsService; + _stringResourcesService = stringResourcesService; _removedVideos = new List(); @@ -271,10 +278,10 @@ namespace VDownload.Core.ViewModels.Home } [RelayCommand] - public void CreateTasksAndDownload() => CreateTasks(true); + public async Task CreateTasksAndDownload() => await CreateTasks(true); [RelayCommand] - public void CreateTasks() => CreateTasks(false); + public async Task CreateTasks() => await CreateTasks(false); #endregion @@ -282,8 +289,16 @@ namespace VDownload.Core.ViewModels.Home #region PRIVATE METHODS - protected void CreateTasks(bool download) + protected async Task CreateTasks(bool download) { + if (download && NetworkHelper.Instance.ConnectionInformation.IsInternetOnMeteredConnection) + { + string title = _stringResourcesService.CommonResources.Get("StartAtMeteredConnectionDialogTitle"); + string message = _stringResourcesService.CommonResources.Get("StartAtMeteredConnectionDialogMessage"); + DialogResultYesNo result = await _dialogsService.ShowYesNo(title, message); + download = result == DialogResultYesNo.Yes; + } + IEnumerable videos = Videos.Cast>() .Where(x => x.Value) .Select(x => x.Key); diff --git a/VDownload.Core/VDownload.Core.ViewModels/Home/HomeVideoViewModel.cs b/VDownload.Core/VDownload.Core.ViewModels/Home/HomeVideoViewModel.cs index be75bed..724bf32 100644 --- a/VDownload.Core/VDownload.Core.ViewModels/Home/HomeVideoViewModel.cs +++ b/VDownload.Core/VDownload.Core.ViewModels/Home/HomeVideoViewModel.cs @@ -1,5 +1,6 @@ using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.Input; +using CommunityToolkit.WinUI.Helpers; using System; using System.Collections.Generic; using System.Collections.ObjectModel; @@ -10,7 +11,9 @@ using System.Threading.Tasks; using VDownload.Core.Tasks; using VDownload.Models; using VDownload.Services.Data.Settings; +using VDownload.Services.UI.Dialogs; using VDownload.Services.UI.StoragePicker; +using VDownload.Services.UI.StringResources; using VDownload.Services.Utility.Filename; namespace VDownload.Core.ViewModels.Home @@ -24,6 +27,8 @@ namespace VDownload.Core.ViewModels.Home protected readonly ISettingsService _settingsService; protected readonly IStoragePickerService _storagePickerService; protected readonly IFilenameService _filenameService; + protected readonly IDialogsService _dialogsService; + protected readonly IStringResourcesService _stringResourcesService; #endregion @@ -91,12 +96,14 @@ namespace VDownload.Core.ViewModels.Home #region CONSTRUCTORS - public HomeVideoViewModel(IDownloadTaskManager tasksManager, ISettingsService settingsService, IStoragePickerService storagePickerService, IFilenameService filenameService) + public HomeVideoViewModel(IDownloadTaskManager tasksManager, ISettingsService settingsService, IStoragePickerService storagePickerService, IFilenameService filenameService, IDialogsService dialogsService, IStringResourcesService stringResourcesService) { _tasksManager = tasksManager; _settingsService = settingsService; _storagePickerService = storagePickerService; _filenameService = filenameService; + _dialogsService = dialogsService; + _stringResourcesService = stringResourcesService; } #endregion @@ -141,19 +148,10 @@ namespace VDownload.Core.ViewModels.Home } [RelayCommand] - public void CreateTask() - { - _tasksManager.AddTask(_video, BuildDownloadOptions()); - CloseRequested?.Invoke(this, EventArgs.Empty); - } + public async Task CreateTask() => await CreateTask(false); [RelayCommand] - public void CreateTaskAndDownload() - { - DownloadTask task = _tasksManager.AddTask(_video, BuildDownloadOptions()); - CloseRequested?.Invoke(this, EventArgs.Empty); - task.Enqueue(); - } + public async Task CreateTaskAndDownload() => await CreateTask(true); #endregion @@ -161,6 +159,24 @@ namespace VDownload.Core.ViewModels.Home #region PRIVATE METHODS + protected async Task CreateTask(bool download) + { + if (download && NetworkHelper.Instance.ConnectionInformation.IsInternetOnMeteredConnection) + { + string title = _stringResourcesService.CommonResources.Get("StartAtMeteredConnectionDialogTitle"); + string message = _stringResourcesService.CommonResources.Get("StartAtMeteredConnectionDialogMessage"); + DialogResultYesNo result = await _dialogsService.ShowYesNo(title, message); + download = result == DialogResultYesNo.Yes; + } + + DownloadTask task = _tasksManager.AddTask(_video, BuildDownloadOptions()); + CloseRequested?.Invoke(this, EventArgs.Empty); + if (download) + { + task.Enqueue(); + } + } + protected VideoDownloadOptions BuildDownloadOptions() { return new VideoDownloadOptions(Duration) diff --git a/VDownload.Core/VDownload.Core.ViewModels/Home/HomeViewModel.cs b/VDownload.Core/VDownload.Core.ViewModels/Home/HomeViewModel.cs index 2a32d43..a9b9d75 100644 --- a/VDownload.Core/VDownload.Core.ViewModels/Home/HomeViewModel.cs +++ b/VDownload.Core/VDownload.Core.ViewModels/Home/HomeViewModel.cs @@ -1,5 +1,6 @@ using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.Input; +using CommunityToolkit.WinUI.Helpers; using System; using System.Collections.Generic; using System.Linq; @@ -9,9 +10,11 @@ using VDownload.Core.Tasks; using VDownload.Models; using VDownload.Services.Data.Configuration; using VDownload.Services.Data.Settings; +using VDownload.Services.UI.Dialogs; using VDownload.Services.UI.StringResources; using VDownload.Sources; using VDownload.Sources.Common; +using VDownload.Sources.Twitch.Configuration.Models; namespace VDownload.Core.ViewModels.Home { @@ -49,6 +52,7 @@ namespace VDownload.Core.ViewModels.Home protected readonly ISettingsService _settingsService; protected readonly IStringResourcesService _stringResourcesService; protected readonly ISearchService _searchService; + protected readonly IDialogsService _dialogsService; protected readonly IDownloadTaskManager _downloadTaskManager; @@ -108,12 +112,13 @@ namespace VDownload.Core.ViewModels.Home #region CONSTRUCTORS - public HomeViewModel(IConfigurationService configurationService, ISettingsService settingsService, IStringResourcesService stringResourcesService, ISearchService searchService, IDownloadTaskManager downloadTaskManager, HomeVideoViewModel videoViewModel, HomePlaylistViewModel playlistViewModel) + public HomeViewModel(IConfigurationService configurationService, ISettingsService settingsService, IStringResourcesService stringResourcesService, ISearchService searchService, IDialogsService dialogsService, IDownloadTaskManager downloadTaskManager, HomeVideoViewModel videoViewModel, HomePlaylistViewModel playlistViewModel) { _configurationService = configurationService; _settingsService = settingsService; _stringResourcesService = stringResourcesService; _searchService = searchService; + _dialogsService = dialogsService; _downloadTaskManager = downloadTaskManager; @@ -258,8 +263,19 @@ namespace VDownload.Core.ViewModels.Home } [RelayCommand] - public void Download() + public async Task Download() { + if (_downloadTaskManager.Tasks.Count > 0 && NetworkHelper.Instance.ConnectionInformation.IsInternetOnMeteredConnection) + { + string title = _stringResourcesService.CommonResources.Get("StartAtMeteredConnectionDialogTitle"); + string message = _stringResourcesService.CommonResources.Get("StartAtMeteredConnectionDialogMessage"); + DialogResultYesNo result = await _dialogsService.ShowYesNo(title, message); + if (result == DialogResultYesNo.No) + { + return; + } + } + foreach (DownloadTask task in _downloadTaskManager.Tasks) { task.Enqueue(); diff --git a/VDownload.Core/VDownload.Core.ViewModels/VDownload.Core.ViewModels.csproj b/VDownload.Core/VDownload.Core.ViewModels/VDownload.Core.ViewModels.csproj index bf7da03..0b5a68b 100644 --- a/VDownload.Core/VDownload.Core.ViewModels/VDownload.Core.ViewModels.csproj +++ b/VDownload.Core/VDownload.Core.ViewModels/VDownload.Core.ViewModels.csproj @@ -10,6 +10,7 @@ + diff --git a/VDownload.Services/VDownload.Services.UI/VDownload.Services.UI.StringResources/StringResourcesService.cs b/VDownload.Services/VDownload.Services.UI/VDownload.Services.UI.StringResources/StringResourcesService.cs index 5fe0549..c064786 100644 --- a/VDownload.Services/VDownload.Services.UI/VDownload.Services.UI.StringResources/StringResourcesService.cs +++ b/VDownload.Services/VDownload.Services.UI/VDownload.Services.UI.StringResources/StringResourcesService.cs @@ -13,6 +13,7 @@ namespace VDownload.Services.UI.StringResources StringResources AuthenticationViewResources { get; } StringResources NotificationsResources { get; } StringResources SearchResources { get; } + StringResources CommonResources { get; } } @@ -37,6 +38,7 @@ namespace VDownload.Services.UI.StringResources public StringResources AuthenticationViewResources { get; protected set; } public StringResources NotificationsResources { get; protected set; } public StringResources SearchResources { get; protected set; } + public StringResources CommonResources { get; protected set; } #endregion @@ -56,6 +58,7 @@ namespace VDownload.Services.UI.StringResources AuthenticationViewResources = BuildResource("AuthenticationViewResources"); NotificationsResources = BuildResource("NotificationsResources"); SearchResources = BuildResource("SearchResources"); + CommonResources = BuildResource("CommonResources"); } #endregion diff --git a/VDownload.Services/VDownload.Services.Utility/VDownload.Services.Utility.Network/NetworkService.cs b/VDownload.Services/VDownload.Services.Utility/VDownload.Services.Utility.Network/NetworkService.cs new file mode 100644 index 0000000..313d3f2 --- /dev/null +++ b/VDownload.Services/VDownload.Services.Utility/VDownload.Services.Utility.Network/NetworkService.cs @@ -0,0 +1,36 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Windows.Networking.Connectivity; + +namespace VDownload.Services.Utility.Network +{ + public interface INetworkService + { + bool IsMetered { get; } + } + + + + public class NetworkService : INetworkService + { + #region FIELDS + + protected readonly IEnumerable _notMeteredTypes = [ + NetworkCostType.Unknown, + NetworkCostType.Unrestricted + ]; + + #endregion + + + + #region PROPERTIES + + public bool IsMetered => !_notMeteredTypes.Contains(NetworkInformation.GetInternetConnectionProfile().GetConnectionCost().NetworkCostType); + + #endregion + } +} diff --git a/VDownload.Services/VDownload.Services.Utility/VDownload.Services.Utility.Network/VDownload.Services.Utility.Network.csproj b/VDownload.Services/VDownload.Services.Utility/VDownload.Services.Utility.Network/VDownload.Services.Utility.Network.csproj new file mode 100644 index 0000000..3fe9a7d --- /dev/null +++ b/VDownload.Services/VDownload.Services.Utility/VDownload.Services.Utility.Network/VDownload.Services.Utility.Network.csproj @@ -0,0 +1,13 @@ + + + + net8.0 + enable + enable + + + + + + + diff --git a/VDownload.sln b/VDownload.sln index 93ba10b..f4a954f 100644 --- a/VDownload.sln +++ b/VDownload.sln @@ -69,7 +69,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "VDownload.Core.Tasks", "VDo EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "VDownload.Services.Utility.FFmpeg", "VDownload.Services\VDownload.Services.Utility\VDownload.Services.Utility.FFmpeg\VDownload.Services.Utility.FFmpeg.csproj", "{A3166F8A-ECAD-4D4B-9BE3-96FEC799B27B}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VDownload.Services.Utility.Filename", "VDownload.Services\VDownload.Services.Utility\VDownload.Services.Utility.Filename\VDownload.Services.Utility.Filename.csproj", "{4647EFB5-A206-4F47-976D-BAED11B52579}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "VDownload.Services.Utility.Filename", "VDownload.Services\VDownload.Services.Utility\VDownload.Services.Utility.Filename\VDownload.Services.Utility.Filename.csproj", "{4647EFB5-A206-4F47-976D-BAED11B52579}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution