From 36b4a45f3a738ecfbdc5bcda9078e132e1fdc4d8 Mon Sep 17 00:00:00 2001
From: Oleksii Holub <1935960+Tyrrrz@users.noreply.github.com>
Date: Wed, 16 Feb 2022 14:30:26 +0200
Subject: [PATCH] Update Gress
---
.../Commands/Base/ExportCommandBase.cs | 10 +-
.../DiscordChatExporter.Cli.csproj | 2 +-
.../Discord/DiscordClient.cs | 20 ++-
.../DiscordChatExporter.Core.csproj | 1 +
.../Exporting/ChannelExporter.cs | 3 +-
.../DiscordChatExporter.Gui.csproj | 2 +-
.../ViewModels/RootViewModel.cs | 50 ++++---
DiscordChatExporter.Gui/Views/RootView.xaml | 126 +++++++++---------
8 files changed, 117 insertions(+), 97 deletions(-)
diff --git a/DiscordChatExporter.Cli/Commands/Base/ExportCommandBase.cs b/DiscordChatExporter.Cli/Commands/Base/ExportCommandBase.cs
index 07e70fa6..b1e090cc 100644
--- a/DiscordChatExporter.Cli/Commands/Base/ExportCommandBase.cs
+++ b/DiscordChatExporter.Cli/Commands/Base/ExportCommandBase.cs
@@ -14,6 +14,7 @@ using DiscordChatExporter.Core.Exceptions;
using DiscordChatExporter.Core.Exporting;
using DiscordChatExporter.Core.Exporting.Filtering;
using DiscordChatExporter.Core.Exporting.Partitioning;
+using Gress;
namespace DiscordChatExporter.Cli.Commands.Base;
@@ -78,8 +79,7 @@ public abstract class ExportCommandBase : TokenCommandBase
{
try
{
- await progressContext.StartTaskAsync(
- $"{channel.Category.Name} / {channel.Name}",
+ await progressContext.StartTaskAsync($"{channel.Category.Name} / {channel.Name}",
async progress =>
{
var guild = await Discord.GetGuildAsync(channel.GuildId, innerCancellationToken);
@@ -98,7 +98,11 @@ public abstract class ExportCommandBase : TokenCommandBase
DateFormat
);
- await Exporter.ExportChannelAsync(request, progress, innerCancellationToken);
+ await Exporter.ExportChannelAsync(
+ request,
+ progress.ToPercentageBased(),
+ innerCancellationToken
+ );
}
);
}
diff --git a/DiscordChatExporter.Cli/DiscordChatExporter.Cli.csproj b/DiscordChatExporter.Cli/DiscordChatExporter.Cli.csproj
index 0a328a61..5d1e173b 100644
--- a/DiscordChatExporter.Cli/DiscordChatExporter.Cli.csproj
+++ b/DiscordChatExporter.Cli/DiscordChatExporter.Cli.csproj
@@ -8,7 +8,7 @@
-
+
diff --git a/DiscordChatExporter.Core/Discord/DiscordClient.cs b/DiscordChatExporter.Core/Discord/DiscordClient.cs
index 10c98693..9115b6c6 100644
--- a/DiscordChatExporter.Core/Discord/DiscordClient.cs
+++ b/DiscordChatExporter.Core/Discord/DiscordClient.cs
@@ -12,6 +12,7 @@ using DiscordChatExporter.Core.Discord.Data;
using DiscordChatExporter.Core.Exceptions;
using DiscordChatExporter.Core.Utils;
using DiscordChatExporter.Core.Utils.Extensions;
+using Gress;
using JsonExtensions.Http;
using JsonExtensions.Reading;
@@ -273,7 +274,7 @@ public class DiscordClient
Snowflake channelId,
Snowflake? after = null,
Snowflake? before = null,
- IProgress? progress = null,
+ IProgress? progress = null,
[EnumeratorCancellation] CancellationToken cancellationToken = default)
{
// Get the last message in the specified range.
@@ -322,16 +323,13 @@ public class DiscordClient
var exportedDuration = (message.Timestamp - firstMessage.Timestamp).Duration();
var totalDuration = (lastMessage.Timestamp - firstMessage.Timestamp).Duration();
- if (totalDuration > TimeSpan.Zero)
- {
- progress.Report(exportedDuration / totalDuration);
- }
- // Avoid division by zero if all messages have the exact same timestamp
- // (which may be the case if there's only one message in the channel)
- else
- {
- progress.Report(1);
- }
+ progress.Report(Percentage.FromFraction(
+ // Avoid division by zero if all messages have the exact same timestamp
+ // (which may be the case if there's only one message in the channel)
+ totalDuration > TimeSpan.Zero
+ ? exportedDuration / totalDuration
+ : 1
+ ));
}
yield return message;
diff --git a/DiscordChatExporter.Core/DiscordChatExporter.Core.csproj b/DiscordChatExporter.Core/DiscordChatExporter.Core.csproj
index 0757c987..d07394f9 100644
--- a/DiscordChatExporter.Core/DiscordChatExporter.Core.csproj
+++ b/DiscordChatExporter.Core/DiscordChatExporter.Core.csproj
@@ -5,6 +5,7 @@
+
diff --git a/DiscordChatExporter.Core/Exporting/ChannelExporter.cs b/DiscordChatExporter.Core/Exporting/ChannelExporter.cs
index e6dcb7df..5d40ee37 100644
--- a/DiscordChatExporter.Core/Exporting/ChannelExporter.cs
+++ b/DiscordChatExporter.Core/Exporting/ChannelExporter.cs
@@ -8,6 +8,7 @@ using DiscordChatExporter.Core.Discord.Data;
using DiscordChatExporter.Core.Discord.Data.Common;
using DiscordChatExporter.Core.Exceptions;
using DiscordChatExporter.Core.Utils.Extensions;
+using Gress;
namespace DiscordChatExporter.Core.Exporting;
@@ -19,7 +20,7 @@ public class ChannelExporter
public async ValueTask ExportChannelAsync(
ExportRequest request,
- IProgress? progress = null,
+ IProgress? progress = null,
CancellationToken cancellationToken = default)
{
// Build context
diff --git a/DiscordChatExporter.Gui/DiscordChatExporter.Gui.csproj b/DiscordChatExporter.Gui/DiscordChatExporter.Gui.csproj
index 42074a0e..2bf4d0c0 100644
--- a/DiscordChatExporter.Gui/DiscordChatExporter.Gui.csproj
+++ b/DiscordChatExporter.Gui/DiscordChatExporter.Gui.csproj
@@ -13,7 +13,7 @@
-
+
diff --git a/DiscordChatExporter.Gui/ViewModels/RootViewModel.cs b/DiscordChatExporter.Gui/ViewModels/RootViewModel.cs
index c9cc78a3..b3a5709c 100644
--- a/DiscordChatExporter.Gui/ViewModels/RootViewModel.cs
+++ b/DiscordChatExporter.Gui/ViewModels/RootViewModel.cs
@@ -13,6 +13,7 @@ using DiscordChatExporter.Gui.Utils;
using DiscordChatExporter.Gui.ViewModels.Dialogs;
using DiscordChatExporter.Gui.ViewModels.Framework;
using Gress;
+using Gress.Completable;
using MaterialDesignThemes.Wpf;
using Stylet;
@@ -25,11 +26,13 @@ public class RootViewModel : Screen
private readonly SettingsService _settingsService;
private readonly UpdateService _updateService;
+ private readonly AutoResetProgressMuxer _progressMuxer;
+
private DiscordClient? _discord;
- public ISnackbarMessageQueue Notifications { get; } = new SnackbarMessageQueue(TimeSpan.FromSeconds(5));
+ public SnackbarMessageQueue Notifications { get; } = new(TimeSpan.FromSeconds(5));
- public IProgressManager ProgressManager { get; } = new ProgressManager();
+ public ProgressContainer Progress { get; } = new();
public bool IsBusy { get; private set; }
@@ -62,17 +65,14 @@ public class RootViewModel : Screen
DisplayName = $"{App.Name} v{App.VersionString}";
- // Update busy state when progress manager changes
- ProgressManager.Bind(o => o.IsActive, (_, _) =>
- IsBusy = ProgressManager.IsActive
+ _progressMuxer = Progress.CreateMuxer().WithAutoReset();
+
+ this.Bind(o => o.IsBusy, (_, _) =>
+ IsProgressIndeterminate = IsBusy && Progress.Current.Fraction is <= 0 or >= 1
);
- ProgressManager.Bind(o => o.IsActive, (_, _) =>
- IsProgressIndeterminate = ProgressManager.IsActive && ProgressManager.Progress is <= 0 or >= 1
- );
-
- ProgressManager.Bind(o => o.Progress, (_, _) =>
- IsProgressIndeterminate = ProgressManager.IsActive && ProgressManager.Progress is <= 0 or >= 1
+ Progress.Bind(o => o.Current, (_, _) =>
+ IsProgressIndeterminate = IsBusy && Progress.Current.Fraction is <= 0 or >= 1
);
}
@@ -147,7 +147,8 @@ public class RootViewModel : Screen
public async void PopulateGuildsAndChannels()
{
- using var operation = ProgressManager.CreateOperation();
+ IsBusy = true;
+ var progress = _progressMuxer.CreateInput();
try
{
@@ -183,6 +184,11 @@ public class RootViewModel : Screen
await _dialogManager.ShowDialogAsync(dialog);
}
+ finally
+ {
+ progress.ReportCompletion();
+ IsBusy = false;
+ }
}
public bool CanExportChannels =>
@@ -194,6 +200,8 @@ public class RootViewModel : Screen
public async void ExportChannels()
{
+ IsBusy = true;
+
try
{
if (_discord is null || SelectedGuild is null || SelectedChannels is null || !SelectedChannels.Any())
@@ -205,18 +213,22 @@ public class RootViewModel : Screen
var exporter = new ChannelExporter(_discord);
- var operations = ProgressManager.CreateOperations(dialog.Channels!.Count);
+ var progresses = Enumerable
+ .Range(0, dialog.Channels!.Count)
+ .Select(_ => _progressMuxer.CreateInput())
+ .ToArray();
+
var successfulExportCount = 0;
await Parallel.ForEachAsync(
- dialog.Channels.Zip(operations),
+ dialog.Channels.Zip(progresses),
new ParallelOptions
{
MaxDegreeOfParallelism = Math.Max(1, _settingsService.ParallelLimit)
},
async (tuple, cancellationToken) =>
{
- var (channel, operation) = tuple;
+ var (channel, progress) = tuple;
try
{
@@ -234,7 +246,7 @@ public class RootViewModel : Screen
_settingsService.DateFormat
);
- await exporter.ExportChannelAsync(request, operation, cancellationToken);
+ await exporter.ExportChannelAsync(request, progress, cancellationToken);
Interlocked.Increment(ref successfulExportCount);
}
@@ -244,7 +256,7 @@ public class RootViewModel : Screen
}
finally
{
- operation.Dispose();
+ progress.ReportCompletion();
}
}
);
@@ -262,5 +274,9 @@ public class RootViewModel : Screen
await _dialogManager.ShowDialogAsync(dialog);
}
+ finally
+ {
+ IsBusy = false;
+ }
}
}
\ No newline at end of file
diff --git a/DiscordChatExporter.Gui/Views/RootView.xaml b/DiscordChatExporter.Gui/Views/RootView.xaml
index 034c4f4f..ed593420 100644
--- a/DiscordChatExporter.Gui/Views/RootView.xaml
+++ b/DiscordChatExporter.Gui/Views/RootView.xaml
@@ -1,7 +1,16 @@
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
-
+
-
+
@@ -46,7 +46,7 @@
-
+
@@ -54,8 +54,8 @@
@@ -66,74 +66,74 @@
+ Width="24" />
+ x:Name="TokenValueTextBox" />
+ Value="{Binding Progress.Current.Fraction, Mode=OneWay}" />