[Feature] Media channel support (#2725)
* initial commit * oops * another typo -_- * Update AttachmentFlags.cs Made this on my phone lol * Update AttachmentFlags.cs * -line * initial impl * some guild methods for media (and forum) channels * file attachment can be a thumbnail * can't edit media channel layout * updatess * Update ChannelPermissions.cs * typo
This commit is contained in:
@@ -16,7 +16,12 @@ public enum ChannelFlags
|
||||
Pinned = 1 << 1,
|
||||
|
||||
/// <summary>
|
||||
/// Flag given to a forum channel that requires people to select tags when posting.
|
||||
/// Flag given to a forum or media channel that requires people to select tags when posting.
|
||||
/// </summary>
|
||||
RequireTag = 1 << 4
|
||||
RequireTag = 1 << 4,
|
||||
|
||||
/// <summary>
|
||||
/// Flag given to a media channel that hides the embedded media download options.
|
||||
/// </summary>
|
||||
HideMediaDownloadOption = 1 << 15,
|
||||
}
|
||||
|
||||
@@ -1,33 +1,75 @@
|
||||
namespace Discord
|
||||
namespace Discord;
|
||||
|
||||
/// <summary> Defines the types of channels. </summary>
|
||||
public enum ChannelType
|
||||
{
|
||||
/// <summary> Defines the types of channels. </summary>
|
||||
public enum ChannelType
|
||||
{
|
||||
/// <summary> The channel is a text channel. </summary>
|
||||
/// <summary>
|
||||
/// The channel is a text channel.
|
||||
/// </summary>
|
||||
Text = 0,
|
||||
/// <summary> The channel is a Direct Message channel. </summary>
|
||||
|
||||
/// <summary>
|
||||
/// The channel is a Direct Message channel.
|
||||
/// </summary>
|
||||
DM = 1,
|
||||
/// <summary> The channel is a voice channel. </summary>
|
||||
|
||||
/// <summary>
|
||||
/// The channel is a voice channel.
|
||||
/// </summary>
|
||||
Voice = 2,
|
||||
/// <summary> The channel is a group channel. </summary>
|
||||
|
||||
/// <summary>
|
||||
/// The channel is a group channel.
|
||||
/// </summary>
|
||||
Group = 3,
|
||||
/// <summary> The channel is a category channel. </summary>
|
||||
|
||||
/// <summary>
|
||||
/// The channel is a category channel.
|
||||
/// </summary>
|
||||
Category = 4,
|
||||
/// <summary> The channel is a news channel. </summary>
|
||||
|
||||
/// <summary>
|
||||
/// The channel is a news channel.
|
||||
/// </summary>
|
||||
News = 5,
|
||||
/// <summary> The channel is a store channel. </summary>
|
||||
|
||||
/// <summary>
|
||||
/// The channel is a store channel.
|
||||
/// </summary>
|
||||
Store = 6,
|
||||
/// <summary> The channel is a temporary thread channel under a news channel. </summary>
|
||||
|
||||
/// <summary>
|
||||
/// The channel is a temporary thread channel under a news channel.
|
||||
/// </summary>
|
||||
NewsThread = 10,
|
||||
/// <summary> The channel is a temporary thread channel under a text channel. </summary>
|
||||
|
||||
/// <summary>
|
||||
/// The channel is a temporary thread channel under a text channel.
|
||||
/// </summary>
|
||||
PublicThread = 11,
|
||||
/// <summary> The channel is a private temporary thread channel under a text channel. </summary>
|
||||
|
||||
/// <summary>
|
||||
/// The channel is a private temporary thread channel under a text channel.
|
||||
/// </summary>
|
||||
PrivateThread = 12,
|
||||
/// <summary> The channel is a stage voice channel. </summary>
|
||||
|
||||
/// <summary>
|
||||
/// The channel is a stage voice channel.
|
||||
/// </summary>
|
||||
Stage = 13,
|
||||
/// <summary> The channel is a guild directory used in hub servers. (Unreleased)</summary>
|
||||
|
||||
/// <summary>
|
||||
/// The channel is a guild directory used in hub servers. (Unreleased)
|
||||
/// </summary>
|
||||
GuildDirectory = 14,
|
||||
/// <summary> The channel is a forum channel containing multiple threads. </summary>
|
||||
Forum = 15
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The channel is a forum channel containing multiple threads.
|
||||
/// </summary>
|
||||
Forum = 15,
|
||||
|
||||
/// <summary>
|
||||
/// The channel is a media channel containing multiple threads.
|
||||
/// </summary>
|
||||
Media = 16,
|
||||
}
|
||||
|
||||
@@ -46,5 +46,8 @@ public class ForumChannelProperties : TextChannelProperties
|
||||
/// <summary>
|
||||
/// Gets or sets the rule used to display posts in a forum channel.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This property cannot be changed in media channels.
|
||||
/// </remarks>
|
||||
public Optional<ForumLayout> DefaultLayout { get; set; }
|
||||
}
|
||||
|
||||
9
src/Discord.Net.Core/Entities/Channels/IMediaChannel.cs
Normal file
9
src/Discord.Net.Core/Entities/Channels/IMediaChannel.cs
Normal file
@@ -0,0 +1,9 @@
|
||||
namespace Discord;
|
||||
|
||||
/// <summary>
|
||||
/// Represents a media channel in a guild that can create posts.
|
||||
/// </summary>
|
||||
public interface IMediaChannel : IForumChannel
|
||||
{
|
||||
|
||||
}
|
||||
@@ -733,6 +733,52 @@ namespace Discord
|
||||
/// </returns>
|
||||
Task<IReadOnlyCollection<IThreadChannel>> GetThreadChannelsAsync(CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null);
|
||||
|
||||
/// <summary>
|
||||
/// Gets a forum channel in this guild.
|
||||
/// </summary>
|
||||
/// <param name="id">The snowflake identifier for the stage channel.</param>
|
||||
/// <param name="mode">The <see cref="CacheMode"/> that determines whether the object should be fetched from cache.</param>
|
||||
/// <param name="options">The options to be used when sending the request.</param>
|
||||
/// <returns>
|
||||
/// A task that represents the asynchronous get operation. The task result contains the stage channel associated
|
||||
/// with the specified <paramref name="id"/>; <see langword="null" /> if none is found.
|
||||
/// </returns>
|
||||
Task<IForumChannel> GetForumChannelAsync(ulong id, CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null);
|
||||
|
||||
/// <summary>
|
||||
/// Gets a collection of all forum channels in this guild.
|
||||
/// </summary>
|
||||
/// <param name="mode">The <see cref="CacheMode"/> that determines whether the object should be fetched from cache.</param>
|
||||
/// <param name="options">The options to be used when sending the request.</param>
|
||||
/// <returns>
|
||||
/// A task that represents the asynchronous get operation. The task result contains a read-only collection of
|
||||
/// forum channels found within this guild.
|
||||
/// </returns>
|
||||
Task<IReadOnlyCollection<IForumChannel>> GetForumChannelsAsync(CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null);
|
||||
|
||||
/// <summary>
|
||||
/// Gets a forum channel in this guild.
|
||||
/// </summary>
|
||||
/// <param name="id">The snowflake identifier for the stage channel.</param>
|
||||
/// <param name="mode">The <see cref="CacheMode"/> that determines whether the object should be fetched from cache.</param>
|
||||
/// <param name="options">The options to be used when sending the request.</param>
|
||||
/// <returns>
|
||||
/// A task that represents the asynchronous get operation. The task result contains the stage channel associated
|
||||
/// with the specified <paramref name="id"/>; <see langword="null" /> if none is found.
|
||||
/// </returns>
|
||||
Task<IMediaChannel> GetMediaChannelAsync(ulong id, CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null);
|
||||
|
||||
/// <summary>
|
||||
/// Gets a collection of all forum channels in this guild.
|
||||
/// </summary>
|
||||
/// <param name="mode">The <see cref="CacheMode"/> that determines whether the object should be fetched from cache.</param>
|
||||
/// <param name="options">The options to be used when sending the request.</param>
|
||||
/// <returns>
|
||||
/// A task that represents the asynchronous get operation. The task result contains a read-only collection of
|
||||
/// media channels found within this guild.
|
||||
/// </returns>
|
||||
Task<IReadOnlyCollection<IMediaChannel>> GetMediaChannelsAsync(CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null);
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new text channel in this guild.
|
||||
/// </summary>
|
||||
@@ -795,6 +841,18 @@ namespace Discord
|
||||
/// </returns>
|
||||
Task<IForumChannel> CreateForumChannelAsync(string name, Action<ForumChannelProperties> func = null, RequestOptions options = null);
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new media channel in this guild.
|
||||
/// </summary>
|
||||
/// <param name="name">The new name for the media channel.</param>
|
||||
/// <param name="func">The delegate containing the properties to be applied to the channel upon its creation.</param>
|
||||
/// <param name="options">The options to be used when sending the request.</param>
|
||||
/// <returns>
|
||||
/// A task that represents the asynchronous creation operation. The task result contains the newly created
|
||||
/// forum channel.
|
||||
/// </returns>
|
||||
Task<IMediaChannel> CreateMediaChannelAsync(string name, Action<ForumChannelProperties> func = null, RequestOptions options = null);
|
||||
|
||||
/// <summary>
|
||||
/// Gets a collection of all the voice regions this guild can access.
|
||||
/// </summary>
|
||||
|
||||
@@ -1,9 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Discord
|
||||
{
|
||||
@@ -26,6 +22,11 @@ namespace Discord
|
||||
/// </summary>
|
||||
public bool IsSpoiler { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets if this file should be a thumbnail for a media channel post.
|
||||
/// </summary>
|
||||
public bool IsThumbnail { get; set; }
|
||||
|
||||
#pragma warning disable IDISP008
|
||||
/// <summary>
|
||||
/// Gets the stream containing the file content.
|
||||
@@ -42,12 +43,14 @@ namespace Discord
|
||||
/// <param name="fileName">The name of the attachment.</param>
|
||||
/// <param name="description">The description of the attachment.</param>
|
||||
/// <param name="isSpoiler">Whether or not the attachment is a spoiler.</param>
|
||||
public FileAttachment(Stream stream, string fileName, string description = null, bool isSpoiler = false)
|
||||
/// <param name="isThumbnail">Whether or not this attachment should be a thumbnail for a media channel post.</param>
|
||||
public FileAttachment(Stream stream, string fileName, string description = null, bool isSpoiler = false, bool isThumbnail = false)
|
||||
{
|
||||
_isDisposed = false;
|
||||
FileName = fileName;
|
||||
Description = description;
|
||||
Stream = stream;
|
||||
IsThumbnail = isThumbnail;
|
||||
try
|
||||
{
|
||||
Stream.Position = 0;
|
||||
@@ -67,6 +70,7 @@ namespace Discord
|
||||
/// <param name="fileName">The name of the attachment.</param>
|
||||
/// <param name="description">The description of the attachment.</param>
|
||||
/// <param name="isSpoiler">Whether or not the attachment is a spoiler.</param>
|
||||
/// <param name="isThumbnail">Whether or not this attachment should be a thumbnail for a media channel post.</param>
|
||||
/// <exception cref="System.ArgumentException">
|
||||
/// <paramref name="path" /> is a zero-length string, contains only white space, or contains one or more invalid
|
||||
/// characters as defined by <see cref="Path.GetInvalidPathChars"/>.
|
||||
@@ -87,13 +91,14 @@ namespace Discord
|
||||
/// <exception cref="FileNotFoundException">The file specified in <paramref name="path" /> was not found.
|
||||
/// </exception>
|
||||
/// <exception cref="IOException">An I/O error occurred while opening the file. </exception>
|
||||
public FileAttachment(string path, string fileName = null, string description = null, bool isSpoiler = false)
|
||||
public FileAttachment(string path, string fileName = null, string description = null, bool isSpoiler = false, bool isThumbnail = false)
|
||||
{
|
||||
_isDisposed = false;
|
||||
Stream = File.OpenRead(path);
|
||||
FileName = fileName ?? Path.GetFileName(path);
|
||||
Description = description;
|
||||
IsSpoiler = isSpoiler;
|
||||
IsThumbnail = isThumbnail;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
|
||||
@@ -50,6 +50,11 @@ namespace Discord
|
||||
/// </summary>
|
||||
public static readonly ChannelPermissions Forum = new(0b01_001110_010010_110011_111101_111111_111101_010001);
|
||||
|
||||
/// <summary>
|
||||
/// Gets a <see cref="ChannelPermissions"/> that grants all permissions for media channels.
|
||||
/// </summary>
|
||||
public static readonly ChannelPermissions Media = new(0b01_001110_010010_110011_111101_111111_111101_010001);
|
||||
|
||||
/// <summary>
|
||||
/// Gets a <see cref="ChannelPermissions"/> that grants all permissions for a given channel type.
|
||||
/// </summary>
|
||||
@@ -64,6 +69,7 @@ namespace Discord
|
||||
ICategoryChannel _ => Category,
|
||||
IDMChannel _ => DM,
|
||||
IGroupChannel _ => Group,
|
||||
IMediaChannel _ => Media,
|
||||
IForumChannel => Forum,
|
||||
_ => throw new ArgumentException(message: "Unknown channel type.", paramName: nameof(channel)),
|
||||
};
|
||||
|
||||
@@ -47,6 +47,9 @@ namespace Discord
|
||||
case ITextChannel:
|
||||
return ChannelType.Text;
|
||||
|
||||
case IMediaChannel:
|
||||
return ChannelType.Media;
|
||||
|
||||
case IForumChannel:
|
||||
return ChannelType.Forum;
|
||||
}
|
||||
|
||||
@@ -9,6 +9,6 @@ public static class ChannelTypeUtils
|
||||
{
|
||||
ChannelType.Forum, ChannelType.Category, ChannelType.DM, ChannelType.Group, ChannelType.GuildDirectory,
|
||||
ChannelType.News, ChannelType.NewsThread, ChannelType.PrivateThread, ChannelType.PublicThread,
|
||||
ChannelType.Stage, ChannelType.Store, ChannelType.Text, ChannelType.Voice
|
||||
ChannelType.Stage, ChannelType.Store, ChannelType.Text, ChannelType.Voice, ChannelType.Media
|
||||
};
|
||||
}
|
||||
|
||||
@@ -69,6 +69,12 @@ namespace Discord.Interactions
|
||||
_ when typeof(ITextChannel).IsAssignableFrom(type)
|
||||
=> new List<ChannelType> { ChannelType.Text },
|
||||
|
||||
_ when typeof(IMediaChannel).IsAssignableFrom(type)
|
||||
=> new List<ChannelType> { ChannelType.Media },
|
||||
|
||||
_ when typeof(IForumChannel).IsAssignableFrom(type)
|
||||
=> new List<ChannelType> { ChannelType.Forum },
|
||||
|
||||
_ => null
|
||||
};
|
||||
}
|
||||
|
||||
@@ -78,7 +78,8 @@ namespace Discord.API.Rest
|
||||
{
|
||||
id = (ulong)n,
|
||||
filename = filename,
|
||||
description = attachment.Description ?? Optional<string>.Unspecified
|
||||
description = attachment.Description ?? Optional<string>.Unspecified,
|
||||
is_thumbnail = attachment.IsThumbnail,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -57,8 +57,7 @@ internal static class ForumHelper
|
||||
emoji.Name : Optional<string>.Unspecified
|
||||
}
|
||||
: Optional<ModifyForumReactionEmojiParams>.Unspecified,
|
||||
DefaultSortOrder = args.DefaultSortOrder,
|
||||
DefaultLayout = args.DefaultLayout,
|
||||
DefaultSortOrder = args.DefaultSortOrder
|
||||
};
|
||||
return await client.ApiClient.ModifyGuildChannelAsync(channel.Id, apiArgs, options).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
@@ -50,7 +50,8 @@ namespace Discord.Rest
|
||||
ChannelType.NewsThread or
|
||||
ChannelType.PrivateThread or
|
||||
ChannelType.PublicThread or
|
||||
ChannelType.Forum
|
||||
ChannelType.Forum or
|
||||
ChannelType.Media
|
||||
=> RestGuildChannel.Create(discord, guild, model),
|
||||
ChannelType.DM or ChannelType.Group => CreatePrivate(discord, model) as RestChannel,
|
||||
ChannelType.Category => RestCategoryChannel.Create(discord, guild, model),
|
||||
|
||||
@@ -42,6 +42,7 @@ namespace Discord.Rest
|
||||
ChannelType.Text => RestTextChannel.Create(discord, guild, model),
|
||||
ChannelType.Voice => RestVoiceChannel.Create(discord, guild, model),
|
||||
ChannelType.Stage => RestStageChannel.Create(discord, guild, model),
|
||||
ChannelType.Media => RestMediaChannel.Create(discord, guild, model),
|
||||
ChannelType.Forum => RestForumChannel.Create(discord, guild, model),
|
||||
ChannelType.Category => RestCategoryChannel.Create(discord, guild, model),
|
||||
ChannelType.PublicThread or ChannelType.PrivateThread or ChannelType.NewsThread => RestThreadChannel.Create(discord, guild, model),
|
||||
|
||||
24
src/Discord.Net.Rest/Entities/Channels/RestMediaChannel.cs
Normal file
24
src/Discord.Net.Rest/Entities/Channels/RestMediaChannel.cs
Normal file
@@ -0,0 +1,24 @@
|
||||
using Model = Discord.API.Channel;
|
||||
|
||||
namespace Discord.Rest;
|
||||
|
||||
public class RestMediaChannel : RestForumChannel, IMediaChannel
|
||||
{
|
||||
internal RestMediaChannel(BaseDiscordClient client, IGuild guild, ulong id)
|
||||
: base(client, guild, id)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
internal new static RestMediaChannel Create(BaseDiscordClient discord, IGuild guild, Model model)
|
||||
{
|
||||
var entity = new RestMediaChannel(discord, guild, model.Id);
|
||||
entity.Update(model);
|
||||
return entity;
|
||||
}
|
||||
|
||||
internal override void Update(Model model)
|
||||
{
|
||||
base.Update(model);
|
||||
}
|
||||
}
|
||||
@@ -428,6 +428,66 @@ namespace Discord.Rest
|
||||
var model = await client.ApiClient.CreateGuildChannelAsync(guild.Id, args, options).ConfigureAwait(false);
|
||||
return RestForumChannel.Create(client, guild, model);
|
||||
}
|
||||
|
||||
/// <exception cref="ArgumentNullException"><paramref name="name"/> is <see langword="null" />.</exception>
|
||||
public static async Task<RestMediaChannel> CreateMediaChannelAsync(IGuild guild, BaseDiscordClient client,
|
||||
string name, RequestOptions options, Action<ForumChannelProperties> func = null)
|
||||
{
|
||||
if (name == null)
|
||||
throw new ArgumentNullException(paramName: nameof(name));
|
||||
|
||||
var props = new ForumChannelProperties();
|
||||
func?.Invoke(props);
|
||||
|
||||
Preconditions.AtMost(props.Tags.IsSpecified ? props.Tags.Value.Count() : 0, 20, nameof(props.Tags), "Media channel can have max 20 tags.");
|
||||
|
||||
var args = new CreateGuildChannelParams(name, ChannelType.Media)
|
||||
{
|
||||
Position = props.Position,
|
||||
Overwrites = props.PermissionOverwrites.IsSpecified
|
||||
? props.PermissionOverwrites.Value.Select(overwrite => new API.Overwrite
|
||||
{
|
||||
TargetId = overwrite.TargetId,
|
||||
TargetType = overwrite.TargetType,
|
||||
Allow = overwrite.Permissions.AllowValue.ToString(),
|
||||
Deny = overwrite.Permissions.DenyValue.ToString()
|
||||
}).ToArray()
|
||||
: Optional.Create<API.Overwrite[]>(),
|
||||
SlowModeInterval = props.ThreadCreationInterval,
|
||||
AvailableTags = props.Tags.GetValueOrDefault(Array.Empty<ForumTagProperties>()).Select(
|
||||
x => new ModifyForumTagParams
|
||||
{
|
||||
Id = x.Id,
|
||||
Name = x.Name,
|
||||
EmojiId = x.Emoji is Emote emote
|
||||
? emote.Id
|
||||
: Optional<ulong?>.Unspecified,
|
||||
EmojiName = x.Emoji is Emoji emoji
|
||||
? emoji.Name
|
||||
: Optional<string>.Unspecified,
|
||||
Moderated = x.IsModerated
|
||||
}).ToArray(),
|
||||
DefaultReactionEmoji = props.DefaultReactionEmoji.IsSpecified
|
||||
? new API.ModifyForumReactionEmojiParams
|
||||
{
|
||||
EmojiId = props.DefaultReactionEmoji.Value is Emote emote ?
|
||||
emote.Id : Optional<ulong?>.Unspecified,
|
||||
EmojiName = props.DefaultReactionEmoji.Value is Emoji emoji ?
|
||||
emoji.Name : Optional<string>.Unspecified
|
||||
}
|
||||
: Optional<ModifyForumReactionEmojiParams>.Unspecified,
|
||||
ThreadRateLimitPerUser = props.DefaultSlowModeInterval,
|
||||
CategoryId = props.CategoryId,
|
||||
IsNsfw = props.IsNsfw,
|
||||
Topic = props.Topic,
|
||||
DefaultAutoArchiveDuration = props.AutoArchiveDuration,
|
||||
DefaultSortOrder = props.DefaultSortOrder.GetValueOrDefault(ForumSortOrder.LatestActivity),
|
||||
};
|
||||
|
||||
var model = await client.ApiClient.CreateGuildChannelAsync(guild.Id, args, options).ConfigureAwait(false);
|
||||
return RestMediaChannel.Create(client, guild, model);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Voice Regions
|
||||
|
||||
@@ -462,6 +462,64 @@ namespace Discord.Rest
|
||||
return channels.OfType<RestTextChannel>().ToImmutableArray();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a forum channel in this guild.
|
||||
/// </summary>
|
||||
/// <param name="id">The snowflake identifier for the forum channel.</param>
|
||||
/// <param name="options">The options to be used when sending the request.</param>
|
||||
/// <returns>
|
||||
/// A task that represents the asynchronous get operation. The task result contains the text channel
|
||||
/// associated with the specified <paramref name="id"/>; <see langword="null"/> if none is found.
|
||||
/// </returns>
|
||||
public async Task<RestForumChannel> GetForumChannelAsync(ulong id, RequestOptions options = null)
|
||||
{
|
||||
var channel = await GuildHelper.GetChannelAsync(this, Discord, id, options).ConfigureAwait(false);
|
||||
return channel as RestForumChannel;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a collection of all forum channels in this guild.
|
||||
/// </summary>
|
||||
/// <param name="options">The options to be used when sending the request.</param>
|
||||
/// <returns>
|
||||
/// A task that represents the asynchronous get operation. The task result contains a read-only collection of
|
||||
/// forum channels found within this guild.
|
||||
/// </returns>
|
||||
public async Task<IReadOnlyCollection<RestForumChannel>> GetForumChannelsAsync(RequestOptions options = null)
|
||||
{
|
||||
var channels = await GuildHelper.GetChannelsAsync(this, Discord, options).ConfigureAwait(false);
|
||||
return channels.OfType<RestForumChannel>().ToImmutableArray();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a media channel in this guild.
|
||||
/// </summary>
|
||||
/// <param name="id">The snowflake identifier for the text channel.</param>
|
||||
/// <param name="options">The options to be used when sending the request.</param>
|
||||
/// <returns>
|
||||
/// A task that represents the asynchronous get operation. The task result contains the media channel
|
||||
/// associated with the specified <paramref name="id"/>; <see langword="null"/> if none is found.
|
||||
/// </returns>
|
||||
public async Task<RestMediaChannel> GetMediaChannelAsync(ulong id, RequestOptions options = null)
|
||||
{
|
||||
var channel = await GuildHelper.GetChannelAsync(this, Discord, id, options).ConfigureAwait(false);
|
||||
return channel as RestMediaChannel;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a collection of all media channels in this guild.
|
||||
/// </summary>
|
||||
/// <param name="options">The options to be used when sending the request.</param>
|
||||
/// <returns>
|
||||
/// A task that represents the asynchronous get operation. The task result contains a read-only collection of
|
||||
/// media channels found within this guild.
|
||||
/// </returns>
|
||||
public async Task<IReadOnlyCollection<RestMediaChannel>> GetMediaChannelsAsync(RequestOptions options = null)
|
||||
{
|
||||
var channels = await GuildHelper.GetChannelsAsync(this, Discord, options).ConfigureAwait(false);
|
||||
return channels.OfType<RestMediaChannel>().ToImmutableArray();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a thread channel in this guild.
|
||||
/// </summary>
|
||||
@@ -735,18 +793,31 @@ namespace Discord.Rest
|
||||
=> GuildHelper.CreateCategoryChannelAsync(this, Discord, name, options, func);
|
||||
|
||||
/// <summary>
|
||||
/// Creates a category channel with the provided name.
|
||||
/// Creates a new forum channel with the provided name.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of the new channel.</param>
|
||||
/// <param name="func">The delegate containing the properties to be applied to the channel upon its creation.</param>
|
||||
/// <param name="options">The options to be used when sending the request.</param>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="name" /> is <see langword="null"/>.</exception>
|
||||
/// <returns>
|
||||
/// The created category channel.
|
||||
/// The created forum channel.
|
||||
/// </returns>
|
||||
public Task<RestForumChannel> CreateForumChannelAsync(string name, Action<ForumChannelProperties> func = null, RequestOptions options = null)
|
||||
=> GuildHelper.CreateForumChannelAsync(this, Discord, name, options, func);
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new media channel in this guild.
|
||||
/// </summary>
|
||||
/// <param name="name">The new name for the media channel.</param>
|
||||
/// <param name="func">The delegate containing the properties to be applied to the channel upon its creation.</param>
|
||||
/// <param name="options">The options to be used when sending the request.</param>
|
||||
/// <returns>
|
||||
/// A task that represents the asynchronous creation operation. The task result contains the newly created
|
||||
/// media channel.
|
||||
/// </returns>
|
||||
public Task<RestMediaChannel> CreateMediaChannelAsync(string name, Action<ForumChannelProperties> func = null, RequestOptions options = null)
|
||||
=> GuildHelper.CreateMediaChannelAsync(this, Discord, name, options, func);
|
||||
|
||||
/// <summary>
|
||||
/// Gets a collection of all the voice regions this guild can access.
|
||||
/// </summary>
|
||||
@@ -1342,6 +1413,43 @@ namespace Discord.Rest
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
async Task<IForumChannel> IGuild.GetForumChannelAsync(ulong id, CacheMode mode, RequestOptions options)
|
||||
{
|
||||
if (mode == CacheMode.AllowDownload)
|
||||
return await GetForumChannelAsync(id, options).ConfigureAwait(false);
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
async Task<IReadOnlyCollection<IForumChannel>> IGuild.GetForumChannelsAsync(CacheMode mode, RequestOptions options)
|
||||
{
|
||||
if (mode == CacheMode.AllowDownload)
|
||||
return await GetForumChannelsAsync(options).ConfigureAwait(false);
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
async Task<IMediaChannel> IGuild.GetMediaChannelAsync(ulong id, CacheMode mode, RequestOptions options)
|
||||
{
|
||||
if (mode == CacheMode.AllowDownload)
|
||||
return await GetMediaChannelAsync(id, options).ConfigureAwait(false);
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
async Task<IReadOnlyCollection<IMediaChannel>> IGuild.GetMediaChannelsAsync(CacheMode mode, RequestOptions options)
|
||||
{
|
||||
if (mode == CacheMode.AllowDownload)
|
||||
return await GetMediaChannelsAsync(options).ConfigureAwait(false);
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
async Task<IThreadChannel> IGuild.GetThreadChannelAsync(ulong id, CacheMode mode, RequestOptions options)
|
||||
{
|
||||
@@ -1462,6 +1570,10 @@ namespace Discord.Rest
|
||||
async Task<IForumChannel> IGuild.CreateForumChannelAsync(string name, Action<ForumChannelProperties> func, RequestOptions options)
|
||||
=> await CreateForumChannelAsync(name, func, options).ConfigureAwait(false);
|
||||
|
||||
/// <inheritdoc />
|
||||
async Task<IMediaChannel> IGuild.CreateMediaChannelAsync(string name, Action<ForumChannelProperties> func, RequestOptions options)
|
||||
=> await CreateMediaChannelAsync(name, func, options).ConfigureAwait(false);
|
||||
|
||||
/// <inheritdoc />
|
||||
async Task<IReadOnlyCollection<IVoiceRegion>> IGuild.GetVoiceRegionsAsync(RequestOptions options)
|
||||
=> await GetVoiceRegionsAsync(options).ConfigureAwait(false);
|
||||
|
||||
@@ -201,7 +201,9 @@ namespace Discord.Rest
|
||||
ChannelType.Stage or
|
||||
ChannelType.NewsThread or
|
||||
ChannelType.PrivateThread or
|
||||
ChannelType.PublicThread
|
||||
ChannelType.PublicThread or
|
||||
ChannelType.Media or
|
||||
ChannelType.Forum
|
||||
=> RestGuildChannel.Create(discord, Guild, model.Channel.Value) as IRestMessageChannel,
|
||||
ChannelType.DM => RestDMChannel.Create(discord, model.Channel.Value),
|
||||
ChannelType.Group => RestGroupChannel.Create(discord, model.Channel.Value),
|
||||
|
||||
@@ -63,6 +63,7 @@ namespace Discord.WebSocket
|
||||
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),
|
||||
ChannelType.Media => SocketMediaChannel.Create(guild, state, model),
|
||||
_ => new SocketGuildChannel(guild.Discord, model.Id, guild),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
using Model = Discord.API.Channel;
|
||||
|
||||
namespace Discord.WebSocket;
|
||||
|
||||
public class SocketMediaChannel : SocketForumChannel, IMediaChannel
|
||||
{
|
||||
internal SocketMediaChannel(DiscordSocketClient discord, ulong id, SocketGuild guild)
|
||||
: base(discord, id, guild)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
internal new static SocketMediaChannel Create(SocketGuild guild, ClientState state, Model model)
|
||||
{
|
||||
var entity = new SocketMediaChannel(guild?.Discord, model.Id, guild);
|
||||
entity.Update(state, model);
|
||||
return entity;
|
||||
}
|
||||
|
||||
internal override void Update(ClientState state, Model model)
|
||||
{
|
||||
base.Update(state, model);
|
||||
}
|
||||
}
|
||||
@@ -339,6 +339,15 @@ namespace Discord.WebSocket
|
||||
public IReadOnlyCollection<SocketForumChannel> ForumChannels
|
||||
=> Channels.OfType<SocketForumChannel>().ToImmutableArray();
|
||||
|
||||
/// <summary>
|
||||
/// Gets a collection of all media channels in this guild.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A read-only collection of forum channels found within this guild.
|
||||
/// </returns>
|
||||
public IReadOnlyCollection<SocketMediaChannel> MediaChannels
|
||||
=> Channels.OfType<SocketMediaChannel>().ToImmutableArray();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current logged-in user.
|
||||
/// </summary>
|
||||
@@ -790,6 +799,16 @@ namespace Discord.WebSocket
|
||||
public SocketCategoryChannel GetCategoryChannel(ulong id)
|
||||
=> GetChannel(id) as SocketCategoryChannel;
|
||||
|
||||
/// <summary>
|
||||
/// Gets a media channel in this guild.
|
||||
/// </summary>
|
||||
/// <param name="id">The snowflake identifier for the stage channel.</param>
|
||||
/// <returns>
|
||||
/// A stage channel associated with the specified <paramref name="id" />; <see langword="null"/> if none is found.
|
||||
/// </returns>
|
||||
public SocketMediaChannel GetMediaChannel(ulong id)
|
||||
=> GetChannel(id) as SocketMediaChannel;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new text channel in this guild.
|
||||
/// </summary>
|
||||
@@ -857,7 +876,7 @@ namespace Discord.WebSocket
|
||||
=> GuildHelper.CreateCategoryChannelAsync(this, Discord, name, options, func);
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new channel forum in this guild.
|
||||
/// Creates a new forum channel in this guild.
|
||||
/// </summary>
|
||||
/// <param name="name">The new name for the forum.</param>
|
||||
/// <param name="func">The delegate containing the properties to be applied to the channel upon its creation.</param>
|
||||
@@ -870,6 +889,20 @@ namespace Discord.WebSocket
|
||||
public Task<RestForumChannel> CreateForumChannelAsync(string name, Action<ForumChannelProperties> func = null, RequestOptions options = null)
|
||||
=> GuildHelper.CreateForumChannelAsync(this, Discord, name, options, func);
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new media channel in this guild.
|
||||
/// </summary>
|
||||
/// <param name="name">The new name for the media channel.</param>
|
||||
/// <param name="func">The delegate containing the properties to be applied to the channel upon its creation.</param>
|
||||
/// <param name="options">The options to be used when sending the request.</param>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="name"/> is <see langword="null"/>.</exception>
|
||||
/// <returns>
|
||||
/// A task that represents the asynchronous creation operation. The task result contains the newly created
|
||||
/// media channel.
|
||||
/// </returns>
|
||||
public Task<RestMediaChannel> CreateMediaChannelAsync(string name, Action<ForumChannelProperties> func = null, RequestOptions options = null)
|
||||
=> GuildHelper.CreateMediaChannelAsync(this, Discord, name, options, func);
|
||||
|
||||
internal SocketGuildChannel AddChannel(ClientState state, ChannelModel model)
|
||||
{
|
||||
var channel = SocketGuildChannel.Create(this, state, model);
|
||||
@@ -2075,6 +2108,21 @@ namespace Discord.WebSocket
|
||||
/// <inheritdoc />
|
||||
Task<ITextChannel> IGuild.GetPublicUpdatesChannelAsync(CacheMode mode, RequestOptions options)
|
||||
=> Task.FromResult<ITextChannel>(PublicUpdatesChannel);
|
||||
|
||||
/// <inheritdoc />
|
||||
Task<IForumChannel> IGuild.GetForumChannelAsync(ulong id, CacheMode mode, RequestOptions options)
|
||||
=> Task.FromResult<IForumChannel>(GetForumChannel(id));
|
||||
/// <inheritdoc />
|
||||
Task<IReadOnlyCollection<IForumChannel>> IGuild.GetForumChannelsAsync(CacheMode mode, RequestOptions options)
|
||||
=> Task.FromResult<IReadOnlyCollection<IForumChannel>>(ForumChannels);
|
||||
|
||||
/// <inheritdoc />
|
||||
Task<IMediaChannel> IGuild.GetMediaChannelAsync(ulong id, CacheMode mode, RequestOptions options)
|
||||
=> Task.FromResult<IMediaChannel>(GetMediaChannel(id));
|
||||
/// <inheritdoc />
|
||||
Task<IReadOnlyCollection<IMediaChannel>> IGuild.GetMediaChannelsAsync(CacheMode mode, RequestOptions options)
|
||||
=> Task.FromResult<IReadOnlyCollection<IMediaChannel>>(MediaChannels);
|
||||
|
||||
/// <inheritdoc />
|
||||
async Task<ITextChannel> IGuild.CreateTextChannelAsync(string name, Action<TextChannelProperties> func, RequestOptions options)
|
||||
=> await CreateTextChannelAsync(name, func, options).ConfigureAwait(false);
|
||||
@@ -2091,6 +2139,10 @@ namespace Discord.WebSocket
|
||||
async Task<IForumChannel> IGuild.CreateForumChannelAsync(string name, Action<ForumChannelProperties> func, RequestOptions options)
|
||||
=> await CreateForumChannelAsync(name, func, options).ConfigureAwait(false);
|
||||
|
||||
/// <inheritdoc />
|
||||
async Task<IMediaChannel> IGuild.CreateMediaChannelAsync(string name, Action<ForumChannelProperties> func, RequestOptions options)
|
||||
=> await CreateMediaChannelAsync(name, func, options).ConfigureAwait(false);
|
||||
|
||||
/// <inheritdoc />
|
||||
async Task<IReadOnlyCollection<IVoiceRegion>> IGuild.GetVoiceRegionsAsync(RequestOptions options)
|
||||
=> await GetVoiceRegionsAsync(options).ConfigureAwait(false);
|
||||
|
||||
@@ -39,6 +39,8 @@ namespace Discord.WebSocket
|
||||
IGroupChannel groupChannel => ChannelType.Group,
|
||||
INewsChannel newsChannel => ChannelType.News,
|
||||
ITextChannel textChannel => ChannelType.Text,
|
||||
IMediaChannel mediaChannel => ChannelType.Media,
|
||||
IForumChannel forumChannel => ChannelType.Forum,
|
||||
_ => throw new InvalidOperationException("Invalid channel type."),
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user