Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: introduce the media channel type #746

Merged
merged 10 commits into from
Aug 7, 2023
46 changes: 27 additions & 19 deletions include/dpp/channel.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,8 @@ enum channel_type : uint8_t {
CHANNEL_PRIVATE_THREAD = 12, //!< a temporary sub-channel within a GUILD_TEXT channel that is only viewable by those invited and those with the MANAGE_THREADS permission
CHANNEL_STAGE = 13, //!< a "stage" channel, like a voice channel with one authorised speaker
CHANNEL_DIRECTORY = 14, //!< the channel in a [hub](https://support.discord.com/hc/en-us/articles/4406046651927-Discord-Student-Hubs-FAQ) containing the listed servers
CHANNEL_FORUM = 15 //!< forum channel that can only contain threads
CHANNEL_FORUM = 15, //!< forum channel that can only contain threads
CHANNEL_MEDIA = 16, //!< Media channel that can only contain threads, similar to forum channels
};

/** @brief Our flags as stored in the object
Expand All @@ -65,27 +66,20 @@ enum channel_type : uint8_t {
* shuffle these values upwards by one bit.
*/
enum channel_flags : uint16_t {
/* Note that bits 1 to 4 are used for the channel type mask */
/// NSFW Gated Channel
c_nsfw = 0b0000000000010000,
/// Video quality forced to 720p
c_video_quality_720p = 0b0000000000100000,
/// Lock permissions (only used when updating channel positions)
c_lock_permissions = 0b0000000001000000,
/// Thread is pinned to the top of its parent forum channel
/// Thread is pinned to the top of its parent forum or media channel
c_pinned_thread = 0b0000000010000000,
/// Whether a tag is required to be specified when creating a thread in a forum channel. Tags are specified in the thread::applied_tags field.
/// Whether a tag is required to be specified when creating a thread in a forum or a media channel. Tags are specified in the thread::applied_tags field.
c_require_tag = 0b0000000100000000,
/* Note that the 9th and 10th bit are used for the forum layout type */
};

/**
* @brief The flags in discord channel's raw "flags" field. We use these for serialisation only, right now. Might be better to create a new field than to make the existing channel::flags from uint8_t to uint16_t, if discord adds more flags in future.
*/
enum discord_channel_flags : uint8_t {
/// Thread is pinned to the top of its parent forum channel
dc_pinned_thread = 1 << 1,
/// Whether a tag is required to be specified when creating a thread in a forum channel. Tags are specified in the thread::applied_tags field.
dc_require_tag = 1 << 4,
/// When set hides the embedded media download options. Available only for media channels
c_hide_media_download_options = 0b0001000000000000,
};

/**
Expand Down Expand Up @@ -200,7 +194,7 @@ struct DPP_EXPORT thread_member
};

/**
* @brief Represents a tag that is able to be applied to a thread in a forum channel
* @brief Represents a tag that is able to be applied to a thread in a forum or media channel
*/
struct DPP_EXPORT forum_tag : public managed {
/** The name of the tag (0-20 characters) */
Expand Down Expand Up @@ -264,7 +258,7 @@ class DPP_EXPORT channel : public managed, public json_interface<channel> {
/** Channel name (1-100 characters) */
std::string name;

/** Channel topic (0-4096 characters for forum channels, 0-1024 characters for all others) */
/** Channel topic (0-4096 characters for forum and media channels, 0-1024 characters for all others) */
std::string topic;

/**
Expand All @@ -278,11 +272,11 @@ class DPP_EXPORT channel : public managed, public json_interface<channel> {
/** Permission overwrites to apply to base permissions */
std::vector<permission_overwrite> permission_overwrites;

/** A set of tags that can be used in a forum channel */
/** A set of tags that can be used in a forum or media channel */
std::vector<forum_tag> available_tags;

/**
* @brief The emoji to show as the default reaction button on a forum post.
* @brief The emoji to show as the default reaction button on a thread in a forum or media channel.
* Contains either nothing, the id of a guild's custom emoji or the unicode character of the emoji
*/
std::variant<std::monostate, snowflake, std::string> default_reaction;
Expand Down Expand Up @@ -333,7 +327,7 @@ class DPP_EXPORT channel : public managed, public json_interface<channel> {
*/
auto_archive_duration_t default_auto_archive_duration;

/** the default sort order type used to order posts in forum channels */
/** the default sort order type used to order posts in forum and media channels */
default_forum_sort_order_t default_sort_order;

/** Flags bitmap (dpp::channel_flags) */
Expand Down Expand Up @@ -671,6 +665,13 @@ class DPP_EXPORT channel : public managed, public json_interface<channel> {
*/
bool is_forum() const;

/**
* @brief Returns true if the channel is a media channel
*
* @return true if media channel
*/
bool is_media_channel() const;

/**
* @brief Returns true if the channel is an announcement channel
*
Expand Down Expand Up @@ -721,6 +722,13 @@ class DPP_EXPORT channel : public managed, public json_interface<channel> {
*/
bool is_tag_required() const;

/**
* @brief Returns true if embedded media download options are hidden in a media channel
*
* @return true, if embedded media download options are hidden in a media channel
*/
bool is_download_options_hidden() const;

};

/** @brief A definition of a discord thread.
Expand All @@ -741,7 +749,7 @@ class DPP_EXPORT thread : public channel {
message msg;

/**
* A list of dpp::forum_tag IDs that have been applied to a thread in a forum channel
* A list of dpp::forum_tag IDs that have been applied to a thread in a forum or media channel
*/
std::vector<snowflake> applied_tags;

Expand Down
2 changes: 1 addition & 1 deletion include/dpp/cluster.h
Original file line number Diff line number Diff line change
Expand Up @@ -3078,7 +3078,7 @@ class DPP_EXPORT cluster {
void current_user_leave_guild(snowflake guild_id, command_completion_event_t callback = utility::log_error());

/**
* @brief Create a thread in forum channel
* @brief Create a thread in a forum or media channel
* @note This method supports audit log reasons set by the cluster::set_audit_reason() method.
*
* @see https://discord.com/developers/docs/resources/channel#start-thread-in-forum-channel
Expand Down
31 changes: 27 additions & 4 deletions src/dpp/channel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,13 @@ namespace dpp {

using json = nlohmann::json;

/* A mapping of discord's flag values to our bitmap (they're different bit positions to fit other stuff in) */
enum discord_channel_flags {
dc_pinned_thread = 1 << 1,
dc_require_tag = 1 << 4,
dc_hide_media_download_options = 1 << 15,
};

permission_overwrite::permission_overwrite() : id(0), allow(0), deny(0), type(0) {}

permission_overwrite::permission_overwrite(snowflake id, uint64_t allow, uint64_t deny, overwrite_type type) : id(id), allow(allow), deny(deny), type(type) {}
Expand Down Expand Up @@ -287,6 +294,10 @@ bool channel::is_forum() const {
return (flags & CHANNEL_TYPE_MASK) == CHANNEL_FORUM;
}

bool channel::is_media_channel() const {
return (flags & CHANNEL_TYPE_MASK) == CHANNEL_MEDIA;
}

bool channel::is_stage_channel() const {
return (flags & CHANNEL_TYPE_MASK) == CHANNEL_STAGE;
}
Expand Down Expand Up @@ -320,6 +331,10 @@ bool channel::is_tag_required() const {
return flags & dpp::c_require_tag;
}

bool channel::is_download_options_hidden() const {
return flags & dpp::c_hide_media_download_options;
}

bool thread::is_news_thread() const {
return (flags & CHANNEL_TYPE_MASK) == CHANNEL_ANNOUNCEMENT_THREAD;
}
Expand Down Expand Up @@ -427,8 +442,9 @@ channel& channel::fill_from_json(json* j) {
this->flags |= ((forum_layout << 9) & DEFAULT_FORUM_LAYOUT_MASK);

uint8_t dflags = int8_not_null(j, "flags");
this->flags |= (dflags & dpp::dc_pinned_thread) ? dpp::c_pinned_thread : 0;
this->flags |= (dflags & dpp::dc_require_tag) ? dpp::c_require_tag : 0;
this->flags |= (dflags & dc_pinned_thread) ? dpp::c_pinned_thread : 0;
this->flags |= (dflags & dc_require_tag) ? dpp::c_require_tag : 0;
this->flags |= (dflags & dc_hide_media_download_options) ? dpp::c_hide_media_download_options : 0;

uint8_t vqm = int8_not_null(j, "video_quality_mode");
if (vqm == 2) {
Expand Down Expand Up @@ -523,9 +539,16 @@ std::string channel::build_json(bool with_id) const {
j["bitrate"] = bitrate * 1000;
}
}
if (is_forum() || is_media_channel()) {
uint32_t _flags = (flags & dpp::c_require_tag) ? dc_require_tag : 0;
if (is_media_channel()) {
_flags |= (flags & dpp::c_hide_media_download_options) ? dc_hide_media_download_options : 0;
}
if (_flags) {
j["flags"] = _flags;
}
}
if (is_forum()) {
j["flags"] = (flags & dpp::c_require_tag) ? dpp::dc_require_tag : 0;

if (get_default_forum_layout()) {
j["default_forum_layout"] = get_default_forum_layout();
}
Expand Down
Loading