Skip to content

Commit

Permalink
feat(experimental): temporary implementation of message forward reading
Browse files Browse the repository at this point in the history
  • Loading branch information
Lulalaby committed Jul 13, 2024
1 parent a30b439 commit 1cf4a64
Show file tree
Hide file tree
Showing 6 changed files with 292 additions and 1 deletion.
33 changes: 33 additions & 0 deletions DisCatSharp/Clients/DiscordClient.Dispatch.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2377,6 +2377,17 @@ internal async Task OnMessageCreateEventAsync(DiscordMessage message, TransportU
message.ReferencedMessage.PopulateMentions();
}

message.MessageSnapshots?.ForEach(x =>
{
x.Message.Discord = this;
if (x.Message.MentionedUsersInternal.Count is not 0)
x.Message.MentionedUsers.ForEach(u => u.Discord = this);
if (x.Message.AttachmentsInternal.Count is not 0)
x.Message.AttachmentsInternal.ForEach(a => a.Discord = this);
if (x.Message.EmbedsInternal.Count is not 0)
x.Message.EmbedsInternal.ForEach(a => a.Discord = this);
});

foreach (var sticker in message.Stickers)
sticker.Discord = this;

Expand Down Expand Up @@ -2435,6 +2446,28 @@ internal async Task OnMessageUpdateEventAsync(DiscordMessage message, TransportU
message.IsTts = eventMessage.IsTts;
}

message.MessageSnapshots?.ForEach(x =>
{
x.Message.Discord = this;
if (x.Message.MentionedUsersInternal.Count is not 0)
x.Message.MentionedUsers.ForEach(u => u.Discord = this);
if (x.Message.AttachmentsInternal.Count is not 0)
x.Message.AttachmentsInternal.ForEach(a => a.Discord = this);
if (x.Message.EmbedsInternal.Count is not 0)
x.Message.EmbedsInternal.ForEach(a => a.Discord = this);
});

oldmsg?.MessageSnapshots?.ForEach(x =>
{
x.Message.Discord = this;
if (x.Message.MentionedUsersInternal.Count is not 0)
x.Message.MentionedUsers.ForEach(u => u.Discord = this);
if (x.Message.AttachmentsInternal.Count is not 0)
x.Message.AttachmentsInternal.ForEach(a => a.Discord = this);
if (x.Message.EmbedsInternal.Count is not 0)
x.Message.EmbedsInternal.ForEach(a => a.Discord = this);
});

message.PopulateMentions();

var ea = new MessageUpdateEventArgs(this.ServiceProvider)
Expand Down
178 changes: 178 additions & 0 deletions DisCatSharp/Entities/Message/DiscordForwardedMessage.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
using System.Collections.Generic;
using System;
using System.Collections.ObjectModel;
using System.Globalization;
using System.Linq;

using DisCatSharp.Attributes;
using DisCatSharp.Enums;
using DisCatSharp.Net.Abstractions;

using Newtonsoft.Json;

namespace DisCatSharp.Entities;

[DiscordInExperiment, Experimental("This is subject to change at any time.")]
public class DiscordForwardedMessage : ObservableApiObject
{
internal DiscordForwardedMessage()
{
this._attachmentsLazy = new(() => new ReadOnlyCollection<DiscordAttachment>(this.AttachmentsInternal));
this._embedsLazy = new(() => new ReadOnlyCollection<DiscordEmbed>(this.EmbedsInternal));
/*this._mentionedChannelsLazy = new(() => this.MentionedChannelsInternal != null
? new ReadOnlyCollection<DiscordChannel>(this.MentionedChannelsInternal)
: Array.Empty<DiscordChannel>());
this._mentionedRolesLazy = new(() => this.MentionedRolesInternal != null ? new ReadOnlyCollection<DiscordRole>(this.MentionedRolesInternal) : Array.Empty<DiscordRole>());
this.MentionedUsersLazy = new(() => new ReadOnlyCollection<DiscordUser>(this.MentionedUsersInternal));*/
}

/// <summary>
/// Gets the type of the message.
/// </summary>
[JsonProperty("type", NullValueHandling = NullValueHandling.Ignore)]
public MessageType? MessageType { get; internal set; }

/// <summary>
/// Gets the message's content.
/// </summary>
[JsonProperty("content", NullValueHandling = NullValueHandling.Ignore)]
public string Content { get; internal set; }

/// <summary>
/// Gets embeds attached to this message.
/// </summary>
[JsonIgnore]
public IReadOnlyList<DiscordEmbed> Embeds
=> this._embedsLazy.Value;

[JsonProperty("embeds", NullValueHandling = NullValueHandling.Ignore)]
internal List<DiscordEmbed> EmbedsInternal = [];

[JsonIgnore]
private readonly Lazy<IReadOnlyList<DiscordEmbed>> _embedsLazy;

/// <summary>
/// Gets files attached to this message.
/// </summary>
[JsonIgnore]
public IReadOnlyList<DiscordAttachment> Attachments
=> this._attachmentsLazy.Value;

[JsonProperty("attachments", NullValueHandling = NullValueHandling.Ignore)]
internal List<DiscordAttachment> AttachmentsInternal = [];

[JsonIgnore]
private readonly Lazy<IReadOnlyList<DiscordAttachment>> _attachmentsLazy;

/// <summary>
/// Gets the message's creation timestamp.
/// </summary>
[JsonIgnore]
public DateTimeOffset? Timestamp
=> !string.IsNullOrWhiteSpace(this.TimestampRaw) && DateTimeOffset.TryParse(this.TimestampRaw, CultureInfo.InvariantCulture, DateTimeStyles.None, out var dto) ? dto : null;

/// <summary>
/// Gets the message's creation timestamp as raw string.
/// </summary>
[JsonProperty("timestamp", NullValueHandling = NullValueHandling.Ignore)]
internal string TimestampRaw { get; set; }

/// <summary>
/// Gets the message's edit timestamp. Will be null if the message was not edited.
/// </summary>
[JsonIgnore]
public DateTimeOffset? EditedTimestamp
=> !string.IsNullOrWhiteSpace(this.EditedTimestampRaw) && DateTimeOffset.TryParse(this.EditedTimestampRaw, CultureInfo.InvariantCulture, DateTimeStyles.None, out var dto) ? dto : null;

/// <summary>
/// Gets the message's edit timestamp as raw string. Will be null if the message was not edited.
/// </summary>
[JsonProperty("edited_timestamp", NullValueHandling = NullValueHandling.Ignore)]
internal string EditedTimestampRaw { get; set; }

/// <summary>
/// Gets whether this message was edited.
/// </summary>
[JsonIgnore]
public bool IsEdited
=> !string.IsNullOrWhiteSpace(this.EditedTimestampRaw);

/// <summary>
/// Gets the bitwise flags for this message.
/// </summary>
[JsonProperty("flags", NullValueHandling = NullValueHandling.Ignore)]
public MessageFlags? Flags { get; internal set; }

/// <summary>
/// Gets whether the message mentions everyone.
/// </summary>
[JsonProperty("mention_everyone", NullValueHandling = NullValueHandling.Ignore)]
public bool MentionEveryone { get; internal set; }

/*
TODO: Implement if stable
/// <summary>
/// Gets users or members mentioned by this message.
/// </summary>
[JsonIgnore]
public IReadOnlyList<DiscordUser> MentionedUsers
=> this.MentionedUsersLazy.Value;
*/

[JsonProperty("mentions", NullValueHandling = NullValueHandling.Ignore)]
internal List<TransportUser> MentionedUsersInternal { get; set; } = [];

/// <summary>
/// Gets users mentioned by this message.
/// </summary>
[JsonIgnore]
public List<DiscordUser> MentionedUsers
=> this.MentionedUsersInternal.Count is not 0
? this.MentionedUsersInternal.Select(x => new DiscordUser(x)
{
Discord = this.Discord
}).ToList()
: [];

/*
TODO: Implement if stable
[JsonIgnore]
internal readonly Lazy<IReadOnlyList<DiscordUser>> MentionedUsersLazy;
/// <summary>
/// Gets roles mentioned by this message.
/// </summary>
[JsonIgnore]
public IReadOnlyList<DiscordRole> MentionedRoles
=> this._mentionedRolesLazy.Value;
[JsonIgnore]
internal List<DiscordRole> MentionedRolesInternal;
*/

/// <summary>
/// Gets role ids mentioned by this message.
/// </summary>
[JsonProperty("mention_roles")]
public List<ulong> MentionedRoleIds = [];

/*
TODO: Implement if stable
[JsonIgnore]
private readonly Lazy<IReadOnlyList<DiscordRole>> _mentionedRolesLazy;
/// <summary>
/// Gets channels mentioned by this message.
/// </summary>
[JsonIgnore]
public IReadOnlyList<DiscordChannel> MentionedChannels
=> this._mentionedChannelsLazy.Value;
[JsonIgnore]
internal List<DiscordChannel> MentionedChannelsInternal;
[JsonIgnore]
private readonly Lazy<IReadOnlyList<DiscordChannel>> _mentionedChannelsLazy;
*/
}
25 changes: 24 additions & 1 deletion DisCatSharp/Entities/Message/DiscordMessage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using System.Linq;
using System.Threading.Tasks;

using DisCatSharp.Attributes;
using DisCatSharp.Enums;
using DisCatSharp.Exceptions;
using DisCatSharp.Net.Abstractions;
Expand Down Expand Up @@ -345,12 +346,32 @@ public IReadOnlyList<DiscordReaction> Reactions
internal InternalDiscordMessageReference? InternalReference { get; set; }

/// <summary>
/// Gets the original message reference from the cross-posted message.
/// Gets the message reference.
/// </summary>
[JsonIgnore]
public DiscordMessageReference Reference
=> this.InternalReference.HasValue ? this?.InternalBuildMessageReference() : null;

/// <summary>
/// Gets the message snapshots.
/// </summary>
[JsonProperty("message_snapshots", NullValueHandling = NullValueHandling.Ignore)]
public List<DiscordMessageSnapshot>? MessageSnapshots { get; internal set; }

/// <summary>
/// Gets whether this message has a message reference (reply, announcement, etc.).
/// </summary>
[Experimental("We provide that temporary, as we figure out things.")]
public bool HasMessageReference
=> this.InternalReference is { Type: ReferenceType.Default };

/// <summary>
/// Gets whether this message has forwarded messages.
/// </summary>
[Experimental("We provide that temporary, as we figure out things.")]
public bool HasMessageSnapshots
=> this.InternalReference is { Type: ReferenceType.Forward };

/// <summary>
/// Gets the bitwise flags for this message.
/// </summary>
Expand Down Expand Up @@ -474,6 +495,7 @@ internal DiscordMessageReference InternalBuildMessageReference()
var guildId = this.InternalReference.Value.GuildId;
var channelId = this.InternalReference.Value.ChannelId;
var messageId = this.InternalReference.Value.MessageId;
var type = this.InternalReference.Value.Type;

var reference = new DiscordMessageReference();

Expand All @@ -487,6 +509,7 @@ internal DiscordMessageReference InternalBuildMessageReference()
};

var channel = client.InternalGetCachedChannel(channelId.Value);
reference.Type = type;

if (channel == null)
{
Expand Down
22 changes: 22 additions & 0 deletions DisCatSharp/Entities/Message/DiscordMessageReference.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
using DisCatSharp.Enums;

using Newtonsoft.Json;

namespace DisCatSharp.Entities;
Expand All @@ -7,6 +9,11 @@ namespace DisCatSharp.Entities;
/// </summary>
public class DiscordMessageReference
{
/// <summary>
/// Gets the type of the reference.
/// </summary>
public ReferenceType Type { get; internal set; }

/// <summary>
/// Gets the original message.
/// </summary>
Expand Down Expand Up @@ -37,6 +44,21 @@ internal DiscordMessageReference()

internal struct InternalDiscordMessageReference
{
public InternalDiscordMessageReference()
{
this.Type = ReferenceType.Default;
this.MessageId = null;
this.ChannelId = null;
this.GuildId = null;
this.FailIfNotExists = false;
}

/// <summary>
/// Gets the type of the reference.
/// </summary>
[JsonProperty("type", NullValueHandling = NullValueHandling.Ignore)]
internal ReferenceType Type { get; set; }

/// <summary>
/// Gets the message id.
/// </summary>
Expand Down
12 changes: 12 additions & 0 deletions DisCatSharp/Entities/Message/DiscordMessageSnapshots.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using DisCatSharp.Attributes;

using Newtonsoft.Json;

namespace DisCatSharp.Entities;

[DiscordInExperiment, Experimental]
public class DiscordMessageSnapshot : ObservableApiObject
{
[JsonProperty("message")]
public DiscordForwardedMessage Message { get; internal set; }
}
23 changes: 23 additions & 0 deletions DisCatSharp/Enums/Message/ReferenceType.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DisCatSharp.Enums;

/// <summary>
/// Represents the message reference type.
/// </summary>
public enum ReferenceType
{
/// <summary>
/// A standard reference used by replies.
/// </summary>
Default = 0,

/// <summary>
/// Reference used to point to a message at a point in time.
/// </summary>
Forward = 1
}

0 comments on commit 1cf4a64

Please sign in to comment.