Merge pull request #78 from mateuszskoczek/features/errors
Features/errors
This commit is contained in:
@@ -117,10 +117,10 @@
|
|||||||
<resheader name="writer">
|
<resheader name="writer">
|
||||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
</resheader>
|
</resheader>
|
||||||
<data name="AuthenticationButtonSignIn.Value" xml:space="preserve">
|
<data name="AuthenticationButtonSignIn.Text" xml:space="preserve">
|
||||||
<value>Sign in</value>
|
<value>Sign in</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="AuthenticationButtonSignOut.Value" xml:space="preserve">
|
<data name="AuthenticationButtonSignOut.Text" xml:space="preserve">
|
||||||
<value>Sign out</value>
|
<value>Sign out</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="AuthenticationDescriptionLoading.Value" xml:space="preserve">
|
<data name="AuthenticationDescriptionLoading.Value" xml:space="preserve">
|
||||||
@@ -135,9 +135,18 @@
|
|||||||
<data name="TwitchAuthenticationDescriptionAuthenticationInvalid" xml:space="preserve">
|
<data name="TwitchAuthenticationDescriptionAuthenticationInvalid" xml:space="preserve">
|
||||||
<value>Token expired or is invalid. Please log in again</value>
|
<value>Token expired or is invalid. Please log in again</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="TwitchAuthenticationDescriptionCannotValidate" xml:space="preserve">
|
||||||
|
<value>Cannot validate token. Check your internet connection and try again later.</value>
|
||||||
|
</data>
|
||||||
<data name="TwitchAuthenticationDescriptionNotAuthenticated" xml:space="preserve">
|
<data name="TwitchAuthenticationDescriptionNotAuthenticated" xml:space="preserve">
|
||||||
<value>You are not authenticated. Please sign in</value>
|
<value>You are not authenticated. Please sign in</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="TwitchAuthenticationDescriptionNotAuthenticatedNoInternetConnection" xml:space="preserve">
|
||||||
|
<value>You are not authenticated and there is no internet connection. Check your internet connection and try again later.</value>
|
||||||
|
</data>
|
||||||
|
<data name="TwitchAuthenticationDialogMessage" xml:space="preserve">
|
||||||
|
<value>An unknown error occured during Twitch login</value>
|
||||||
|
</data>
|
||||||
<data name="TwitchAuthenticationDialogTitle" xml:space="preserve">
|
<data name="TwitchAuthenticationDialogTitle" xml:space="preserve">
|
||||||
<value>Twitch authentication error</value>
|
<value>Twitch authentication error</value>
|
||||||
</data>
|
</data>
|
||||||
|
|||||||
@@ -117,6 +117,21 @@
|
|||||||
<resheader name="writer">
|
<resheader name="writer">
|
||||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
</resheader>
|
</resheader>
|
||||||
|
<data name="DialogErrorMessageNoInternetConnection" xml:space="preserve">
|
||||||
|
<value>No internet connection. Try again later.</value>
|
||||||
|
</data>
|
||||||
|
<data name="DialogErrorTitle" xml:space="preserve">
|
||||||
|
<value>Error</value>
|
||||||
|
</data>
|
||||||
|
<data name="ErrorDownloadingTimeout" xml:space="preserve">
|
||||||
|
<value>Downloading timeout. Check your internet connection and try again later.</value>
|
||||||
|
</data>
|
||||||
|
<data name="ErrorFFmpeg" xml:space="preserve">
|
||||||
|
<value>FFmpeg exited with error.</value>
|
||||||
|
</data>
|
||||||
|
<data name="ErrorFFmpegPath" xml:space="preserve">
|
||||||
|
<value>No FFmpeg executables found. Check path in settings and try again.</value>
|
||||||
|
</data>
|
||||||
<data name="StatusCancelled.Text" xml:space="preserve">
|
<data name="StatusCancelled.Text" xml:space="preserve">
|
||||||
<value>Cancelled</value>
|
<value>Cancelled</value>
|
||||||
</data>
|
</data>
|
||||||
|
|||||||
@@ -117,6 +117,18 @@
|
|||||||
<resheader name="writer">
|
<resheader name="writer">
|
||||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
</resheader>
|
</resheader>
|
||||||
|
<data name="ErrorInfoBar.Title" xml:space="preserve">
|
||||||
|
<value>Error</value>
|
||||||
|
</data>
|
||||||
|
<data name="ErrorInfoBarNoInternetConnection" xml:space="preserve">
|
||||||
|
<value>No internet connection</value>
|
||||||
|
</data>
|
||||||
|
<data name="OptionBarCancelAll.Label" xml:space="preserve">
|
||||||
|
<value>Cancel all</value>
|
||||||
|
</data>
|
||||||
|
<data name="OptionBarCancelAll.Width" xml:space="preserve">
|
||||||
|
<value>80</value>
|
||||||
|
</data>
|
||||||
<data name="OptionBarDownloadAll.Label" xml:space="preserve">
|
<data name="OptionBarDownloadAll.Label" xml:space="preserve">
|
||||||
<value>Download all</value>
|
<value>Download all</value>
|
||||||
</data>
|
</data>
|
||||||
|
|||||||
@@ -123,6 +123,9 @@
|
|||||||
<data name="EmptyUrl" xml:space="preserve">
|
<data name="EmptyUrl" xml:space="preserve">
|
||||||
<value>Invalid url. Url cannot be empty.</value>
|
<value>Invalid url. Url cannot be empty.</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="SearchTimeout" xml:space="preserve">
|
||||||
|
<value>Search timeout. Check your internet connection.</value>
|
||||||
|
</data>
|
||||||
<data name="SourceNotSupported" xml:space="preserve">
|
<data name="SourceNotSupported" xml:space="preserve">
|
||||||
<value>Invalid url. Url does not match any of supported source.</value>
|
<value>Invalid url. Url does not match any of supported source.</value>
|
||||||
</data>
|
</data>
|
||||||
|
|||||||
@@ -126,6 +126,9 @@
|
|||||||
<data name="Header.Text" xml:space="preserve">
|
<data name="Header.Text" xml:space="preserve">
|
||||||
<value>Subscriptions</value>
|
<value>Subscriptions</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="NoInternetConnectionError" xml:space="preserve">
|
||||||
|
<value>No internet connection</value>
|
||||||
|
</data>
|
||||||
<data name="PlaylistSearchButton.Content" xml:space="preserve">
|
<data name="PlaylistSearchButton.Content" xml:space="preserve">
|
||||||
<value>Add</value>
|
<value>Add</value>
|
||||||
</data>
|
</data>
|
||||||
|
|||||||
@@ -13,6 +13,9 @@ using System.IO;
|
|||||||
using VDownload.Services.UI.Notifications;
|
using VDownload.Services.UI.Notifications;
|
||||||
using VDownload.Services.UI.StringResources;
|
using VDownload.Services.UI.StringResources;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Net.Http;
|
||||||
|
using Instances.Exceptions;
|
||||||
|
using FFMpegCore.Exceptions;
|
||||||
|
|
||||||
namespace VDownload.Core.Tasks
|
namespace VDownload.Core.Tasks
|
||||||
{
|
{
|
||||||
@@ -140,7 +143,11 @@ namespace VDownload.Core.Tasks
|
|||||||
|
|
||||||
await _settingsService.Load();
|
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}\\{Guid.NewGuid()}";
|
||||||
|
if (Directory.Exists(tempDirectory))
|
||||||
|
{
|
||||||
|
Directory.Delete(tempDirectory, true);
|
||||||
|
}
|
||||||
Directory.CreateDirectory(tempDirectory);
|
Directory.CreateDirectory(tempDirectory);
|
||||||
|
|
||||||
List<string> content = new List<string>()
|
List<string> content = new List<string>()
|
||||||
@@ -180,10 +187,11 @@ namespace VDownload.Core.Tasks
|
|||||||
.JoinProgressReporter(onProgressProcessing, downloadResult.NewDuration);
|
.JoinProgressReporter(onProgressProcessing, downloadResult.NewDuration);
|
||||||
await ffmpegBuilder.RunAsync(downloadResult.File, outputPath);
|
await ffmpegBuilder.RunAsync(downloadResult.File, outputPath);
|
||||||
|
|
||||||
|
StorageFile outputFile = await StorageFile.GetFileFromPathAsync(outputPath);
|
||||||
|
|
||||||
UpdateStatusWithDispatcher(DownloadTaskStatus.Finalizing);
|
UpdateStatusWithDispatcher(DownloadTaskStatus.Finalizing);
|
||||||
|
|
||||||
string destination = $"{DownloadOptions.Directory}\\{DownloadOptions.Filename}.{DownloadOptions.Extension}";
|
await Finalizing(outputFile);
|
||||||
File.Copy(outputPath, destination, true);
|
|
||||||
|
|
||||||
UpdateStatusWithDispatcher(DownloadTaskStatus.EndedSuccessfully);
|
UpdateStatusWithDispatcher(DownloadTaskStatus.EndedSuccessfully);
|
||||||
|
|
||||||
@@ -199,7 +207,26 @@ namespace VDownload.Core.Tasks
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
UpdateErrorWithDispatcher(ex.Message);
|
string message;
|
||||||
|
|
||||||
|
if (ex is TaskCanceledException || ex is HttpRequestException)
|
||||||
|
{
|
||||||
|
message = _stringResourcesService.HomeDownloadsViewResources.Get("ErrorDownloadingTimeout");
|
||||||
|
}
|
||||||
|
else if (ex is InstanceFileNotFoundException)
|
||||||
|
{
|
||||||
|
message = _stringResourcesService.HomeDownloadsViewResources.Get("ErrorFFmpegPath");
|
||||||
|
}
|
||||||
|
else if (ex is FFMpegException)
|
||||||
|
{
|
||||||
|
message = _stringResourcesService.HomeDownloadsViewResources.Get("ErrorFFmpeg");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
message = ex.Message;
|
||||||
|
}
|
||||||
|
|
||||||
|
UpdateErrorWithDispatcher(message);
|
||||||
UpdateStatusWithDispatcher(DownloadTaskStatus.EndedUnsuccessfully);
|
UpdateStatusWithDispatcher(DownloadTaskStatus.EndedUnsuccessfully);
|
||||||
|
|
||||||
if (_settingsService.Data.Common.Notifications.OnUnsuccessful)
|
if (_settingsService.Data.Common.Notifications.OnUnsuccessful)
|
||||||
@@ -218,11 +245,19 @@ namespace VDownload.Core.Tasks
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UpdateStatusWithDispatcher(DownloadTaskStatus status) => _dispatcherQueue.TryEnqueue(() => Status = status);
|
protected async Task Finalizing(StorageFile outputFile)
|
||||||
|
{
|
||||||
|
StorageFolder destination = await StorageFolder.GetFolderFromPathAsync(DownloadOptions.Directory);
|
||||||
|
|
||||||
private void UpdateProgressWithDispatcher(double progress) => _dispatcherQueue.TryEnqueue(() => Progress = progress);
|
string filename = $"{DownloadOptions.Filename}.{DownloadOptions.Extension}";
|
||||||
|
await outputFile.CopyAsync(destination, filename, NameCollisionOption.ReplaceExisting);
|
||||||
|
}
|
||||||
|
|
||||||
private void UpdateErrorWithDispatcher(string message) => _dispatcherQueue.TryEnqueue(() => Error = message);
|
protected void UpdateStatusWithDispatcher(DownloadTaskStatus status) => _dispatcherQueue.TryEnqueue(() => Status = status);
|
||||||
|
|
||||||
|
protected void UpdateProgressWithDispatcher(double progress) => _dispatcherQueue.TryEnqueue(() => Progress = progress);
|
||||||
|
|
||||||
|
protected void UpdateErrorWithDispatcher(string message) => _dispatcherQueue.TryEnqueue(() => Error = message);
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
using CommunityToolkit.Mvvm.ComponentModel;
|
using CommunityToolkit.Mvvm.ComponentModel;
|
||||||
using CommunityToolkit.Mvvm.Input;
|
using CommunityToolkit.Mvvm.Input;
|
||||||
|
using CommunityToolkit.WinUI.Helpers;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Net.Http;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
@@ -44,10 +46,13 @@ namespace VDownload.Core.ViewModels.Authentication
|
|||||||
#region PROPERTIES
|
#region PROPERTIES
|
||||||
|
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private AuthenticationButton _twitchButtonState = AuthenticationButton.Loading;
|
protected AuthenticationButton _twitchButtonState = AuthenticationButton.Loading;
|
||||||
|
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string _twitchDescription;
|
protected bool _twitchButtonEnable = true;
|
||||||
|
|
||||||
|
[ObservableProperty]
|
||||||
|
protected string _twitchDescription;
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
@@ -107,7 +112,9 @@ namespace VDownload.Core.ViewModels.Authentication
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
await _dialogsService.ShowOk(_stringResourcesService.AuthenticationViewResources.Get("TwitchAuthenticationDialogTitle"), "An unknown error occured"); // TODO : Change to string resource
|
string title = _stringResourcesService.AuthenticationViewResources.Get("TwitchAuthenticationDialogTitle");
|
||||||
|
string message = _stringResourcesService.AuthenticationViewResources.Get("TwitchAuthenticationDialogMessage");
|
||||||
|
await _dialogsService.ShowOk(title, message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
await TwitchAuthenticationRefresh();
|
await TwitchAuthenticationRefresh();
|
||||||
@@ -122,17 +129,38 @@ namespace VDownload.Core.ViewModels.Authentication
|
|||||||
private async Task TwitchAuthenticationRefresh()
|
private async Task TwitchAuthenticationRefresh()
|
||||||
{
|
{
|
||||||
TwitchButtonState = AuthenticationButton.Loading;
|
TwitchButtonState = AuthenticationButton.Loading;
|
||||||
|
TwitchButtonEnable = true;
|
||||||
|
|
||||||
byte[]? token = await _twitchAuthenticationService.GetToken();
|
byte[]? token = await _twitchAuthenticationService.GetToken();
|
||||||
|
|
||||||
if (token is null)
|
if (token is null)
|
||||||
|
{
|
||||||
|
if (!NetworkHelper.Instance.ConnectionInformation.IsInternetAvailable)
|
||||||
|
{
|
||||||
|
TwitchButtonEnable = false;
|
||||||
|
TwitchDescription = _stringResourcesService.AuthenticationViewResources.Get("TwitchAuthenticationDescriptionNotAuthenticatedNoInternetConnection");
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
TwitchDescription = _stringResourcesService.AuthenticationViewResources.Get("TwitchAuthenticationDescriptionNotAuthenticated");
|
TwitchDescription = _stringResourcesService.AuthenticationViewResources.Get("TwitchAuthenticationDescriptionNotAuthenticated");
|
||||||
|
}
|
||||||
TwitchButtonState = AuthenticationButton.SignIn;
|
TwitchButtonState = AuthenticationButton.SignIn;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
TwitchValidationResult validationResult = await _twitchAuthenticationService.ValidateToken(token);
|
TwitchValidationResult validationResult;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
validationResult = await _twitchAuthenticationService.ValidateToken(token);
|
||||||
|
}
|
||||||
|
catch (Exception ex) when (ex is TaskCanceledException || ex is HttpRequestException)
|
||||||
|
{
|
||||||
|
TwitchDescription = _stringResourcesService.AuthenticationViewResources.Get("TwitchAuthenticationDescriptionCannotValidate");
|
||||||
|
TwitchButtonState = AuthenticationButton.SignIn;
|
||||||
|
TwitchButtonEnable = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (validationResult.Success)
|
if (validationResult.Success)
|
||||||
{
|
{
|
||||||
TwitchDescription = string.Format(_stringResourcesService.AuthenticationViewResources.Get("TwitchAuthenticationDescriptionAuthenticated"), validationResult.TokenData.Login, validationResult.TokenData.ExpirationDate);
|
TwitchDescription = string.Format(_stringResourcesService.AuthenticationViewResources.Get("TwitchAuthenticationDescriptionAuthenticated"), validationResult.TokenData.Login, validationResult.TokenData.ExpirationDate);
|
||||||
|
|||||||
@@ -68,6 +68,14 @@ namespace VDownload.Core.ViewModels.Home
|
|||||||
];
|
];
|
||||||
if (idleStatuses.Contains(task.Status))
|
if (idleStatuses.Contains(task.Status))
|
||||||
{
|
{
|
||||||
|
if (!NetworkHelper.Instance.ConnectionInformation.IsInternetAvailable)
|
||||||
|
{
|
||||||
|
string title = _stringResourcesService.HomeDownloadsViewResources.Get("DialogErrorTitle");
|
||||||
|
string message = _stringResourcesService.HomeDownloadsViewResources.Get("DialogErrorMessageNoInternetConnection");
|
||||||
|
await _dialogsService.ShowOk(title, message);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
bool continueEnqueue = true;
|
bool continueEnqueue = true;
|
||||||
if (NetworkHelper.Instance.ConnectionInformation.IsInternetOnMeteredConnection)
|
if (NetworkHelper.Instance.ConnectionInformation.IsInternetOnMeteredConnection)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ using CommunityToolkit.WinUI.Helpers;
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Net.Http;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using VDownload.Core.Tasks;
|
using VDownload.Core.Tasks;
|
||||||
@@ -23,13 +24,6 @@ namespace VDownload.Core.ViewModels.Home
|
|||||||
{
|
{
|
||||||
#region ENUMS
|
#region ENUMS
|
||||||
|
|
||||||
public enum OptionBarMessageIconType
|
|
||||||
{
|
|
||||||
None,
|
|
||||||
ProgressRing,
|
|
||||||
Error
|
|
||||||
}
|
|
||||||
|
|
||||||
public enum OptionBarContentType
|
public enum OptionBarContentType
|
||||||
{
|
{
|
||||||
None,
|
None,
|
||||||
@@ -80,6 +74,11 @@ namespace VDownload.Core.ViewModels.Home
|
|||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private Type _mainContent;
|
private Type _mainContent;
|
||||||
|
|
||||||
|
[ObservableProperty]
|
||||||
|
private string _optionBarError;
|
||||||
|
|
||||||
|
[ObservableProperty]
|
||||||
|
private bool _optionBarIsErrorOpened;
|
||||||
|
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private OptionBarContentType _optionBarContent;
|
private OptionBarContentType _optionBarContent;
|
||||||
@@ -88,7 +87,7 @@ namespace VDownload.Core.ViewModels.Home
|
|||||||
private string _optionBarMessage;
|
private string _optionBarMessage;
|
||||||
|
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private OptionBarMessageIconType _optionBarMessageIcon;
|
private bool _optionBarLoading;
|
||||||
|
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private bool _optionBarLoadSubscriptionButtonChecked;
|
private bool _optionBarLoadSubscriptionButtonChecked;
|
||||||
@@ -149,8 +148,10 @@ namespace VDownload.Core.ViewModels.Home
|
|||||||
MainContent = _downloadsView;
|
MainContent = _downloadsView;
|
||||||
|
|
||||||
OptionBarContent = OptionBarContentType.None;
|
OptionBarContent = OptionBarContentType.None;
|
||||||
OptionBarMessageIcon = OptionBarMessageIconType.None;
|
OptionBarLoading = false;
|
||||||
OptionBarMessage = null;
|
OptionBarMessage = null;
|
||||||
|
OptionBarError = null;
|
||||||
|
OptionBarIsErrorOpened = true;
|
||||||
OptionBarLoadSubscriptionButtonChecked = false;
|
OptionBarLoadSubscriptionButtonChecked = false;
|
||||||
OptionBarVideoSearchButtonChecked = false;
|
OptionBarVideoSearchButtonChecked = false;
|
||||||
OptionBarPlaylistSearchButtonChecked = false;
|
OptionBarPlaylistSearchButtonChecked = false;
|
||||||
@@ -163,22 +164,27 @@ namespace VDownload.Core.ViewModels.Home
|
|||||||
[RelayCommand]
|
[RelayCommand]
|
||||||
public async Task LoadFromSubscription()
|
public async Task LoadFromSubscription()
|
||||||
{
|
{
|
||||||
MainContent = _downloadsView;
|
SearchButtonClicked();
|
||||||
OptionBarMessageIcon = OptionBarMessageIconType.None;
|
|
||||||
OptionBarMessage = null;
|
|
||||||
|
|
||||||
if (OptionBarLoadSubscriptionButtonChecked)
|
if (OptionBarLoadSubscriptionButtonChecked)
|
||||||
{
|
{
|
||||||
|
if (!NetworkHelper.Instance.ConnectionInformation.IsInternetAvailable)
|
||||||
|
{
|
||||||
|
ShowError(ErrorNoInternetConnection());
|
||||||
|
OptionBarLoadSubscriptionButtonChecked = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
OptionBarContent = OptionBarContentType.None;
|
OptionBarContent = OptionBarContentType.None;
|
||||||
OptionBarVideoSearchButtonChecked = false;
|
OptionBarVideoSearchButtonChecked = false;
|
||||||
OptionBarPlaylistSearchButtonChecked = false;
|
OptionBarPlaylistSearchButtonChecked = false;
|
||||||
|
|
||||||
OptionBarSearchNotPending = false;
|
StartSearch();
|
||||||
OptionBarMessageIcon = OptionBarMessageIconType.ProgressRing;
|
|
||||||
OptionBarMessage = _stringResourcesService.HomeViewResources.Get("OptionBarMessageLoading");
|
|
||||||
|
|
||||||
SubscriptionsVideoList subList = new SubscriptionsVideoList { Name = _stringResourcesService.CommonResources.Get("SubscriptionVideoListName") };
|
SubscriptionsVideoList subList = new SubscriptionsVideoList { Name = _stringResourcesService.CommonResources.Get("SubscriptionVideoListName") };
|
||||||
List<Task> tasks = new List<Task>();
|
List<Task> tasks = new List<Task>();
|
||||||
|
try
|
||||||
|
{
|
||||||
foreach (Subscription sub in _subscriptionsDataService.Data.ToArray())
|
foreach (Subscription sub in _subscriptionsDataService.Data.ToArray())
|
||||||
{
|
{
|
||||||
tasks.Add(Task.Run(async () =>
|
tasks.Add(Task.Run(async () =>
|
||||||
@@ -203,6 +209,12 @@ namespace VDownload.Core.ViewModels.Home
|
|||||||
}
|
}
|
||||||
await Task.WhenAll(tasks);
|
await Task.WhenAll(tasks);
|
||||||
await _subscriptionsDataService.Save();
|
await _subscriptionsDataService.Save();
|
||||||
|
}
|
||||||
|
catch (Exception ex) when (ex is TaskCanceledException || ex is HttpRequestException)
|
||||||
|
{
|
||||||
|
ShowError(ErrorSearchTimeout());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (subList.Count > 0)
|
if (subList.Count > 0)
|
||||||
{
|
{
|
||||||
@@ -217,17 +229,14 @@ namespace VDownload.Core.ViewModels.Home
|
|||||||
}
|
}
|
||||||
|
|
||||||
OptionBarSearchNotPending = true;
|
OptionBarSearchNotPending = true;
|
||||||
OptionBarMessageIcon = OptionBarMessageIconType.None;
|
OptionBarLoading = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[RelayCommand]
|
[RelayCommand]
|
||||||
public void VideoSearchShow()
|
public void VideoSearchShow()
|
||||||
{
|
{
|
||||||
OptionBarSearchNotPending = true;
|
SearchButtonClicked();
|
||||||
OptionBarMessageIcon = OptionBarMessageIconType.None;
|
|
||||||
OptionBarMessage = null;
|
|
||||||
MainContent = _downloadsView;
|
|
||||||
|
|
||||||
if (OptionBarContent != OptionBarContentType.VideoSearch)
|
if (OptionBarContent != OptionBarContentType.VideoSearch)
|
||||||
{
|
{
|
||||||
@@ -244,10 +253,7 @@ namespace VDownload.Core.ViewModels.Home
|
|||||||
[RelayCommand]
|
[RelayCommand]
|
||||||
public void PlaylistSearchShow()
|
public void PlaylistSearchShow()
|
||||||
{
|
{
|
||||||
OptionBarSearchNotPending = true;
|
SearchButtonClicked();
|
||||||
OptionBarMessageIcon = OptionBarMessageIconType.None;
|
|
||||||
OptionBarMessage = null;
|
|
||||||
MainContent = _downloadsView;
|
|
||||||
|
|
||||||
if (OptionBarContent != OptionBarContentType.PlaylistSearch)
|
if (OptionBarContent != OptionBarContentType.PlaylistSearch)
|
||||||
{
|
{
|
||||||
@@ -264,9 +270,13 @@ namespace VDownload.Core.ViewModels.Home
|
|||||||
[RelayCommand]
|
[RelayCommand]
|
||||||
public async Task VideoSearchStart()
|
public async Task VideoSearchStart()
|
||||||
{
|
{
|
||||||
OptionBarSearchNotPending = false;
|
if (!NetworkHelper.Instance.ConnectionInformation.IsInternetAvailable)
|
||||||
OptionBarMessageIcon = OptionBarMessageIconType.ProgressRing;
|
{
|
||||||
OptionBarMessage = _stringResourcesService.HomeViewResources.Get("OptionBarMessageLoading");
|
ShowError(ErrorNoInternetConnection());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
StartSearch();
|
||||||
|
|
||||||
Video video;
|
Video video;
|
||||||
try
|
try
|
||||||
@@ -275,9 +285,12 @@ namespace VDownload.Core.ViewModels.Home
|
|||||||
}
|
}
|
||||||
catch (MediaSearchException ex)
|
catch (MediaSearchException ex)
|
||||||
{
|
{
|
||||||
OptionBarMessageIcon = OptionBarMessageIconType.Error;
|
ShowError(_stringResourcesService.SearchResources.Get(ex.StringCode));
|
||||||
OptionBarMessage = _stringResourcesService.SearchResources.Get(ex.StringCode);
|
return;
|
||||||
OptionBarSearchNotPending = true;
|
}
|
||||||
|
catch (Exception ex) when (ex is TaskCanceledException || ex is HttpRequestException)
|
||||||
|
{
|
||||||
|
ShowError(ErrorSearchTimeout());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -286,16 +299,20 @@ namespace VDownload.Core.ViewModels.Home
|
|||||||
MainContent = _videoView;
|
MainContent = _videoView;
|
||||||
|
|
||||||
OptionBarSearchNotPending = true;
|
OptionBarSearchNotPending = true;
|
||||||
OptionBarMessageIcon = OptionBarMessageIconType.None;
|
OptionBarLoading = false;
|
||||||
OptionBarMessage = null;
|
OptionBarMessage = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
[RelayCommand]
|
[RelayCommand]
|
||||||
public async Task PlaylistSearchStart()
|
public async Task PlaylistSearchStart()
|
||||||
{
|
{
|
||||||
OptionBarSearchNotPending = false;
|
if (!NetworkHelper.Instance.ConnectionInformation.IsInternetAvailable)
|
||||||
OptionBarMessageIcon = OptionBarMessageIconType.ProgressRing;
|
{
|
||||||
OptionBarMessage = _stringResourcesService.HomeViewResources.Get("OptionBarMessageLoading");
|
ShowError(ErrorNoInternetConnection());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
StartSearch();
|
||||||
|
|
||||||
Playlist playlist;
|
Playlist playlist;
|
||||||
try
|
try
|
||||||
@@ -304,9 +321,12 @@ namespace VDownload.Core.ViewModels.Home
|
|||||||
}
|
}
|
||||||
catch (MediaSearchException ex)
|
catch (MediaSearchException ex)
|
||||||
{
|
{
|
||||||
OptionBarMessageIcon = OptionBarMessageIconType.Error;
|
ShowError(_stringResourcesService.SearchResources.Get(ex.StringCode));
|
||||||
OptionBarMessage = _stringResourcesService.SearchResources.Get(ex.StringCode);
|
return;
|
||||||
OptionBarSearchNotPending = true;
|
}
|
||||||
|
catch (Exception ex) when (ex is TaskCanceledException || ex is HttpRequestException)
|
||||||
|
{
|
||||||
|
ShowError(ErrorSearchTimeout());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -315,13 +335,19 @@ namespace VDownload.Core.ViewModels.Home
|
|||||||
MainContent = _videoCollectionView;
|
MainContent = _videoCollectionView;
|
||||||
|
|
||||||
OptionBarSearchNotPending = true;
|
OptionBarSearchNotPending = true;
|
||||||
OptionBarMessageIcon = OptionBarMessageIconType.None;
|
OptionBarLoading = false;
|
||||||
OptionBarMessage = null;
|
OptionBarMessage = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
[RelayCommand]
|
[RelayCommand]
|
||||||
public async Task Download()
|
public async Task Download()
|
||||||
{
|
{
|
||||||
|
if (!NetworkHelper.Instance.ConnectionInformation.IsInternetAvailable)
|
||||||
|
{
|
||||||
|
ShowError(ErrorNoInternetConnection());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (_downloadTaskManager.Tasks.Count > 0 && NetworkHelper.Instance.ConnectionInformation.IsInternetOnMeteredConnection)
|
if (_downloadTaskManager.Tasks.Count > 0 && NetworkHelper.Instance.ConnectionInformation.IsInternetOnMeteredConnection)
|
||||||
{
|
{
|
||||||
string title = _stringResourcesService.CommonResources.Get("StartAtMeteredConnectionDialogTitle");
|
string title = _stringResourcesService.CommonResources.Get("StartAtMeteredConnectionDialogTitle");
|
||||||
@@ -339,13 +365,58 @@ namespace VDownload.Core.ViewModels.Home
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[RelayCommand]
|
||||||
|
public async Task Cancel()
|
||||||
|
{
|
||||||
|
List<Task> tasks = new List<Task>();
|
||||||
|
foreach (DownloadTask task in _downloadTaskManager.Tasks)
|
||||||
|
{
|
||||||
|
tasks.Add(task.Cancel());
|
||||||
|
}
|
||||||
|
await Task.WhenAll(tasks);
|
||||||
|
}
|
||||||
|
|
||||||
|
[RelayCommand]
|
||||||
|
public void CloseError()
|
||||||
|
{
|
||||||
|
OptionBarError = null;
|
||||||
|
OptionBarIsErrorOpened = true;
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#region PRIVATE METHODS
|
#region PRIVATE METHODS
|
||||||
|
|
||||||
private async void BackToDownload_EventHandler(object sender, EventArgs e) => await Navigation();
|
protected void ShowError(string message)
|
||||||
|
{
|
||||||
|
OptionBarError = message;
|
||||||
|
OptionBarSearchNotPending = true;
|
||||||
|
OptionBarLoading = false;
|
||||||
|
OptionBarMessage = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void SearchButtonClicked()
|
||||||
|
{
|
||||||
|
OptionBarSearchNotPending = true;
|
||||||
|
OptionBarLoading = false;
|
||||||
|
OptionBarMessage = null;
|
||||||
|
MainContent = _downloadsView;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void StartSearch()
|
||||||
|
{
|
||||||
|
OptionBarSearchNotPending = false;
|
||||||
|
OptionBarLoading = true;
|
||||||
|
OptionBarMessage = _stringResourcesService.HomeViewResources.Get("OptionBarMessageLoading");
|
||||||
|
}
|
||||||
|
|
||||||
|
protected async void BackToDownload_EventHandler(object sender, EventArgs e) => await Navigation();
|
||||||
|
|
||||||
|
protected string ErrorNoInternetConnection() => _stringResourcesService.HomeViewResources.Get("ErrorInfoBarNoInternetConnection");
|
||||||
|
|
||||||
|
protected string ErrorSearchTimeout() => _stringResourcesService.SearchResources.Get("SearchTimeout");
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,12 @@
|
|||||||
using ABI.System;
|
using CommunityToolkit.Mvvm.ComponentModel;
|
||||||
using CommunityToolkit.Mvvm.ComponentModel;
|
|
||||||
using CommunityToolkit.Mvvm.Input;
|
using CommunityToolkit.Mvvm.Input;
|
||||||
|
using CommunityToolkit.WinUI.Helpers;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Collections.ObjectModel;
|
using System.Collections.ObjectModel;
|
||||||
|
using System.Diagnostics;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Net.Http;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using VDownload.Core.ViewModels.Subscriptions.Helpers;
|
using VDownload.Core.ViewModels.Subscriptions.Helpers;
|
||||||
@@ -92,6 +94,12 @@ namespace VDownload.Core.ViewModels.Subscriptions
|
|||||||
[RelayCommand]
|
[RelayCommand]
|
||||||
public async Task Add()
|
public async Task Add()
|
||||||
{
|
{
|
||||||
|
if (!NetworkHelper.Instance.ConnectionInformation.IsInternetAvailable)
|
||||||
|
{
|
||||||
|
ShowError(_stringResourcesService.SubscriptionsViewResources.Get("NoInternetConnectionError"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
Loading = true;
|
Loading = true;
|
||||||
|
|
||||||
Playlist playlist;
|
Playlist playlist;
|
||||||
@@ -101,16 +109,18 @@ namespace VDownload.Core.ViewModels.Subscriptions
|
|||||||
}
|
}
|
||||||
catch (MediaSearchException ex)
|
catch (MediaSearchException ex)
|
||||||
{
|
{
|
||||||
Error = _stringResourcesService.SearchResources.Get(ex.StringCode);
|
ShowError(_stringResourcesService.SearchResources.Get(ex.StringCode));
|
||||||
Loading = false;
|
return;
|
||||||
|
}
|
||||||
|
catch (Exception ex) when (ex is TaskCanceledException || ex is HttpRequestException)
|
||||||
|
{
|
||||||
|
ShowError(_stringResourcesService.SearchResources.Get("SearchTimeout"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (_subscriptionsDataService.Data.Any(x => x.Source == playlist.Source && x.Name == playlist.Name))
|
if (_subscriptionsDataService.Data.Any(x => x.Source == playlist.Source && x.Name == playlist.Name))
|
||||||
{
|
{
|
||||||
Error = _stringResourcesService.SubscriptionsViewResources.Get("DuplicateError");
|
ShowError(_stringResourcesService.SubscriptionsViewResources.Get("DuplicateError"));
|
||||||
Loading = false;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -137,5 +147,17 @@ namespace VDownload.Core.ViewModels.Subscriptions
|
|||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#region PRIVATE METHODS
|
||||||
|
|
||||||
|
protected void ShowError(string message)
|
||||||
|
{
|
||||||
|
Error = message;
|
||||||
|
Loading = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,21 +39,18 @@
|
|||||||
Value="{Binding TwitchDescription}"/>
|
Value="{Binding TwitchDescription}"/>
|
||||||
<ic:ChangePropertyAction PropertyName="Content">
|
<ic:ChangePropertyAction PropertyName="Content">
|
||||||
<ic:ChangePropertyAction.Value>
|
<ic:ChangePropertyAction.Value>
|
||||||
<Button Command="{Binding TwitchAuthenticationCommand}">
|
<Button Command="{Binding TwitchAuthenticationCommand}"
|
||||||
<i:Interaction.Behaviors>
|
IsEnabled="{Binding TwitchButtonEnable}">
|
||||||
<ic:DataTriggerBehavior Binding="{Binding TwitchButtonState, Converter={StaticResource ObjectToStringConverter}}"
|
<Button.Content>
|
||||||
ComparisonCondition="Equal"
|
<ctuc:SwitchPresenter Value="{Binding TwitchButtonState, Converter={StaticResource ObjectToStringConverter}}">
|
||||||
Value="SignIn">
|
<ctuc:Case Value="SignIn">
|
||||||
<ic:ChangePropertyAction x:Uid="/VDownload.Core.Strings/AuthenticationViewResources/AuthenticationButtonSignIn"
|
<TextBlock x:Uid="/VDownload.Core.Strings/AuthenticationViewResources/AuthenticationButtonSignIn"/>
|
||||||
PropertyName="Content"/>
|
</ctuc:Case>
|
||||||
</ic:DataTriggerBehavior>
|
<ctuc:Case Value="SignOut">
|
||||||
<ic:DataTriggerBehavior Binding="{Binding TwitchButtonState, Converter={StaticResource ObjectToStringConverter}}"
|
<TextBlock x:Uid="/VDownload.Core.Strings/AuthenticationViewResources/AuthenticationButtonSignOut"/>
|
||||||
ComparisonCondition="Equal"
|
</ctuc:Case>
|
||||||
Value="SignOut">
|
</ctuc:SwitchPresenter>
|
||||||
<ic:ChangePropertyAction x:Uid="/VDownload.Core.Strings/AuthenticationViewResources/AuthenticationButtonSignOut"
|
</Button.Content>
|
||||||
PropertyName="Content"/>
|
|
||||||
</ic:DataTriggerBehavior>
|
|
||||||
</i:Interaction.Behaviors>
|
|
||||||
</Button>
|
</Button>
|
||||||
</ic:ChangePropertyAction.Value>
|
</ic:ChangePropertyAction.Value>
|
||||||
</ic:ChangePropertyAction>
|
</ic:ChangePropertyAction>
|
||||||
|
|||||||
@@ -25,8 +25,10 @@
|
|||||||
<Frame Content="{Binding MainContent, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, Converter={StaticResource ViewModelToViewConverter}}">
|
<Frame Content="{Binding MainContent, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, Converter={StaticResource ViewModelToViewConverter}}">
|
||||||
|
|
||||||
</Frame>
|
</Frame>
|
||||||
<Grid Grid.Row="1"
|
<ctuc:SwitchPresenter Grid.Row="1"
|
||||||
Background="{ThemeResource OptionBarBackgroundColor}"
|
Value="{Binding OptionBarError, Converter={StaticResource IsNotNullConverter}}">
|
||||||
|
<ctuc:Case Value="False">
|
||||||
|
<Grid Background="{ThemeResource OptionBarBackgroundColor}"
|
||||||
CornerRadius="10">
|
CornerRadius="10">
|
||||||
<Grid.ColumnDefinitions>
|
<Grid.ColumnDefinitions>
|
||||||
<ColumnDefinition/>
|
<ColumnDefinition/>
|
||||||
@@ -106,29 +108,16 @@
|
|||||||
</ctuc:SwitchPresenter>
|
</ctuc:SwitchPresenter>
|
||||||
<StackPanel VerticalAlignment="Center"
|
<StackPanel VerticalAlignment="Center"
|
||||||
Orientation="Horizontal">
|
Orientation="Horizontal">
|
||||||
<StackPanel.Resources>
|
<ProgressRing Width="20"
|
||||||
<x:Double x:Key="IconSize">20</x:Double>
|
Height="20"
|
||||||
<Thickness x:Key="IconMargin">0,0,10,0</Thickness>
|
Margin="0,0,10,0"
|
||||||
</StackPanel.Resources>
|
Visibility="{Binding OptionBarLoading, Converter={StaticResource BoolToVisibilityConverter}}"/>
|
||||||
<ctuc:SwitchPresenter Value="{Binding OptionBarMessageIcon, Converter={StaticResource ObjectToStringConverter}}">
|
|
||||||
<ctuc:Case Value="None"/>
|
|
||||||
<ctuc:Case Value="ProgressRing">
|
|
||||||
<ProgressRing Width="{StaticResource IconSize}"
|
|
||||||
Height="{StaticResource IconSize}"
|
|
||||||
Margin="{StaticResource IconMargin}"/>
|
|
||||||
</ctuc:Case>
|
|
||||||
<ctuc:Case Value="Error">
|
|
||||||
<Image Width="{StaticResource IconSize}"
|
|
||||||
Height="{StaticResource IconSize}"
|
|
||||||
Margin="{StaticResource IconMargin}"
|
|
||||||
Source="{StaticResource ImageHomeViewError}"/>
|
|
||||||
</ctuc:Case>
|
|
||||||
</ctuc:SwitchPresenter>
|
|
||||||
<TextBlock Text="{Binding OptionBarMessage}"/>
|
<TextBlock Text="{Binding OptionBarMessage}"/>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</ctuc:UniformGrid>
|
</ctuc:UniformGrid>
|
||||||
<StackPanel Grid.Column="2"
|
<StackPanel Grid.Column="2"
|
||||||
Orientation="Horizontal">
|
Orientation="Horizontal"
|
||||||
|
Margin="0,0,4,0">
|
||||||
<AppBarToggleButton x:Uid="/VDownload.Core.Strings/HomeViewResources/OptionBarLoadSubscription"
|
<AppBarToggleButton x:Uid="/VDownload.Core.Strings/HomeViewResources/OptionBarLoadSubscription"
|
||||||
Icon="Favorite"
|
Icon="Favorite"
|
||||||
IsEnabled="{Binding OptionBarSearchNotPending}"
|
IsEnabled="{Binding OptionBarSearchNotPending}"
|
||||||
@@ -145,10 +134,23 @@
|
|||||||
IsChecked="{Binding OptionBarPlaylistSearchButtonChecked, Mode=TwoWay}"
|
IsChecked="{Binding OptionBarPlaylistSearchButtonChecked, Mode=TwoWay}"
|
||||||
Command="{Binding PlaylistSearchShowCommand}"/>
|
Command="{Binding PlaylistSearchShowCommand}"/>
|
||||||
<AppBarSeparator/>
|
<AppBarSeparator/>
|
||||||
|
<AppBarButton x:Uid="/VDownload.Core.Strings/HomeViewResources/OptionBarCancelAll"
|
||||||
|
Icon="Cancel"
|
||||||
|
Command="{Binding CancelCommand}"/>
|
||||||
<AppBarButton x:Uid="/VDownload.Core.Strings/HomeViewResources/OptionBarDownloadAll"
|
<AppBarButton x:Uid="/VDownload.Core.Strings/HomeViewResources/OptionBarDownloadAll"
|
||||||
Icon="Download"
|
Icon="Download"
|
||||||
Command="{Binding DownloadCommand}"/>
|
Command="{Binding DownloadCommand}"/>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
</ctuc:Case>
|
||||||
|
<ctuc:Case Value="True">
|
||||||
|
<InfoBar x:Uid="/VDownload.Core.Strings/HomeViewResources/ErrorInfoBar"
|
||||||
|
Severity="Error"
|
||||||
|
IsOpen="{Binding OptionBarIsErrorOpened, Mode=TwoWay}"
|
||||||
|
Message="{Binding OptionBarError}"
|
||||||
|
CloseButtonCommand="{Binding CloseErrorCommand}"/>
|
||||||
|
</ctuc:Case>
|
||||||
|
</ctuc:SwitchPresenter>
|
||||||
|
|
||||||
</Grid>
|
</Grid>
|
||||||
</Page>
|
</Page>
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
mc:Ignorable="d"
|
mc:Ignorable="d"
|
||||||
Closed="Window_Closed">
|
Closed="Window_Closed"
|
||||||
|
Activated="Window_Activated">
|
||||||
<WebView2 x:Name="WebView" NavigationCompleted="WebView_NavigationCompleted"/>
|
<WebView2 x:Name="WebView" NavigationCompleted="WebView_NavigationCompleted"/>
|
||||||
</Window>
|
</Window>
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
using Microsoft.UI;
|
||||||
|
using Microsoft.UI.Windowing;
|
||||||
using Microsoft.UI.Xaml;
|
using Microsoft.UI.Xaml;
|
||||||
using Microsoft.UI.Xaml.Controls;
|
using Microsoft.UI.Xaml.Controls;
|
||||||
using Microsoft.UI.Xaml.Controls.Primitives;
|
using Microsoft.UI.Xaml.Controls.Primitives;
|
||||||
@@ -84,6 +86,14 @@ namespace VDownload.Services.UI.WebView
|
|||||||
_isOpened = false;
|
_isOpened = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void Window_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
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,6 +40,9 @@ namespace VDownload.Services.Utility.FFmpeg
|
|||||||
protected string _inputFile;
|
protected string _inputFile;
|
||||||
protected string _outputFile;
|
protected string _outputFile;
|
||||||
|
|
||||||
|
protected string _audioCodec;
|
||||||
|
protected string _videoCodec;
|
||||||
|
|
||||||
protected FFOptions _options;
|
protected FFOptions _options;
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
@@ -103,6 +106,10 @@ namespace VDownload.Services.Utility.FFmpeg
|
|||||||
_inputFile = inputFile;
|
_inputFile = inputFile;
|
||||||
_outputFile = outputFile;
|
_outputFile = outputFile;
|
||||||
|
|
||||||
|
IMediaAnalysis analysis = await FFProbe.AnalyseAsync(_inputFile, _options);
|
||||||
|
_audioCodec = analysis.AudioStreams.First().CodecName;
|
||||||
|
_videoCodec = analysis.VideoStreams.First().CodecName;
|
||||||
|
|
||||||
FFMpegArgumentProcessor ffmpegArguments = FFMpegArguments.FromFileInput(inputFile, true, async (options) => await BuildInputArgumentOptions(options))
|
FFMpegArgumentProcessor ffmpegArguments = FFMpegArguments.FromFileInput(inputFile, true, async (options) => await BuildInputArgumentOptions(options))
|
||||||
.OutputToFile(outputFile, true, async (options) => await BuildOutputArgumentOptions(options));
|
.OutputToFile(outputFile, true, async (options) => await BuildOutputArgumentOptions(options));
|
||||||
|
|
||||||
@@ -154,17 +161,13 @@ namespace VDownload.Services.Utility.FFmpeg
|
|||||||
|
|
||||||
private async Task BuildOutputArgumentOptions(FFMpegArgumentOptions options)
|
private async Task BuildOutputArgumentOptions(FFMpegArgumentOptions options)
|
||||||
{
|
{
|
||||||
IMediaAnalysis analysis = await FFProbe.AnalyseAsync(_inputFile, _options);
|
|
||||||
string audioCodec = analysis.AudioStreams.First().CodecName;
|
|
||||||
string videoCodec = analysis.VideoStreams.First().CodecName;
|
|
||||||
|
|
||||||
string extension = Path.GetExtension(_outputFile).Replace(".", string.Empty);
|
string extension = Path.GetExtension(_outputFile).Replace(".", string.Empty);
|
||||||
Data.Configuration.Models.Muxer muxer = _configurationService.Common.Processing.Muxers.First(x => x.Extension == extension);
|
Data.Configuration.Models.Muxer muxer = _configurationService.Common.Processing.Muxers.First(x => x.Extension == extension);
|
||||||
|
|
||||||
if (_mediaType != MediaType.OnlyAudio)
|
if (_mediaType != MediaType.OnlyAudio)
|
||||||
{
|
{
|
||||||
IEnumerable<string> availableCodecs = muxer.VideoCodecs;
|
IEnumerable<string> availableCodecs = muxer.VideoCodecs;
|
||||||
string selectedCodec = availableCodecs.Contains(videoCodec) ? "copy" : availableCodecs.First();
|
string selectedCodec = availableCodecs.Contains(_videoCodec) ? "copy" : availableCodecs.First();
|
||||||
options.WithCustomArgument($"-vcodec {selectedCodec}");
|
options.WithCustomArgument($"-vcodec {selectedCodec}");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -175,7 +178,7 @@ namespace VDownload.Services.Utility.FFmpeg
|
|||||||
if (_mediaType != MediaType.OnlyVideo)
|
if (_mediaType != MediaType.OnlyVideo)
|
||||||
{
|
{
|
||||||
IEnumerable<string> availableCodecs = muxer.AudioCodecs;
|
IEnumerable<string> availableCodecs = muxer.AudioCodecs;
|
||||||
string selectedCodec = availableCodecs.Contains(audioCodec) ? "copy" : availableCodecs.First();
|
string selectedCodec = availableCodecs.Contains(_audioCodec) ? "copy" : availableCodecs.First();
|
||||||
options.WithCustomArgument($"-acodec {selectedCodec}");
|
options.WithCustomArgument($"-acodec {selectedCodec}");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -145,15 +145,17 @@ namespace VDownload.Sources.Twitch.Models
|
|||||||
{
|
{
|
||||||
token.ThrowIfCancellationRequested();
|
token.ThrowIfCancellationRequested();
|
||||||
|
|
||||||
using (FileStream inputStream = File.OpenRead(path))
|
using (FileStream inputStream = File.Open(path, FileMode.Open, FileAccess.Read, FileShare.Read))
|
||||||
{
|
{
|
||||||
inputStream.CopyTo(outputStream);
|
inputStream.CopyTo(outputStream);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
foreach (string item in sourceFiles)
|
||||||
|
{
|
||||||
if (deleteSource)
|
if (deleteSource)
|
||||||
{
|
{
|
||||||
File.Delete(path);
|
File.Delete(item);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -184,10 +186,7 @@ namespace VDownload.Sources.Twitch.Models
|
|||||||
int retriesCount = 0;
|
int retriesCount = 0;
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
if (token.IsCancellationRequested)
|
token.ThrowIfCancellationRequested();
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
byte[] data = await _httpClient.GetByteArrayAsync(chunk.Url, token);
|
byte[] data = await _httpClient.GetByteArrayAsync(chunk.Url, token);
|
||||||
@@ -195,10 +194,6 @@ namespace VDownload.Sources.Twitch.Models
|
|||||||
onTaskEndSuccessfully.Invoke();
|
onTaskEndSuccessfully.Invoke();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
catch (OperationCanceledException)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
catch (Exception ex) when (ex is HttpRequestException || ex is TaskCanceledException)
|
catch (Exception ex) when (ex is HttpRequestException || ex is TaskCanceledException)
|
||||||
{
|
{
|
||||||
if (_settingsService.Data.Twitch.Vod.ChunkDownloadingError.Retry && retriesCount < _settingsService.Data.Twitch.Vod.ChunkDownloadingError.RetriesCount)
|
if (_settingsService.Data.Twitch.Vod.ChunkDownloadingError.Retry && retriesCount < _settingsService.Data.Twitch.Vod.ChunkDownloadingError.RetriesCount)
|
||||||
|
|||||||
Reference in New Issue
Block a user