diff --git a/VDownload.Core/VDownload.Core.Strings/Strings/en-US/HomePlaylistViewResources.resw b/VDownload.Core/VDownload.Core.Strings/Strings/en-US/HomePlaylistViewResources.resw
new file mode 100644
index 0000000..874d57f
--- /dev/null
+++ b/VDownload.Core/VDownload.Core.Strings/Strings/en-US/HomePlaylistViewResources.resw
@@ -0,0 +1,207 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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
+
+
+ Selected directory will be applied to all videos in playlist
+
+
+ Create download tasks and start
+
+
+ Create download tasks
+
+
+ Directory
+
+
+ Browse
+
+
+ Filename
+
+
+ File options
+
+
+ If original video is not in selected type, it will be converted
+
+
+ File type
+
+
+ Author
+
+
+ Enter regular expression
+
+
+ Date
+
+
+ Duration
+
+
+ Restore
+
+
+ Removed
+
+
+ Title
+
+
+ Enter regular expression
+
+
+ Views
+
+
+ Filter
+
+
+ Hidden:
+
+
+ Media options
+
+
+ Only audio
+
+
+ Only video
+
+
+ Original
+
+
+ Media type
+
+
+ Quality
+
+
+ End at
+
+
+ Trim
+
+
+ Start at
+
+
\ No newline at end of file
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 bd7293e..15b82f1 100644
--- a/VDownload.Core/VDownload.Core.Tasks/DownloadTask.cs
+++ b/VDownload.Core/VDownload.Core.Tasks/DownloadTask.cs
@@ -140,7 +140,7 @@ namespace VDownload.Core.Tasks
await _settingsService.Load();
- string tempDirectory = $"{_settingsService.Data.Common.Temp.Directory}\\{_configurationService.Common.Path.Temp.TasksDirectory}\\{_id}";
+ string tempDirectory = $"{_settingsService.Data.Common.Temp.Directory}\\{_configurationService.Common.Path.Temp.TasksDirectory}\\{Id}";
Directory.CreateDirectory(tempDirectory);
List content = new List()
diff --git a/VDownload.Core/VDownload.Core.ViewModels/Home/Helpers/VideoViewModel.cs b/VDownload.Core/VDownload.Core.ViewModels/Home/Helpers/VideoViewModel.cs
new file mode 100644
index 0000000..513cb3e
--- /dev/null
+++ b/VDownload.Core/VDownload.Core.ViewModels/Home/Helpers/VideoViewModel.cs
@@ -0,0 +1,146 @@
+using CommunityToolkit.Mvvm.ComponentModel;
+using CommunityToolkit.Mvvm.Input;
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using VDownload.Models;
+using VDownload.Services.Data.Settings;
+using VDownload.Services.UI.StoragePicker;
+
+namespace VDownload.Core.ViewModels.Home.Helpers
+{
+ public partial class VideoViewModel : ObservableObject
+ {
+ #region SERVICES
+
+ protected readonly ISettingsService _settingsService;
+ protected readonly IStoragePickerService _storagePickerService;
+
+ #endregion
+
+
+
+ #region PROPERTIES
+
+ [ObservableProperty]
+ protected Uri _thumbnailUrl;
+
+ [ObservableProperty]
+ protected string _title;
+
+ [ObservableProperty]
+ protected string _author;
+
+ [ObservableProperty]
+ protected DateTime _publishDate;
+
+ [ObservableProperty]
+ protected TimeSpan _duration;
+
+ [ObservableProperty]
+ protected long _views;
+
+
+ [ObservableProperty]
+ protected ObservableCollection _streams;
+
+ [ObservableProperty]
+ protected VideoStream _selectedStream;
+
+ [ObservableProperty]
+ protected MediaType _mediaType;
+
+ [ObservableProperty]
+ protected TimeSpan _trimStart;
+
+ [ObservableProperty]
+ protected TimeSpan _trimEnd;
+
+ [ObservableProperty]
+ protected string _directoryPath;
+
+ [ObservableProperty]
+ protected string _filename;
+
+ [ObservableProperty]
+ protected VideoExtension _videoExtension;
+
+ [ObservableProperty]
+ protected AudioExtension _audioExtension;
+
+ public Video Video { get; protected set; }
+
+ #endregion
+
+
+
+ #region CONSTRUCTORS
+
+ public VideoViewModel(Video video, ISettingsService settingsService, IStoragePickerService storagePickerService)
+ {
+ _settingsService = settingsService;
+ _storagePickerService = storagePickerService;
+
+ Video = video;
+
+ ThumbnailUrl = video.ThumbnailUrl;
+ Title = video.Title;
+ Author = video.Author;
+ PublishDate = video.PublishDate;
+ Duration = video.Duration;
+ Views = video.Views;
+
+ Streams = [.. video.Streams];
+ SelectedStream = Streams[0];
+ MediaType = _settingsService.Data.Common.Tasks.DefaultMediaType;
+ TrimStart = TimeSpan.Zero;
+ TrimEnd = Duration;
+ DirectoryPath = _settingsService.Data.Common.Tasks.DefaultOutputDirectory;
+ Filename = Title.Length > 50 ? Title.Substring(0, 50) : Title;
+ VideoExtension = _settingsService.Data.Common.Tasks.DefaultVideoExtension;
+ AudioExtension = _settingsService.Data.Common.Tasks.DefaultAudioExtension;
+ }
+
+ #endregion
+
+
+
+ #region PUBLIC METHODS
+
+ public VideoDownloadOptions BuildDownloadOptions()
+ {
+ return new VideoDownloadOptions(Duration)
+ {
+ MediaType = this.MediaType,
+ SelectedStream = this.SelectedStream,
+ TrimStart = this.TrimStart,
+ TrimEnd = this.TrimEnd,
+ Directory = this.DirectoryPath,
+ Filename = string.Join("_", this.Filename.Split(Path.GetInvalidFileNameChars())),
+ Extension = (this.MediaType == MediaType.OnlyAudio ? this.AudioExtension.ToString() : this.VideoExtension.ToString()).ToLower(),
+ };
+ }
+
+ #endregion
+
+
+
+ #region COMMANDS
+
+ [RelayCommand]
+ public async Task Browse()
+ {
+ string? newDirectory = await _storagePickerService.OpenDirectory();
+ if (newDirectory is not null)
+ {
+ this.DirectoryPath = newDirectory;
+ }
+ }
+
+ #endregion
+ }
+}
diff --git a/VDownload.Core/VDownload.Core.ViewModels/Home/HomePlaylistViewModel.cs b/VDownload.Core/VDownload.Core.ViewModels/Home/HomePlaylistViewModel.cs
index de45d65..921901e 100644
--- a/VDownload.Core/VDownload.Core.ViewModels/Home/HomePlaylistViewModel.cs
+++ b/VDownload.Core/VDownload.Core.ViewModels/Home/HomePlaylistViewModel.cs
@@ -1,12 +1,21 @@
using CommunityToolkit.Mvvm.ComponentModel;
+using CommunityToolkit.Mvvm.Input;
using System;
using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
+using VDownload.Core.Tasks;
+using VDownload.Core.ViewModels.Home.Helpers;
using VDownload.Models;
+using VDownload.Services.Data.Settings;
+using VDownload.Services.UI.StoragePicker;
using VDownload.Sources.Twitch.Configuration.Models;
+using SimpleToolkit.MVVM;
+using System.Text.RegularExpressions;
namespace VDownload.Core.ViewModels.Home
{
@@ -14,7 +23,10 @@ namespace VDownload.Core.ViewModels.Home
{
#region SERVICES
+ protected readonly IDownloadTaskManager _tasksManager;
+ protected readonly ISettingsService _settingsService;
+ protected readonly IStoragePickerService _storagePickerService;
#endregion
@@ -22,7 +34,9 @@ namespace VDownload.Core.ViewModels.Home
#region FIELDS
+ protected Playlist _playlist;
+ protected List _removedVideos;
#endregion
@@ -33,14 +47,140 @@ namespace VDownload.Core.ViewModels.Home
[ObservableProperty]
protected string _name;
+ [ObservableProperty]
+ protected ObservableDictionary _videos;
+
+ [ObservableProperty]
+ protected int _removedCount;
+
+ [ObservableProperty]
+ protected int _hiddenCount;
+
+ [ObservableProperty]
+ protected bool _isSomethingHidden;
+
+ public string TitleFilter
+ {
+ get => _titleFilter;
+ set
+ {
+ SetProperty(ref _titleFilter, value, nameof(TitleFilter));
+ UpdateFilter();
+ }
+ }
+ protected string _titleFilter;
+
+ public string AuthorFilter
+ {
+ get => _authorFilter;
+ set
+ {
+ SetProperty(ref _authorFilter, value, nameof(AuthorFilter));
+ UpdateFilter();
+ }
+ }
+ protected string _authorFilter;
+
+ public long MinViewsFilter
+ {
+ get => _minViewsFilter;
+ set
+ {
+ SetProperty(ref _minViewsFilter, value, nameof(MinViewsFilter));
+ UpdateFilter();
+ }
+ }
+ protected long _minViewsFilter;
+
+ public long MaxViewsFilter
+ {
+ get => _maxViewsFilter;
+ set
+ {
+ SetProperty(ref _maxViewsFilter, value, nameof(MaxViewsFilter));
+ UpdateFilter();
+ }
+ }
+ protected long _maxViewsFilter;
+
+ [ObservableProperty]
+ protected long _minViews;
+
+ [ObservableProperty]
+ protected long _maxViews;
+
+ public DateTimeOffset MinDateFilter
+ {
+ get => _minDateFilter;
+ set
+ {
+ SetProperty(ref _minDateFilter, value, nameof(MinDateFilter));
+ UpdateFilter();
+ }
+ }
+ protected DateTimeOffset _minDateFilter;
+
+ public DateTimeOffset MaxDateFilter
+ {
+ get => _maxDateFilter;
+ set
+ {
+ SetProperty(ref _maxDateFilter, value, nameof(MaxDateFilter));
+ UpdateFilter();
+ }
+ }
+ protected DateTimeOffset _maxDateFilter;
+
+ [ObservableProperty]
+ protected DateTimeOffset _minDate;
+
+ [ObservableProperty]
+ protected DateTimeOffset _maxDate;
+
+
+ public TimeSpan MinDurationFilter
+ {
+ get => _minDurationFilter;
+ set
+ {
+ SetProperty(ref _minDurationFilter, value, nameof(MinDurationFilter));
+ UpdateFilter();
+ }
+ }
+ protected TimeSpan _minDurationFilter;
+
+ public TimeSpan MaxDurationFilter
+ {
+ get => _maxDurationFilter;
+ set
+ {
+ SetProperty(ref _maxDurationFilter, value, nameof(MaxDurationFilter));
+ UpdateFilter();
+ }
+ }
+ protected TimeSpan _maxDurationFilter;
+
+ [ObservableProperty]
+ protected TimeSpan _minDuration;
+
+ [ObservableProperty]
+ protected TimeSpan _maxDuration;
+
#endregion
#region CONSTRUCTORS
- public HomePlaylistViewModel()
- {
+ public HomePlaylistViewModel(IDownloadTaskManager tasksManager, ISettingsService settingsService, IStoragePickerService storagePickerService)
+ {
+ _tasksManager = tasksManager;
+ _settingsService = settingsService;
+ _storagePickerService = storagePickerService;
+
+ _removedVideos = new List();
+
+ _videos = new ObservableDictionary();
}
#endregion
@@ -49,9 +189,41 @@ namespace VDownload.Core.ViewModels.Home
#region PUBLIC METHODS
- public async Task LoadPlaylist(Playlist playlist)
+ public void LoadPlaylist(Playlist playlist)
{
- Name = playlist.Name;
+ _playlist = playlist;
+ ParallelQuery