diff --git a/VDownload.Core/VDownload.Core.Strings/Strings/en-US/AuthenticationViewResources.resw b/VDownload.Core/VDownload.Core.Strings/Strings/en-US/AuthenticationViewResources.resw
index f1c32dd..5943cab 100644
--- a/VDownload.Core/VDownload.Core.Strings/Strings/en-US/AuthenticationViewResources.resw
+++ b/VDownload.Core/VDownload.Core.Strings/Strings/en-US/AuthenticationViewResources.resw
@@ -117,10 +117,10 @@
System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
+
Sign in
-
+
Sign out
@@ -135,9 +135,18 @@
Token expired or is invalid. Please log in again
+
+ Cannot validate token. Check your internet connection and try again later.
+
You are not authenticated. Please sign in
+
+ You are not authenticated and there is no internet connection. Check your internet connection and try again later.
+
+
+ An unknown error occured during Twitch login
+
Twitch authentication error
diff --git a/VDownload.Core/VDownload.Core.Strings/Strings/en-US/HomeDownloadsViewResources.resw b/VDownload.Core/VDownload.Core.Strings/Strings/en-US/HomeDownloadsViewResources.resw
index f6b9601..07e88ad 100644
--- a/VDownload.Core/VDownload.Core.Strings/Strings/en-US/HomeDownloadsViewResources.resw
+++ b/VDownload.Core/VDownload.Core.Strings/Strings/en-US/HomeDownloadsViewResources.resw
@@ -117,6 +117,21 @@
System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+ No internet connection. Try again later.
+
+
+ Error
+
+
+ Downloading timeout. Check your internet connection and try again later.
+
+
+ FFmpeg exited with error.
+
+
+ No FFmpeg executables found. Check path in settings and try again.
+
Cancelled
diff --git a/VDownload.Core/VDownload.Core.Strings/Strings/en-US/HomeViewResources.resw b/VDownload.Core/VDownload.Core.Strings/Strings/en-US/HomeViewResources.resw
index 5601658..6096f2a 100644
--- a/VDownload.Core/VDownload.Core.Strings/Strings/en-US/HomeViewResources.resw
+++ b/VDownload.Core/VDownload.Core.Strings/Strings/en-US/HomeViewResources.resw
@@ -117,6 +117,18 @@
System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+ Error
+
+
+ No internet connection
+
+
+ Cancel all
+
+
+ 80
+
Download all
diff --git a/VDownload.Core/VDownload.Core.Strings/Strings/en-US/SearchResources.resw b/VDownload.Core/VDownload.Core.Strings/Strings/en-US/SearchResources.resw
index 093321f..bb15590 100644
--- a/VDownload.Core/VDownload.Core.Strings/Strings/en-US/SearchResources.resw
+++ b/VDownload.Core/VDownload.Core.Strings/Strings/en-US/SearchResources.resw
@@ -123,6 +123,9 @@
Invalid url. Url cannot be empty.
+
+ Search timeout. Check your internet connection.
+
Invalid url. Url does not match any of supported source.
diff --git a/VDownload.Core/VDownload.Core.Strings/Strings/en-US/SubscriptionsViewResources.resw b/VDownload.Core/VDownload.Core.Strings/Strings/en-US/SubscriptionsViewResources.resw
index 1e97e5b..8f03e2f 100644
--- a/VDownload.Core/VDownload.Core.Strings/Strings/en-US/SubscriptionsViewResources.resw
+++ b/VDownload.Core/VDownload.Core.Strings/Strings/en-US/SubscriptionsViewResources.resw
@@ -126,6 +126,9 @@
Subscriptions
+
+ No internet connection
+
Add
diff --git a/VDownload.Core/VDownload.Core.Tasks/DownloadTask.cs b/VDownload.Core/VDownload.Core.Tasks/DownloadTask.cs
index 05fa933..f19fd9b 100644
--- a/VDownload.Core/VDownload.Core.Tasks/DownloadTask.cs
+++ b/VDownload.Core/VDownload.Core.Tasks/DownloadTask.cs
@@ -13,6 +13,9 @@ using System.IO;
using VDownload.Services.UI.Notifications;
using VDownload.Services.UI.StringResources;
using System.Collections.Generic;
+using System.Net.Http;
+using Instances.Exceptions;
+using FFMpegCore.Exceptions;
namespace VDownload.Core.Tasks
{
@@ -140,7 +143,11 @@ namespace VDownload.Core.Tasks
await _settingsService.Load();
- string tempDirectory = $"{_settingsService.Data.Common.Temp.Directory}\\{_configurationService.Common.Path.Temp.TasksDirectory}\\{Id}";
+ string tempDirectory = $"{_settingsService.Data.Common.Temp.Directory}\\{_configurationService.Common.Path.Temp.TasksDirectory}\\{Guid.NewGuid()}";
+ if (Directory.Exists(tempDirectory))
+ {
+ Directory.Delete(tempDirectory, true);
+ }
Directory.CreateDirectory(tempDirectory);
List content = new List()
@@ -180,10 +187,11 @@ namespace VDownload.Core.Tasks
.JoinProgressReporter(onProgressProcessing, downloadResult.NewDuration);
await ffmpegBuilder.RunAsync(downloadResult.File, outputPath);
+ StorageFile outputFile = await StorageFile.GetFileFromPathAsync(outputPath);
+
UpdateStatusWithDispatcher(DownloadTaskStatus.Finalizing);
- string destination = $"{DownloadOptions.Directory}\\{DownloadOptions.Filename}.{DownloadOptions.Extension}";
- File.Copy(outputPath, destination, true);
+ await Finalizing(outputFile);
UpdateStatusWithDispatcher(DownloadTaskStatus.EndedSuccessfully);
@@ -199,7 +207,26 @@ namespace VDownload.Core.Tasks
}
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);
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
}
diff --git a/VDownload.Core/VDownload.Core.ViewModels/Authentication/AuthenticationViewModel.cs b/VDownload.Core/VDownload.Core.ViewModels/Authentication/AuthenticationViewModel.cs
index 623cf20..4356c02 100644
--- a/VDownload.Core/VDownload.Core.ViewModels/Authentication/AuthenticationViewModel.cs
+++ b/VDownload.Core/VDownload.Core.ViewModels/Authentication/AuthenticationViewModel.cs
@@ -1,8 +1,10 @@
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
+using CommunityToolkit.WinUI.Helpers;
using System;
using System.Collections.Generic;
using System.Linq;
+using System.Net.Http;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
@@ -44,10 +46,13 @@ namespace VDownload.Core.ViewModels.Authentication
#region PROPERTIES
[ObservableProperty]
- private AuthenticationButton _twitchButtonState = AuthenticationButton.Loading;
+ protected AuthenticationButton _twitchButtonState = AuthenticationButton.Loading;
[ObservableProperty]
- private string _twitchDescription;
+ protected bool _twitchButtonEnable = true;
+
+ [ObservableProperty]
+ protected string _twitchDescription;
#endregion
@@ -107,7 +112,9 @@ namespace VDownload.Core.ViewModels.Authentication
}
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();
@@ -122,17 +129,38 @@ namespace VDownload.Core.ViewModels.Authentication
private async Task TwitchAuthenticationRefresh()
{
TwitchButtonState = AuthenticationButton.Loading;
+ TwitchButtonEnable = true;
byte[]? token = await _twitchAuthenticationService.GetToken();
if (token is null)
{
- TwitchDescription = _stringResourcesService.AuthenticationViewResources.Get("TwitchAuthenticationDescriptionNotAuthenticated");
+ if (!NetworkHelper.Instance.ConnectionInformation.IsInternetAvailable)
+ {
+ TwitchButtonEnable = false;
+ TwitchDescription = _stringResourcesService.AuthenticationViewResources.Get("TwitchAuthenticationDescriptionNotAuthenticatedNoInternetConnection");
+ }
+ else
+ {
+ TwitchDescription = _stringResourcesService.AuthenticationViewResources.Get("TwitchAuthenticationDescriptionNotAuthenticated");
+ }
TwitchButtonState = AuthenticationButton.SignIn;
}
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)
{
TwitchDescription = string.Format(_stringResourcesService.AuthenticationViewResources.Get("TwitchAuthenticationDescriptionAuthenticated"), validationResult.TokenData.Login, validationResult.TokenData.ExpirationDate);
diff --git a/VDownload.Core/VDownload.Core.ViewModels/Home/HomeDownloadsViewModel.cs b/VDownload.Core/VDownload.Core.ViewModels/Home/HomeDownloadsViewModel.cs
index cf82579..7d03e7f 100644
--- a/VDownload.Core/VDownload.Core.ViewModels/Home/HomeDownloadsViewModel.cs
+++ b/VDownload.Core/VDownload.Core.ViewModels/Home/HomeDownloadsViewModel.cs
@@ -68,6 +68,14 @@ namespace VDownload.Core.ViewModels.Home
];
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;
if (NetworkHelper.Instance.ConnectionInformation.IsInternetOnMeteredConnection)
{
diff --git a/VDownload.Core/VDownload.Core.ViewModels/Home/HomeViewModel.cs b/VDownload.Core/VDownload.Core.ViewModels/Home/HomeViewModel.cs
index 8dd6d3f..1841391 100644
--- a/VDownload.Core/VDownload.Core.ViewModels/Home/HomeViewModel.cs
+++ b/VDownload.Core/VDownload.Core.ViewModels/Home/HomeViewModel.cs
@@ -4,6 +4,7 @@ using CommunityToolkit.WinUI.Helpers;
using System;
using System.Collections.Generic;
using System.Linq;
+using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using VDownload.Core.Tasks;
@@ -23,13 +24,6 @@ namespace VDownload.Core.ViewModels.Home
{
#region ENUMS
- public enum OptionBarMessageIconType
- {
- None,
- ProgressRing,
- Error
- }
-
public enum OptionBarContentType
{
None,
@@ -80,6 +74,11 @@ namespace VDownload.Core.ViewModels.Home
[ObservableProperty]
private Type _mainContent;
+ [ObservableProperty]
+ private string _optionBarError;
+
+ [ObservableProperty]
+ private bool _optionBarIsErrorOpened;
[ObservableProperty]
private OptionBarContentType _optionBarContent;
@@ -88,7 +87,7 @@ namespace VDownload.Core.ViewModels.Home
private string _optionBarMessage;
[ObservableProperty]
- private OptionBarMessageIconType _optionBarMessageIcon;
+ private bool _optionBarLoading;
[ObservableProperty]
private bool _optionBarLoadSubscriptionButtonChecked;
@@ -149,8 +148,10 @@ namespace VDownload.Core.ViewModels.Home
MainContent = _downloadsView;
OptionBarContent = OptionBarContentType.None;
- OptionBarMessageIcon = OptionBarMessageIconType.None;
+ OptionBarLoading = false;
OptionBarMessage = null;
+ OptionBarError = null;
+ OptionBarIsErrorOpened = true;
OptionBarLoadSubscriptionButtonChecked = false;
OptionBarVideoSearchButtonChecked = false;
OptionBarPlaylistSearchButtonChecked = false;
@@ -163,46 +164,57 @@ namespace VDownload.Core.ViewModels.Home
[RelayCommand]
public async Task LoadFromSubscription()
{
- MainContent = _downloadsView;
- OptionBarMessageIcon = OptionBarMessageIconType.None;
- OptionBarMessage = null;
+ SearchButtonClicked();
if (OptionBarLoadSubscriptionButtonChecked)
{
+ if (!NetworkHelper.Instance.ConnectionInformation.IsInternetAvailable)
+ {
+ ShowError(ErrorNoInternetConnection());
+ OptionBarLoadSubscriptionButtonChecked = false;
+ return;
+ }
+
OptionBarContent = OptionBarContentType.None;
OptionBarVideoSearchButtonChecked = false;
OptionBarPlaylistSearchButtonChecked = false;
- OptionBarSearchNotPending = false;
- OptionBarMessageIcon = OptionBarMessageIconType.ProgressRing;
- OptionBarMessage = _stringResourcesService.HomeViewResources.Get("OptionBarMessageLoading");
+ StartSearch();
SubscriptionsVideoList subList = new SubscriptionsVideoList { Name = _stringResourcesService.CommonResources.Get("SubscriptionVideoListName") };
List tasks = new List();
- foreach (Subscription sub in _subscriptionsDataService.Data.ToArray())
+ try
{
- tasks.Add(Task.Run(async () =>
+ foreach (Subscription sub in _subscriptionsDataService.Data.ToArray())
{
- Playlist playlist;
- try
+ tasks.Add(Task.Run(async () =>
{
- playlist = await _searchService.SearchPlaylist(sub.Url.OriginalString, 0);
- }
- catch (MediaSearchException)
- {
- return;
- }
+ Playlist playlist;
+ try
+ {
+ playlist = await _searchService.SearchPlaylist(sub.Url.OriginalString, 0);
+ }
+ catch (MediaSearchException)
+ {
+ return;
+ }
- IEnumerable