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();
|
ExportSetupViewModel CreateExportSetupViewModel();
|
||||||
|
|
||||||
|
MessageBoxViewModel CreateMessageBoxViewModel();
|
||||||
|
|
||||||
SettingsViewModel CreateSettingsViewModel();
|
SettingsViewModel CreateSettingsViewModel();
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -178,6 +178,15 @@ namespace DiscordChatExporter.Gui.ViewModels
|
||||||
{
|
{
|
||||||
Notifications.Enqueue(ex.Message.TrimEnd('.'));
|
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 =>
|
public bool CanExportChannels =>
|
||||||
|
@ -185,56 +194,68 @@ namespace DiscordChatExporter.Gui.ViewModels
|
||||||
|
|
||||||
public async void ExportChannels()
|
public async void ExportChannels()
|
||||||
{
|
{
|
||||||
var token = _settingsService.LastToken;
|
try
|
||||||
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 =>
|
|
||||||
{
|
{
|
||||||
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(
|
var (channel, operation) = tuple;
|
||||||
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
|
|
||||||
);
|
|
||||||
|
|
||||||
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);
|
await exporter.ExportChannelAsync(request, operation);
|
||||||
}
|
|
||||||
catch (DiscordChatExporterException ex) when (!ex.IsCritical)
|
|
||||||
{
|
|
||||||
Notifications.Enqueue(ex.Message.TrimEnd('.'));
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
operation.Dispose();
|
|
||||||
}
|
|
||||||
}, _settingsService.ParallelLimit.ClampMin(1));
|
|
||||||
|
|
||||||
// Notify of overall completion
|
Interlocked.Increment(ref successfulExportCount);
|
||||||
if (successfulExportCount > 0)
|
}
|
||||||
Notifications.Enqueue($"Successfully exported {successfulExportCount} channel(s)");
|
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