mirror of
https://github.com/Tyrrrz/DiscordChatExporter.git
synced 2025-06-07 09:54:50 -04:00
Show threads in GUI at the bottom of the list, in specialized groups
Related to #1119
This commit is contained in:
parent
f1c094ac14
commit
5f6e51f6fb
11 changed files with 49 additions and 13 deletions
|
@ -184,7 +184,7 @@ public abstract class ExportCommandBase : DiscordCommandBase
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
await progressContext.StartTaskAsync(
|
await progressContext.StartTaskAsync(
|
||||||
$"{channel.Category} / {channel.Name}",
|
$"{channel.ParentNameWithFallback} / {channel.Name}",
|
||||||
async progress =>
|
async progress =>
|
||||||
{
|
{
|
||||||
var guild = await Discord.GetGuildAsync(
|
var guild = await Discord.GetGuildAsync(
|
||||||
|
@ -246,7 +246,7 @@ public abstract class ExportCommandBase : DiscordCommandBase
|
||||||
|
|
||||||
foreach (var (channel, error) in errorsByChannel)
|
foreach (var (channel, error) in errorsByChannel)
|
||||||
{
|
{
|
||||||
await console.Error.WriteAsync($"{channel.Category} / {channel.Name}: ");
|
await console.Error.WriteAsync($"{channel.ParentNameWithFallback} / {channel.Name}: ");
|
||||||
|
|
||||||
using (console.WithForegroundColor(ConsoleColor.Red))
|
using (console.WithForegroundColor(ConsoleColor.Red))
|
||||||
await console.Error.WriteLineAsync(error);
|
await console.Error.WriteLineAsync(error);
|
||||||
|
|
|
@ -77,7 +77,7 @@ public class GetChannelsCommand : DiscordCommandBase
|
||||||
|
|
||||||
// Channel category / name
|
// Channel category / name
|
||||||
using (console.WithForegroundColor(ConsoleColor.White))
|
using (console.WithForegroundColor(ConsoleColor.White))
|
||||||
await console.Output.WriteLineAsync($"{channel.Category} / {channel.Name}");
|
await console.Output.WriteLineAsync($"{channel.ParentNameWithFallback} / {channel.Name}");
|
||||||
|
|
||||||
var channelThreads = threads.Where(t => t.Parent?.Id == channel.Id).ToArray();
|
var channelThreads = threads.Where(t => t.Parent?.Id == channel.Id).ToArray();
|
||||||
var channelThreadIdMaxLength = channelThreads
|
var channelThreadIdMaxLength = channelThreads
|
||||||
|
|
|
@ -44,7 +44,7 @@ public class GetDirectChannelsCommand : DiscordCommandBase
|
||||||
|
|
||||||
// Channel category / name
|
// Channel category / name
|
||||||
using (console.WithForegroundColor(ConsoleColor.White))
|
using (console.WithForegroundColor(ConsoleColor.White))
|
||||||
await console.Output.WriteLineAsync($"{channel.Category} / {channel.Name}");
|
await console.Output.WriteLineAsync($"{channel.ParentNameWithFallback} / {channel.Name}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,7 @@ public partial record Channel(
|
||||||
// channels without a parent (i.e. mostly DM channels) or channels
|
// channels without a parent (i.e. mostly DM channels) or channels
|
||||||
// with an inaccessible parent (i.e. inside private categories) had
|
// with an inaccessible parent (i.e. inside private categories) had
|
||||||
// a fallback category created for them.
|
// a fallback category created for them.
|
||||||
public string Category =>
|
public string ParentNameWithFallback =>
|
||||||
Parent?.Name
|
Parent?.Name
|
||||||
?? Kind switch
|
?? Kind switch
|
||||||
{
|
{
|
||||||
|
@ -41,6 +41,9 @@ public partial record Channel(
|
||||||
|
|
||||||
// Only needed for WPF data binding. Don't use anywhere else.
|
// Only needed for WPF data binding. Don't use anywhere else.
|
||||||
public bool IsVoice => Kind.IsVoice();
|
public bool IsVoice => Kind.IsVoice();
|
||||||
|
|
||||||
|
// Only needed for WPF data binding. Don't use anywhere else.
|
||||||
|
public bool IsThread => Kind.IsThread();
|
||||||
}
|
}
|
||||||
|
|
||||||
public partial record Channel
|
public partial record Channel
|
||||||
|
|
|
@ -92,7 +92,9 @@ public partial class ExportRequest
|
||||||
var buffer = new StringBuilder();
|
var buffer = new StringBuilder();
|
||||||
|
|
||||||
// Guild and channel names
|
// Guild and channel names
|
||||||
buffer.Append($"{guild.Name} - {channel.Category} - {channel.Name} [{channel.Id}]");
|
buffer.Append(
|
||||||
|
$"{guild.Name} - {channel.ParentNameWithFallback} - {channel.Name} [{channel.Id}]"
|
||||||
|
);
|
||||||
|
|
||||||
// Date range
|
// Date range
|
||||||
if (after is not null || before is not null)
|
if (after is not null || before is not null)
|
||||||
|
|
|
@ -273,7 +273,7 @@ internal class JsonMessageWriter : MessageWriter
|
||||||
_writer.WriteString("id", Context.Request.Channel.Id.ToString());
|
_writer.WriteString("id", Context.Request.Channel.Id.ToString());
|
||||||
_writer.WriteString("type", Context.Request.Channel.Kind.ToString());
|
_writer.WriteString("type", Context.Request.Channel.Kind.ToString());
|
||||||
_writer.WriteString("categoryId", Context.Request.Channel.Parent?.Id.ToString());
|
_writer.WriteString("categoryId", Context.Request.Channel.Parent?.Id.ToString());
|
||||||
_writer.WriteString("category", Context.Request.Channel.Category);
|
_writer.WriteString("category", Context.Request.Channel.ParentNameWithFallback);
|
||||||
_writer.WriteString("name", Context.Request.Channel.Name);
|
_writer.WriteString("name", Context.Request.Channel.Name);
|
||||||
_writer.WriteString("topic", Context.Request.Channel.Topic);
|
_writer.WriteString("topic", Context.Request.Channel.Topic);
|
||||||
|
|
||||||
|
|
|
@ -201,7 +201,7 @@ internal class PlainTextMessageWriter : MessageWriter
|
||||||
await _writer.WriteLineAsync(new string('=', 62));
|
await _writer.WriteLineAsync(new string('=', 62));
|
||||||
await _writer.WriteLineAsync($"Guild: {Context.Request.Guild.Name}");
|
await _writer.WriteLineAsync($"Guild: {Context.Request.Guild.Name}");
|
||||||
await _writer.WriteLineAsync(
|
await _writer.WriteLineAsync(
|
||||||
$"Channel: {Context.Request.Channel.Category} / {Context.Request.Channel.Name}"
|
$"Channel: {Context.Request.Channel.ParentNameWithFallback} / {Context.Request.Channel.Name}"
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!string.IsNullOrWhiteSpace(Context.Request.Channel.Topic))
|
if (!string.IsNullOrWhiteSpace(Context.Request.Channel.Topic))
|
||||||
|
|
|
@ -1004,7 +1004,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="preamble__entries-container">
|
<div class="preamble__entries-container">
|
||||||
<div class="preamble__entry">@Context.Request.Guild.Name</div>
|
<div class="preamble__entry">@Context.Request.Guild.Name</div>
|
||||||
<div class="preamble__entry">@Context.Request.Channel.Category / @Context.Request.Channel.Name</div>
|
<div class="preamble__entry">@Context.Request.Channel.ParentNameWithFallback / @Context.Request.Channel.Name</div>
|
||||||
|
|
||||||
@if (!string.IsNullOrWhiteSpace(Context.Request.Channel.Topic))
|
@if (!string.IsNullOrWhiteSpace(Context.Request.Channel.Topic))
|
||||||
{
|
{
|
||||||
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
using System;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.Windows.Data;
|
||||||
|
using DiscordChatExporter.Core.Discord.Data;
|
||||||
|
|
||||||
|
namespace DiscordChatExporter.Gui.Converters;
|
||||||
|
|
||||||
|
[ValueConversion(typeof(Channel), typeof(string))]
|
||||||
|
public class ChannelToGroupKeyConverter : IValueConverter
|
||||||
|
{
|
||||||
|
public static ChannelToGroupKeyConverter Instance { get; } = new();
|
||||||
|
|
||||||
|
public object? Convert(object value, Type targetType, object parameter, CultureInfo culture) =>
|
||||||
|
value switch
|
||||||
|
{
|
||||||
|
Channel channel when channel.Kind.IsThread()
|
||||||
|
=> $"Threads in #{channel.ParentNameWithFallback}",
|
||||||
|
|
||||||
|
Channel channel => channel.ParentNameWithFallback,
|
||||||
|
|
||||||
|
_ => null
|
||||||
|
};
|
||||||
|
|
||||||
|
public object ConvertBack(
|
||||||
|
object value,
|
||||||
|
Type targetType,
|
||||||
|
object parameter,
|
||||||
|
CultureInfo culture
|
||||||
|
) => throw new NotSupportedException();
|
||||||
|
}
|
|
@ -19,19 +19,20 @@
|
||||||
Loaded="{s:Action OnViewLoaded}"
|
Loaded="{s:Action OnViewLoaded}"
|
||||||
mc:Ignorable="d">
|
mc:Ignorable="d">
|
||||||
<UserControl.Resources>
|
<UserControl.Resources>
|
||||||
<!-- Sort DMs by last message -->
|
<!-- Collection view for DM channels -->
|
||||||
<CollectionViewSource x:Key="AvailableDirectChannelsViewSource" Source="{Binding AvailableChannels, Mode=OneWay}">
|
<CollectionViewSource x:Key="AvailableDirectChannelsViewSource" Source="{Binding AvailableChannels, Mode=OneWay}">
|
||||||
<CollectionViewSource.SortDescriptions>
|
<CollectionViewSource.SortDescriptions>
|
||||||
<componentModel:SortDescription Direction="Descending" PropertyName="LastMessageId" />
|
<componentModel:SortDescription Direction="Descending" PropertyName="LastMessageId" />
|
||||||
<componentModel:SortDescription Direction="Ascending" PropertyName="Name" />
|
<componentModel:SortDescription Direction="Ascending" PropertyName="Name" />
|
||||||
</CollectionViewSource.SortDescriptions>
|
</CollectionViewSource.SortDescriptions>
|
||||||
</CollectionViewSource>
|
</CollectionViewSource>
|
||||||
<!-- Sort guild channels by position -->
|
<!-- Collection view for guild channels -->
|
||||||
<CollectionViewSource x:Key="AvailableChannelsViewSource" Source="{Binding AvailableChannels, Mode=OneWay}">
|
<CollectionViewSource x:Key="AvailableChannelsViewSource" Source="{Binding AvailableChannels, Mode=OneWay}">
|
||||||
<CollectionViewSource.GroupDescriptions>
|
<CollectionViewSource.GroupDescriptions>
|
||||||
<PropertyGroupDescription PropertyName="Category" />
|
<PropertyGroupDescription Converter="{x:Static converters:ChannelToGroupKeyConverter.Instance}" />
|
||||||
</CollectionViewSource.GroupDescriptions>
|
</CollectionViewSource.GroupDescriptions>
|
||||||
<CollectionViewSource.SortDescriptions>
|
<CollectionViewSource.SortDescriptions>
|
||||||
|
<componentModel:SortDescription Direction="Ascending" PropertyName="IsThread" />
|
||||||
<componentModel:SortDescription Direction="Ascending" PropertyName="Position" />
|
<componentModel:SortDescription Direction="Ascending" PropertyName="Position" />
|
||||||
<componentModel:SortDescription Direction="Ascending" PropertyName="Name" />
|
<componentModel:SortDescription Direction="Ascending" PropertyName="Name" />
|
||||||
</CollectionViewSource.SortDescriptions>
|
</CollectionViewSource.SortDescriptions>
|
||||||
|
|
|
@ -60,7 +60,7 @@
|
||||||
FontWeight="Light"
|
FontWeight="Light"
|
||||||
TextTrimming="CharacterEllipsis"
|
TextTrimming="CharacterEllipsis"
|
||||||
Visibility="{Binding IsSingleChannel, Converter={x:Static s:BoolToVisibilityConverter.Instance}}">
|
Visibility="{Binding IsSingleChannel, Converter={x:Static s:BoolToVisibilityConverter.Instance}}">
|
||||||
<Run Text="{Binding Channels[0].Category, Mode=OneWay}" ToolTip="{Binding Channels[0].Category, Mode=OneWay}" />
|
<Run Text="{Binding Channels[0].ParentNameWithFallback, Mode=OneWay}" ToolTip="{Binding Channels[0].ParentNameWithFallback, Mode=OneWay}" />
|
||||||
<Run Text="/" />
|
<Run Text="/" />
|
||||||
<Run
|
<Run
|
||||||
FontWeight="SemiBold"
|
FontWeight="SemiBold"
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue