diff --git a/include/dpp/message.h b/include/dpp/message.h index 5f11536f98..5fe427c985 100644 --- a/include/dpp/message.h +++ b/include/dpp/message.h @@ -80,6 +80,31 @@ enum component_style : uint8_t { cos_link }; +/** + * Represents the type of a dpp::component_default_value + * + * @note They're different to discord's value types + */ +enum component_default_value_type: uint8_t { + cdt_user = 0, + cdt_role = 1, + cdt_channel = 2, +}; + +/** + * @brief A Default value structure for components + */ +struct DPP_EXPORT component_default_value { + /** + * @brief The type this default value represents + */ + component_default_value_type type; + /** + * @brief Default value. ID of a user, role, or channel + */ + dpp::snowflake id; +}; + /** * @brief An option for a select component */ @@ -282,6 +307,13 @@ class DPP_EXPORT component : public json_interface { */ std::vector channel_types; + /** + * List of default values for auto-populated select menu components. The amount of default values must be in the range defined by dpp::component::min_value and dpp::component::max_values. + * + * @note Only available for auto-populated select menu components, which include dpp::cot_user_selectmenu, dpp::cot_role_selectmenu, dpp::cot_mentionable_selectmenu, and dpp::cot_channel_selectmenu components. + */ + std::vector default_values; + /** Disabled flag (for buttons) */ bool disabled; @@ -490,6 +522,14 @@ class DPP_EXPORT component : public json_interface { */ component& add_component(const component& c); + /** + * @brief Add a default value. + * + * @param id Default value. ID of a user, role, or channel + * @param type The type this default value represents + */ + component& add_default_value(const snowflake id, const component_default_value_type type); + /** * @brief Set the emoji of the current sub-component. * Only valid for buttons. Adding an emoji to a component diff --git a/include/dpp/user.h b/include/dpp/user.h index 0f84ac4c35..badc193d12 100644 --- a/include/dpp/user.h +++ b/include/dpp/user.h @@ -93,6 +93,8 @@ class DPP_EXPORT user : public managed, public json_interface { std::string global_name; /** Avatar hash */ utility::iconhash avatar; + /** Avatar decoration hash */ + utility::iconhash avatar_decoration; /** Flags built from a bitmask of values in dpp::user_flags */ uint32_t flags; /** Discriminator (aka tag), 4 digits usually displayed with leading zeroes. @@ -157,6 +159,15 @@ class DPP_EXPORT user : public managed, public json_interface { */ std::string get_default_avatar_url() const; + /** + * @brief Get the avatar decoration url of the user if they have one, otherwise returns an empty string. + * + * @param size The size of the avatar decoration in pixels. It can be any power of two between 16 and 4096, + * otherwise the default sized avatar decoration is returned. + * @return std::string avatar url or an empty string + */ + std::string get_avatar_decoration_url(uint16_t size = 0) const; + /** * @brief Return a ping/mention for the user * diff --git a/src/dpp/message.cpp b/src/dpp/message.cpp index 3f4331ad05..da63e4dccf 100644 --- a/src/dpp/message.cpp +++ b/src/dpp/message.cpp @@ -57,6 +57,14 @@ component& component::fill_from_json(nlohmann::json* j) { if (j->contains("max_values") && j->at("max_values").is_number_integer()) { max_values = j->at("max_values").get(); } + if (j->contains("default_values") && !j->at("default_values").is_null()) { + for (auto const &v : j->at("default_values")) { + component_default_value d; + d.id = snowflake_not_null(&v, "id"); + d.type = static_cast(int8_not_null(&v, "type")); + default_values.push_back(d); + } + } if (type == cot_action_row) { for (json sub_component : (*j)["components"]) { dpp::component new_component; @@ -345,6 +353,21 @@ void to_json(json& j, const component& cp) { if (cp.max_values >= 0) { j["max_values"] = cp.max_values; } + if (!cp.default_values.empty()) { + j["default_values"] = json::array(); + for (auto const &v : cp.default_values) { + json o; + o["id"] = v.id; + if (v.type == dpp::cdt_role) { + o["type"] = "role"; + } else if (v.type == dpp::cdt_channel) { + o["type"] = "channel"; + } else if (v.type == dpp::cdt_user) { + o["type"] = "user"; + } + j["default_values"].push_back(o); + } + } } else if (cp.type == cot_channel_selectmenu) { j["custom_id"] = cp.custom_id; j["disabled"] = cp.disabled; @@ -363,6 +386,21 @@ void to_json(json& j, const component& cp) { j["channel_types"].push_back(type); } } + if (!cp.default_values.empty()) { + j["default_values"] = json::array(); + for (auto const &v : cp.default_values) { + json o; + o["id"] = v.id; + if (v.type == dpp::cdt_role) { + o["type"] = "role"; + } else if (v.type == dpp::cdt_channel) { + o["type"] = "channel"; + } else if (v.type == dpp::cdt_user) { + o["type"] = "user"; + } + j["default_values"].push_back(o); + } + } } } @@ -446,6 +484,14 @@ component& component::add_select_option(const select_option &option) { return *this; } +component &component::add_default_value(const snowflake id, const component_default_value_type type) { + component_default_value default_value; + default_value.id = id; + default_value.type = type; + this->default_values.push_back(default_value); + return *this; +} + embed::~embed() = default; embed::embed() : timestamp(0), color(0) { diff --git a/src/dpp/user.cpp b/src/dpp/user.cpp index b9faa8767d..1f6ea8530e 100644 --- a/src/dpp/user.cpp +++ b/src/dpp/user.cpp @@ -126,6 +126,16 @@ std::string user::get_default_avatar_url() const { } } +std::string user::get_avatar_decoration_url(uint16_t size) const { + if (this->id) { + return utility::cdn_endpoint_url_hash({ i_png }, + "avatar-decorations/" + std::to_string(this->id), this->avatar_decoration.to_string(), + i_png, size); + } else { + return std::string(); + } +} + std::string user::format_username() const { return username + '#' + leading_zeroes(discriminator, 4); } @@ -279,6 +289,8 @@ void from_json(const nlohmann::json& j, user& u) { } u.avatar = av; + u.avatar_decoration = string_not_null(&j, "avatar_decoration"); + u.discriminator = (uint16_t)snowflake_not_null(&j, "discriminator"); u.flags |= bool_not_null(&j, "bot") ? dpp::u_bot : 0;