feature: Forum channels (#2316)
* initial implementation * Update SocketForumChannel.cs * rest forum channel and remove message builder for 4.x * Update src/Discord.Net.Core/DiscordConfig.cs Co-authored-by: Jared L <48422312+lhjt@users.noreply.github.com> * Update src/Discord.Net.Core/Entities/Channels/IForumChannel.cs Co-authored-by: Jared L <48422312+lhjt@users.noreply.github.com> * Update src/Discord.Net.Core/DiscordConfig.cs Co-authored-by: Jared L <48422312+lhjt@users.noreply.github.com> * Update src/Discord.Net.Core/Entities/Channels/IForumChannel.cs Co-authored-by: Jared L <48422312+lhjt@users.noreply.github.com> * Update src/Discord.Net.Core/Entities/Channels/IForumChannel.cs Co-authored-by: Jared L <48422312+lhjt@users.noreply.github.com> * Update src/Discord.Net.Core/Entities/Channels/IForumChannel.cs Co-authored-by: Jared L <48422312+lhjt@users.noreply.github.com> Co-authored-by: Jared L <48422312+lhjt@users.noreply.github.com>
This commit is contained in:
@@ -0,0 +1,128 @@
|
||||
using Discord.Rest;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Model = Discord.API.Channel;
|
||||
|
||||
namespace Discord.WebSocket
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a forum channel in a guild.
|
||||
/// </summary>
|
||||
public class SocketForumChannel : SocketGuildChannel, IForumChannel
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public bool IsNsfw { get; private set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string Topic { get; private set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public ThreadArchiveDuration DefaultAutoArchiveDuration { get; private set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IReadOnlyCollection<ForumTag> Tags { get; private set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string Mention => MentionUtils.MentionChannel(Id);
|
||||
|
||||
internal SocketForumChannel(DiscordSocketClient discord, ulong id, SocketGuild guild) : base(discord, id, guild) { }
|
||||
|
||||
internal new static SocketForumChannel Create(SocketGuild guild, ClientState state, Model model)
|
||||
{
|
||||
var entity = new SocketForumChannel(guild.Discord, model.Id, guild);
|
||||
entity.Update(state, model);
|
||||
return entity;
|
||||
}
|
||||
|
||||
internal override void Update(ClientState state, Model model)
|
||||
{
|
||||
base.Update(state, model);
|
||||
IsNsfw = model.Nsfw.GetValueOrDefault(false);
|
||||
Topic = model.Topic.GetValueOrDefault();
|
||||
DefaultAutoArchiveDuration = model.AutoArchiveDuration.GetValueOrDefault(ThreadArchiveDuration.OneDay);
|
||||
|
||||
Tags = model.ForumTags.GetValueOrDefault(Array.Empty<API.ForumTags>()).Select(
|
||||
x => new ForumTag(x.Id, x.Name, x.EmojiId.GetValueOrDefault(null), x.EmojiName.GetValueOrDefault())
|
||||
).ToImmutableArray();
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IForumChannel.CreatePostAsync(string, ThreadArchiveDuration, int?, string, Embed, RequestOptions, AllowedMentions, MessageComponent, ISticker[], Embed[], MessageFlags)"/>
|
||||
public Task<RestThreadChannel> CreatePostAsync(string title, ThreadArchiveDuration archiveDuration = ThreadArchiveDuration.OneDay, int? slowmode = null, string text = null, Embed embed = null, RequestOptions options = null, AllowedMentions allowedMentions = null, MessageComponent components = null, ISticker[] stickers = null, Embed[] embeds = null, MessageFlags flags = MessageFlags.None)
|
||||
=> ThreadHelper.CreatePostAsync(this, Discord, title, archiveDuration, slowmode, text, embed, options, allowedMentions, components, stickers, embeds, flags);
|
||||
|
||||
/// <inheritdoc cref="IForumChannel.CreatePostWithFileAsync(string, string, ThreadArchiveDuration, int?, string, Embed, RequestOptions, bool, AllowedMentions, MessageComponent, ISticker[], Embed[], MessageFlags)"/>
|
||||
public async Task<RestThreadChannel> CreatePostWithFileAsync(string title, string filePath, ThreadArchiveDuration archiveDuration = ThreadArchiveDuration.OneDay,
|
||||
int? slowmode = null, string text = null, Embed embed = null, RequestOptions options = null, bool isSpoiler = false,
|
||||
AllowedMentions allowedMentions = null, MessageComponent components = null,
|
||||
ISticker[] stickers = null, Embed[] embeds = null, MessageFlags flags = MessageFlags.None)
|
||||
{
|
||||
using var file = new FileAttachment(filePath, isSpoiler: isSpoiler);
|
||||
return await ThreadHelper.CreatePostAsync(this, Discord, title, new FileAttachment[] { file }, archiveDuration, slowmode, text, embed, options, allowedMentions, components, stickers, embeds, flags).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IForumChannel.CreatePostWithFileAsync(string, Stream, string, ThreadArchiveDuration, int?, string, Embed, RequestOptions, bool, AllowedMentions, MessageComponent, ISticker[], Embed[], MessageFlags)"/>
|
||||
public async Task<RestThreadChannel> CreatePostWithFileAsync(string title, Stream stream, string filename, ThreadArchiveDuration archiveDuration = ThreadArchiveDuration.OneDay,
|
||||
int? slowmode = null, string text = null, Embed embed = null, RequestOptions options = null, bool isSpoiler = false,
|
||||
AllowedMentions allowedMentions = null, MessageComponent components = null,
|
||||
ISticker[] stickers = null, Embed[] embeds = null, MessageFlags flags = MessageFlags.None)
|
||||
{
|
||||
using var file = new FileAttachment(stream, filename, isSpoiler: isSpoiler);
|
||||
return await ThreadHelper.CreatePostAsync(this, Discord, title, new FileAttachment[] { file }, archiveDuration, slowmode, text, embed, options, allowedMentions, components, stickers, embeds, flags).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IForumChannel.CreatePostWithFileAsync(string, FileAttachment, ThreadArchiveDuration, int?, string, Embed, RequestOptions, AllowedMentions, MessageComponent, ISticker[], Embed[], MessageFlags)"/>
|
||||
public Task<RestThreadChannel> CreatePostWithFileAsync(string title, FileAttachment attachment, ThreadArchiveDuration archiveDuration = ThreadArchiveDuration.OneDay,
|
||||
int? slowmode = null, string text = null, Embed embed = null, RequestOptions options = null, AllowedMentions allowedMentions = null,
|
||||
MessageComponent components = null, ISticker[] stickers = null, Embed[] embeds = null, MessageFlags flags = MessageFlags.None)
|
||||
=> ThreadHelper.CreatePostAsync(this, Discord, title, new FileAttachment[] { attachment }, archiveDuration, slowmode, text, embed, options, allowedMentions, components, stickers, embeds, flags);
|
||||
|
||||
/// <inheritdoc cref="IForumChannel.CreatePostWithFilesAsync(string, IEnumerable{FileAttachment}, ThreadArchiveDuration, int?, string, Embed, RequestOptions, AllowedMentions, MessageComponent, ISticker[], Embed[], MessageFlags)"/>
|
||||
public Task<RestThreadChannel> CreatePostWithFilesAsync(string title, IEnumerable<FileAttachment> attachments, ThreadArchiveDuration archiveDuration = ThreadArchiveDuration.OneDay,
|
||||
int? slowmode = null, string text = null, Embed embed = null, RequestOptions options = null, AllowedMentions allowedMentions = null,
|
||||
MessageComponent components = null, ISticker[] stickers = null, Embed[] embeds = null, MessageFlags flags = MessageFlags.None)
|
||||
=> ThreadHelper.CreatePostAsync(this, Discord, title, attachments, archiveDuration, slowmode, text, embed, options, allowedMentions, components, stickers, embeds, flags);
|
||||
|
||||
/// <inheritdoc cref="IForumChannel.GetActiveThreadsAsync(RequestOptions)"/>
|
||||
public Task<IReadOnlyCollection<RestThreadChannel>> GetActiveThreadsAsync(RequestOptions options = null)
|
||||
=> ThreadHelper.GetActiveThreadsAsync(Guild, Discord, options);
|
||||
|
||||
/// <inheritdoc cref="IForumChannel.GetJoinedPrivateArchivedThreadsAsync(int?, DateTimeOffset?, RequestOptions)"/>
|
||||
public Task<IReadOnlyCollection<RestThreadChannel>> GetJoinedPrivateArchivedThreadsAsync(int? limit = null, DateTimeOffset? before = null, RequestOptions options = null)
|
||||
=> ThreadHelper.GetJoinedPrivateArchivedThreadsAsync(this, Discord, limit, before, options);
|
||||
|
||||
/// <inheritdoc cref="IForumChannel.GetPrivateArchivedThreadsAsync(int?, DateTimeOffset?, RequestOptions)"/>
|
||||
public Task<IReadOnlyCollection<RestThreadChannel>> GetPrivateArchivedThreadsAsync(int? limit = null, DateTimeOffset? before = null, RequestOptions options = null)
|
||||
=> ThreadHelper.GetPrivateArchivedThreadsAsync(this, Discord, limit, before, options);
|
||||
|
||||
/// <inheritdoc cref="IForumChannel.GetPublicArchivedThreadsAsync(int?, DateTimeOffset?, RequestOptions)"/>
|
||||
public Task<IReadOnlyCollection<RestThreadChannel>> GetPublicArchivedThreadsAsync(int? limit = null, DateTimeOffset? before = null, RequestOptions options = null)
|
||||
=> ThreadHelper.GetPublicArchivedThreadsAsync(this, Discord, limit, before, options);
|
||||
|
||||
#region IForumChannel
|
||||
async Task<IReadOnlyCollection<IThreadChannel>> IForumChannel.GetActiveThreadsAsync(RequestOptions options)
|
||||
=> await GetActiveThreadsAsync(options).ConfigureAwait(false);
|
||||
async Task<IReadOnlyCollection<IThreadChannel>> IForumChannel.GetPublicArchivedThreadsAsync(int? limit, DateTimeOffset? before, RequestOptions options)
|
||||
=> await GetPublicArchivedThreadsAsync(limit, before, options).ConfigureAwait(false);
|
||||
async Task<IReadOnlyCollection<IThreadChannel>> IForumChannel.GetPrivateArchivedThreadsAsync(int? limit, DateTimeOffset? before, RequestOptions options)
|
||||
=> await GetPrivateArchivedThreadsAsync(limit, before, options).ConfigureAwait(false);
|
||||
async Task<IReadOnlyCollection<IThreadChannel>> IForumChannel.GetJoinedPrivateArchivedThreadsAsync(int? limit, DateTimeOffset? before, RequestOptions options)
|
||||
=> await GetJoinedPrivateArchivedThreadsAsync(limit, before, options).ConfigureAwait(false);
|
||||
async Task<IThreadChannel> IForumChannel.CreatePostAsync(string title, ThreadArchiveDuration archiveDuration, int? slowmode, string text, Embed embed, RequestOptions options, AllowedMentions allowedMentions, MessageComponent components, ISticker[] stickers, Embed[] embeds, MessageFlags flags)
|
||||
=> await CreatePostAsync(title, archiveDuration, slowmode, text, embed, options, allowedMentions, components, stickers, embeds, flags).ConfigureAwait(false);
|
||||
async Task<IThreadChannel> IForumChannel.CreatePostWithFileAsync(string title, string filePath, ThreadArchiveDuration archiveDuration, int? slowmode, string text, Embed embed, RequestOptions options, bool isSpoiler, AllowedMentions allowedMentions, MessageComponent components, ISticker[] stickers, Embed[] embeds, MessageFlags flags)
|
||||
=> await CreatePostWithFileAsync(title, filePath, archiveDuration, slowmode, text, embed, options, isSpoiler, allowedMentions, components, stickers, embeds, flags).ConfigureAwait(false);
|
||||
async Task<IThreadChannel> IForumChannel.CreatePostWithFileAsync(string title, Stream stream, string filename, ThreadArchiveDuration archiveDuration, int? slowmode, string text, Embed embed, RequestOptions options, bool isSpoiler, AllowedMentions allowedMentions, MessageComponent components, ISticker[] stickers, Embed[] embeds, MessageFlags flags)
|
||||
=> await CreatePostWithFileAsync(title, stream, filename, archiveDuration, slowmode, text, embed, options, isSpoiler, allowedMentions, components, stickers, embeds, flags).ConfigureAwait(false);
|
||||
async Task<IThreadChannel> IForumChannel.CreatePostWithFileAsync(string title, FileAttachment attachment, ThreadArchiveDuration archiveDuration, int? slowmode, string text, Embed embed, RequestOptions options, AllowedMentions allowedMentions, MessageComponent components, ISticker[] stickers, Embed[] embeds, MessageFlags flags)
|
||||
=> await CreatePostWithFileAsync(title, attachment, archiveDuration, slowmode, text, embed, options, allowedMentions, components, stickers, embeds, flags).ConfigureAwait(false);
|
||||
async Task<IThreadChannel> IForumChannel.CreatePostWithFilesAsync(string title, IEnumerable<FileAttachment> attachments, ThreadArchiveDuration archiveDuration, int? slowmode, string text, Embed embed, RequestOptions options, AllowedMentions allowedMentions, MessageComponent components, ISticker[] stickers, Embed[] embeds, MessageFlags flags)
|
||||
=> await CreatePostWithFilesAsync(title, attachments, archiveDuration, slowmode, text, embed, options, allowedMentions, components, stickers, embeds, flags);
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -59,6 +59,7 @@ namespace Discord.WebSocket
|
||||
ChannelType.Category => SocketCategoryChannel.Create(guild, state, model),
|
||||
ChannelType.PrivateThread or ChannelType.PublicThread or ChannelType.NewsThread => SocketThreadChannel.Create(guild, state, model),
|
||||
ChannelType.Stage => SocketStageChannel.Create(guild, state, model),
|
||||
ChannelType.Forum => SocketForumChannel.Create(guild, state, model),
|
||||
_ => new SocketGuildChannel(guild.Discord, model.Id, guild),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -705,7 +705,15 @@ namespace Discord.WebSocket
|
||||
/// </returns>
|
||||
public SocketThreadChannel GetThreadChannel(ulong id)
|
||||
=> GetChannel(id) as SocketThreadChannel;
|
||||
|
||||
/// <summary>
|
||||
/// Gets a forum channel in this guild.
|
||||
/// </summary>
|
||||
/// <param name="id">The snowflake identifier for the forum channel.</param>
|
||||
/// <returns>
|
||||
/// A forum channel associated with the specified <paramref name="id" />; <see langword="null"/> if none is found.
|
||||
/// </returns>
|
||||
public SocketForumChannel GetForumChannel(ulong id)
|
||||
=> GetChannel(id) as SocketForumChannel;
|
||||
/// <summary>
|
||||
/// Gets a voice channel in this guild.
|
||||
/// </summary>
|
||||
|
||||
Reference in New Issue
Block a user