From 3740d646017fd41a272eb21b887612fd4d9291b6 Mon Sep 17 00:00:00 2001 From: Tyrrrz <1935960+Tyrrrz@users.noreply.github.com> Date: Mon, 28 Aug 2023 22:08:51 +0300 Subject: [PATCH] Optimize thread inclusion UX across GUI and CLI Related to #1119 --- .../Commands/ExportAllCommand.cs | 14 ++++------ .../Commands/ExportGuildCommand.cs | 10 +++---- .../Commands/GetChannelsCommand.cs | 27 +++++++++---------- .../Commands/Shared/ThreadInclusion.cs | 12 +++------ .../Models/ThreadInclusion.cs | 8 ++++++ .../Services/SettingsService.cs | 5 ++-- .../Components/DashboardViewModel.cs | 5 ++-- .../ViewModels/Dialogs/SettingsViewModel.cs | 22 +++++---------- .../Views/Dialogs/SettingsView.xaml | 25 ++++------------- 9 files changed, 49 insertions(+), 79 deletions(-) create mode 100644 DiscordChatExporter.Gui/Models/ThreadInclusion.cs diff --git a/DiscordChatExporter.Cli/Commands/ExportAllCommand.cs b/DiscordChatExporter.Cli/Commands/ExportAllCommand.cs index c854935..5a5cc0b 100644 --- a/DiscordChatExporter.Cli/Commands/ExportAllCommand.cs +++ b/DiscordChatExporter.Cli/Commands/ExportAllCommand.cs @@ -29,15 +29,11 @@ public class ExportAllCommand : ExportCommandBase [CommandOption( "include-threads", - Description = "Specifies which types of threads should be included.", + Description = "Which types of threads should be included.", Converter = typeof(ThreadInclusionBindingConverter) )] public ThreadInclusion ThreadInclusion { get; init; } = ThreadInclusion.None; - private bool IncludeThreads => ThreadInclusion != ThreadInclusion.None; - - private bool IncludeArchivedThreads => ThreadInclusion.HasFlag(ThreadInclusion.Archived); - [CommandOption( "data-package", Description = "Path to the personal data package (ZIP file) requested from Discord. " @@ -74,12 +70,12 @@ public class ExportAllCommand : ExportCommandBase } // Threads - if (IncludeThreads) + if (ThreadInclusion != ThreadInclusion.None) { await foreach ( var thread in Discord.GetGuildThreadsAsync( guild.Id, - IncludeArchivedThreads, + ThreadInclusion == ThreadInclusion.All, cancellationToken ) ) @@ -136,9 +132,9 @@ public class ExportAllCommand : ExportCommandBase channels.RemoveAll(c => c.Kind.IsGuild()); if (!IncludeVoiceChannels) channels.RemoveAll(c => c.Kind.IsVoice()); - if (!IncludeThreads) + if (ThreadInclusion == ThreadInclusion.None) channels.RemoveAll(c => c.Kind.IsThread()); - if (!IncludeArchivedThreads) + if (ThreadInclusion != ThreadInclusion.All) channels.RemoveAll(c => c.Kind.IsThread() && c.IsArchived); await ExportAsync(console, channels); diff --git a/DiscordChatExporter.Cli/Commands/ExportGuildCommand.cs b/DiscordChatExporter.Cli/Commands/ExportGuildCommand.cs index c338ebc..20ad0f0 100644 --- a/DiscordChatExporter.Cli/Commands/ExportGuildCommand.cs +++ b/DiscordChatExporter.Cli/Commands/ExportGuildCommand.cs @@ -21,15 +21,11 @@ public class ExportGuildCommand : ExportCommandBase [CommandOption( "include-threads", - Description = "Specifies which types of threads should be included.", + Description = "Which types of threads should be included.", Converter = typeof(ThreadInclusionBindingConverter) )] public ThreadInclusion ThreadInclusion { get; init; } = ThreadInclusion.None; - private bool IncludeThreads => ThreadInclusion != ThreadInclusion.None; - - private bool IncludeArchivedThreads => ThreadInclusion.HasFlag(ThreadInclusion.Archived); - public override async ValueTask ExecuteAsync(IConsole console) { await base.ExecuteAsync(console); @@ -52,12 +48,12 @@ public class ExportGuildCommand : ExportCommandBase } // Threads - if (IncludeThreads) + if (ThreadInclusion != ThreadInclusion.None) { await foreach ( var thread in Discord.GetGuildThreadsAsync( GuildId, - IncludeArchivedThreads, + ThreadInclusion == ThreadInclusion.All, cancellationToken ) ) diff --git a/DiscordChatExporter.Cli/Commands/GetChannelsCommand.cs b/DiscordChatExporter.Cli/Commands/GetChannelsCommand.cs index aca0ed5..f74ca35 100644 --- a/DiscordChatExporter.Cli/Commands/GetChannelsCommand.cs +++ b/DiscordChatExporter.Cli/Commands/GetChannelsCommand.cs @@ -23,15 +23,11 @@ public class GetChannelsCommand : DiscordCommandBase [CommandOption( "include-threads", - Description = "Specifies which types of threads should be included.", + Description = "Which types of threads should be included.", Converter = typeof(ThreadInclusionBindingConverter) )] public ThreadInclusion ThreadInclusion { get; init; } = ThreadInclusion.None; - private bool IncludeThreads => ThreadInclusion != ThreadInclusion.None; - - private bool IncludeArchivedThreads => ThreadInclusion.HasFlag(ThreadInclusion.Archived); - public override async ValueTask ExecuteAsync(IConsole console) { await base.ExecuteAsync(console); @@ -50,17 +46,18 @@ public class GetChannelsCommand : DiscordCommandBase .OrderDescending() .FirstOrDefault(); - var threads = IncludeThreads - ? ( - await Discord.GetGuildThreadsAsync( - GuildId, - IncludeArchivedThreads, - cancellationToken + var threads = + ThreadInclusion != ThreadInclusion.None + ? ( + await Discord.GetGuildThreadsAsync( + GuildId, + ThreadInclusion == ThreadInclusion.All, + cancellationToken + ) ) - ) - .OrderBy(c => c.Name) - .ToArray() - : Array.Empty(); + .OrderBy(c => c.Name) + .ToArray() + : Array.Empty(); foreach (var channel in channels) { diff --git a/DiscordChatExporter.Cli/Commands/Shared/ThreadInclusion.cs b/DiscordChatExporter.Cli/Commands/Shared/ThreadInclusion.cs index dfdf3bb..afe201a 100644 --- a/DiscordChatExporter.Cli/Commands/Shared/ThreadInclusion.cs +++ b/DiscordChatExporter.Cli/Commands/Shared/ThreadInclusion.cs @@ -1,12 +1,8 @@ -using System; +namespace DiscordChatExporter.Cli.Commands.Shared; -namespace DiscordChatExporter.Cli.Commands.Shared; - -[Flags] public enum ThreadInclusion { - None = 0, - Active = 1, - Archived = 2, - All = Active | Archived + None, + Active, + All } diff --git a/DiscordChatExporter.Gui/Models/ThreadInclusion.cs b/DiscordChatExporter.Gui/Models/ThreadInclusion.cs new file mode 100644 index 0000000..98bc6d7 --- /dev/null +++ b/DiscordChatExporter.Gui/Models/ThreadInclusion.cs @@ -0,0 +1,8 @@ +namespace DiscordChatExporter.Gui.Models; + +public enum ThreadInclusion +{ + None, + Active, + All +} diff --git a/DiscordChatExporter.Gui/Services/SettingsService.cs b/DiscordChatExporter.Gui/Services/SettingsService.cs index 18f5a85..ba20113 100644 --- a/DiscordChatExporter.Gui/Services/SettingsService.cs +++ b/DiscordChatExporter.Gui/Services/SettingsService.cs @@ -2,6 +2,7 @@ using System.IO; using Cogwheel; using DiscordChatExporter.Core.Exporting; +using DiscordChatExporter.Gui.Models; using Microsoft.Win32; namespace DiscordChatExporter.Gui.Services; @@ -16,9 +17,7 @@ public partial class SettingsService : SettingsBase public bool IsTokenPersisted { get; set; } = true; - public bool ShouldShowThreads { get; set; } - - public bool ShouldShowArchivedThreads { get; set; } + public ThreadInclusion ThreadInclusion { get; set; } = ThreadInclusion.None; public string DateFormat { get; set; } = "MM/dd/yyyy h:mm tt"; diff --git a/DiscordChatExporter.Gui/ViewModels/Components/DashboardViewModel.cs b/DiscordChatExporter.Gui/ViewModels/Components/DashboardViewModel.cs index 9fa09b4..e6e660f 100644 --- a/DiscordChatExporter.Gui/ViewModels/Components/DashboardViewModel.cs +++ b/DiscordChatExporter.Gui/ViewModels/Components/DashboardViewModel.cs @@ -8,6 +8,7 @@ using DiscordChatExporter.Core.Discord.Data; using DiscordChatExporter.Core.Exceptions; using DiscordChatExporter.Core.Exporting; using DiscordChatExporter.Core.Utils.Extensions; +using DiscordChatExporter.Gui.Models; using DiscordChatExporter.Gui.Services; using DiscordChatExporter.Gui.Utils; using DiscordChatExporter.Gui.ViewModels.Dialogs; @@ -169,12 +170,12 @@ public class DashboardViewModel : PropertyChangedBase } // Threads - if (_settingsService.ShouldShowThreads) + if (_settingsService.ThreadInclusion != ThreadInclusion.None) { await foreach ( var thread in _discord.GetGuildThreadsAsync( SelectedGuild.Id, - _settingsService.ShouldShowArchivedThreads + _settingsService.ThreadInclusion == ThreadInclusion.All ) ) { diff --git a/DiscordChatExporter.Gui/ViewModels/Dialogs/SettingsViewModel.cs b/DiscordChatExporter.Gui/ViewModels/Dialogs/SettingsViewModel.cs index 2014d87..2ab0d82 100644 --- a/DiscordChatExporter.Gui/ViewModels/Dialogs/SettingsViewModel.cs +++ b/DiscordChatExporter.Gui/ViewModels/Dialogs/SettingsViewModel.cs @@ -1,4 +1,6 @@ using System; +using System.Collections.Generic; +using DiscordChatExporter.Gui.Models; using DiscordChatExporter.Gui.Services; using DiscordChatExporter.Gui.ViewModels.Framework; @@ -26,23 +28,13 @@ public class SettingsViewModel : DialogScreen set => _settingsService.IsTokenPersisted = value; } - public bool ShouldShowThreads - { - get => _settingsService.ShouldShowThreads; - set => _settingsService.ShouldShowThreads = value; - } + public IReadOnlyList AvailableThreadInclusions { get; } = + Enum.GetValues(); - public bool ShouldShowArchivedThreads + public ThreadInclusion ThreadInclusion { - get => _settingsService.ShouldShowArchivedThreads; - set - { - _settingsService.ShouldShowArchivedThreads = value; - - // Enabling archived threads implicitly enables threads - if (value) - ShouldShowThreads = true; - } + get => _settingsService.ThreadInclusion; + set => _settingsService.ThreadInclusion = value; } public string DateFormat diff --git a/DiscordChatExporter.Gui/Views/Dialogs/SettingsView.xaml b/DiscordChatExporter.Gui/Views/Dialogs/SettingsView.xaml index 52f366c..45a7b7a 100644 --- a/DiscordChatExporter.Gui/Views/Dialogs/SettingsView.xaml +++ b/DiscordChatExporter.Gui/Views/Dialogs/SettingsView.xaml @@ -82,36 +82,21 @@ IsChecked="{Binding IsTokenPersisted}" /> - + + ToolTip="Which types of threads to show in the channel list"> - - - - - - - + ItemsSource="{Binding AvailableThreadInclusions}" + SelectedItem="{Binding ThreadInclusion}" />