changes
This commit is contained in:
@@ -9,8 +9,8 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.WindowsAppSDK" Version="1.4.230913002" />
|
||||
<PackageReference Include="Microsoft.Windows.SDK.BuildTools" Version="10.0.22621.755" />
|
||||
<PackageReference Include="Microsoft.WindowsAppSDK" Version="1.4.240211001" />
|
||||
<PackageReference Include="Microsoft.Windows.SDK.BuildTools" Version="10.0.22621.2428" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -140,7 +140,7 @@ namespace VDownload.Core.Tasks
|
||||
|
||||
await _settingsService.Load();
|
||||
|
||||
string tempDirectory = $"{_settingsService.Data.Common.TempDirectory}\\{_configurationService.Common.Path.Temp.TasksDirectory}\\{_id}";
|
||||
string tempDirectory = $"{_settingsService.Data.Common.Temp.Directory}\\{_configurationService.Common.Path.Temp.TasksDirectory}\\{_id}";
|
||||
Directory.CreateDirectory(tempDirectory);
|
||||
|
||||
List<string> content = new List<string>()
|
||||
@@ -211,7 +211,7 @@ namespace VDownload.Core.Tasks
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (Status != DownloadTaskStatus.EndedUnsuccessfully || _settingsService.Data.Common.DeleteTempOnError)
|
||||
if (Status != DownloadTaskStatus.EndedUnsuccessfully || _settingsService.Data.Common.Temp.DeleteOnError)
|
||||
{
|
||||
Directory.Delete(tempDirectory, true);
|
||||
}
|
||||
|
||||
@@ -129,13 +129,12 @@ namespace VDownload.Core.Tasks
|
||||
DownloadTaskStatus.Processing,
|
||||
DownloadTaskStatus.Finalizing
|
||||
];
|
||||
|
||||
while (true)
|
||||
{
|
||||
try
|
||||
{
|
||||
IEnumerable<DownloadTask> pendingTasks = Tasks.Where(x => pendingStatuses.Contains(x.Status));
|
||||
int freeSlots = _settingsService.Data.Common.MaxNumberOfRunningTasks - pendingTasks.Count();
|
||||
int freeSlots = _settingsService.Data.Common.Tasks.MaxNumberOfRunningTasks - pendingTasks.Count();
|
||||
if (freeSlots > 0)
|
||||
{
|
||||
IEnumerable<DownloadTask> queuedTasks = Tasks.Where(x => x.Status == DownloadTaskStatus.Queued).OrderBy(x => x.CreateDate).Take(freeSlots);
|
||||
|
||||
@@ -11,7 +11,7 @@ using VDownload.Core.ViewModels.Home;
|
||||
using VDownload.Core.ViewModels.Settings;
|
||||
using VDownload.Services.UI.DictionaryResources;
|
||||
using VDownload.Services.UI.StringResources;
|
||||
using VDownload.Toolkit.UI.Models;
|
||||
using SimpleToolkit.UI.Models;
|
||||
|
||||
namespace VDownload.Core.ViewModels
|
||||
{
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using VDownload.Models;
|
||||
using VDownload.Sources.Twitch.Configuration.Models;
|
||||
|
||||
namespace VDownload.Core.ViewModels.Home
|
||||
{
|
||||
public partial class HomePlaylistViewModel : ObservableObject
|
||||
{
|
||||
#region SERVICES
|
||||
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
#region FIELDS
|
||||
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
#region PROPERTIES
|
||||
|
||||
[ObservableProperty]
|
||||
protected string _name;
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
#region CONSTRUCTORS
|
||||
|
||||
public HomePlaylistViewModel()
|
||||
{
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
#region PUBLIC METHODS
|
||||
|
||||
public async Task LoadPlaylist(Playlist playlist)
|
||||
{
|
||||
Name = playlist.Name;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
#region COMMANDS
|
||||
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
#region EVENTS
|
||||
|
||||
public event EventHandler CloseRequested;
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -87,14 +87,6 @@ namespace VDownload.Core.ViewModels.Home
|
||||
|
||||
|
||||
|
||||
#region EVENTS
|
||||
|
||||
public event EventHandler TaskAdded;
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
#region CONSTRUCTORS
|
||||
|
||||
public HomeVideoViewModel(IDownloadTaskManager tasksManager, ISettingsService settingsService, IStoragePickerService storagePickerService)
|
||||
@@ -110,7 +102,7 @@ namespace VDownload.Core.ViewModels.Home
|
||||
|
||||
#region PUBLIC METHODS
|
||||
|
||||
public async void LoadVideo(Video video)
|
||||
public async Task LoadVideo(Video video)
|
||||
{
|
||||
await _settingsService.Load();
|
||||
|
||||
@@ -125,13 +117,13 @@ namespace VDownload.Core.ViewModels.Home
|
||||
|
||||
Streams = [.. video.Streams];
|
||||
SelectedStream = Streams[0];
|
||||
MediaType = _settingsService.Data.Common.DefaultTaskSettings.MediaType;
|
||||
MediaType = _settingsService.Data.Common.Tasks.DefaultMediaType;
|
||||
TrimStart = TimeSpan.Zero;
|
||||
TrimEnd = Duration;
|
||||
DirectoryPath = _settingsService.Data.Common.DefaultTaskSettings.OutputDirectory;
|
||||
DirectoryPath = _settingsService.Data.Common.Tasks.DefaultOutputDirectory;
|
||||
Filename = Title.Length > 50 ? Title.Substring(0, 50) : Title;
|
||||
VideoExtension = _settingsService.Data.Common.DefaultTaskSettings.VideoExtension;
|
||||
AudioExtension = _settingsService.Data.Common.DefaultTaskSettings.AudioExtension;
|
||||
VideoExtension = _settingsService.Data.Common.Tasks.DefaultVideoExtension;
|
||||
AudioExtension = _settingsService.Data.Common.Tasks.DefaultAudioExtension;
|
||||
}
|
||||
|
||||
|
||||
@@ -149,14 +141,14 @@ namespace VDownload.Core.ViewModels.Home
|
||||
public void CreateTask()
|
||||
{
|
||||
_tasksManager.AddTask(_video, BuildDownloadOptions());
|
||||
TaskAdded?.Invoke(this, EventArgs.Empty);
|
||||
CloseRequested?.Invoke(this, EventArgs.Empty);
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
public void CreateTaskAndDownload()
|
||||
{
|
||||
DownloadTask task = _tasksManager.AddTask(_video, BuildDownloadOptions());
|
||||
TaskAdded?.Invoke(this, EventArgs.Empty);
|
||||
CloseRequested?.Invoke(this, EventArgs.Empty);
|
||||
task.Enqueue();
|
||||
}
|
||||
|
||||
@@ -181,5 +173,13 @@ namespace VDownload.Core.ViewModels.Home
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
#region EVENTS
|
||||
|
||||
public event EventHandler CloseRequested;
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using VDownload.Core.Tasks;
|
||||
using VDownload.Models;
|
||||
using VDownload.Services.Data.Configuration;
|
||||
using VDownload.Services.Data.Settings;
|
||||
@@ -42,7 +43,10 @@ namespace VDownload.Core.ViewModels.Home
|
||||
protected readonly IStringResourcesService _stringResourcesService;
|
||||
protected readonly ISearchService _searchService;
|
||||
|
||||
protected readonly IDownloadTaskManager _downloadTaskManager;
|
||||
|
||||
protected readonly HomeVideoViewModel _videoViewModel;
|
||||
protected readonly HomePlaylistViewModel _playlistViewModel;
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -52,6 +56,7 @@ namespace VDownload.Core.ViewModels.Home
|
||||
|
||||
protected readonly Type _downloadsView = typeof(HomeDownloadsViewModel);
|
||||
protected readonly Type _videoView = typeof(HomeVideoViewModel);
|
||||
protected readonly Type _playlistView = typeof(HomePlaylistViewModel);
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -96,15 +101,20 @@ namespace VDownload.Core.ViewModels.Home
|
||||
|
||||
#region CONSTRUCTORS
|
||||
|
||||
public HomeViewModel(IConfigurationService configurationService, ISettingsService settingsService, IStringResourcesService stringResourcesService, ISearchService searchService, HomeVideoViewModel videoViewModel)
|
||||
public HomeViewModel(IConfigurationService configurationService, ISettingsService settingsService, IStringResourcesService stringResourcesService, ISearchService searchService, IDownloadTaskManager downloadTaskManager, HomeVideoViewModel videoViewModel, HomePlaylistViewModel playlistViewModel)
|
||||
{
|
||||
_configurationService = configurationService;
|
||||
_settingsService = settingsService;
|
||||
_stringResourcesService = stringResourcesService;
|
||||
_searchService = searchService;
|
||||
|
||||
_downloadTaskManager = downloadTaskManager;
|
||||
|
||||
_videoViewModel = videoViewModel;
|
||||
_videoViewModel.TaskAdded += VideoViewModel_TaskAdded;
|
||||
_videoViewModel.CloseRequested += BackToDownload_EventHandler;
|
||||
|
||||
_playlistViewModel = playlistViewModel;
|
||||
_playlistViewModel.CloseRequested += BackToDownload_EventHandler;
|
||||
}
|
||||
|
||||
#endregion
|
||||
@@ -195,7 +205,7 @@ namespace VDownload.Core.ViewModels.Home
|
||||
return;
|
||||
}
|
||||
|
||||
_videoViewModel.LoadVideo(video);
|
||||
await _videoViewModel.LoadVideo(video);
|
||||
|
||||
MainContent = _videoView;
|
||||
|
||||
@@ -224,6 +234,10 @@ namespace VDownload.Core.ViewModels.Home
|
||||
return;
|
||||
}
|
||||
|
||||
await _playlistViewModel.LoadPlaylist(playlist);
|
||||
|
||||
MainContent = _playlistView;
|
||||
|
||||
OptionBarSearchNotPending = true;
|
||||
OptionBarLoading = false;
|
||||
OptionBarMessage = null;
|
||||
@@ -232,7 +246,10 @@ namespace VDownload.Core.ViewModels.Home
|
||||
[RelayCommand]
|
||||
public void Download()
|
||||
{
|
||||
|
||||
foreach (DownloadTask task in _downloadTaskManager.Tasks)
|
||||
{
|
||||
task.Enqueue();
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
@@ -241,7 +258,7 @@ namespace VDownload.Core.ViewModels.Home
|
||||
|
||||
#region PRIVATE METHODS
|
||||
|
||||
private async void VideoViewModel_TaskAdded(object sender, EventArgs e) => await Navigation();
|
||||
private async void BackToDownload_EventHandler(object sender, EventArgs e) => await Navigation();
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
<PackageReference Include="Microsoft.WindowsAppSDK" Version="1.4.240211001" />
|
||||
<PackageReference Include="Microsoft.Windows.SDK.BuildTools" Version="10.0.22621.2428" />
|
||||
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.2.2" />
|
||||
<PackageReference Include="SimpleToolkit.UI.Models" Version="1.4.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
@@ -23,7 +24,6 @@
|
||||
<ProjectReference Include="..\..\VDownload.Services\VDownload.Services.UI\VDownload.Services.UI.WebView\VDownload.Services.UI.WebView.csproj" />
|
||||
<ProjectReference Include="..\..\VDownload.Sources\VDownload.Sources.Twitch\VDownload.Sources.Twitch.Authentication\VDownload.Sources.Twitch.Authentication.csproj" />
|
||||
<ProjectReference Include="..\..\VDownload.Sources\VDownload.Sources\VDownload.Sources.csproj" />
|
||||
<ProjectReference Include="..\..\VDownload.Toolkit\VDownload.Toolkit.UI\VDownload.Toolkit.UI.Models\VDownload.Toolkit.UI.Models.csproj" />
|
||||
<ProjectReference Include="..\VDownload.Core.Tasks\VDownload.Core.Tasks.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:i="using:Microsoft.Xaml.Interactivity"
|
||||
xmlns:ic="using:Microsoft.Xaml.Interactions.Core"
|
||||
xmlns:cb="using:VDownload.Toolkit.UI.Behaviors"
|
||||
xmlns:cb="using:SimpleToolkit.UI.WinUI.Behaviors"
|
||||
mc:Ignorable="d">
|
||||
<Window.SystemBackdrop>
|
||||
<MicaBackdrop Kind="Base"/>
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Page
|
||||
x:Class="VDownload.Core.Views.Home.HomePlaylistView"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="using:VDownload.Core.Views.Home"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
mc:Ignorable="d"
|
||||
Background="{ThemeResource ViewBackgroundColor}">
|
||||
|
||||
<Grid Padding="15"
|
||||
RowSpacing="20">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
<Grid Grid.Row="0">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Grid.Column="0"
|
||||
VerticalAlignment="Center"
|
||||
Text="{Binding Name}"
|
||||
FontWeight="Bold"
|
||||
FontSize="20"
|
||||
TextWrapping="WrapWholeWords"/>
|
||||
<AppBarButton Grid.Column="2"
|
||||
Margin="-5"
|
||||
Icon="Filter"
|
||||
Width="40"
|
||||
Height="48">
|
||||
<AppBarButton.Resources>
|
||||
<TeachingTip x:Name="FilterWindow">
|
||||
|
||||
</TeachingTip>
|
||||
</AppBarButton.Resources>
|
||||
</AppBarButton>
|
||||
</Grid>
|
||||
<ItemsControl Grid.Row="1">
|
||||
|
||||
</ItemsControl>
|
||||
<StackPanel Grid.Row="2"
|
||||
HorizontalAlignment="Right"
|
||||
Orientation="Horizontal">
|
||||
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</Page>
|
||||
@@ -0,0 +1,31 @@
|
||||
using Microsoft.UI.Xaml;
|
||||
using Microsoft.UI.Xaml.Controls;
|
||||
using Microsoft.UI.Xaml.Controls.Primitives;
|
||||
using Microsoft.UI.Xaml.Data;
|
||||
using Microsoft.UI.Xaml.Input;
|
||||
using Microsoft.UI.Xaml.Media;
|
||||
using Microsoft.UI.Xaml.Navigation;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices.WindowsRuntime;
|
||||
using VDownload.Core.ViewModels.Home;
|
||||
using Windows.Foundation;
|
||||
using Windows.Foundation.Collections;
|
||||
|
||||
namespace VDownload.Core.Views.Home
|
||||
{
|
||||
public sealed partial class HomePlaylistView : Page
|
||||
{
|
||||
#region CONSTRUCTORS
|
||||
|
||||
public HomePlaylistView(HomePlaylistViewModel viewModel)
|
||||
{
|
||||
this.InitializeComponent();
|
||||
this.DataContext = viewModel;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -12,7 +12,7 @@
|
||||
xmlns:ct="using:CommunityToolkit.WinUI"
|
||||
xmlns:ctc="using:CommunityToolkit.WinUI.Controls"
|
||||
xmlns:ctuc="using:CommunityToolkit.WinUI.UI.Controls"
|
||||
xmlns:c="using:VDownload.Toolkit.UI.Controls"
|
||||
xmlns:c="using:SimpleToolkit.UI.WinUI.Controls"
|
||||
mc:Ignorable="d"
|
||||
Background="{ThemeResource ViewBackgroundColor}">
|
||||
|
||||
|
||||
@@ -7,6 +7,9 @@
|
||||
<UseWinUI>true</UseWinUI>
|
||||
<UseRidGraph>true</UseRidGraph>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<None Remove="Home\HomePlaylistView.xaml" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="CommunityToolkit.WinUI" Version="7.1.2" />
|
||||
@@ -16,11 +19,11 @@
|
||||
<PackageReference Include="Microsoft.WindowsAppSDK" Version="1.4.240211001" />
|
||||
<PackageReference Include="Microsoft.Windows.SDK.BuildTools" Version="10.0.22621.2428" />
|
||||
<PackageReference Include="Microsoft.Xaml.Behaviors.WinUI.Managed" Version="2.0.9" />
|
||||
<PackageReference Include="SimpleToolkit.UI.WinUI.Behaviors" Version="1.4.0" />
|
||||
<PackageReference Include="SimpleToolkit.UI.WinUI.Controls" Version="1.4.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\VDownload.Toolkit\VDownload.Toolkit.UI\VDownload.Toolkit.UI.Behaviors\VDownload.Toolkit.UI.Behaviors.csproj" />
|
||||
<ProjectReference Include="..\..\VDownload.Toolkit\VDownload.Toolkit.UI\VDownload.Toolkit.UI.Controls\VDownload.Toolkit.UI.Controls.csproj" />
|
||||
<ProjectReference Include="..\VDownload.Core.Strings\VDownload.Core.Strings.csproj" />
|
||||
<ProjectReference Include="..\VDownload.Core.ViewModels\VDownload.Core.ViewModels.csproj" />
|
||||
</ItemGroup>
|
||||
@@ -35,6 +38,9 @@
|
||||
<None Update="Home\HomeDownloadsView.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</None>
|
||||
<Page Update="Home\HomePlaylistView.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<None Update="Home\HomeVideoView.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</None>
|
||||
|
||||
@@ -20,6 +20,7 @@ namespace VDownload.Core.Views
|
||||
{ typeof(HomeViewModel), typeof(HomeView) },
|
||||
{ typeof(HomeDownloadsViewModel), typeof(HomeDownloadsView) },
|
||||
{ typeof(HomeVideoViewModel), typeof(HomeVideoView) },
|
||||
{ typeof(HomePlaylistViewModel), typeof(HomePlaylistView) },
|
||||
{ typeof(SettingsViewModel), typeof(SettingsView) },
|
||||
{ typeof(AuthenticationViewModel), typeof(AuthenticationView) }
|
||||
};
|
||||
|
||||
@@ -6,7 +6,15 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace VDownload.Models
|
||||
{
|
||||
public abstract class Playlist
|
||||
public abstract class Playlist : List<Video>
|
||||
{
|
||||
#region PROPERTIES
|
||||
|
||||
public required string Name { get; set; }
|
||||
public required string Description { get; set; }
|
||||
public required Uri Url { get; set; }
|
||||
public Source Source { get; protected set; }
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,9 +17,9 @@ namespace VDownload.Models
|
||||
public TimeSpan Duration { get; set; }
|
||||
public long Views { get; set; }
|
||||
public Uri ThumbnailUrl { get; set; }
|
||||
public ICollection<VideoStream> Streams { get; set; }
|
||||
public Uri Url { get; set; }
|
||||
public Source Source { get; set; }
|
||||
public ICollection<VideoStream> Streams { get; private set; }
|
||||
public Source Source { get; protected set; }
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
@@ -15,17 +15,11 @@ namespace VDownload.Services.Data.Settings
|
||||
[JsonProperty("max_number_of_videos_to_get_from_playlist")]
|
||||
public int MaxNumberOfVideosToGetFromPlaylist { get; set; } = 0;
|
||||
|
||||
[JsonProperty("max_number_of_running_tasks")]
|
||||
public int MaxNumberOfRunningTasks { get; set; } = 5;
|
||||
[JsonProperty("temp")]
|
||||
public Temp Temp { get; set; } = new Temp();
|
||||
|
||||
[JsonProperty("temp_directory")]
|
||||
public string TempDirectory { get; set; } = $"{Path.GetTempPath()}\\VDownload";
|
||||
|
||||
[JsonProperty("delete_temp_on_error")]
|
||||
public bool DeleteTempOnError { get; set; } = true;
|
||||
|
||||
[JsonProperty("default_task_settings")]
|
||||
public DefaultTaskSettings DefaultTaskSettings { get; set; } = new DefaultTaskSettings();
|
||||
[JsonProperty("tasks")]
|
||||
public Tasks Tasks { get; set; } = new Tasks();
|
||||
|
||||
[JsonProperty("notifications")]
|
||||
public Notifications Notifications { get; set; } = new Notifications();
|
||||
|
||||
@@ -1,28 +0,0 @@
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using VDownload.Models;
|
||||
|
||||
namespace VDownload.Services.Data.Settings.Models
|
||||
{
|
||||
public class DefaultTaskSettings
|
||||
{
|
||||
[JsonProperty("media_type")]
|
||||
public MediaType MediaType { get; set; } = MediaType.Original;
|
||||
|
||||
[JsonProperty("video_extension")]
|
||||
public VideoExtension VideoExtension { get; set; } = VideoExtension.MP4;
|
||||
|
||||
[JsonProperty("audio_extension")]
|
||||
public AudioExtension AudioExtension { get; set; } = AudioExtension.MP3;
|
||||
|
||||
[JsonProperty("output_directory")]
|
||||
public string OutputDirectory { get; set; } = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
|
||||
|
||||
[JsonProperty("save_last_output_directory")]
|
||||
public bool SaveLastOutputDirectory { get; set; } = false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using VDownload.Models;
|
||||
|
||||
namespace VDownload.Services.Data.Settings.Models
|
||||
{
|
||||
public class Tasks
|
||||
{
|
||||
[JsonProperty("default_media_type")]
|
||||
public MediaType DefaultMediaType { get; set; } = MediaType.Original;
|
||||
|
||||
[JsonProperty("default_video_extension")]
|
||||
public VideoExtension DefaultVideoExtension { get; set; } = VideoExtension.MP4;
|
||||
|
||||
[JsonProperty("default_audio_extension")]
|
||||
public AudioExtension DefaultAudioExtension { get; set; } = AudioExtension.MP3;
|
||||
|
||||
[JsonProperty("default_output_directory")]
|
||||
public string DefaultOutputDirectory { get; set; } = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
|
||||
|
||||
[JsonProperty("save_last_output_directory")]
|
||||
public bool SaveLastOutputDirectory { get; set; } = false;
|
||||
|
||||
[JsonProperty("max_number_of_running_tasks")]
|
||||
public int MaxNumberOfRunningTasks { get; set; } = 5;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace VDownload.Services.Data.Settings.Models
|
||||
{
|
||||
public class Temp
|
||||
{
|
||||
[JsonProperty("directory")]
|
||||
public string Directory { get; set; } = $"{Path.GetTempPath()}\\VDownload";
|
||||
|
||||
[JsonProperty("delete_on_error")]
|
||||
public bool DeleteOnError { get; set; } = true;
|
||||
}
|
||||
}
|
||||
@@ -75,15 +75,15 @@ namespace VDownload.Services.Data.Settings
|
||||
|
||||
public async Task Load()
|
||||
{
|
||||
Data = null;
|
||||
|
||||
if (File.Exists(_filePath))
|
||||
{
|
||||
string content = await File.ReadAllTextAsync(_filePath);
|
||||
Data = JsonConvert.DeserializeObject<SettingsData>(content);
|
||||
}
|
||||
|
||||
Data ??= new SettingsData();
|
||||
else
|
||||
{
|
||||
Data = new SettingsData();
|
||||
}
|
||||
}
|
||||
|
||||
public async Task Save()
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.WindowsAppSDK" Version="1.4.230913002" />
|
||||
<PackageReference Include="Microsoft.Windows.SDK.BuildTools" Version="10.0.22621.755" />
|
||||
<PackageReference Include="Microsoft.WindowsAppSDK" Version="1.4.240211001" />
|
||||
<PackageReference Include="Microsoft.Windows.SDK.BuildTools" Version="10.0.22621.2428" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
||||
@@ -9,8 +9,8 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.WindowsAppSDK" Version="1.4.230913002" />
|
||||
<PackageReference Include="Microsoft.Windows.SDK.BuildTools" Version="10.0.22621.755" />
|
||||
<PackageReference Include="Microsoft.WindowsAppSDK" Version="1.4.240211001" />
|
||||
<PackageReference Include="Microsoft.Windows.SDK.BuildTools" Version="10.0.22621.2428" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -86,7 +86,9 @@ namespace VDownload.Services.Utility.HttpClient
|
||||
|
||||
HttpResponseMessage response = await _httpClient.SendAsync(httpRequest);
|
||||
|
||||
return await response.Content.ReadAsStringAsync();
|
||||
string responseString = await response.Content.ReadAsStringAsync();
|
||||
|
||||
return responseString;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace VDownload.Sources.Twitch.Api.Helix.GetUsers.Response
|
||||
{
|
||||
public class Data
|
||||
{
|
||||
[JsonProperty("id")]
|
||||
public string Id { get; set; }
|
||||
|
||||
[JsonProperty("login")]
|
||||
public string Login { get; set; }
|
||||
|
||||
[JsonProperty("display_name")]
|
||||
public string DisplayName { get; set; }
|
||||
|
||||
[JsonProperty("type")]
|
||||
public string Type { get; set; }
|
||||
|
||||
[JsonProperty("broadcaster_type")]
|
||||
public string BroadcasterType { get; set; }
|
||||
|
||||
[JsonProperty("description")]
|
||||
public string Description { get; set; }
|
||||
|
||||
[JsonProperty("profile_image_url")]
|
||||
public string ProfileImageUrl { get; set; }
|
||||
|
||||
[JsonProperty("offline_image_url")]
|
||||
public string OfflineImageUrl { get; set; }
|
||||
|
||||
[JsonProperty("view_count")]
|
||||
public int ViewCount { get; set; }
|
||||
|
||||
[JsonProperty("email")]
|
||||
public string Email { get; set; }
|
||||
|
||||
[JsonProperty("created_at")]
|
||||
public DateTime CreatedAt { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace VDownload.Sources.Twitch.Api.Helix.GetUsers.Response
|
||||
{
|
||||
public class GetUsersResponse
|
||||
{
|
||||
[JsonProperty("data")]
|
||||
public List<Data> Data { get; } = new List<Data>();
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
using VDownload.Services.Data.Configuration;
|
||||
using VDownload.Services.Utility.HttpClient;
|
||||
using VDownload.Sources.Twitch.Api.GQL.GetVideoToken.Response;
|
||||
using VDownload.Sources.Twitch.Api.Helix.GetUsers.Response;
|
||||
using VDownload.Sources.Twitch.Api.Helix.GetVideos.Response;
|
||||
using VDownload.Sources.Twitch.Search.Models.GetVideoToken.Request;
|
||||
|
||||
@@ -10,7 +11,9 @@ namespace VDownload.Sources.Twitch.Api
|
||||
{
|
||||
Task<string> AuthValidate(byte[] token);
|
||||
Task<GetVideoTokenResponse> GQLGetVideoToken(string id);
|
||||
Task<GetVideosResponse> HelixGetVideos(string id, byte[] token);
|
||||
Task<GetUsersResponse> HelixGetUser(string login, byte[] token);
|
||||
Task<GetVideosResponse> HelixGetVideo(string id, byte[] token);
|
||||
Task<GetVideosResponse> HelixGetUserVideos(string user_id, byte[] token, int count, string? cursor = null);
|
||||
Task<string> UsherGetVideoPlaylist(string id, string videoToken, string videoTokenSignature);
|
||||
}
|
||||
|
||||
@@ -49,12 +52,47 @@ namespace VDownload.Sources.Twitch.Api
|
||||
return await _httpClientService.SendRequestAsync(request);
|
||||
}
|
||||
|
||||
public async Task<GetVideosResponse> HelixGetVideos(string id, byte[] token)
|
||||
public async Task<GetUsersResponse> HelixGetUser(string login, byte[] token)
|
||||
{
|
||||
Token tokenData = new Token(_configurationService.Twitch.Api.Helix.TokenSchema, token);
|
||||
|
||||
HttpRequest request = new HttpRequest(HttpMethodType.GET, _configurationService.Twitch.Api.Helix.Endpoints.GetUsers);
|
||||
|
||||
request.Query.Add("login", login);
|
||||
|
||||
request.Headers.Add("Authorization", $"{tokenData}");
|
||||
request.Headers.Add("Client-Id", _configurationService.Twitch.Api.Helix.ClientId);
|
||||
|
||||
return await _httpClientService.SendRequestAsync<GetUsersResponse>(request);
|
||||
}
|
||||
|
||||
public async Task<GetVideosResponse> HelixGetVideo(string id, byte[] token)
|
||||
{
|
||||
Token tokenData = new Token(_configurationService.Twitch.Api.Helix.TokenSchema, token);
|
||||
|
||||
HttpRequest request = new HttpRequest(HttpMethodType.GET, _configurationService.Twitch.Api.Helix.Endpoints.GetVideos);
|
||||
|
||||
request.Query.Add("id", id);
|
||||
|
||||
request.Headers.Add("Authorization", tokenData.ToString());
|
||||
request.Headers.Add("Client-Id", _configurationService.Twitch.Api.Helix.ClientId);
|
||||
|
||||
return await _httpClientService.SendRequestAsync<GetVideosResponse>(request);
|
||||
}
|
||||
|
||||
public async Task<GetVideosResponse> HelixGetUserVideos(string user_id, byte[] token, int count, string? cursor = null)
|
||||
{
|
||||
Token tokenData = new Token(_configurationService.Twitch.Api.Helix.TokenSchema, token);
|
||||
|
||||
HttpRequest request = new HttpRequest(HttpMethodType.GET, _configurationService.Twitch.Api.Helix.Endpoints.GetVideos);
|
||||
|
||||
request.Query.Add("user_id", user_id);
|
||||
request.Query.Add("first", count);
|
||||
if (cursor is not null)
|
||||
{
|
||||
request.Query.Add("after", cursor);
|
||||
}
|
||||
|
||||
request.Headers.Add("Authorization", tokenData.ToString());
|
||||
request.Headers.Add("Client-Id", _configurationService.Twitch.Api.Helix.ClientId);
|
||||
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace VDownload.Sources.Twitch.Configuration.Models
|
||||
{
|
||||
public class Channel
|
||||
{
|
||||
[ConfigurationKeyName("regexes")]
|
||||
public List<string> Regexes { get; } = new List<string>();
|
||||
|
||||
[ConfigurationKeyName("url")]
|
||||
public string Url { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace VDownload.Sources.Twitch.Configuration.Models
|
||||
{
|
||||
public class Clip
|
||||
{
|
||||
[ConfigurationKeyName("regexes")]
|
||||
public List<string> Regexes { get; } = new List<string>();
|
||||
}
|
||||
}
|
||||
@@ -6,5 +6,8 @@ namespace VDownload.Sources.Twitch.Configuration.Models
|
||||
{
|
||||
[ConfigurationKeyName("get_videos")]
|
||||
public string GetVideos { get; set; }
|
||||
|
||||
[ConfigurationKeyName("get_users")]
|
||||
public string GetUsers { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -8,6 +8,12 @@ namespace VDownload.Sources.Twitch.Configuration.Models{
|
||||
|
||||
[ConfigurationKeyName("vod")]
|
||||
public Vod Vod { get; set; }
|
||||
|
||||
[ConfigurationKeyName("clip")]
|
||||
public Clip Clip { get; set; }
|
||||
|
||||
[ConfigurationKeyName("channel")]
|
||||
public Channel Channel { get; set; }
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace VDownload.Sources.Twitch.Models
|
||||
{
|
||||
public class TwitchChannel : TwitchPlaylist
|
||||
{
|
||||
#region PROPERTIES
|
||||
|
||||
public required string Id { get; set; }
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -9,5 +9,13 @@ namespace VDownload.Sources.Twitch.Models
|
||||
{
|
||||
public abstract class TwitchPlaylist : Playlist
|
||||
{
|
||||
#region CONSTRUCTORS
|
||||
|
||||
protected TwitchPlaylist()
|
||||
{
|
||||
Source = Source.Twitch;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ using VDownload.Services.Data.Configuration;
|
||||
using VDownload.Sources.Common;
|
||||
using VDownload.Sources.Twitch.Api;
|
||||
using VDownload.Sources.Twitch.Api.GQL.GetVideoToken.Response;
|
||||
using VDownload.Sources.Twitch.Api.Helix.GetUsers.Response;
|
||||
using VDownload.Sources.Twitch.Api.Helix.GetVideos.Response;
|
||||
using VDownload.Sources.Twitch.Authentication;
|
||||
using VDownload.Sources.Twitch.Configuration.Models;
|
||||
@@ -71,7 +72,16 @@ namespace VDownload.Sources.Twitch
|
||||
async Task<Playlist> ISourceSearchService.SearchPlaylist(string url, int maxVideoCount) => await SearchPlaylist(url, maxVideoCount);
|
||||
public async Task<TwitchPlaylist> SearchPlaylist(string url, int maxVideoCount)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
foreach (Regex regex in _configurationService.Twitch.Search.Channel.Regexes.Select(x => new Regex(x)))
|
||||
{
|
||||
Match match = regex.Match(url);
|
||||
if (match.Success)
|
||||
{
|
||||
string id = match.Groups[1].Value;
|
||||
return await GetChannel(id, maxVideoCount);
|
||||
}
|
||||
}
|
||||
throw new MediaSearchException("Invalid url");
|
||||
}
|
||||
|
||||
#endregion
|
||||
@@ -82,23 +92,68 @@ namespace VDownload.Sources.Twitch
|
||||
|
||||
protected async Task<TwitchVod> GetVod(string id)
|
||||
{
|
||||
Task<IEnumerable<TwitchVodStream>> streamsTask = GetVodStreams(id);
|
||||
|
||||
byte[] token = await GetToken();
|
||||
GetVideosResponse info = await _apiService.HelixGetVideos(id, token);
|
||||
Data vodResponse = info.Data[0];
|
||||
|
||||
GetVideosResponse info = await _apiService.HelixGetVideo(id, token);
|
||||
|
||||
Api.Helix.GetVideos.Response.Data vodResponse = info.Data[0];
|
||||
|
||||
TwitchVod vod = await ParseVod(vodResponse);
|
||||
|
||||
return vod;
|
||||
}
|
||||
|
||||
protected async Task<TwitchChannel> GetChannel(string id, int count)
|
||||
{
|
||||
byte[] token = await GetToken();
|
||||
GetUsersResponse info = await _apiService.HelixGetUser(id, token);
|
||||
Api.Helix.GetUsers.Response.Data userResponse = info.Data[0];
|
||||
|
||||
TwitchChannel channel = new TwitchChannel
|
||||
{
|
||||
Id = userResponse.Id,
|
||||
Name = userResponse.DisplayName,
|
||||
Description = userResponse.Description,
|
||||
Url = new Uri(string.Format(_configurationService.Twitch.Search.Channel.Url, id)),
|
||||
};
|
||||
|
||||
List<Task<TwitchVod>> tasks = new List<Task<TwitchVod>>();
|
||||
string? cursor = null;
|
||||
List<Api.Helix.GetVideos.Response.Data> videosList;
|
||||
int videos = 0;
|
||||
do
|
||||
{
|
||||
videos = count == 0 || count > 100 ? 100 : count;
|
||||
GetVideosResponse videosResponse = await _apiService.HelixGetUserVideos(channel.Id, token, videos, cursor);
|
||||
videosList = videosResponse.Data;
|
||||
count -= videosList.Count;
|
||||
cursor = videosResponse.Pagination.Cursor;
|
||||
tasks.AddRange(videosList.Select(ParseVod));
|
||||
}
|
||||
while (videosList.Count == videos);
|
||||
|
||||
await Task.WhenAll(tasks);
|
||||
|
||||
channel.AddRange(tasks.Select(x => x.Result));
|
||||
|
||||
return channel;
|
||||
}
|
||||
|
||||
public async Task<TwitchVod> ParseVod(Api.Helix.GetVideos.Response.Data data)
|
||||
{
|
||||
Task<IEnumerable<TwitchVodStream>> streamsTask = GetVodStreams(data.Id);
|
||||
|
||||
Thumbnail thumbnail = _configurationService.Twitch.Search.Vod.Thumbnail;
|
||||
TwitchVod vod = new TwitchVod
|
||||
{
|
||||
Title = vodResponse.Title,
|
||||
Description = vodResponse.Description,
|
||||
Author = vodResponse.UserName,
|
||||
PublishDate = vodResponse.PublishedAt,
|
||||
Duration = ParseVodDuration(vodResponse.Duration),
|
||||
Views = vodResponse.ViewCount,
|
||||
ThumbnailUrl = new Uri(vodResponse.ThumbnailUrl.Replace("%{width}", thumbnail.Width.ToString()).Replace("%{height}", thumbnail.Height.ToString())),
|
||||
Url = new Uri(vodResponse.Url),
|
||||
Title = data.Title,
|
||||
Description = data.Description,
|
||||
Author = data.UserName,
|
||||
PublishDate = data.PublishedAt,
|
||||
Duration = ParseVodDuration(data.Duration),
|
||||
Views = data.ViewCount,
|
||||
ThumbnailUrl = new Uri(data.ThumbnailUrl.Replace("%{width}", thumbnail.Width.ToString()).Replace("%{height}", thumbnail.Height.ToString())),
|
||||
Url = new Uri(data.Url),
|
||||
};
|
||||
|
||||
await streamsTask;
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
namespace VDownload.Toolkit.Extensions
|
||||
{
|
||||
public static class StringExtensions
|
||||
{
|
||||
#region STATIC
|
||||
|
||||
public static string CreateRandom(int length) => CreateRandom(length, "QWERTYUIOPASDFGHJKLZXCVBNMqwertyuiopasdfghjklzxcvbnm1234567890`~!@#$%^&*()-_=+[{]};:'\"\\|,<.>/?");
|
||||
public static string CreateRandom(int length, IEnumerable<char> characters) => new string(Enumerable.Repeat(characters, length).Select(s => s.ElementAt(Random.Shared.Next(s.Count()))).ToArray());
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
#region INSTANCE
|
||||
|
||||
public static string Shuffle(this string instance)
|
||||
{
|
||||
char[] array = instance.ToCharArray();
|
||||
Random rng = Random.Shared;
|
||||
int n = array.Length;
|
||||
while (n > 1)
|
||||
{
|
||||
n--;
|
||||
int k = rng.Next(n + 1);
|
||||
char value = array[k];
|
||||
array[k] = array[n];
|
||||
array[n] = value;
|
||||
}
|
||||
return new string(array);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
||||
@@ -1,91 +0,0 @@
|
||||
using Microsoft.UI.Xaml;
|
||||
using Microsoft.Xaml.Interactivity;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Input;
|
||||
|
||||
namespace VDownload.Toolkit.UI.Behaviors
|
||||
{
|
||||
public class EventToCommandBehavior : Behavior<FrameworkElement>
|
||||
{
|
||||
#region FIELDS
|
||||
|
||||
private Delegate _handler;
|
||||
private EventInfo _oldEvent;
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
#region PROPERTIES
|
||||
|
||||
public string Event { get { return (string)GetValue(EventProperty); } set { SetValue(EventProperty, value); } }
|
||||
public static readonly DependencyProperty EventProperty = DependencyProperty.Register("Event", typeof(string), typeof(EventToCommandBehavior), new PropertyMetadata(null, OnEventChanged));
|
||||
|
||||
public ICommand Command { get { return (ICommand)GetValue(CommandProperty); } set { SetValue(CommandProperty, value); } }
|
||||
public static readonly DependencyProperty CommandProperty = DependencyProperty.Register("Command", typeof(ICommand), typeof(EventToCommandBehavior), new PropertyMetadata(null));
|
||||
|
||||
public bool PassArguments { get { return (bool)GetValue(PassArgumentsProperty); } set { SetValue(PassArgumentsProperty, value); } }
|
||||
public static readonly DependencyProperty PassArgumentsProperty = DependencyProperty.Register("PassArguments", typeof(bool), typeof(EventToCommandBehavior), new PropertyMetadata(false));
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
#region PRIVATE METHODS
|
||||
|
||||
private static void OnEventChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
EventToCommandBehavior beh = (EventToCommandBehavior)d;
|
||||
|
||||
if (beh.AssociatedObject != null)
|
||||
{
|
||||
beh.AttachHandler((string)e.NewValue);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnAttached()
|
||||
{
|
||||
AttachHandler(this.Event);
|
||||
}
|
||||
|
||||
private void AttachHandler(string eventName)
|
||||
{
|
||||
if (_oldEvent != null)
|
||||
{
|
||||
_oldEvent.RemoveEventHandler(this.AssociatedObject, _handler);
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(eventName))
|
||||
{
|
||||
EventInfo ei = this.AssociatedObject.GetType().GetEvent(eventName);
|
||||
if (ei != null)
|
||||
{
|
||||
MethodInfo mi = this.GetType().GetMethod("ExecuteCommand", BindingFlags.Instance | BindingFlags.NonPublic);
|
||||
_handler = Delegate.CreateDelegate(ei.EventHandlerType, this, mi);
|
||||
ei.AddEventHandler(this.AssociatedObject, _handler);
|
||||
_oldEvent = ei;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new ArgumentException(string.Format("The event '{0}' was not found on type '{1}'", eventName, this.AssociatedObject.GetType().Name));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void ExecuteCommand(object sender, object e)
|
||||
{
|
||||
object parameter = this.PassArguments ? e : null;
|
||||
if (this.Command != null && this.Command.CanExecute(parameter))
|
||||
{
|
||||
this.Command.Execute(parameter);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0-windows10.0.19041.0</TargetFramework>
|
||||
<TargetPlatformMinVersion>10.0.17763.0</TargetPlatformMinVersion>
|
||||
<RootNamespace>VDownload.Toolkit.UI.Behaviors</RootNamespace>
|
||||
<RuntimeIdentifiers>win10-x86;win10-x64;win10-arm64</RuntimeIdentifiers>
|
||||
<UseWinUI>true</UseWinUI>
|
||||
<UseRidGraph>true</UseRidGraph>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.WindowsAppSDK" Version="1.4.240211001" />
|
||||
<PackageReference Include="Microsoft.Windows.SDK.BuildTools" Version="10.0.22621.2428" />
|
||||
<PackageReference Include="Microsoft.Xaml.Behaviors.WinUI.Managed" Version="2.0.9" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -1,19 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<UserControl
|
||||
x:Class="VDownload.Toolkit.UI.Controls.TimeSpanControl"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
mc:Ignorable="d"
|
||||
x:Name="Control"
|
||||
Loaded="Control_Loaded">
|
||||
|
||||
<StackPanel Orientation="Horizontal" Spacing="4">
|
||||
<NumberBox x:Name="Hours" SpinButtonPlacementMode="Compact" Minimum="0" Value="0" ValueChanged="ValueChanged"/>
|
||||
<TextBlock VerticalAlignment="Center" Padding="0,0,0,5" Text=":"/>
|
||||
<NumberBox x:Name="Minutes" SpinButtonPlacementMode="Compact" Minimum="0" Value="0" Maximum="59" ValueChanged="ValueChanged"/>
|
||||
<TextBlock VerticalAlignment="Center" Padding="0,0,0,5" Text=":"/>
|
||||
<NumberBox x:Name="Seconds" SpinButtonPlacementMode="Compact" Minimum="0" Value="0" Maximum="59" ValueChanged="ValueChanged"/>
|
||||
</StackPanel>
|
||||
</UserControl>
|
||||
@@ -1,119 +0,0 @@
|
||||
using Microsoft.UI.Xaml;
|
||||
using Microsoft.UI.Xaml.Controls;
|
||||
using Microsoft.UI.Xaml.Controls.Primitives;
|
||||
using Microsoft.UI.Xaml.Data;
|
||||
using Microsoft.UI.Xaml.Input;
|
||||
using Microsoft.UI.Xaml.Media;
|
||||
using Microsoft.UI.Xaml.Navigation;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices.WindowsRuntime;
|
||||
using Windows.Foundation;
|
||||
using Windows.Foundation.Collections;
|
||||
|
||||
namespace VDownload.Toolkit.UI.Controls
|
||||
{
|
||||
public sealed partial class TimeSpanControl : UserControl
|
||||
{
|
||||
#region PROPERTIES
|
||||
|
||||
public TimeSpan Value
|
||||
{
|
||||
get => (TimeSpan)GetValue(ValueProperty);
|
||||
set => SetValue(ValueProperty, value);
|
||||
}
|
||||
public static readonly DependencyProperty ValueProperty = DependencyProperty.Register("Value", typeof(TimeSpan), typeof(TimeSpanControl), new PropertyMetadata(TimeSpan.Zero, new PropertyChangedCallback(ValuePropertyChanged)));
|
||||
|
||||
public TimeSpan Maximum
|
||||
{
|
||||
get => (TimeSpan)GetValue(MaximumProperty);
|
||||
set => SetValue(MaximumProperty, value);
|
||||
}
|
||||
public static readonly DependencyProperty MaximumProperty = DependencyProperty.Register("Maximum", typeof(TimeSpan), typeof(TimeSpanControl), new PropertyMetadata(TimeSpan.MaxValue, new PropertyChangedCallback(RangePropertyChanged)));
|
||||
|
||||
public TimeSpan Minimum
|
||||
{
|
||||
get => (TimeSpan)GetValue(MinimumProperty);
|
||||
set => SetValue(MinimumProperty, value);
|
||||
}
|
||||
public static readonly DependencyProperty MinimumProperty = DependencyProperty.Register("Minimum", typeof(TimeSpan), typeof(TimeSpanControl), new PropertyMetadata(TimeSpan.Zero, new PropertyChangedCallback(RangePropertyChanged)));
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
#region CONSTRUCTORS
|
||||
|
||||
public TimeSpanControl()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
#region PRIVATE METHODS
|
||||
|
||||
private void UpdateOnChanges()
|
||||
{
|
||||
if (this.IsLoaded)
|
||||
{
|
||||
TimeSpan hoursTimeSpan = TimeSpan.FromHours(Hours.Value);
|
||||
TimeSpan minutesTimeSpan = TimeSpan.FromMinutes(Minutes.Value);
|
||||
TimeSpan secondsTimeSpan = TimeSpan.FromSeconds(Seconds.Value);
|
||||
TimeSpan value = secondsTimeSpan + minutesTimeSpan + hoursTimeSpan;
|
||||
if (value >= Maximum)
|
||||
{
|
||||
Hours.Value = Math.Floor(Maximum.TotalHours);
|
||||
Minutes.Value = Maximum.Minutes;
|
||||
Seconds.Value = Maximum.Seconds;
|
||||
}
|
||||
else if (value <= Minimum)
|
||||
{
|
||||
Hours.Value = Math.Floor(Minimum.TotalHours);
|
||||
Minutes.Value = Minimum.Minutes;
|
||||
Seconds.Value = Minimum.Seconds;
|
||||
}
|
||||
Value = value;
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateOnValueChange()
|
||||
{
|
||||
if (this.IsLoaded)
|
||||
{
|
||||
TimeSpan value = Value;
|
||||
if (value > Maximum)
|
||||
{
|
||||
value = Maximum;
|
||||
}
|
||||
else if (value < Minimum)
|
||||
{
|
||||
value = Minimum;
|
||||
}
|
||||
Hours.Value = Math.Floor(value.TotalHours);
|
||||
Minutes.Value = value.Minutes;
|
||||
Seconds.Value = value.Seconds;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
#region EVENT HANDLERS
|
||||
|
||||
private void ValueChanged(NumberBox sender, NumberBoxValueChangedEventArgs args) => UpdateOnChanges();
|
||||
|
||||
private static void ValuePropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e) => ((TimeSpanControl)obj).UpdateOnValueChange();
|
||||
|
||||
private static void RangePropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e) => ((TimeSpanControl)obj).UpdateOnChanges();
|
||||
|
||||
private void Control_Loaded(object sender, RoutedEventArgs e) => UpdateOnValueChange();
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0-windows10.0.19041.0</TargetFramework>
|
||||
<TargetPlatformMinVersion>10.0.17763.0</TargetPlatformMinVersion>
|
||||
<RootNamespace>VDownload.Toolkit.UI.Controls</RootNamespace>
|
||||
<RuntimeIdentifiers>win10-x86;win10-x64;win10-arm64</RuntimeIdentifiers>
|
||||
<UseWinUI>true</UseWinUI>
|
||||
<UseRidGraph>true</UseRidGraph>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<None Remove="TimeSpanControl.xaml" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.WindowsAppSDK" Version="1.4.240211001" />
|
||||
<PackageReference Include="Microsoft.Windows.SDK.BuildTools" Version="10.0.22621.2428" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Page Update="TimeSpanControl.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -1,22 +0,0 @@
|
||||
using Microsoft.UI.Xaml.Data;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace VDownload.Toolkit.UI.Converters
|
||||
{
|
||||
public class ObjectToIntConverter : IValueConverter
|
||||
{
|
||||
public object Convert(object value, Type targetType, object parameter, string language)
|
||||
{
|
||||
return (int)value;
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, string language)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
using Microsoft.UI.Xaml.Data;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace VDownload.Toolkit.UI.Converters
|
||||
{
|
||||
public class ObjectToStringConverter : IValueConverter
|
||||
{
|
||||
#region METHODS
|
||||
|
||||
public object Convert(object value, Type targetType, object parameter, string language) => value.ToString();
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, string language) => throw new NotImplementedException();
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0-windows10.0.19041.0</TargetFramework>
|
||||
<TargetPlatformMinVersion>10.0.17763.0</TargetPlatformMinVersion>
|
||||
<RootNamespace>VDownload.Toolkit.UI.Converters</RootNamespace>
|
||||
<RuntimeIdentifiers>win10-x86;win10-x64;win10-arm64</RuntimeIdentifiers>
|
||||
<UseWinUI>true</UseWinUI>
|
||||
<UseRidGraph>true</UseRidGraph>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.WindowsAppSDK" Version="1.4.240211001" />
|
||||
<PackageReference Include="Microsoft.Windows.SDK.BuildTools" Version="10.0.22621.2428" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -1,19 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace VDownload.Toolkit.UI.Models
|
||||
{
|
||||
public class NavigationViewItem
|
||||
{
|
||||
#region PROPERTIES
|
||||
|
||||
public string Name { get; set; }
|
||||
public string IconSource { get; set; }
|
||||
public Type ViewModel { get; set; }
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
||||
104
VDownload.sln
104
VDownload.sln
@@ -5,18 +5,6 @@ VisualStudioVersion = 17.8.34330.188
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "VDownload", "VDownload\VDownload.csproj", "{62A8EAD3-6D6A-40FC-9E1E-C57C02E27244}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "VDownload.Toolkit", "VDownload.Toolkit", "{5881405B-CA88-4A10-A8AC-1822249AC0FA}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "VDownload.Toolkit.UI", "VDownload.Toolkit.UI", "{2DABFD88-246F-47C2-B752-24DCF7477CEC}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "VDownload.Toolkit.UI.Controls", "VDownload.Toolkit\VDownload.Toolkit.UI\VDownload.Toolkit.UI.Controls\VDownload.Toolkit.UI.Controls.csproj", "{4D762F1C-0905-4B82-9F2C-C0FCD96E2F74}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "VDownload.Toolkit.UI.Converters", "VDownload.Toolkit\VDownload.Toolkit.UI\VDownload.Toolkit.UI.Converters\VDownload.Toolkit.UI.Converters.csproj", "{D6C92F41-B72D-4FE3-AF1C-C1D093CF312D}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "VDownload.Toolkit.UI.Behaviors", "VDownload.Toolkit\VDownload.Toolkit.UI\VDownload.Toolkit.UI.Behaviors\VDownload.Toolkit.UI.Behaviors.csproj", "{5DB5CE22-96F4-4789-8A48-4F3C164A5972}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "VDownload.Toolkit.Extensions", "VDownload.Toolkit\VDownload.Toolkit.Extensions\VDownload.Toolkit.Extensions.csproj", "{8091445A-2CAB-43A4-9459-745974D69834}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "VDownload.Sources", "VDownload.Sources", "{9A8EB967-1EAB-439E-8FDB-B9ACAC6499EC}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "VDownload.Sources.Twitch", "VDownload.Sources.Twitch", "{8D94F264-4EE9-4C24-AB77-2CCA36858309}"
|
||||
@@ -69,8 +57,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "VDownload.Services.UI.Strin
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "VDownload.Services.UI.DictionaryResources", "VDownload.Services\VDownload.Services.UI\VDownload.Services.UI.DictionaryResources\VDownload.Services.UI.DictionaryResources.csproj", "{8DC55331-B9F3-4811-8474-348662963260}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "VDownload.Toolkit.UI.Models", "VDownload.Toolkit\VDownload.Toolkit.UI\VDownload.Toolkit.UI.Models\VDownload.Toolkit.UI.Models.csproj", "{C3C44E06-E03A-4971-99DA-06F6AD606B3B}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "VDownload.Sources.Twitch.Settings", "VDownload.Sources\VDownload.Sources.Twitch\VDownload.Sources.Twitch.Settings\VDownload.Sources.Twitch.Settings.csproj", "{A726FD43-B111-423B-BAF6-D65B4C0E37B5}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "VDownload.Core.Strings", "VDownload.Core\VDownload.Core.Strings\VDownload.Core.Strings.csproj", "{E1D4352C-51AC-4572-8515-0B4E89A2442F}"
|
||||
@@ -79,9 +65,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "VDownload.Core.ViewModels",
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "VDownload.Core.Views", "VDownload.Core\VDownload.Core.Views\VDownload.Core.Views.csproj", "{E470FCE2-DB0D-4771-8C9D-43D8AB85FB80}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VDownload.Core.Tasks", "VDownload.Core\VDownload.Core.Tasks\VDownload.Core.Tasks.csproj", "{3BE998A3-1126-4496-BF60-80D0CEA4D24F}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "VDownload.Core.Tasks", "VDownload.Core\VDownload.Core.Tasks\VDownload.Core.Tasks.csproj", "{3BE998A3-1126-4496-BF60-80D0CEA4D24F}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VDownload.Services.Utility.FFmpeg", "VDownload.Services\VDownload.Services.Utility\VDownload.Services.Utility.FFmpeg\VDownload.Services.Utility.FFmpeg.csproj", "{A3166F8A-ECAD-4D4B-9BE3-96FEC799B27B}"
|
||||
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
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
@@ -117,70 +103,6 @@ Global
|
||||
{62A8EAD3-6D6A-40FC-9E1E-C57C02E27244}.Release|x86.ActiveCfg = Release|x86
|
||||
{62A8EAD3-6D6A-40FC-9E1E-C57C02E27244}.Release|x86.Build.0 = Release|x86
|
||||
{62A8EAD3-6D6A-40FC-9E1E-C57C02E27244}.Release|x86.Deploy.0 = Release|x86
|
||||
{4D762F1C-0905-4B82-9F2C-C0FCD96E2F74}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{4D762F1C-0905-4B82-9F2C-C0FCD96E2F74}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{4D762F1C-0905-4B82-9F2C-C0FCD96E2F74}.Debug|ARM64.ActiveCfg = Debug|Any CPU
|
||||
{4D762F1C-0905-4B82-9F2C-C0FCD96E2F74}.Debug|ARM64.Build.0 = Debug|Any CPU
|
||||
{4D762F1C-0905-4B82-9F2C-C0FCD96E2F74}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{4D762F1C-0905-4B82-9F2C-C0FCD96E2F74}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{4D762F1C-0905-4B82-9F2C-C0FCD96E2F74}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{4D762F1C-0905-4B82-9F2C-C0FCD96E2F74}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{4D762F1C-0905-4B82-9F2C-C0FCD96E2F74}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{4D762F1C-0905-4B82-9F2C-C0FCD96E2F74}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{4D762F1C-0905-4B82-9F2C-C0FCD96E2F74}.Release|ARM64.ActiveCfg = Release|Any CPU
|
||||
{4D762F1C-0905-4B82-9F2C-C0FCD96E2F74}.Release|ARM64.Build.0 = Release|Any CPU
|
||||
{4D762F1C-0905-4B82-9F2C-C0FCD96E2F74}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{4D762F1C-0905-4B82-9F2C-C0FCD96E2F74}.Release|x64.Build.0 = Release|Any CPU
|
||||
{4D762F1C-0905-4B82-9F2C-C0FCD96E2F74}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{4D762F1C-0905-4B82-9F2C-C0FCD96E2F74}.Release|x86.Build.0 = Release|Any CPU
|
||||
{D6C92F41-B72D-4FE3-AF1C-C1D093CF312D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{D6C92F41-B72D-4FE3-AF1C-C1D093CF312D}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{D6C92F41-B72D-4FE3-AF1C-C1D093CF312D}.Debug|ARM64.ActiveCfg = Debug|Any CPU
|
||||
{D6C92F41-B72D-4FE3-AF1C-C1D093CF312D}.Debug|ARM64.Build.0 = Debug|Any CPU
|
||||
{D6C92F41-B72D-4FE3-AF1C-C1D093CF312D}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{D6C92F41-B72D-4FE3-AF1C-C1D093CF312D}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{D6C92F41-B72D-4FE3-AF1C-C1D093CF312D}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{D6C92F41-B72D-4FE3-AF1C-C1D093CF312D}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{D6C92F41-B72D-4FE3-AF1C-C1D093CF312D}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{D6C92F41-B72D-4FE3-AF1C-C1D093CF312D}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{D6C92F41-B72D-4FE3-AF1C-C1D093CF312D}.Release|ARM64.ActiveCfg = Release|Any CPU
|
||||
{D6C92F41-B72D-4FE3-AF1C-C1D093CF312D}.Release|ARM64.Build.0 = Release|Any CPU
|
||||
{D6C92F41-B72D-4FE3-AF1C-C1D093CF312D}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{D6C92F41-B72D-4FE3-AF1C-C1D093CF312D}.Release|x64.Build.0 = Release|Any CPU
|
||||
{D6C92F41-B72D-4FE3-AF1C-C1D093CF312D}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{D6C92F41-B72D-4FE3-AF1C-C1D093CF312D}.Release|x86.Build.0 = Release|Any CPU
|
||||
{5DB5CE22-96F4-4789-8A48-4F3C164A5972}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{5DB5CE22-96F4-4789-8A48-4F3C164A5972}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{5DB5CE22-96F4-4789-8A48-4F3C164A5972}.Debug|ARM64.ActiveCfg = Debug|Any CPU
|
||||
{5DB5CE22-96F4-4789-8A48-4F3C164A5972}.Debug|ARM64.Build.0 = Debug|Any CPU
|
||||
{5DB5CE22-96F4-4789-8A48-4F3C164A5972}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{5DB5CE22-96F4-4789-8A48-4F3C164A5972}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{5DB5CE22-96F4-4789-8A48-4F3C164A5972}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{5DB5CE22-96F4-4789-8A48-4F3C164A5972}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{5DB5CE22-96F4-4789-8A48-4F3C164A5972}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{5DB5CE22-96F4-4789-8A48-4F3C164A5972}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{5DB5CE22-96F4-4789-8A48-4F3C164A5972}.Release|ARM64.ActiveCfg = Release|Any CPU
|
||||
{5DB5CE22-96F4-4789-8A48-4F3C164A5972}.Release|ARM64.Build.0 = Release|Any CPU
|
||||
{5DB5CE22-96F4-4789-8A48-4F3C164A5972}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{5DB5CE22-96F4-4789-8A48-4F3C164A5972}.Release|x64.Build.0 = Release|Any CPU
|
||||
{5DB5CE22-96F4-4789-8A48-4F3C164A5972}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{5DB5CE22-96F4-4789-8A48-4F3C164A5972}.Release|x86.Build.0 = Release|Any CPU
|
||||
{8091445A-2CAB-43A4-9459-745974D69834}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{8091445A-2CAB-43A4-9459-745974D69834}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{8091445A-2CAB-43A4-9459-745974D69834}.Debug|ARM64.ActiveCfg = Debug|Any CPU
|
||||
{8091445A-2CAB-43A4-9459-745974D69834}.Debug|ARM64.Build.0 = Debug|Any CPU
|
||||
{8091445A-2CAB-43A4-9459-745974D69834}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{8091445A-2CAB-43A4-9459-745974D69834}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{8091445A-2CAB-43A4-9459-745974D69834}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{8091445A-2CAB-43A4-9459-745974D69834}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{8091445A-2CAB-43A4-9459-745974D69834}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{8091445A-2CAB-43A4-9459-745974D69834}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{8091445A-2CAB-43A4-9459-745974D69834}.Release|ARM64.ActiveCfg = Release|Any CPU
|
||||
{8091445A-2CAB-43A4-9459-745974D69834}.Release|ARM64.Build.0 = Release|Any CPU
|
||||
{8091445A-2CAB-43A4-9459-745974D69834}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{8091445A-2CAB-43A4-9459-745974D69834}.Release|x64.Build.0 = Release|Any CPU
|
||||
{8091445A-2CAB-43A4-9459-745974D69834}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{8091445A-2CAB-43A4-9459-745974D69834}.Release|x86.Build.0 = Release|Any CPU
|
||||
{FB21E094-B723-4E7F-B7CB-434BF19B66E1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{FB21E094-B723-4E7F-B7CB-434BF19B66E1}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{FB21E094-B723-4E7F-B7CB-434BF19B66E1}.Debug|ARM64.ActiveCfg = Debug|Any CPU
|
||||
@@ -485,22 +407,6 @@ Global
|
||||
{8DC55331-B9F3-4811-8474-348662963260}.Release|x64.Build.0 = Release|Any CPU
|
||||
{8DC55331-B9F3-4811-8474-348662963260}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{8DC55331-B9F3-4811-8474-348662963260}.Release|x86.Build.0 = Release|Any CPU
|
||||
{C3C44E06-E03A-4971-99DA-06F6AD606B3B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{C3C44E06-E03A-4971-99DA-06F6AD606B3B}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{C3C44E06-E03A-4971-99DA-06F6AD606B3B}.Debug|ARM64.ActiveCfg = Debug|Any CPU
|
||||
{C3C44E06-E03A-4971-99DA-06F6AD606B3B}.Debug|ARM64.Build.0 = Debug|Any CPU
|
||||
{C3C44E06-E03A-4971-99DA-06F6AD606B3B}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{C3C44E06-E03A-4971-99DA-06F6AD606B3B}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{C3C44E06-E03A-4971-99DA-06F6AD606B3B}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{C3C44E06-E03A-4971-99DA-06F6AD606B3B}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{C3C44E06-E03A-4971-99DA-06F6AD606B3B}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{C3C44E06-E03A-4971-99DA-06F6AD606B3B}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{C3C44E06-E03A-4971-99DA-06F6AD606B3B}.Release|ARM64.ActiveCfg = Release|Any CPU
|
||||
{C3C44E06-E03A-4971-99DA-06F6AD606B3B}.Release|ARM64.Build.0 = Release|Any CPU
|
||||
{C3C44E06-E03A-4971-99DA-06F6AD606B3B}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{C3C44E06-E03A-4971-99DA-06F6AD606B3B}.Release|x64.Build.0 = Release|Any CPU
|
||||
{C3C44E06-E03A-4971-99DA-06F6AD606B3B}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{C3C44E06-E03A-4971-99DA-06F6AD606B3B}.Release|x86.Build.0 = Release|Any CPU
|
||||
{A726FD43-B111-423B-BAF6-D65B4C0E37B5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{A726FD43-B111-423B-BAF6-D65B4C0E37B5}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{A726FD43-B111-423B-BAF6-D65B4C0E37B5}.Debug|ARM64.ActiveCfg = Debug|Any CPU
|
||||
@@ -602,11 +508,6 @@ Global
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(NestedProjects) = preSolution
|
||||
{2DABFD88-246F-47C2-B752-24DCF7477CEC} = {5881405B-CA88-4A10-A8AC-1822249AC0FA}
|
||||
{4D762F1C-0905-4B82-9F2C-C0FCD96E2F74} = {2DABFD88-246F-47C2-B752-24DCF7477CEC}
|
||||
{D6C92F41-B72D-4FE3-AF1C-C1D093CF312D} = {2DABFD88-246F-47C2-B752-24DCF7477CEC}
|
||||
{5DB5CE22-96F4-4789-8A48-4F3C164A5972} = {2DABFD88-246F-47C2-B752-24DCF7477CEC}
|
||||
{8091445A-2CAB-43A4-9459-745974D69834} = {5881405B-CA88-4A10-A8AC-1822249AC0FA}
|
||||
{8D94F264-4EE9-4C24-AB77-2CCA36858309} = {9A8EB967-1EAB-439E-8FDB-B9ACAC6499EC}
|
||||
{4CC2DC7D-27D2-4F52-89DF-7D45B41BB40F} = {8D351DB0-74E6-4C1E-A123-34D6BBBD5585}
|
||||
{05A45688-7EEF-4656-818A-2477625C3707} = {8D351DB0-74E6-4C1E-A123-34D6BBBD5585}
|
||||
@@ -629,7 +530,6 @@ Global
|
||||
{64A217AE-4E95-468E-85C3-67C27D689FF4} = {9A8EB967-1EAB-439E-8FDB-B9ACAC6499EC}
|
||||
{6F6CA153-1AC6-454A-ACDC-2C706E2A437E} = {4CC2DC7D-27D2-4F52-89DF-7D45B41BB40F}
|
||||
{8DC55331-B9F3-4811-8474-348662963260} = {4CC2DC7D-27D2-4F52-89DF-7D45B41BB40F}
|
||||
{C3C44E06-E03A-4971-99DA-06F6AD606B3B} = {2DABFD88-246F-47C2-B752-24DCF7477CEC}
|
||||
{A726FD43-B111-423B-BAF6-D65B4C0E37B5} = {8D94F264-4EE9-4C24-AB77-2CCA36858309}
|
||||
{E1D4352C-51AC-4572-8515-0B4E89A2442F} = {8539067C-9968-4AEB-928C-FEDC43989A79}
|
||||
{54DCFBDC-7A2E-439A-92F5-E5A19A2D0DFC} = {8539067C-9968-4AEB-928C-FEDC43989A79}
|
||||
|
||||
@@ -4,6 +4,7 @@ using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.UI.Xaml;
|
||||
using System;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using VDownload.Core.Tasks;
|
||||
using VDownload.Core.ViewModels;
|
||||
using VDownload.Core.ViewModels.Authentication;
|
||||
@@ -145,6 +146,7 @@ namespace VDownload
|
||||
services.AddSingleton<SettingsViewModel>();
|
||||
services.AddSingleton<HomeDownloadsViewModel>();
|
||||
services.AddSingleton<HomeVideoViewModel>();
|
||||
services.AddSingleton<HomePlaylistViewModel>();
|
||||
services.AddSingleton<HomeViewModel>();
|
||||
services.AddSingleton<BaseViewModel>();
|
||||
|
||||
@@ -153,10 +155,29 @@ namespace VDownload
|
||||
services.AddTransient<SettingsView>();
|
||||
services.AddTransient<HomeDownloadsView>();
|
||||
services.AddTransient<HomeVideoView>();
|
||||
services.AddTransient<HomePlaylistView>();
|
||||
services.AddTransient<HomeView>();
|
||||
services.AddTransient<BaseWindow>();
|
||||
}
|
||||
|
||||
protected override async void OnLaunched(LaunchActivatedEventArgs args)
|
||||
{
|
||||
await InitData();
|
||||
|
||||
_window = _serviceProvider.GetService<BaseWindow>();
|
||||
_window.RootLoaded += Window_RootLoaded;
|
||||
_window.Activate();
|
||||
|
||||
AssignStaticProperties();
|
||||
}
|
||||
|
||||
protected async Task InitData()
|
||||
{
|
||||
ISettingsService settingsService = _serviceProvider.GetService<ISettingsService>();
|
||||
IAuthenticationDataService authenticationDataService = _serviceProvider.GetService<IAuthenticationDataService>();
|
||||
await Task.WhenAll(settingsService.Load(), authenticationDataService.Load());
|
||||
}
|
||||
|
||||
protected void AssignStaticProperties()
|
||||
{
|
||||
IStoragePickerService storagePickerService = _serviceProvider.GetService<IStoragePickerService>();
|
||||
@@ -165,15 +186,6 @@ namespace VDownload
|
||||
ViewModelToViewConverter.ServiceProvider = _serviceProvider;
|
||||
}
|
||||
|
||||
protected override void OnLaunched(LaunchActivatedEventArgs args)
|
||||
{
|
||||
_window = _serviceProvider.GetService<BaseWindow>();
|
||||
_window.RootLoaded += Window_RootLoaded;
|
||||
_window.Activate();
|
||||
|
||||
AssignStaticProperties();
|
||||
}
|
||||
|
||||
protected void Window_RootLoaded(object sender, EventArgs e)
|
||||
{
|
||||
IDialogsService dialogsService = _serviceProvider.GetService<IDialogsService>();
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:v="using:VDownload.Core.Views"
|
||||
xmlns:lt="using:VDownload.Toolkit.UI.Converters"
|
||||
xmlns:lt="using:SimpleToolkit.UI.WinUI.Converters"
|
||||
xmlns:ct="using:CommunityToolkit.WinUI.Converters">
|
||||
<v:ViewModelToViewConverter x:Key="ViewModelToViewConverter"/>
|
||||
|
||||
|
||||
@@ -132,6 +132,7 @@
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="8.0.0" />
|
||||
<PackageReference Include="Microsoft.WindowsAppSDK" Version="1.4.240211001" />
|
||||
<PackageReference Include="Microsoft.Windows.SDK.BuildTools" Version="10.0.22621.2428" />
|
||||
<PackageReference Include="SimpleToolkit.UI.WinUI.Converters" Version="1.4.0" />
|
||||
<Manifest Include="$(ApplicationManifest)" />
|
||||
</ItemGroup>
|
||||
|
||||
@@ -160,7 +161,6 @@
|
||||
<ProjectReference Include="..\VDownload.Sources\VDownload.Sources.Twitch\VDownload.Sources.Twitch.Authentication\VDownload.Sources.Twitch.Authentication.csproj" />
|
||||
<ProjectReference Include="..\VDownload.Sources\VDownload.Sources.Twitch\VDownload.Sources.Twitch\VDownload.Sources.Twitch.csproj" />
|
||||
<ProjectReference Include="..\VDownload.Sources\VDownload.Sources\VDownload.Sources.csproj" />
|
||||
<ProjectReference Include="..\VDownload.Toolkit\VDownload.Toolkit.UI\VDownload.Toolkit.UI.Converters\VDownload.Toolkit.UI.Converters.csproj" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Update="Assets\BaseView\AuthenticationDark.png">
|
||||
|
||||
@@ -116,7 +116,8 @@
|
||||
"token_schema": "Bearer",
|
||||
"client_id": "yukkqkwp61wsv3u1pya17crpyaa98y",
|
||||
"endpoints": {
|
||||
"get_videos": "https://api.twitch.tv/helix/videos"
|
||||
"get_videos": "https://api.twitch.tv/helix/videos",
|
||||
"get_users": "https://api.twitch.tv/helix/users"
|
||||
}
|
||||
},
|
||||
"gql": {
|
||||
@@ -148,6 +149,18 @@
|
||||
"height": 1080
|
||||
},
|
||||
"stream_playlist_regex": "#EXT-X-MEDIA:TYPE=VIDEO,GROUP-ID=\"\\w+\",NAME=\"(?<id>.+)\",AUTOSELECT=\\w+,DEFAULT=\\w+\\n#EXT-X-STREAM-INF:BANDWIDTH=\\d+,CODECS=\"(?<video_codec>.+),(?<audio_codec>.+)\",RESOLUTION=(?<width>\\d+)x(?<height>\\d+),VIDEO=\".+\"(?:,FRAME-RATE=(?<framerate>\\d+.\\d+))?\n(?<url>.+)"
|
||||
},
|
||||
"clip": {
|
||||
"regexes": [
|
||||
"clip\\/(\\w+-\\w+)",
|
||||
"clips\\.twitch\\.tv\\/(\\w+-\\w+)"
|
||||
]
|
||||
},
|
||||
"channel": {
|
||||
"regexes": [
|
||||
"twitch\\.tv\\/(\\w+)(?:\\/)?(?:\\/videos)?$"
|
||||
],
|
||||
"url": "https://www.twitch.tv/{0}"
|
||||
}
|
||||
},
|
||||
"download": {
|
||||
|
||||
Reference in New Issue
Block a user