Self-contained export (#321)

This commit is contained in:
Alexey Golub
2020-07-18 15:45:09 +03:00
committed by GitHub
parent 94a85cdb01
commit ac64d9943a
56 changed files with 813 additions and 581 deletions

View File

@@ -19,7 +19,7 @@
<PackageReference Include="Microsoft.Xaml.Behaviors.Wpf" Version="1.1.19" />
<PackageReference Include="Ookii.Dialogs.Wpf" Version="1.1.0" />
<PackageReference Include="Onova" Version="2.6.0" />
<PackageReference Include="Stylet" Version="1.3.2" />
<PackageReference Include="Stylet" Version="1.3.3" />
<PackageReference Include="Tyrrrz.Extensions" Version="1.6.5" />
<PackageReference Include="Tyrrrz.Settings" Version="1.3.4" />
<PackageReference Include="PropertyChanged.Fody" Version="3.2.8" PrivateAssets="all" />

View File

@@ -20,6 +20,8 @@ namespace DiscordChatExporter.Gui.Services
public int? LastPartitionLimit { get; set; }
public bool LastShouldDownloadMedia { get; set; }
public SettingsService()
{
Configuration.StorageSpace = StorageSpace.Instance;

View File

@@ -32,6 +32,16 @@ namespace DiscordChatExporter.Gui.ViewModels.Dialogs
public int? PartitionLimit { get; set; }
public bool ShouldDownloadMedia { get; set; }
// Whether to show the "advanced options" by default when the dialog opens.
// This is active if any of the advanced options are set to non-default values.
public bool IsAdvancedSectionDisplayedByDefault =>
After != default ||
Before != default ||
PartitionLimit != default ||
ShouldDownloadMedia != default;
public ExportSetupViewModel(DialogManager dialogManager, SettingsService settingsService)
{
_dialogManager = dialogManager;
@@ -40,6 +50,7 @@ namespace DiscordChatExporter.Gui.ViewModels.Dialogs
// Persist preferences
SelectedFormat = _settingsService.LastExportFormat;
PartitionLimit = _settingsService.LastPartitionLimit;
ShouldDownloadMedia = _settingsService.LastShouldDownloadMedia;
}
public void Confirm()
@@ -47,6 +58,7 @@ namespace DiscordChatExporter.Gui.ViewModels.Dialogs
// Persist preferences
_settingsService.LastExportFormat = SelectedFormat;
_settingsService.LastPartitionLimit = PartitionLimit;
_settingsService.LastShouldDownloadMedia = ShouldDownloadMedia;
// Clamp 'after' and 'before' values
if (After > Before)
@@ -57,23 +69,18 @@ namespace DiscordChatExporter.Gui.ViewModels.Dialogs
// If single channel - prompt file path
if (IsSingleChannel)
{
// Get single channel
var channel = Channels.Single();
var defaultFileName = ExportRequest.GetDefaultOutputFileName(Guild!, channel, SelectedFormat, After, Before);
// Generate default file name
var defaultFileName = ChannelExporter.GetDefaultExportFileName(Guild!, channel, SelectedFormat, After, Before);
// Generate filter
// Filter
var ext = SelectedFormat.GetFileExtension();
var filter = $"{ext.ToUpperInvariant()} files|*.{ext}";
// Prompt user
OutputPath = _dialogManager.PromptSaveFilePath(filter, defaultFileName);
}
// If multiple channels - prompt dir path
else
{
// Prompt user
OutputPath = _dialogManager.PromptDirectoryPath();
}
@@ -81,7 +88,6 @@ namespace DiscordChatExporter.Gui.ViewModels.Dialogs
if (string.IsNullOrWhiteSpace(OutputPath))
return;
// Close dialog
Close(true);
}
}

View File

@@ -190,9 +190,19 @@ namespace DiscordChatExporter.Gui.ViewModels
try
{
await exporter.ExportAsync(dialog.Guild!, channel!,
dialog.OutputPath!, dialog.SelectedFormat, _settingsService.DateFormat,
dialog.PartitionLimit, dialog.After, dialog.Before, operation);
var request = new ExportRequest(
dialog.Guild!,
channel!,
dialog.OutputPath!,
dialog.SelectedFormat,
dialog.After,
dialog.Before,
dialog.PartitionLimit,
dialog.ShouldDownloadMedia,
_settingsService.DateFormat
);
await exporter.ExportChannelAsync(request, operation);
Interlocked.Increment(ref successfulExportCount);
}

View File

@@ -74,54 +74,100 @@
</ComboBox.ItemTemplate>
</ComboBox>
<!-- Date limits -->
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<DatePicker
Grid.Row="0"
Grid.Column="0"
Margin="16,8"
materialDesign:HintAssist.Hint="From (optional)"
materialDesign:HintAssist.IsFloating="True"
DisplayDateEnd="{Binding Before, Converter={x:Static converters:DateTimeOffsetToDateTimeConverter.Instance}}"
SelectedDate="{Binding After, Converter={x:Static converters:DateTimeOffsetToDateTimeConverter.Instance}}"
ToolTip="If this is set, only messages sent after this date will be exported" />
<DatePicker
Grid.Row="0"
Grid.Column="1"
Margin="16,8"
materialDesign:HintAssist.Hint="To (optional)"
materialDesign:HintAssist.IsFloating="True"
DisplayDateStart="{Binding After, Converter={x:Static converters:DateTimeOffsetToDateTimeConverter.Instance}}"
SelectedDate="{Binding Before, Converter={x:Static converters:DateTimeOffsetToDateTimeConverter.Instance}}"
ToolTip="If this is set, only messages sent before this date will be exported" />
</Grid>
<!-- Advanced section -->
<StackPanel Visibility="{Binding IsChecked, ElementName=AdvancedSectionToggleButton, Converter={x:Static s:BoolToVisibilityConverter.Instance}}">
<!-- Date limits -->
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<DatePicker
Grid.Row="0"
Grid.Column="0"
Margin="16,8"
materialDesign:HintAssist.Hint="From (optional)"
materialDesign:HintAssist.IsFloating="True"
DisplayDateEnd="{Binding Before, Converter={x:Static converters:DateTimeOffsetToDateTimeConverter.Instance}}"
SelectedDate="{Binding After, Converter={x:Static converters:DateTimeOffsetToDateTimeConverter.Instance}}"
ToolTip="If this is set, only messages sent after this date will be exported" />
<DatePicker
Grid.Row="0"
Grid.Column="1"
Margin="16,8"
materialDesign:HintAssist.Hint="To (optional)"
materialDesign:HintAssist.IsFloating="True"
DisplayDateStart="{Binding After, Converter={x:Static converters:DateTimeOffsetToDateTimeConverter.Instance}}"
SelectedDate="{Binding Before, Converter={x:Static converters:DateTimeOffsetToDateTimeConverter.Instance}}"
ToolTip="If this is set, only messages sent before this date will be exported" />
</Grid>
<!-- Partitioning -->
<TextBox
Margin="16,8"
materialDesign:HintAssist.Hint="Messages per partition (optional)"
materialDesign:HintAssist.IsFloating="True"
Text="{Binding PartitionLimit, TargetNullValue=''}"
ToolTip="If this is set, the exported file will be split into multiple partitions, each containing no more than specified number of messages" />
<!-- Partitioning -->
<TextBox
Margin="16,8"
materialDesign:HintAssist.Hint="Messages per partition (optional)"
materialDesign:HintAssist.IsFloating="True"
Text="{Binding PartitionLimit, TargetNullValue=''}"
ToolTip="If this is set, the exported file will be split into multiple partitions, each containing no more than specified number of messages" />
<!-- Download media -->
<Grid Margin="16,16" ToolTip="If this is set, the export will include additional files such as user avatars, attached files, embedded images, etc">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<TextBlock
Grid.Column="0"
VerticalAlignment="Center"
Text="Download referenced media content" />
<ToggleButton
Grid.Column="1"
HorizontalAlignment="Right"
VerticalAlignment="Center"
IsChecked="{Binding ShouldDownloadMedia}" />
</Grid>
</StackPanel>
<!-- Buttons -->
<StackPanel HorizontalAlignment="Right" Orientation="Horizontal">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<ToggleButton
x:Name="AdvancedSectionToggleButton"
Grid.Column="0"
Margin="8"
Cursor="Hand"
Loaded="AdvancedSectionToggleButton_OnLoaded"
Style="{DynamicResource MaterialDesignFlatToggleButton}"
ToolTip="Show advanced options">
<ToggleButton.Content>
<materialDesign:PackIcon
Width="24"
Height="24"
Kind="Menu" />
</ToggleButton.Content>
</ToggleButton>
<Button
Grid.Column="2"
Margin="8"
Command="{s:Action Confirm}"
Content="EXPORT"
IsDefault="True"
Style="{DynamicResource MaterialDesignFlatButton}" />
<Button
Grid.Column="3"
Margin="8"
Command="{s:Action Close}"
Content="CANCEL"
IsCancel="True"
Style="{DynamicResource MaterialDesignFlatButton}" />
</StackPanel>
</Grid>
</StackPanel>
</UserControl>

View File

@@ -1,4 +1,7 @@
namespace DiscordChatExporter.Gui.Views.Dialogs
using System.Windows;
using DiscordChatExporter.Gui.ViewModels.Dialogs;
namespace DiscordChatExporter.Gui.Views.Dialogs
{
public partial class ExportSetupView
{
@@ -6,5 +9,11 @@
{
InitializeComponent();
}
private void AdvancedSectionToggleButton_OnLoaded(object sender, RoutedEventArgs e)
{
if (DataContext is ExportSetupViewModel vm)
AdvancedSectionToggleButton.IsChecked = vm.IsAdvancedSectionDisplayedByDefault;
}
}
}