diff --git a/Flow.Launcher.Plugin/IProgressBoxEx.cs b/Flow.Launcher.Plugin/IProgressBoxEx.cs
deleted file mode 100644
index 50ee6eb5536..00000000000
--- a/Flow.Launcher.Plugin/IProgressBoxEx.cs
+++ /dev/null
@@ -1,22 +0,0 @@
-using System.Threading.Tasks;
-
-namespace Flow.Launcher.Plugin;
-
-///
-/// Interface for progress box
-///
-public interface IProgressBoxEx
-{
- ///
- /// Show progress box.
- ///
- ///
- /// Progress value. Should be between 0 and 100. When progress is 100, the progress box will be closed.
- ///
- public void ReportProgress(double progress);
-
- ///
- /// Close progress box.
- ///
- public Task CloseAsync();
-}
diff --git a/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs b/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
index 9cd45a1d313..c4bfd7033fb 100644
--- a/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
+++ b/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
@@ -322,8 +322,13 @@ public interface IPublicAPI
/// If there is issue when showing the message box, it will return null.
///
/// The caption of the message box.
+ ///
+ /// Time-consuming task function, whose input is the action to report progress.
+ /// The input of the action is the progress value which is a double value between 0 and 100.
+ /// If there are any exceptions, this action will be null.
+ ///
/// When user closes the progress box manually by button or esc key, this action will be called.
/// A progress box interface.
- public IProgressBoxEx ShowProgressBox(string caption, Action forceClosed = null);
+ public Task ShowProgressBoxAsync(string caption, Func, Task> reportProgressAsync, Action forceClosed = null);
}
}
diff --git a/Flow.Launcher/ProgressBoxEx.xaml.cs b/Flow.Launcher/ProgressBoxEx.xaml.cs
index 507710e90c9..37ee2b0cb29 100644
--- a/Flow.Launcher/ProgressBoxEx.xaml.cs
+++ b/Flow.Launcher/ProgressBoxEx.xaml.cs
@@ -3,11 +3,10 @@
using System.Windows;
using System.Windows.Input;
using Flow.Launcher.Infrastructure.Logger;
-using Flow.Launcher.Plugin;
namespace Flow.Launcher
{
- public partial class ProgressBoxEx : Window, IProgressBoxEx
+ public partial class ProgressBoxEx : Window
{
private readonly Action _forceClosed;
@@ -17,31 +16,48 @@ private ProgressBoxEx(Action forceClosed)
InitializeComponent();
}
- public static IProgressBoxEx Show(string caption, Action forceClosed = null)
+ public static async Task ShowAsync(string caption, Func, Task> reportProgressAsync, Action forceClosed = null)
{
- if (!Application.Current.Dispatcher.CheckAccess())
- {
- return Application.Current.Dispatcher.Invoke(() => Show(caption, forceClosed));
- }
-
+ ProgressBoxEx prgBox = null;
try
{
- var prgBox = new ProgressBoxEx(forceClosed)
+ if (!Application.Current.Dispatcher.CheckAccess())
{
- Title = caption
- };
- prgBox.TitleTextBlock.Text = caption;
- prgBox.Show();
- return prgBox;
+ await Application.Current.Dispatcher.InvokeAsync(() =>
+ {
+ prgBox = new ProgressBoxEx(forceClosed)
+ {
+ Title = caption
+ };
+ prgBox.TitleTextBlock.Text = caption;
+ prgBox.Show();
+ });
+ }
+
+ await reportProgressAsync(prgBox.ReportProgress).ConfigureAwait(false);
}
catch (Exception e)
{
Log.Error($"|ProgressBoxEx.Show|An error occurred: {e.Message}");
- return null;
+
+ await reportProgressAsync(null).ConfigureAwait(false);
+ }
+ finally
+ {
+ if (!Application.Current.Dispatcher.CheckAccess())
+ {
+ await Application.Current.Dispatcher.InvokeAsync(async () =>
+ {
+ if (prgBox != null)
+ {
+ await prgBox.CloseAsync();
+ }
+ });
+ }
}
}
- public void ReportProgress(double progress)
+ private void ReportProgress(double progress)
{
if (!Application.Current.Dispatcher.CheckAccess())
{
@@ -64,7 +80,7 @@ public void ReportProgress(double progress)
}
}
- public async Task CloseAsync()
+ private async Task CloseAsync()
{
if (!Application.Current.Dispatcher.CheckAccess())
{
diff --git a/Flow.Launcher/PublicAPIInstance.cs b/Flow.Launcher/PublicAPIInstance.cs
index b403d604662..95d371fb09f 100644
--- a/Flow.Launcher/PublicAPIInstance.cs
+++ b/Flow.Launcher/PublicAPIInstance.cs
@@ -324,7 +324,7 @@ public bool IsGameModeOn()
public MessageBoxResult ShowMsgBox(string messageBoxText, string caption = "", MessageBoxButton button = MessageBoxButton.OK, MessageBoxImage icon = MessageBoxImage.None, MessageBoxResult defaultResult = MessageBoxResult.OK) =>
MessageBoxEx.Show(messageBoxText, caption, button, icon, defaultResult);
- public IProgressBoxEx ShowProgressBox(string caption, Action forceClosed = null) => ProgressBoxEx.Show(caption, forceClosed);
+ public Task ShowProgressBoxAsync(string caption, Func, Task> reportProgressAsync, Action forceClosed = null) => ProgressBoxEx.ShowAsync(caption, reportProgressAsync, forceClosed);
#endregion
diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
index 081f8d489e6..c3ed04a4da2 100644
--- a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
+++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
@@ -144,7 +144,6 @@ internal async Task InstallOrUpdateAsync(UserPlugin plugin)
var filePath = Path.Combine(Path.GetTempPath(), downloadFilename);
- IProgressBoxEx prgBox = null;
var downloadCancelled = false;
try
{
@@ -162,42 +161,45 @@ internal async Task InstallOrUpdateAsync(UserPlugin plugin)
var canReportProgress = totalBytes != -1;
var prgBoxTitle = $"{Context.API.GetTranslation("plugin_pluginsmanager_downloading_plugin")} {plugin.Name}";
- if (canReportProgress &&
- (prgBox = Context.API.ShowProgressBox(prgBoxTitle, () =>
- {
- if (prgBox != null)
- {
- cts.Cancel();
- downloadCancelled = true;
- }
- })) != null)
+ if (canReportProgress)
{
- await using var contentStream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false);
- await using var fileStream = new FileStream(filePath, FileMode.Create, FileAccess.Write, FileShare.None, 8192, true);
-
- var buffer = new byte[8192];
- long totalRead = 0;
- int read;
+ await Context.API.ShowProgressBoxAsync(prgBoxTitle,
+ async (reportProgress) =>
+ {
+ if (reportProgress == null)
+ {
+ // cannot use progress box
+ await Http.DownloadAsync(plugin.UrlDownload, filePath).ConfigureAwait(false);
+ }
+ else
+ {
+ await using var contentStream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false);
+ await using var fileStream = new FileStream(filePath, FileMode.Create, FileAccess.Write, FileShare.None, 8192, true);
- while ((read = await contentStream.ReadAsync(buffer).ConfigureAwait(false)) > 0)
- {
- await fileStream.WriteAsync(buffer.AsMemory(0, read)).ConfigureAwait(false);
- totalRead += read;
+ var buffer = new byte[8192];
+ long totalRead = 0;
+ int read;
- var progressValue = totalRead * 100 / totalBytes;
+ while ((read = await contentStream.ReadAsync(buffer).ConfigureAwait(false)) > 0)
+ {
+ await fileStream.WriteAsync(buffer.AsMemory(0, read)).ConfigureAwait(false);
+ totalRead += read;
- // check if user cancelled download before reporting progress
- if (downloadCancelled)
- return;
- else
- prgBox.ReportProgress(progressValue);
- }
+ var progressValue = totalRead * 100 / totalBytes;
- // check if user cancelled download before closing progress box
- if (downloadCancelled)
- return;
- else
- await prgBox?.CloseAsync();
+ // check if user cancelled download before reporting progress
+ if (downloadCancelled)
+ return;
+ else
+ reportProgress(progressValue);
+ }
+ }
+ },
+ () =>
+ {
+ cts.Cancel();
+ downloadCancelled = true;
+ });
}
else
{
@@ -217,9 +219,6 @@ internal async Task InstallOrUpdateAsync(UserPlugin plugin)
}
catch (HttpRequestException e)
{
- // force close progress box
- await prgBox?.CloseAsync();
-
// show error message
Context.API.ShowMsgError(
string.Format(Context.API.GetTranslation("plugin_pluginsmanager_downloading_plugin"), plugin.Name),
@@ -230,9 +229,6 @@ internal async Task InstallOrUpdateAsync(UserPlugin plugin)
}
catch (Exception e)
{
- // force close progress box
- await prgBox?.CloseAsync();
-
// show error message
Context.API.ShowMsgError(Context.API.GetTranslation("plugin_pluginsmanager_install_error_title"),
string.Format(Context.API.GetTranslation("plugin_pluginsmanager_install_error_subtitle"),