|
4 | 4 |
|
5 | 5 | import interactions.models as models |
6 | 6 | from interactions.client.const import MISSING |
| 7 | +from interactions.client.mixins.serialization import DictSerializationMixin |
7 | 8 | from interactions.client.mixins.send import SendMixin |
8 | 9 | from interactions.client.utils.attr_converters import optional |
9 | 10 | from interactions.client.utils.attr_converters import timestamp_converter |
10 | | -from interactions.models.discord.emoji import PartialEmoji |
| 11 | +from interactions.models.discord.emoji import PartialEmoji, process_emoji |
11 | 12 | from interactions.models.discord.snowflake import to_snowflake |
12 | 13 | from interactions.models.discord.timestamp import Timestamp |
13 | 14 | from .base import DiscordObject, ClientObject |
|
25 | 26 | "ThreadMember", |
26 | 27 | "ThreadList", |
27 | 28 | "ThreadTag", |
| 29 | + "DefaultReaction", |
| 30 | + "process_thread_tag", |
| 31 | + "process_default_reaction", |
28 | 32 | ) |
29 | 33 |
|
30 | 34 |
|
@@ -122,11 +126,46 @@ class ThreadTag(DiscordObject): |
122 | 126 | name: str = attrs.field( |
123 | 127 | repr=False, |
124 | 128 | ) |
125 | | - emoji_id: "Snowflake_Type" = attrs.field(repr=False, default=None) |
| 129 | + moderated: bool = attrs.field(repr=False) |
| 130 | + emoji_id: "Snowflake_Type | None" = attrs.field(repr=False, default=None) |
126 | 131 | emoji_name: str | None = attrs.field(repr=False, default=None) |
127 | 132 |
|
128 | 133 | _parent_channel_id: "Snowflake_Type" = attrs.field(repr=False, default=MISSING) |
129 | 134 |
|
| 135 | + @classmethod |
| 136 | + def create( |
| 137 | + cls, |
| 138 | + name: str, |
| 139 | + *, |
| 140 | + moderated: bool = False, |
| 141 | + emoji: Union["models.PartialEmoji", dict, str, None] = None, |
| 142 | + ) -> "ThreadTag": |
| 143 | + """ |
| 144 | + Create a new thread tag - this is useful if you're making a new forum |
| 145 | +
|
| 146 | + !!! warning |
| 147 | + This does not create the tag on Discord, it only creates a local object |
| 148 | + Do not expect the tag to contain valid values or for its methods to work |
| 149 | +
|
| 150 | + Args: |
| 151 | + name: The name for this tag |
| 152 | + moderated: Whether this tag is moderated |
| 153 | + emoji: The emoji for this tag |
| 154 | +
|
| 155 | + Returns: |
| 156 | + This object |
| 157 | + """ |
| 158 | + if emoji := models.process_emoji(emoji): |
| 159 | + return cls( |
| 160 | + client=None, |
| 161 | + moderated=moderated, |
| 162 | + id=0, |
| 163 | + name=name, |
| 164 | + emoji_id=emoji.get("id"), |
| 165 | + emoji_name=emoji.get("name"), |
| 166 | + ) |
| 167 | + return cls(client=None, moderated=moderated, id=0, name=name) |
| 168 | + |
130 | 169 | @property |
131 | 170 | def parent_channel(self) -> "GuildForum": |
132 | 171 | """The parent forum for this tag.""" |
@@ -170,3 +209,66 @@ async def delete(self) -> None: |
170 | 209 | """Delete this tag.""" |
171 | 210 | data = await self._client.http.delete_tag(self._parent_channel_id, self.id) |
172 | 211 | self._client.cache.place_channel_data(data) |
| 212 | + |
| 213 | + |
| 214 | +@attrs.define(eq=False, order=False, hash=False, kw_only=True) |
| 215 | +class DefaultReaction(DictSerializationMixin): |
| 216 | + """Represents a default reaction for a forum.""" |
| 217 | + |
| 218 | + emoji_id: "Snowflake_Type | None" = attrs.field(default=None) |
| 219 | + emoji_name: str | None = attrs.field(default=None) |
| 220 | + |
| 221 | + @classmethod |
| 222 | + def from_emoji(cls, emoji: PartialEmoji) -> "DefaultReaction": |
| 223 | + """Create a default reaction from an emoji.""" |
| 224 | + if emoji.id: |
| 225 | + return cls(emoji_id=emoji.id) |
| 226 | + return cls(emoji_name=emoji.name) |
| 227 | + |
| 228 | + |
| 229 | +def process_thread_tag(tag: Optional[dict | ThreadTag]) -> Optional[dict]: |
| 230 | + """ |
| 231 | + Processes the tag parameter into the dictionary format required by the API. |
| 232 | +
|
| 233 | + Args: |
| 234 | + tag: The tag to process |
| 235 | +
|
| 236 | + Returns: |
| 237 | + formatted dictionary for discrd |
| 238 | + """ |
| 239 | + if not tag: |
| 240 | + return tag |
| 241 | + |
| 242 | + if isinstance(tag, ThreadTag): |
| 243 | + return tag.to_dict() |
| 244 | + |
| 245 | + if isinstance(tag, dict): |
| 246 | + return tag |
| 247 | + |
| 248 | + raise ValueError(f"Invalid tag: {tag}") |
| 249 | + |
| 250 | + |
| 251 | +def process_default_reaction(reaction: Optional[dict | DefaultReaction | PartialEmoji | str]) -> Optional[dict]: |
| 252 | + """ |
| 253 | + Processes the reaction parameter into the dictionary format required by the API. |
| 254 | +
|
| 255 | + Args: |
| 256 | + reaction: The reaction to process. |
| 257 | +
|
| 258 | + Returns: |
| 259 | + formatted dictionary for discrd |
| 260 | + """ |
| 261 | + if not reaction: |
| 262 | + return reaction |
| 263 | + |
| 264 | + if isinstance(reaction, dict): |
| 265 | + return reaction |
| 266 | + |
| 267 | + if not isinstance(reaction, DefaultReaction): |
| 268 | + emoji = process_emoji(reaction) |
| 269 | + if emoji_id := emoji.get("id"): |
| 270 | + reaction = DefaultReaction(emoji_id=emoji_id) |
| 271 | + else: |
| 272 | + reaction = DefaultReaction(emoji_name=emoji["name"]) |
| 273 | + |
| 274 | + return reaction.to_dict() |
0 commit comments