new_version_init

This commit is contained in:
2024-02-13 02:59:40 +01:00
Unverified
parent e36c1404ee
commit 91f9b645bd
352 changed files with 6777 additions and 8326 deletions

View File

@@ -0,0 +1,147 @@
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using Microsoft.UI.Xaml.Controls;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection.Metadata.Ecma335;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using VDownload.GUI.Services.Dialog;
using VDownload.GUI.Services.WebView;
using VDownload.Sources.Twitch;
using VDownload.Sources.Twitch.Authentication;
namespace VDownload.GUI.ViewModels
{
public partial class AuthenticationViewModel : ObservableObject
{
#region ENUMS
public enum AuthenticationButton
{
SignIn,
SignOut,
Loading
}
#endregion
#region SERVICES
private IDialogService _dialogService;
private IWebViewService _webViewService;
private ITwitchAuthenticationService _twitchAuthenticationService;
#endregion
#region PROPERTIES
[ObservableProperty]
private string _twitchDescription;
[ObservableProperty]
private AuthenticationButton _twitchButtonState;
#endregion
#region CONSTRUCTORS
public AuthenticationViewModel(IDialogService dialogService, IWebViewService webViewService, ITwitchAuthenticationService twitchAuthenticationService)
{
_dialogService = dialogService;
_webViewService = webViewService;
_twitchAuthenticationService = twitchAuthenticationService;
TwitchButtonState = AuthenticationButton.Loading;
}
#endregion
#region PUBLIC METHODS
[RelayCommand]
public async Task TwitchAuthentication()
{
AuthenticationButton state = TwitchButtonState;
TwitchButtonState = AuthenticationButton.Loading;
if (state == AuthenticationButton.SignOut)
{
await _twitchAuthenticationService.DeleteToken();
}
else
{
string url = await _webViewService.Show(new Uri(_twitchAuthenticationService.AuthenticationPageUrl), _twitchAuthenticationService.AuthenticationPageClosePredicate, "Twitch authentication");
Match match = _twitchAuthenticationService.AuthenticationPageRedirectUrlRegex.Match(url);
if (match.Success)
{
string token = match.Groups[1].Value;
await _twitchAuthenticationService.SetToken(Encoding.UTF8.GetBytes(token));
}
else
{
await _dialogService.ShowOk("Twitch authentication error", "An error occured");
}
}
await TwitchAuthenticationRefresh();
}
[RelayCommand]
public async Task Navigation()
{
List<Task> refreshTasks = new List<Task>
{
TwitchAuthenticationRefresh()
};
await Task.WhenAll(refreshTasks);
}
#endregion
#region PRIVATE METHODS
private async Task TwitchAuthenticationRefresh()
{
TwitchButtonState = AuthenticationButton.Loading;
byte[]? token = await _twitchAuthenticationService.GetToken();
if (token is null)
{
TwitchDescription = "You are not authenticated. Please sign in";
TwitchButtonState = AuthenticationButton.SignIn;
}
else
{
TwitchValidationResult validationResult = await _twitchAuthenticationService.ValidateToken(token);
if (validationResult.Success)
{
TwitchDescription = $"Signed in as {validationResult.TokenData.Login}. Expiration date: {validationResult.TokenData.ExpirationDate:dd.MM.yyyy HH:mm}";
TwitchButtonState = AuthenticationButton.SignOut;
}
else
{
await _twitchAuthenticationService.DeleteToken();
TwitchDescription = "Token expired or is invalid. Please log in again";
TwitchButtonState = AuthenticationButton.SignIn;
}
}
}
#endregion
}
}

View File

@@ -0,0 +1,315 @@
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.Common;
using VDownload.Common.Exceptions;
using VDownload.Common.Models;
using VDownload.GUI.Services.StoragePicker;
using VDownload.Services.Search;
using VDownload.Tasks;
namespace VDownload.GUI.ViewModels
{
public partial class HomeViewModel : ObservableObject
{
#region ENUMS
public enum OptionBarContentType
{
None,
VideoSearch,
PlaylistSearch
}
public enum MainContentType
{
Downloads,
Video
}
#endregion
#region SERVICES
private IStoragePickerService _storagePickerService;
private ISearchService _searchService;
private IDownloadTasksManager _tasksService;
#endregion
#region PROPERTIES
// MAIN
[ObservableProperty]
private MainContentType _mainContent;
// DOWNLOADS
public ObservableCollection<DownloadTask> Tasks => _tasksService.Tasks;
[ObservableProperty]
private bool _taskListIsEmpty;
// VIDEO
[ObservableProperty]
private DownloadTask _task;
// OPTION BAR
[ObservableProperty]
private OptionBarContentType _optionBarContent;
[ObservableProperty]
private string _optionBarMessage;
[ObservableProperty]
private bool _optionBarLoading;
[ObservableProperty]
private bool _optionBarVideoSearchButtonChecked;
[ObservableProperty]
private bool _optionBarPlaylistSearchButtonChecked;
[ObservableProperty]
private bool _optionBarSearchNotPending;
[ObservableProperty]
private string _optionBarVideoSearchTBValue;
[ObservableProperty]
private string _optionBarPlaylistSearchTBValue;
[ObservableProperty]
private int _optionBarPlaylistSearchNBValue;
#endregion
#region CONSTRUCTORS
public HomeViewModel(IStoragePickerService storagePickerService, ISearchService searchService, IDownloadTasksManager tasksService)
{
_storagePickerService = storagePickerService;
_searchService = searchService;
_tasksService = tasksService;
_tasksService.Tasks.CollectionChanged += Tasks_CollectionChanged;
_taskListIsEmpty = _tasksService.Tasks.Count == 0;
}
#endregion
#region COMMANDS
[RelayCommand]
public void Navigation()
{
MainContent = MainContentType.Downloads;
OptionBarContent = OptionBarContentType.None;
OptionBarMessage = null;
OptionBarVideoSearchButtonChecked = false;
OptionBarPlaylistSearchButtonChecked = false;
OptionBarSearchNotPending = true;
OptionBarVideoSearchTBValue = string.Empty;
OptionBarPlaylistSearchNBValue = 1; // TODO: load from settings
OptionBarPlaylistSearchTBValue = string.Empty;
}
// DOWNLOADS
[RelayCommand]
public void StartCancelTask(DownloadTask task)
{
DownloadTaskStatus[] idleStatuses =
[
DownloadTaskStatus.Idle,
DownloadTaskStatus.EndedUnsuccessfully,
DownloadTaskStatus.EndedSuccessfully,
DownloadTaskStatus.EndedCancelled
];
if (idleStatuses.Contains(task.Status))
{
task.Enqueue();
}
else
{
task.Cancel();
}
}
// VIDEO
[RelayCommand]
public async Task Browse()
{
string? newDirectory = await _storagePickerService.OpenDirectory();
if (newDirectory is not null)
{
Task.DirectoryPath = newDirectory;
}
}
[RelayCommand]
public async Task CreateTask()
{
string extension = Task.MediaType switch
{
MediaType.OnlyAudio => Task.AudioExtension.ToString(),
_ => Task.VideoExtension.ToString()
};
Task.Filename = string.Join("_", Task.Filename.Split(Path.GetInvalidFileNameChars()));
string file = $"{Task.Filename}.{extension}";
string path = Path.Combine(Task.DirectoryPath, file);
await File.WriteAllBytesAsync(path, [0x00]);
File.Delete(path);
_tasksService.AddTask(Task);
Navigation();
}
// OPTION BAR
[RelayCommand]
public void LoadFromSubscription()
{
MainContent = MainContentType.Downloads;
OptionBarContent = OptionBarContentType.None;
OptionBarVideoSearchButtonChecked = false;
OptionBarPlaylistSearchButtonChecked = false;
OptionBarSearchNotPending = false;
//TODO: Load videos
}
[RelayCommand]
public void VideoSearchShow()
{
MainContent = MainContentType.Downloads;
if (OptionBarContent != OptionBarContentType.VideoSearch)
{
OptionBarContent = OptionBarContentType.VideoSearch;
OptionBarPlaylistSearchButtonChecked = false;
}
else
{
OptionBarContent = OptionBarContentType.None;
}
}
[RelayCommand]
public void PlaylistSearchShow()
{
MainContent = MainContentType.Downloads;
if (OptionBarContent != OptionBarContentType.PlaylistSearch)
{
OptionBarContent = OptionBarContentType.PlaylistSearch;
OptionBarVideoSearchButtonChecked = false;
}
else
{
OptionBarContent = OptionBarContentType.None;
}
}
[RelayCommand]
public async Task VideoSearchStart()
{
OptionBarSearchNotPending = false;
OptionBarLoading = true;
OptionBarMessage = "Loading...";
Video video;
try
{
video = await _searchService.SearchVideo(OptionBarVideoSearchTBValue);
}
catch (MediaSearchException ex)
{
OptionBarLoading = false;
OptionBarMessage = ex.Message;
OptionBarSearchNotPending = true;
return;
}
Task = new DownloadTask(video);
MainContent = MainContentType.Video;
OptionBarSearchNotPending = true;
OptionBarLoading = false;
OptionBarMessage = null;
}
[RelayCommand]
public async Task PlaylistSearchStart()
{
OptionBarSearchNotPending = false;
OptionBarLoading = true;
OptionBarMessage = "Loading...";
Playlist playlist;
try
{
playlist = await _searchService.SearchPlaylist(OptionBarPlaylistSearchTBValue, OptionBarPlaylistSearchNBValue);
}
catch (MediaSearchException ex)
{
OptionBarLoading = false;
OptionBarMessage = ex.Message;
OptionBarSearchNotPending = true;
return;
}
OptionBarSearchNotPending = true;
OptionBarLoading = false;
OptionBarMessage = null;
}
[RelayCommand]
public void Download()
{
}
#endregion
#region EVENT HANDLERS
private void Tasks_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
TaskListIsEmpty = Tasks.Count == 0;
}
#endregion
}
}

View File

@@ -0,0 +1,19 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace VDownload.GUI.ViewModels
{
public class SettingsViewModel
{
#region CONSTRUCTORS
public SettingsViewModel()
{
}
#endregion
}
}

View File

@@ -0,0 +1,27 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0-windows10.0.19041.0</TargetFramework>
<TargetPlatformMinVersion>10.0.17763.0</TargetPlatformMinVersion>
<RootNamespace>VDownload.GUI.ViewModels</RootNamespace>
<RuntimeIdentifiers>win10-x86;win10-x64;win10-arm64</RuntimeIdentifiers>
<UseWinUI>true</UseWinUI>
<UseRidGraph>true</UseRidGraph>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.2.2" />
<PackageReference Include="Microsoft.WindowsAppSDK" Version="1.4.231219000" />
<PackageReference Include="Microsoft.Windows.SDK.BuildTools" Version="10.0.22621.2428" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\VDownload.Common\VDownload.Common.csproj" />
<ProjectReference Include="..\..\VDownload.Services\VDownload.Services.Search\VDownload.Services.Search.csproj" />
<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.Tasks\VDownload.Tasks.csproj" />
<ProjectReference Include="..\VDownload.GUI.Services\VDownload.GUI.Services.Dialog\VDownload.GUI.Services.Dialog.csproj" />
<ProjectReference Include="..\VDownload.GUI.Services\VDownload.GUI.Services.StoragePicker\VDownload.GUI.Services.StoragePicker.csproj" />
<ProjectReference Include="..\VDownload.GUI.Services\VDownload.GUI.Services.WebView\VDownload.GUI.Services.WebView.csproj" />
</ItemGroup>
</Project>