mirror of
https://github.com/Tyrrrz/DiscordChatExporter.git
synced 2025-05-28 13:44:12 -04:00
[GUI] Show error in a dialog when pull or export fails, instead of crashing the whole app
This commit is contained in:
parent
650c55bbd1
commit
2ab6773c17
5 changed files with 153 additions and 44 deletions
|
@ -0,0 +1,27 @@
|
|||
using DiscordChatExporter.Gui.ViewModels.Framework;
|
||||
|
||||
namespace DiscordChatExporter.Gui.ViewModels.Dialogs
|
||||
{
|
||||
public class MessageBoxViewModel : DialogScreen
|
||||
{
|
||||
public string? Title { get; set; }
|
||||
|
||||
public string? Message { get; set; }
|
||||
}
|
||||
|
||||
public static class MessageBoxViewModelExtensions
|
||||
{
|
||||
public static MessageBoxViewModel CreateMessageBoxViewModel(
|
||||
this IViewModelFactory factory,
|
||||
string title,
|
||||
string message)
|
||||
{
|
||||
var viewModel = factory.CreateMessageBoxViewModel();
|
||||
|
||||
viewModel.Title = title;
|
||||
viewModel.Message = message;
|
||||
|
||||
return viewModel;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -7,6 +7,8 @@ namespace DiscordChatExporter.Gui.ViewModels.Framework
|
|||
{
|
||||
ExportSetupViewModel CreateExportSetupViewModel();
|
||||
|
||||
MessageBoxViewModel CreateMessageBoxViewModel();
|
||||
|
||||
SettingsViewModel CreateSettingsViewModel();
|
||||
}
|
||||
}
|
|
@ -178,6 +178,15 @@ namespace DiscordChatExporter.Gui.ViewModels
|
|||
{
|
||||
Notifications.Enqueue(ex.Message.TrimEnd('.'));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
var dialog = _viewModelFactory.CreateMessageBoxViewModel(
|
||||
"Error pulling guilds and channels",
|
||||
ex.ToString()
|
||||
);
|
||||
|
||||
await _dialogManager.ShowDialogAsync(dialog);
|
||||
}
|
||||
}
|
||||
|
||||
public bool CanExportChannels =>
|
||||
|
@ -185,56 +194,68 @@ namespace DiscordChatExporter.Gui.ViewModels
|
|||
|
||||
public async void ExportChannels()
|
||||
{
|
||||
var token = _settingsService.LastToken;
|
||||
if (token is null || SelectedGuild is null || SelectedChannels is null || !SelectedChannels.Any())
|
||||
return;
|
||||
|
||||
var dialog = _viewModelFactory.CreateExportSetupViewModel(SelectedGuild, SelectedChannels);
|
||||
if (await _dialogManager.ShowDialogAsync(dialog) != true)
|
||||
return;
|
||||
|
||||
var exporter = new ChannelExporter(token);
|
||||
|
||||
var operations = ProgressManager.CreateOperations(dialog.Channels!.Count);
|
||||
var successfulExportCount = 0;
|
||||
|
||||
await dialog.Channels.Zip(operations).ParallelForEachAsync(async tuple =>
|
||||
try
|
||||
{
|
||||
var (channel, operation) = tuple;
|
||||
var token = _settingsService.LastToken;
|
||||
if (token is null || SelectedGuild is null || SelectedChannels is null || !SelectedChannels.Any())
|
||||
return;
|
||||
|
||||
try
|
||||
var dialog = _viewModelFactory.CreateExportSetupViewModel(SelectedGuild, SelectedChannels);
|
||||
if (await _dialogManager.ShowDialogAsync(dialog) != true)
|
||||
return;
|
||||
|
||||
var exporter = new ChannelExporter(token);
|
||||
|
||||
var operations = ProgressManager.CreateOperations(dialog.Channels!.Count);
|
||||
var successfulExportCount = 0;
|
||||
|
||||
await dialog.Channels.Zip(operations).ParallelForEachAsync(async tuple =>
|
||||
{
|
||||
var request = new ExportRequest(
|
||||
dialog.Guild!,
|
||||
channel!,
|
||||
dialog.OutputPath!,
|
||||
dialog.SelectedFormat,
|
||||
dialog.After?.Pipe(Snowflake.FromDate),
|
||||
dialog.Before?.Pipe(Snowflake.FromDate),
|
||||
dialog.PartitionLimit,
|
||||
dialog.MessageFilter,
|
||||
dialog.ShouldDownloadMedia,
|
||||
_settingsService.ShouldReuseMedia,
|
||||
_settingsService.DateFormat
|
||||
);
|
||||
var (channel, operation) = tuple;
|
||||
|
||||
await exporter.ExportChannelAsync(request, operation);
|
||||
try
|
||||
{
|
||||
var request = new ExportRequest(
|
||||
dialog.Guild!,
|
||||
channel!,
|
||||
dialog.OutputPath!,
|
||||
dialog.SelectedFormat,
|
||||
dialog.After?.Pipe(Snowflake.FromDate),
|
||||
dialog.Before?.Pipe(Snowflake.FromDate),
|
||||
dialog.PartitionLimit,
|
||||
dialog.MessageFilter,
|
||||
dialog.ShouldDownloadMedia,
|
||||
_settingsService.ShouldReuseMedia,
|
||||
_settingsService.DateFormat
|
||||
);
|
||||
|
||||
Interlocked.Increment(ref successfulExportCount);
|
||||
}
|
||||
catch (DiscordChatExporterException ex) when (!ex.IsCritical)
|
||||
{
|
||||
Notifications.Enqueue(ex.Message.TrimEnd('.'));
|
||||
}
|
||||
finally
|
||||
{
|
||||
operation.Dispose();
|
||||
}
|
||||
}, _settingsService.ParallelLimit.ClampMin(1));
|
||||
await exporter.ExportChannelAsync(request, operation);
|
||||
|
||||
// Notify of overall completion
|
||||
if (successfulExportCount > 0)
|
||||
Notifications.Enqueue($"Successfully exported {successfulExportCount} channel(s)");
|
||||
Interlocked.Increment(ref successfulExportCount);
|
||||
}
|
||||
catch (DiscordChatExporterException ex) when (!ex.IsCritical)
|
||||
{
|
||||
Notifications.Enqueue(ex.Message.TrimEnd('.'));
|
||||
}
|
||||
finally
|
||||
{
|
||||
operation.Dispose();
|
||||
}
|
||||
}, _settingsService.ParallelLimit.ClampMin(1));
|
||||
|
||||
// Notify of overall completion
|
||||
if (successfulExportCount > 0)
|
||||
Notifications.Enqueue($"Successfully exported {successfulExportCount} channel(s)");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
var dialog = _viewModelFactory.CreateMessageBoxViewModel(
|
||||
"Error exporting channel(s)",
|
||||
ex.ToString()
|
||||
);
|
||||
|
||||
await _dialogManager.ShowDialogAsync(dialog);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
49
DiscordChatExporter.Gui/Views/Dialogs/MessageBoxView.xaml
Normal file
49
DiscordChatExporter.Gui/Views/Dialogs/MessageBoxView.xaml
Normal file
|
@ -0,0 +1,49 @@
|
|||
<UserControl
|
||||
x:Class="DiscordChatExporter.Gui.Views.Dialogs.MessageBoxView"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:dialogs="clr-namespace:DiscordChatExporter.Gui.ViewModels.Dialogs"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:s="https://github.com/canton7/Stylet"
|
||||
MinWidth="500"
|
||||
d:DataContext="{d:DesignInstance Type=dialogs:MessageBoxViewModel}"
|
||||
d:DesignHeight="450"
|
||||
d:DesignWidth="800"
|
||||
Style="{DynamicResource MaterialDesignRoot}"
|
||||
mc:Ignorable="d">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="*" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<!-- Title -->
|
||||
<TextBlock
|
||||
Grid.Row="0"
|
||||
Margin="16"
|
||||
FontSize="17"
|
||||
Text="{Binding Title}"
|
||||
TextTrimming="CharacterEllipsis"
|
||||
ToolTip="{Binding Title}" />
|
||||
|
||||
<!-- Message -->
|
||||
<TextBlock
|
||||
Grid.Row="1"
|
||||
Margin="16,0,16,16"
|
||||
Text="{Binding Message}"
|
||||
TextWrapping="Wrap" />
|
||||
|
||||
<!-- Close -->
|
||||
<Button
|
||||
Grid.Row="2"
|
||||
Margin="8"
|
||||
HorizontalAlignment="Right"
|
||||
Command="{s:Action Close}"
|
||||
Content="CLOSE"
|
||||
IsCancel="True"
|
||||
IsDefault="True"
|
||||
Style="{DynamicResource MaterialDesignFlatButton}" />
|
||||
</Grid>
|
||||
</UserControl>
|
10
DiscordChatExporter.Gui/Views/Dialogs/MessageBoxView.xaml.cs
Normal file
10
DiscordChatExporter.Gui/Views/Dialogs/MessageBoxView.xaml.cs
Normal file
|
@ -0,0 +1,10 @@
|
|||
namespace DiscordChatExporter.Gui.Views.Dialogs
|
||||
{
|
||||
public partial class MessageBoxView
|
||||
{
|
||||
public MessageBoxView()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue