mirror of
https://github.com/Tyrrrz/DiscordChatExporter.git
synced 2025-05-11 10:26:57 +02:00
Refactor
This commit is contained in:
parent
789e5af8ba
commit
1fb6156187
15 changed files with 47 additions and 43 deletions
|
@ -7,7 +7,7 @@ namespace DiscordChatExporter.Core.Discord.Data;
|
||||||
// https://discord.com/developers/docs/resources/application#application-object
|
// https://discord.com/developers/docs/resources/application#application-object
|
||||||
public partial record Application(Snowflake Id, string Name, ApplicationFlags Flags)
|
public partial record Application(Snowflake Id, string Name, ApplicationFlags Flags)
|
||||||
{
|
{
|
||||||
public bool IsMessageContentIntentEnabled =>
|
public bool IsMessageContentIntentEnabled { get; } =
|
||||||
Flags.HasFlag(ApplicationFlags.GatewayMessageContent)
|
Flags.HasFlag(ApplicationFlags.GatewayMessageContent)
|
||||||
|| Flags.HasFlag(ApplicationFlags.GatewayMessageContentLimited);
|
|| Flags.HasFlag(ApplicationFlags.GatewayMessageContentLimited);
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,7 @@ public partial record Attachment(
|
||||||
FileSize FileSize
|
FileSize FileSize
|
||||||
) : IHasId
|
) : IHasId
|
||||||
{
|
{
|
||||||
public string FileExtension => Path.GetExtension(FileName);
|
public string FileExtension { get; } = Path.GetExtension(FileName);
|
||||||
|
|
||||||
public bool IsImage =>
|
public bool IsImage =>
|
||||||
string.Equals(FileExtension, ".jpg", StringComparison.OrdinalIgnoreCase)
|
string.Equals(FileExtension, ".jpg", StringComparison.OrdinalIgnoreCase)
|
||||||
|
@ -41,7 +41,7 @@ public partial record Attachment(
|
||||||
|| string.Equals(FileExtension, ".flac", StringComparison.OrdinalIgnoreCase)
|
|| string.Equals(FileExtension, ".flac", StringComparison.OrdinalIgnoreCase)
|
||||||
|| string.Equals(FileExtension, ".m4a", StringComparison.OrdinalIgnoreCase);
|
|| string.Equals(FileExtension, ".m4a", StringComparison.OrdinalIgnoreCase);
|
||||||
|
|
||||||
public bool IsSpoiler => FileName.StartsWith("SPOILER_", StringComparison.Ordinal);
|
public bool IsSpoiler { get; } = FileName.StartsWith("SPOILER_", StringComparison.Ordinal);
|
||||||
}
|
}
|
||||||
|
|
||||||
public partial record Attachment
|
public partial record Attachment
|
||||||
|
|
|
@ -21,21 +21,23 @@ public partial record Channel(
|
||||||
Snowflake? LastMessageId
|
Snowflake? LastMessageId
|
||||||
) : IHasId
|
) : IHasId
|
||||||
{
|
{
|
||||||
public bool IsDirect => Kind is ChannelKind.DirectTextChat or ChannelKind.DirectGroupTextChat;
|
public bool IsDirect { get; } =
|
||||||
|
Kind is ChannelKind.DirectTextChat or ChannelKind.DirectGroupTextChat;
|
||||||
|
|
||||||
public bool IsGuild => !IsDirect;
|
public bool IsGuild => !IsDirect;
|
||||||
|
|
||||||
public bool IsCategory => Kind == ChannelKind.GuildCategory;
|
public bool IsCategory { get; } = Kind == ChannelKind.GuildCategory;
|
||||||
|
|
||||||
public bool IsVoice => Kind is ChannelKind.GuildVoiceChat or ChannelKind.GuildStageVoice;
|
public bool IsVoice { get; } =
|
||||||
|
Kind is ChannelKind.GuildVoiceChat or ChannelKind.GuildStageVoice;
|
||||||
|
|
||||||
public bool IsThread =>
|
public bool IsThread { get; } =
|
||||||
Kind
|
Kind
|
||||||
is ChannelKind.GuildNewsThread
|
is ChannelKind.GuildNewsThread
|
||||||
or ChannelKind.GuildPublicThread
|
or ChannelKind.GuildPublicThread
|
||||||
or ChannelKind.GuildPrivateThread;
|
or ChannelKind.GuildPrivateThread;
|
||||||
|
|
||||||
public bool IsEmpty => LastMessageId is null;
|
public bool IsEmpty { get; } = LastMessageId is null;
|
||||||
|
|
||||||
public IEnumerable<Channel> GetParents()
|
public IEnumerable<Channel> GetParents()
|
||||||
{
|
{
|
||||||
|
|
21
DiscordChatExporter.Core/Discord/Data/ChannelConnection.cs
Normal file
21
DiscordChatExporter.Core/Discord/Data/ChannelConnection.cs
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace DiscordChatExporter.Core.Discord.Data;
|
||||||
|
|
||||||
|
public record ChannelConnection(Channel Channel, IReadOnlyList<ChannelConnection> Children)
|
||||||
|
{
|
||||||
|
public static IReadOnlyList<ChannelConnection> BuildTree(IReadOnlyList<Channel> channels)
|
||||||
|
{
|
||||||
|
IReadOnlyList<ChannelConnection> GetChildren(Channel parent) =>
|
||||||
|
channels
|
||||||
|
.Where(c => c.Parent?.Id == parent.Id)
|
||||||
|
.Select(c => new ChannelConnection(c, GetChildren(c)))
|
||||||
|
.ToArray();
|
||||||
|
|
||||||
|
return channels
|
||||||
|
.Where(c => c.Parent is null)
|
||||||
|
.Select(c => new ChannelConnection(c, GetChildren(c)))
|
||||||
|
.ToArray();
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,21 +0,0 @@
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
|
|
||||||
namespace DiscordChatExporter.Core.Discord.Data;
|
|
||||||
|
|
||||||
public record ChannelNode(Channel Channel, IReadOnlyList<ChannelNode> Children)
|
|
||||||
{
|
|
||||||
public static IReadOnlyList<ChannelNode> BuildTree(IReadOnlyList<Channel> channels)
|
|
||||||
{
|
|
||||||
IReadOnlyList<ChannelNode> GetChildren(Channel parent) =>
|
|
||||||
channels
|
|
||||||
.Where(c => c.Parent?.Id == parent.Id)
|
|
||||||
.Select(c => new ChannelNode(c, GetChildren(c)))
|
|
||||||
.ToArray();
|
|
||||||
|
|
||||||
return channels
|
|
||||||
.Where(c => c.Parent is null)
|
|
||||||
.Select(c => new ChannelNode(c, GetChildren(c)))
|
|
||||||
.ToArray();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -4,7 +4,7 @@ namespace DiscordChatExporter.Core.Discord.Data.Embeds;
|
||||||
|
|
||||||
public partial record SpotifyTrackEmbedProjection(string TrackId)
|
public partial record SpotifyTrackEmbedProjection(string TrackId)
|
||||||
{
|
{
|
||||||
public string Url => $"https://open.spotify.com/embed/track/{TrackId}";
|
public string Url { get; } = $"https://open.spotify.com/embed/track/{TrackId}";
|
||||||
}
|
}
|
||||||
|
|
||||||
public partial record SpotifyTrackEmbedProjection
|
public partial record SpotifyTrackEmbedProjection
|
||||||
|
|
|
@ -4,7 +4,7 @@ namespace DiscordChatExporter.Core.Discord.Data.Embeds;
|
||||||
|
|
||||||
public partial record TwitchClipEmbedProjection(string ClipId)
|
public partial record TwitchClipEmbedProjection(string ClipId)
|
||||||
{
|
{
|
||||||
public string Url => $"https://clips.twitch.tv/embed?clip={ClipId}&parent=localhost";
|
public string Url { get; } = $"https://clips.twitch.tv/embed?clip={ClipId}&parent=localhost";
|
||||||
}
|
}
|
||||||
|
|
||||||
public partial record TwitchClipEmbedProjection
|
public partial record TwitchClipEmbedProjection
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
public partial record YouTubeVideoEmbedProjection(string VideoId)
|
public partial record YouTubeVideoEmbedProjection(string VideoId)
|
||||||
{
|
{
|
||||||
public string Url => $"https://www.youtube.com/embed/{VideoId}";
|
public string Url { get; } = $"https://www.youtube.com/embed/{VideoId}";
|
||||||
}
|
}
|
||||||
|
|
||||||
public partial record YouTubeVideoEmbedProjection
|
public partial record YouTubeVideoEmbedProjection
|
||||||
|
|
|
@ -8,7 +8,7 @@ namespace DiscordChatExporter.Core.Discord.Data;
|
||||||
// https://discord.com/developers/docs/resources/guild#guild-object
|
// https://discord.com/developers/docs/resources/guild#guild-object
|
||||||
public partial record Guild(Snowflake Id, string Name, string IconUrl) : IHasId
|
public partial record Guild(Snowflake Id, string Name, string IconUrl) : IHasId
|
||||||
{
|
{
|
||||||
public bool IsDirect => Id == DirectMessages.Id;
|
public bool IsDirect { get; } = Id == DirectMessages.Id;
|
||||||
}
|
}
|
||||||
|
|
||||||
public partial record Guild
|
public partial record Guild
|
||||||
|
|
|
@ -15,7 +15,7 @@ public partial record Member(
|
||||||
IReadOnlyList<Snowflake> RoleIds
|
IReadOnlyList<Snowflake> RoleIds
|
||||||
) : IHasId
|
) : IHasId
|
||||||
{
|
{
|
||||||
public Snowflake Id => User.Id;
|
public Snowflake Id { get; } = User.Id;
|
||||||
}
|
}
|
||||||
|
|
||||||
public partial record Member
|
public partial record Member
|
||||||
|
|
|
@ -30,15 +30,15 @@ public partial record Message(
|
||||||
Interaction? Interaction
|
Interaction? Interaction
|
||||||
) : IHasId
|
) : IHasId
|
||||||
{
|
{
|
||||||
public bool IsSystemNotification =>
|
public bool IsSystemNotification { get; } =
|
||||||
Kind is >= MessageKind.RecipientAdd and <= MessageKind.ThreadCreated;
|
Kind is >= MessageKind.RecipientAdd and <= MessageKind.ThreadCreated;
|
||||||
|
|
||||||
public bool IsReply => Kind == MessageKind.Reply;
|
public bool IsReply { get; } = Kind == MessageKind.Reply;
|
||||||
|
|
||||||
// App interactions are rendered as replies in the Discord client, but they are not actually replies
|
// App interactions are rendered as replies in the Discord client, but they are not actually replies
|
||||||
public bool IsReplyLike => IsReply || Interaction is not null;
|
public bool IsReplyLike => IsReply || Interaction is not null;
|
||||||
|
|
||||||
public bool IsEmpty =>
|
public bool IsEmpty { get; } =
|
||||||
string.IsNullOrWhiteSpace(Content)
|
string.IsNullOrWhiteSpace(Content)
|
||||||
&& !Attachments.Any()
|
&& !Attachments.Any()
|
||||||
&& !Embeds.Any()
|
&& !Embeds.Any()
|
||||||
|
|
|
@ -9,7 +9,7 @@ namespace DiscordChatExporter.Core.Discord.Data;
|
||||||
// https://discord.com/developers/docs/resources/sticker#sticker-resource
|
// https://discord.com/developers/docs/resources/sticker#sticker-resource
|
||||||
public partial record Sticker(Snowflake Id, string Name, StickerFormat Format, string SourceUrl)
|
public partial record Sticker(Snowflake Id, string Name, StickerFormat Format, string SourceUrl)
|
||||||
{
|
{
|
||||||
public bool IsImage => Format != StickerFormat.Lottie;
|
public bool IsImage { get; } = Format != StickerFormat.Lottie;
|
||||||
}
|
}
|
||||||
|
|
||||||
public partial record Sticker
|
public partial record Sticker
|
||||||
|
|
|
@ -18,7 +18,7 @@ public partial record User(
|
||||||
string AvatarUrl
|
string AvatarUrl
|
||||||
) : IHasId
|
) : IHasId
|
||||||
{
|
{
|
||||||
public string DiscriminatorFormatted =>
|
public string DiscriminatorFormatted { get; } =
|
||||||
Discriminator is not null ? $"{Discriminator:0000}" : "0000";
|
Discriminator is not null ? $"{Discriminator:0000}" : "0000";
|
||||||
|
|
||||||
// This effectively represents the user's true identity.
|
// This effectively represents the user's true identity.
|
||||||
|
|
|
@ -53,7 +53,7 @@ public partial class DashboardViewModel : ViewModelBase
|
||||||
private Guild? _selectedGuild;
|
private Guild? _selectedGuild;
|
||||||
|
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private IReadOnlyList<ChannelNode>? _availableChannels;
|
private IReadOnlyList<ChannelConnection>? _availableChannels;
|
||||||
|
|
||||||
public DashboardViewModel(
|
public DashboardViewModel(
|
||||||
ViewModelManager viewModelManager,
|
ViewModelManager viewModelManager,
|
||||||
|
@ -88,7 +88,7 @@ public partial class DashboardViewModel : ViewModelBase
|
||||||
|
|
||||||
public bool IsProgressIndeterminate => IsBusy && Progress.Current.Fraction is <= 0 or >= 1;
|
public bool IsProgressIndeterminate => IsBusy && Progress.Current.Fraction is <= 0 or >= 1;
|
||||||
|
|
||||||
public ObservableCollection<ChannelNode> SelectedChannels { get; } = [];
|
public ObservableCollection<ChannelConnection> SelectedChannels { get; } = [];
|
||||||
|
|
||||||
[RelayCommand]
|
[RelayCommand]
|
||||||
private void Initialize()
|
private void Initialize()
|
||||||
|
@ -190,7 +190,7 @@ public partial class DashboardViewModel : ViewModelBase
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build a hierarchy of channels
|
// Build a hierarchy of channels
|
||||||
var channelTree = ChannelNode.BuildTree(
|
var channelTree = ChannelConnection.BuildTree(
|
||||||
channels
|
channels
|
||||||
.OrderByDescending(c => c.IsDirect ? c.LastMessageId : null)
|
.OrderByDescending(c => c.IsDirect ? c.LastMessageId : null)
|
||||||
.ThenBy(c => c.Position)
|
.ThenBy(c => c.Position)
|
||||||
|
|
|
@ -28,7 +28,9 @@ public partial class DashboardView : UserControl<DashboardViewModel>
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
// Hack: unselect categories because they cannot be exported
|
// Hack: unselect categories because they cannot be exported
|
||||||
foreach (var item in args.AddedItems.OfType<ChannelNode>().Where(x => x.Channel.IsCategory))
|
foreach (
|
||||||
|
var item in args.AddedItems.OfType<ChannelConnection>().Where(x => x.Channel.IsCategory)
|
||||||
|
)
|
||||||
{
|
{
|
||||||
if (AvailableChannelsTreeView.TreeContainerFromItem(item) is TreeViewItem container)
|
if (AvailableChannelsTreeView.TreeContainerFromItem(item) is TreeViewItem container)
|
||||||
container.IsSelected = false;
|
container.IsSelected = false;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue