Skip to content

Commit

Permalink
Use function to delegate the progress task
Browse files Browse the repository at this point in the history
  • Loading branch information
Jack251970 committed Jan 10, 2025
1 parent ed7265d commit 297d191
Show file tree
Hide file tree
Showing 5 changed files with 74 additions and 79 deletions.
22 changes: 0 additions & 22 deletions Flow.Launcher.Plugin/IProgressBoxEx.cs

This file was deleted.

7 changes: 6 additions & 1 deletion Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
Original file line number Diff line number Diff line change
Expand Up @@ -322,8 +322,13 @@ public interface IPublicAPI
/// If there is issue when showing the message box, it will return null.
/// </summary>
/// <param name="caption">The caption of the message box.</param>
/// <param name="reportProgressAsync">
/// 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.
/// </param>
/// <param name="forceClosed">When user closes the progress box manually by button or esc key, this action will be called.</param>
/// <returns>A progress box interface.</returns>
public IProgressBoxEx ShowProgressBox(string caption, Action forceClosed = null);
public Task ShowProgressBoxAsync(string caption, Func<Action<double>, Task> reportProgressAsync, Action forceClosed = null);
}
}
50 changes: 33 additions & 17 deletions Flow.Launcher/ProgressBoxEx.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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<Action<double>, 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())
{
Expand All @@ -64,7 +80,7 @@ public void ReportProgress(double progress)
}
}

public async Task CloseAsync()
private async Task CloseAsync()
{
if (!Application.Current.Dispatcher.CheckAccess())
{
Expand Down
2 changes: 1 addition & 1 deletion Flow.Launcher/PublicAPIInstance.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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<Action<double>, Task> reportProgressAsync, Action forceClosed = null) => ProgressBoxEx.ShowAsync(caption, reportProgressAsync, forceClosed);

#endregion

Expand Down
72 changes: 34 additions & 38 deletions Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,6 @@ internal async Task InstallOrUpdateAsync(UserPlugin plugin)

var filePath = Path.Combine(Path.GetTempPath(), downloadFilename);

IProgressBoxEx prgBox = null;
var downloadCancelled = false;
try
{
Expand All @@ -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
{
Expand All @@ -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),
Expand All @@ -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"),
Expand Down

0 comments on commit 297d191

Please sign in to comment.