diff --git a/DiscordChatExporter.Cli/Commands/Base/ExportCommandBase.cs b/DiscordChatExporter.Cli/Commands/Base/ExportCommandBase.cs index 6064389d..a237f936 100644 --- a/DiscordChatExporter.Cli/Commands/Base/ExportCommandBase.cs +++ b/DiscordChatExporter.Cli/Commands/Base/ExportCommandBase.cs @@ -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; diff --git a/DiscordChatExporter.Gui/ViewModels/Components/DashboardViewModel.cs b/DiscordChatExporter.Gui/ViewModels/Components/DashboardViewModel.cs index 47dc6dfc..9f5b5272 100644 --- a/DiscordChatExporter.Gui/ViewModels/Components/DashboardViewModel.cs +++ b/DiscordChatExporter.Gui/ViewModels/Components/DashboardViewModel.cs @@ -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 { diff --git a/DiscordChatExporter.Gui/ViewModels/Dialogs/ExportSetupViewModel.cs b/DiscordChatExporter.Gui/ViewModels/Dialogs/ExportSetupViewModel.cs index d81994a8..6410e7a5 100644 --- a/DiscordChatExporter.Gui/ViewModels/Dialogs/ExportSetupViewModel.cs +++ b/DiscordChatExporter.Gui/ViewModels/Dialogs/ExportSetupViewModel.cs @@ -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); } diff --git a/DiscordChatExporter.Gui/Views/Dialogs/ExportSetupView.xaml b/DiscordChatExporter.Gui/Views/Dialogs/ExportSetupView.xaml index 7ee8144b..0267697b 100644 --- a/DiscordChatExporter.Gui/Views/Dialogs/ExportSetupView.xaml +++ b/DiscordChatExporter.Gui/Views/Dialogs/ExportSetupView.xaml @@ -76,6 +76,86 @@ BorderThickness="0,1"> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Style="{DynamicResource MaterialDesignOutlinedComboBox}" + ToolTip="Export format"> diff --git a/DiscordChatExporter.Gui/Views/Dialogs/SettingsView.xaml b/DiscordChatExporter.Gui/Views/Dialogs/SettingsView.xaml index 66cc9fa0..20159486 100644 --- a/DiscordChatExporter.Gui/Views/Dialogs/SettingsView.xaml +++ b/DiscordChatExporter.Gui/Views/Dialogs/SettingsView.xaml @@ -40,7 +40,7 @@ + Text="Auto-update" /> + Text="Persist token" />