From 8e838433ef71a3bce96b518b123df2bdb05930b0 Mon Sep 17 00:00:00 2001 From: Phil B Date: Wed, 2 Aug 2023 21:06:51 +0200 Subject: [PATCH] feat: introduce the media channel type --- include/dpp/channel.h | 46 +++++++++++++++++++++++++------------------ include/dpp/cluster.h | 2 +- src/dpp/channel.cpp | 31 +++++++++++++++++++++++++---- 3 files changed, 55 insertions(+), 24 deletions(-) diff --git a/include/dpp/channel.h b/include/dpp/channel.h index df47429828..0afd069fd1 100644 --- a/include/dpp/channel.h +++ b/include/dpp/channel.h @@ -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 @@ -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, }; /** @@ -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) */ @@ -264,7 +258,7 @@ class DPP_EXPORT channel : public managed, public json_interface { /** 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; /** @@ -278,11 +272,11 @@ class DPP_EXPORT channel : public managed, public json_interface { /** Permission overwrites to apply to base permissions */ std::vector 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 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 default_reaction; @@ -333,7 +327,7 @@ class DPP_EXPORT channel : public managed, public json_interface { */ 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) */ @@ -671,6 +665,13 @@ class DPP_EXPORT channel : public managed, public json_interface { */ 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 * @@ -721,6 +722,13 @@ class DPP_EXPORT channel : public managed, public json_interface { */ 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. @@ -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 applied_tags; diff --git a/include/dpp/cluster.h b/include/dpp/cluster.h index 5389f9434d..0ae3660798 100644 --- a/include/dpp/cluster.h +++ b/include/dpp/cluster.h @@ -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 diff --git a/src/dpp/channel.cpp b/src/dpp/channel.cpp index e22db2d7e5..6af44550ad 100644 --- a/src/dpp/channel.cpp +++ b/src/dpp/channel.cpp @@ -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) {} @@ -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; } @@ -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; } @@ -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) { @@ -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(); }