diff --git a/VDownload.Core/VDownload.Core.Strings/Strings/en-US/CommonResources.resw b/VDownload.Core/VDownload.Core.Strings/Strings/en-US/CommonResources.resw index 2deb893..9632010 100644 --- a/VDownload.Core/VDownload.Core.Strings/Strings/en-US/CommonResources.resw +++ b/VDownload.Core/VDownload.Core.Strings/Strings/en-US/CommonResources.resw @@ -117,6 +117,42 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + Only audio + + + Only video + + + Original + + + Fast + + + Faster + + + Medium + + + Slow + + + Slower + + + Super fast + + + Ultra fast + + + Very fast + + + Very slow + You are trying to download a video using a metered connection. Do you want to continue? diff --git a/VDownload.Core/VDownload.Core.Strings/Strings/en-US/HomeDownloadsViewResources.resw b/VDownload.Core/VDownload.Core.Strings/Strings/en-US/HomeDownloadsViewResources.resw index 3867e3d..f6b9601 100644 --- a/VDownload.Core/VDownload.Core.Strings/Strings/en-US/HomeDownloadsViewResources.resw +++ b/VDownload.Core/VDownload.Core.Strings/Strings/en-US/HomeDownloadsViewResources.resw @@ -117,15 +117,6 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - Only audio - - - Only video - - - Original - Cancelled diff --git a/VDownload.Core/VDownload.Core.Strings/Strings/en-US/HomePlaylistViewResources.resw b/VDownload.Core/VDownload.Core.Strings/Strings/en-US/HomePlaylistViewResources.resw index 874d57f..512a21d 100644 --- a/VDownload.Core/VDownload.Core.Strings/Strings/en-US/HomePlaylistViewResources.resw +++ b/VDownload.Core/VDownload.Core.Strings/Strings/en-US/HomePlaylistViewResources.resw @@ -180,15 +180,6 @@ Media options - - Only audio - - - Only video - - - Original - Media type diff --git a/VDownload.Core/VDownload.Core.Strings/Strings/en-US/HomeVideoViewResources.resw b/VDownload.Core/VDownload.Core.Strings/Strings/en-US/HomeVideoViewResources.resw index b8b8cf7..5e860a6 100644 --- a/VDownload.Core/VDownload.Core.Strings/Strings/en-US/HomeVideoViewResources.resw +++ b/VDownload.Core/VDownload.Core.Strings/Strings/en-US/HomeVideoViewResources.resw @@ -144,15 +144,6 @@ Media options - - Only audio - - - Only video - - - Original - Media type diff --git a/VDownload.Core/VDownload.Core.Strings/Strings/en-US/SettingsViewResources.resw b/VDownload.Core/VDownload.Core.Strings/Strings/en-US/SettingsViewResources.resw new file mode 100644 index 0000000..afeb536 --- /dev/null +++ b/VDownload.Core/VDownload.Core.Strings/Strings/en-US/SettingsViewResources.resw @@ -0,0 +1,231 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 + + + Settings + + + Notifications + + + Show notifications when task ended successfully + + + Show notifications when task ended unsuccessfully + + + FFmpeg location + + + Browse + + + Processing + + + Speed + + + Use hardware acceleration + + + Use multithreading + + + Restore settings to default + + + Searching + + + 0 = Get all + + + Default number of videos fetched from playlist + + + Audio extension + + + Default media options + + + Default output directory + + + Browse + + + Filename template + + + Tasks + + + Media type + + + Maximum number of tasks running in parallel + + + Otherwise, default directory defined below (after expanding) will be used + + + Save last output directory + + + Video extension + + + Delete task's temporary files when an error occurs + + + Temporary files location + + + Browse + + + Temporary files + + + Twitch + + + Retry when downloading single VOD chunk fails + + + Number of retries + + + Time between fail and retry (in miliseconds) + + + WARNING: Too many chunks downloaded at once may cause performance problems + + + Maximum number of VOD chunks downloaded in parallel + + + Only chunks from trim start to trim end range will be downloaded + + + VOD passive trimming + + \ No newline at end of file diff --git a/VDownload.Core/VDownload.Core.ViewModels/Home/HomeViewModel.cs b/VDownload.Core/VDownload.Core.ViewModels/Home/HomeViewModel.cs index a9b9d75..9d17d50 100644 --- a/VDownload.Core/VDownload.Core.ViewModels/Home/HomeViewModel.cs +++ b/VDownload.Core/VDownload.Core.ViewModels/Home/HomeViewModel.cs @@ -149,7 +149,7 @@ namespace VDownload.Core.ViewModels.Home OptionBarPlaylistSearchButtonChecked = false; OptionBarSearchNotPending = true; OptionBarVideoSearchTBValue = string.Empty; - OptionBarPlaylistSearchNBValue = _settingsService.Data.Common.MaxNumberOfVideosToGetFromPlaylist; + OptionBarPlaylistSearchNBValue = _settingsService.Data.Common.Searching.MaxNumberOfVideosToGetFromPlaylist; OptionBarPlaylistSearchTBValue = string.Empty; } diff --git a/VDownload.Core/VDownload.Core.ViewModels/Settings/SettingsViewModel.cs b/VDownload.Core/VDownload.Core.ViewModels/Settings/SettingsViewModel.cs index 3d57811..9ea848e 100644 --- a/VDownload.Core/VDownload.Core.ViewModels/Settings/SettingsViewModel.cs +++ b/VDownload.Core/VDownload.Core.ViewModels/Settings/SettingsViewModel.cs @@ -1,12 +1,238 @@ -using System; +using CommunityToolkit.Mvvm.ComponentModel; +using CommunityToolkit.Mvvm.Input; +using System; using System.Collections.Generic; using System.Linq; +using System.Reflection; using System.Text; using System.Threading.Tasks; +using VDownload.Models; +using VDownload.Services.Data.Configuration; +using VDownload.Services.Data.Settings; +using VDownload.Services.UI.StoragePicker; +using VDownload.Services.UI.StringResources; namespace VDownload.Core.ViewModels.Settings { - public class SettingsViewModel + public partial class SettingsViewModel : ObservableObject { + #region SERVICES + + protected readonly ISettingsService _settingsService; + protected readonly IConfigurationService _configurationService; + protected readonly IStringResourcesService _stringResourcesService; + protected readonly IStoragePickerService _storagePickerService; + + #endregion + + + + #region PROPERTIES + + public int SearchingPlaylistCount + { + get => _settingsService.Data.Common.Searching.MaxNumberOfVideosToGetFromPlaylist; + set => SetProperty(_settingsService.Data.Common.Searching.MaxNumberOfVideosToGetFromPlaylist, value, _settingsService.Data.Common.Searching, (u, n) => u.MaxNumberOfVideosToGetFromPlaylist = n); + } + + public int TasksRunningTasks + { + get => _settingsService.Data.Common.Tasks.MaxNumberOfRunningTasks; + set => SetProperty(_settingsService.Data.Common.Tasks.MaxNumberOfRunningTasks, value, _settingsService.Data.Common.Tasks, (u, n) => u.MaxNumberOfRunningTasks = n); + } + + public MediaType TasksMediaType + { + get => _settingsService.Data.Common.Tasks.DefaultMediaType; + set => SetProperty(_settingsService.Data.Common.Tasks.DefaultMediaType, value, _settingsService.Data.Common.Tasks, (u, n) => u.DefaultMediaType = n); + } + + public VideoExtension TasksVideoExtension + { + get => _settingsService.Data.Common.Tasks.DefaultVideoExtension; + set => SetProperty(_settingsService.Data.Common.Tasks.DefaultVideoExtension, value, _settingsService.Data.Common.Tasks, (u, n) => u.DefaultVideoExtension = n); + } + + public AudioExtension TasksAudioExtension + { + get => _settingsService.Data.Common.Tasks.DefaultAudioExtension; + set => SetProperty(_settingsService.Data.Common.Tasks.DefaultAudioExtension, value, _settingsService.Data.Common.Tasks, (u, n) => u.DefaultAudioExtension = n); + } + + public string TasksFilenameTemplate + { + get => _settingsService.Data.Common.Tasks.FilenameTemplate; + set => SetProperty(_settingsService.Data.Common.Tasks.FilenameTemplate, value, _settingsService.Data.Common.Tasks, (u, n) => u.FilenameTemplate = n); + } + + public bool TasksSaveLastOutputDirectory + { + get => _settingsService.Data.Common.Tasks.SaveLastOutputDirectory; + set => SetProperty(_settingsService.Data.Common.Tasks.SaveLastOutputDirectory, value, _settingsService.Data.Common.Tasks, (u, n) => u.SaveLastOutputDirectory = n); + } + + public string TasksDefaultOutputDirectory + { + get => _settingsService.Data.Common.Tasks.DefaultOutputDirectory; + set => SetProperty(_settingsService.Data.Common.Tasks.DefaultOutputDirectory, value, _settingsService.Data.Common.Tasks, (u, n) => u.DefaultOutputDirectory = n); + } + + public string ProcessingFFmpegLocation + { + get => _settingsService.Data.Common.Processing.FFmpegLocation; + set => SetProperty(_settingsService.Data.Common.Processing.FFmpegLocation, value, _settingsService.Data.Common.Processing, (u, n) => u.FFmpegLocation = n); + } + + public bool ProcessingUseHardwareAcceleration + { + get => _settingsService.Data.Common.Processing.UseHardwareAcceleration; + set => SetProperty(_settingsService.Data.Common.Processing.UseHardwareAcceleration, value, _settingsService.Data.Common.Processing, (u, n) => u.UseHardwareAcceleration = n); + } + + public bool ProcessingUseMultithreading + { + get => _settingsService.Data.Common.Processing.UseMultithreading; + set => SetProperty(_settingsService.Data.Common.Processing.UseMultithreading, value, _settingsService.Data.Common.Processing, (u, n) => u.UseMultithreading = n); + } + + public ProcessingSpeed ProcessingSpeed + { + get => _settingsService.Data.Common.Processing.Speed; + set => SetProperty(_settingsService.Data.Common.Processing.Speed, value, _settingsService.Data.Common.Processing, (u, n) => u.Speed = n); + } + + public bool NotificationsOnSuccessful + { + get => _settingsService.Data.Common.Notifications.OnSuccessful; + set => SetProperty(_settingsService.Data.Common.Notifications.OnSuccessful, value, _settingsService.Data.Common.Notifications, (u, n) => u.OnSuccessful = n); + } + + public bool NotificationsOnUnsuccessful + { + get => _settingsService.Data.Common.Notifications.OnUnsuccessful; + set => SetProperty(_settingsService.Data.Common.Notifications.OnUnsuccessful, value, _settingsService.Data.Common.Notifications, (u, n) => u.OnUnsuccessful = n); + } + + public string TempDirectory + { + get => _settingsService.Data.Common.Temp.Directory; + set => SetProperty(_settingsService.Data.Common.Temp.Directory, value, _settingsService.Data.Common.Temp, (u, n) => u.Directory = n); + } + + public bool TempDeleteOnFail + { + get => _settingsService.Data.Common.Temp.DeleteOnError; + set => SetProperty(_settingsService.Data.Common.Temp.DeleteOnError, value, _settingsService.Data.Common.Temp, (u, n) => u.DeleteOnError = n); + } + + public bool TwitchVodPassiveTrimming + { + get => _settingsService.Data.Twitch.Vod.PassiveTrimming; + set => SetProperty(_settingsService.Data.Twitch.Vod.PassiveTrimming, value, _settingsService.Data.Twitch.Vod, (u, n) => u.PassiveTrimming = n); + } + + public int TwitchVodParallelDownloads + { + get => _settingsService.Data.Twitch.Vod.MaxNumberOfParallelDownloads; + set => SetProperty(_settingsService.Data.Twitch.Vod.MaxNumberOfParallelDownloads, value, _settingsService.Data.Twitch.Vod, (u, n) => u.MaxNumberOfParallelDownloads = n); + } + + public bool TwitchVodChunkDownloadingErrorRetry + { + get => _settingsService.Data.Twitch.Vod.ChunkDownloadingError.Retry; + set => SetProperty(_settingsService.Data.Twitch.Vod.ChunkDownloadingError.Retry, value, _settingsService.Data.Twitch.Vod.ChunkDownloadingError, (u, n) => u.Retry = n); + } + + public int TwitchVodChunkDownloadingErrorRetryCount + { + get => _settingsService.Data.Twitch.Vod.ChunkDownloadingError.RetriesCount; + set => SetProperty(_settingsService.Data.Twitch.Vod.ChunkDownloadingError.RetriesCount, value, _settingsService.Data.Twitch.Vod.ChunkDownloadingError, (u, n) => u.RetriesCount = n); + } + + public int TwitchVodChunkDownloadingErrorRetryDelay + { + get => _settingsService.Data.Twitch.Vod.ChunkDownloadingError.RetryDelay; + set => SetProperty(_settingsService.Data.Twitch.Vod.ChunkDownloadingError.RetryDelay, value, _settingsService.Data.Twitch.Vod.ChunkDownloadingError, (u, n) => u.RetryDelay = n); + } + + [ObservableProperty] + protected string _tasksFilenameTemplateTooltip; + + #endregion + + + + #region CONSTRUCTORS + + public SettingsViewModel(ISettingsService settingsService, IConfigurationService configurationService, IStringResourcesService stringResourcesService, IStoragePickerService storagePickerService) + { + _settingsService = settingsService; + _configurationService = configurationService; + _stringResourcesService = stringResourcesService; + _storagePickerService = storagePickerService; + + base.PropertyChanged += PropertyChangedEventHandler; + + _tasksFilenameTemplateTooltip = string.Join('\n', _configurationService.Common.FilenameTemplates.Select(x => _stringResourcesService.FilenameTemplateResources.Get(x.Name))); + } + + #endregion + + + + #region COMMANDS + + [RelayCommand] + public async Task BrowseTasksDefaultOutputDirectory() + { + string? newDirectory = await _storagePickerService.OpenDirectory(); + if (newDirectory is not null) + { + this.TasksDefaultOutputDirectory = newDirectory; + } + } + + [RelayCommand] + public async Task BrowseTempDirectory() + { + string? newDirectory = await _storagePickerService.OpenDirectory(); + if (newDirectory is not null) + { + this.TempDirectory = newDirectory; + } + } + + [RelayCommand] + public async Task BrowseProcessingFFmpegLocation() + { + string? newDirectory = await _storagePickerService.OpenDirectory(); + if (newDirectory is not null) + { + this.ProcessingFFmpegLocation = newDirectory; + } + } + + [RelayCommand] + public async Task RestoreToDefault() + { + await _settingsService.Restore(); + foreach (PropertyInfo property in this.GetType().GetProperties()) + { + base.OnPropertyChanged(property.Name); + } + } + + #endregion + + + + #region PRIVATE METHODS + + private async void PropertyChangedEventHandler(object sender, System.ComponentModel.PropertyChangedEventArgs e) + { + await _settingsService.Save(); + } + + #endregion } } diff --git a/VDownload.Core/VDownload.Core.Views/BaseWindow.xaml.cs b/VDownload.Core/VDownload.Core.Views/BaseWindow.xaml.cs index c6dcf97..ade7603 100644 --- a/VDownload.Core/VDownload.Core.Views/BaseWindow.xaml.cs +++ b/VDownload.Core/VDownload.Core.Views/BaseWindow.xaml.cs @@ -1,3 +1,5 @@ +using Microsoft.UI; +using Microsoft.UI.Windowing; using Microsoft.UI.Xaml; using Microsoft.UI.Xaml.Controls; using Microsoft.UI.Xaml.Controls.Primitives; @@ -39,6 +41,7 @@ namespace VDownload.Core.Views public BaseWindow(BaseViewModel viewModel) { this.InitializeComponent(); + this.Activated += BaseWindow_Activated; this.ExtendsContentIntoTitleBar = true; this.SetTitleBar(this.AppTitleBar); @@ -54,6 +57,14 @@ namespace VDownload.Core.Views private void Root_Loaded(object sender, RoutedEventArgs e) => RootLoaded?.Invoke(this, EventArgs.Empty); + private void BaseWindow_Activated(object sender, WindowActivatedEventArgs args) + { + IntPtr windowHandle = WinRT.Interop.WindowNative.GetWindowHandle(this); + WindowId windowId = Win32Interop.GetWindowIdFromWindow(windowHandle); + AppWindow appWindow = AppWindow.GetFromWindowId(windowId); + appWindow.SetIcon(@"Assets\Logo\Logo.ico"); + } + #endregion } } diff --git a/VDownload.Core/VDownload.Core.Views/Home/HomeDownloadsView.xaml b/VDownload.Core/VDownload.Core.Views/Home/HomeDownloadsView.xaml index 911e767..b2a9a6d 100644 --- a/VDownload.Core/VDownload.Core.Views/Home/HomeDownloadsView.xaml +++ b/VDownload.Core/VDownload.Core.Views/Home/HomeDownloadsView.xaml @@ -98,15 +98,15 @@ Orientation="Horizontal"> - - - diff --git a/VDownload.Core/VDownload.Core.Views/Home/HomePlaylistView.xaml b/VDownload.Core/VDownload.Core.Views/Home/HomePlaylistView.xaml index ebfbe2f..9b13f73 100644 --- a/VDownload.Core/VDownload.Core.Views/Home/HomePlaylistView.xaml +++ b/VDownload.Core/VDownload.Core.Views/Home/HomePlaylistView.xaml @@ -311,13 +311,13 @@ - + - + - + diff --git a/VDownload.Core/VDownload.Core.Views/Home/HomeVideoView.xaml b/VDownload.Core/VDownload.Core.Views/Home/HomeVideoView.xaml index 73832dc..aff7cb3 100644 --- a/VDownload.Core/VDownload.Core.Views/Home/HomeVideoView.xaml +++ b/VDownload.Core/VDownload.Core.Views/Home/HomeVideoView.xaml @@ -111,13 +111,13 @@ - + - + - + diff --git a/VDownload.Core/VDownload.Core.Views/Settings/SettingsView.xaml b/VDownload.Core/VDownload.Core.Views/Settings/SettingsView.xaml index 1b000e8..8fcb718 100644 --- a/VDownload.Core/VDownload.Core.Views/Settings/SettingsView.xaml +++ b/VDownload.Core/VDownload.Core.Views/Settings/SettingsView.xaml @@ -6,10 +6,293 @@ xmlns:local="using:VDownload.Core.Views.Settings" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" + xmlns:ctuc="using:CommunityToolkit.WinUI.UI.Controls" + xmlns:ctc="using:CommunityToolkit.WinUI.Controls" + xmlns:ct="using:CommunityToolkit.WinUI" + xmlns:i="using:Microsoft.Xaml.Interactivity" + xmlns:ic="using:Microsoft.Xaml.Interactions.Core" + xmlns:m="using:VDownload.Models" mc:Ignorable="d" - Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"> + Background="{ThemeResource ViewBackgroundColor}"> - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +