mirror of
https://github.com/Tyrrrz/DiscordChatExporter.git
synced 2025-05-25 04:04:22 -04:00
Enhance output path selection in the GUI
Enables the use of template tokens when exporting multiple channels Closes #676
This commit is contained in:
parent
f1ae0266f1
commit
c8d83beb8d
5 changed files with 115 additions and 25 deletions
|
@ -26,7 +26,11 @@ public abstract class ExportCommandBase : TokenCommandBase
|
|||
[CommandOption(
|
||||
"output",
|
||||
'o',
|
||||
Description = "Output file or directory path. Directory path should end in a slash."
|
||||
Description =
|
||||
"Output file or directory path. " +
|
||||
"If a directory is specified, file names will be generated automatically based on the channel names and other parameters. " +
|
||||
"Directory path should end with a slash to avoid ambiguity. " +
|
||||
"Supports template tokens, see the documentation for more info."
|
||||
)]
|
||||
public string OutputPath
|
||||
{
|
||||
|
@ -58,7 +62,8 @@ public abstract class ExportCommandBase : TokenCommandBase
|
|||
[CommandOption(
|
||||
"partition",
|
||||
'p',
|
||||
Description = "Split output into partitions, each limited to this number of messages (e.g. '100') or file size (e.g. '10mb')."
|
||||
Description =
|
||||
"Split output into partitions, each limited to this number of messages (e.g. '100') or file size (e.g. '10mb')."
|
||||
)]
|
||||
public PartitionLimit PartitionLimit { get; init; } = PartitionLimit.Null;
|
||||
|
||||
|
|
|
@ -158,22 +158,27 @@ public class DashboardViewModel : PropertyChangedBase
|
|||
|
||||
var exporter = new ChannelExporter(_discord);
|
||||
|
||||
var progresses = Enumerable
|
||||
.Range(0, dialog.Channels!.Count)
|
||||
.Select(_ => _progressMuxer.CreateInput())
|
||||
var channelProgressPairs = dialog
|
||||
.Channels!
|
||||
.Select(c => new
|
||||
{
|
||||
Channel = c,
|
||||
Progress = _progressMuxer.CreateInput()
|
||||
})
|
||||
.ToArray();
|
||||
|
||||
var successfulExportCount = 0;
|
||||
|
||||
await Parallel.ForEachAsync(
|
||||
dialog.Channels.Zip(progresses),
|
||||
channelProgressPairs,
|
||||
new ParallelOptions
|
||||
{
|
||||
MaxDegreeOfParallelism = Math.Max(1, _settingsService.ParallelLimit)
|
||||
},
|
||||
async (tuple, cancellationToken) =>
|
||||
async (pair, cancellationToken) =>
|
||||
{
|
||||
var (channel, progress) = tuple;
|
||||
var channel = pair.Channel;
|
||||
var progress = pair.Progress;
|
||||
|
||||
try
|
||||
{
|
||||
|
|
|
@ -86,15 +86,8 @@ public class ExportSetupViewModel : DialogScreen
|
|||
|
||||
public void ToggleAdvancedSection() => IsAdvancedSectionDisplayed = !IsAdvancedSectionDisplayed;
|
||||
|
||||
public void Confirm()
|
||||
public void ShowOutputPathPrompt()
|
||||
{
|
||||
// Persist preferences
|
||||
_settingsService.LastExportFormat = SelectedFormat;
|
||||
_settingsService.LastPartitionLimitValue = PartitionLimitValue;
|
||||
_settingsService.LastMessageFilterValue = MessageFilterValue;
|
||||
_settingsService.LastShouldDownloadAssets = ShouldDownloadAssets;
|
||||
|
||||
// If single channel - prompt file path
|
||||
if (IsSingleChannel)
|
||||
{
|
||||
var defaultFileName = ExportRequest.GetDefaultOutputFileName(
|
||||
|
@ -105,20 +98,26 @@ public class ExportSetupViewModel : DialogScreen
|
|||
Before?.Pipe(Snowflake.FromDate)
|
||||
);
|
||||
|
||||
// Filter
|
||||
var ext = SelectedFormat.GetFileExtension();
|
||||
var filter = $"{ext.ToUpperInvariant()} files|*.{ext}";
|
||||
var extension = SelectedFormat.GetFileExtension();
|
||||
var filter = $"{extension.ToUpperInvariant()} files|*.{extension}";
|
||||
|
||||
OutputPath = _dialogManager.PromptSaveFilePath(filter, defaultFileName);
|
||||
}
|
||||
// If multiple channels - prompt dir path
|
||||
else
|
||||
{
|
||||
OutputPath = _dialogManager.PromptDirectoryPath();
|
||||
}
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(OutputPath))
|
||||
return;
|
||||
public bool CanConfirm => !string.IsNullOrWhiteSpace(OutputPath);
|
||||
|
||||
public void Confirm()
|
||||
{
|
||||
// Persist preferences
|
||||
_settingsService.LastExportFormat = SelectedFormat;
|
||||
_settingsService.LastPartitionLimitValue = PartitionLimitValue;
|
||||
_settingsService.LastMessageFilterValue = MessageFilterValue;
|
||||
_settingsService.LastShouldDownloadAssets = ShouldDownloadAssets;
|
||||
|
||||
Close(true);
|
||||
}
|
||||
|
|
|
@ -76,6 +76,86 @@
|
|||
BorderThickness="0,1">
|
||||
<ScrollViewer HorizontalScrollBarVisibility="Disabled" VerticalScrollBarVisibility="Auto">
|
||||
<StackPanel>
|
||||
<!-- Output path -->
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBox
|
||||
Grid.Column="0"
|
||||
Margin="16,8,8,8"
|
||||
materialDesign:HintAssist.Hint="Output path"
|
||||
materialDesign:HintAssist.IsFloating="True"
|
||||
Style="{DynamicResource MaterialDesignOutlinedTextBox}"
|
||||
Text="{Binding OutputPath}">
|
||||
<TextBox.ToolTip>
|
||||
<TextBlock>
|
||||
<Run Text="Output file or directory path." />
|
||||
<Run Text="If a directory is specified, file names will be generated automatically based on the channel names and other parameters." />
|
||||
<Run Text="Directory path should end with a slash to avoid ambiguity." />
|
||||
<LineBreak />
|
||||
<LineBreak />
|
||||
<Run Text="Available template tokens:" />
|
||||
<LineBreak />
|
||||
<Run FontWeight="SemiBold" Text="%g" />
|
||||
<Run Text="— guild ID" />
|
||||
<LineBreak />
|
||||
<Run FontWeight="SemiBold" Text="%G" />
|
||||
<Run Text="— guild name" />
|
||||
<LineBreak />
|
||||
<Run FontWeight="SemiBold" Text="%t" />
|
||||
<Run Text="— category ID" />
|
||||
<LineBreak />
|
||||
<Run FontWeight="SemiBold" Text="%T" />
|
||||
<Run Text="— category name" />
|
||||
<LineBreak />
|
||||
<Run FontWeight="SemiBold" Text="%c" />
|
||||
<Run Text="— channel ID" />
|
||||
<LineBreak />
|
||||
<Run FontWeight="SemiBold" Text="%C" />
|
||||
<Run Text="— channel name" />
|
||||
<LineBreak />
|
||||
<Run FontWeight="SemiBold" Text="%p" />
|
||||
<Run Text="— channel position" />
|
||||
<LineBreak />
|
||||
<Run FontWeight="SemiBold" Text="%P" />
|
||||
<Run Text="— category position" />
|
||||
<LineBreak />
|
||||
<Run FontWeight="SemiBold" Text="%a" />
|
||||
<Run Text="— after date" />
|
||||
<LineBreak />
|
||||
<Run FontWeight="SemiBold" Text="%b" />
|
||||
<Run Text="— before date" />
|
||||
<LineBreak />
|
||||
<Run FontWeight="SemiBold" Text="%d" />
|
||||
<Run Text="— current date" />
|
||||
</TextBlock>
|
||||
</TextBox.ToolTip>
|
||||
</TextBox>
|
||||
<Button
|
||||
Grid.Column="1"
|
||||
Height="48"
|
||||
Margin="0,8,16,8"
|
||||
Command="{s:Action ShowOutputPathPrompt}"
|
||||
Style="{DynamicResource MaterialDesignOutlinedButton}">
|
||||
<materialDesign:PackIcon Width="24" Height="24">
|
||||
<materialDesign:PackIcon.Style>
|
||||
<Style TargetType="{x:Type materialDesign:PackIcon}">
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding IsSingleChannel}" Value="True">
|
||||
<Setter Property="Kind" Value="FileFind" />
|
||||
</DataTrigger>
|
||||
<DataTrigger Binding="{Binding IsSingleChannel}" Value="False">
|
||||
<Setter Property="Kind" Value="FolderSearch" />
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</materialDesign:PackIcon.Style>
|
||||
</materialDesign:PackIcon>
|
||||
</Button>
|
||||
</Grid>
|
||||
|
||||
<!-- Format -->
|
||||
<ComboBox
|
||||
Margin="16,8"
|
||||
|
@ -84,7 +164,8 @@
|
|||
IsReadOnly="True"
|
||||
ItemsSource="{Binding AvailableFormats}"
|
||||
SelectedItem="{Binding SelectedFormat}"
|
||||
Style="{DynamicResource MaterialDesignOutlinedComboBox}">
|
||||
Style="{DynamicResource MaterialDesignOutlinedComboBox}"
|
||||
ToolTip="Export format">
|
||||
<ComboBox.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<TextBlock Text="{Binding Converter={x:Static converters:ExportFormatToStringConverter.Instance}, ConverterCulture={x:Static globalization:CultureInfo.CurrentCulture}}" />
|
||||
|
|
|
@ -40,7 +40,7 @@
|
|||
<TextBlock
|
||||
VerticalAlignment="Center"
|
||||
DockPanel.Dock="Left"
|
||||
Text="Auto-updates" />
|
||||
Text="Auto-update" />
|
||||
<ToggleButton
|
||||
VerticalAlignment="Center"
|
||||
DockPanel.Dock="Right"
|
||||
|
@ -75,7 +75,7 @@
|
|||
<TextBlock
|
||||
VerticalAlignment="Center"
|
||||
DockPanel.Dock="Left"
|
||||
Text="Save token" />
|
||||
Text="Persist token" />
|
||||
<ToggleButton
|
||||
VerticalAlignment="Center"
|
||||
DockPanel.Dock="Right"
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue