componentsv2 0.2.3__tar.gz → 0.3.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {componentsv2-0.2.3 → componentsv2-0.3.0}/PKG-INFO +1 -1
- {componentsv2-0.2.3 → componentsv2-0.3.0}/componentsv2/component_holder.py +4 -3
- {componentsv2-0.2.3 → componentsv2-0.3.0}/componentsv2/components/action_row.py +10 -3
- {componentsv2-0.2.3 → componentsv2-0.3.0}/componentsv2/components/button.py +17 -14
- {componentsv2-0.2.3 → componentsv2-0.3.0}/componentsv2/components/holders/container.py +8 -0
- {componentsv2-0.2.3 → componentsv2-0.3.0}/componentsv2/components/select.py +10 -35
- {componentsv2-0.2.3 → componentsv2-0.3.0}/componentsv2/wrapper.py +65 -7
- {componentsv2-0.2.3 → componentsv2-0.3.0}/componentsv2.egg-info/PKG-INFO +1 -1
- {componentsv2-0.2.3 → componentsv2-0.3.0}/pyproject.toml +1 -1
- {componentsv2-0.2.3 → componentsv2-0.3.0}/LICENSE.txt +0 -0
- {componentsv2-0.2.3 → componentsv2-0.3.0}/README.md +0 -0
- {componentsv2-0.2.3 → componentsv2-0.3.0}/componentsv2/__init__.py +0 -0
- {componentsv2-0.2.3 → componentsv2-0.3.0}/componentsv2/components/__init__.py +0 -0
- {componentsv2-0.2.3 → componentsv2-0.3.0}/componentsv2/components/base.py +0 -0
- {componentsv2-0.2.3 → componentsv2-0.3.0}/componentsv2/components/checkbox.py +0 -0
- {componentsv2-0.2.3 → componentsv2-0.3.0}/componentsv2/components/file_upload.py +0 -0
- {componentsv2-0.2.3 → componentsv2-0.3.0}/componentsv2/components/gallery.py +0 -0
- {componentsv2-0.2.3 → componentsv2-0.3.0}/componentsv2/components/holders/__init__.py +0 -0
- {componentsv2-0.2.3 → componentsv2-0.3.0}/componentsv2/components/holders/label.py +0 -0
- {componentsv2-0.2.3 → componentsv2-0.3.0}/componentsv2/components/holders/nestable.py +0 -0
- {componentsv2-0.2.3 → componentsv2-0.3.0}/componentsv2/components/holders/section.py +0 -0
- {componentsv2-0.2.3 → componentsv2-0.3.0}/componentsv2/components/media.py +0 -0
- {componentsv2-0.2.3 → componentsv2-0.3.0}/componentsv2/components/radio_group.py +0 -0
- {componentsv2-0.2.3 → componentsv2-0.3.0}/componentsv2/components/separator.py +0 -0
- {componentsv2-0.2.3 → componentsv2-0.3.0}/componentsv2/components/text_display.py +0 -0
- {componentsv2-0.2.3 → componentsv2-0.3.0}/componentsv2/components/text_input.py +0 -0
- {componentsv2-0.2.3 → componentsv2-0.3.0}/componentsv2/utils/__init__.py +0 -0
- {componentsv2-0.2.3 → componentsv2-0.3.0}/componentsv2/utils/serialize.py +0 -0
- {componentsv2-0.2.3 → componentsv2-0.3.0}/componentsv2.egg-info/SOURCES.txt +0 -0
- {componentsv2-0.2.3 → componentsv2-0.3.0}/componentsv2.egg-info/dependency_links.txt +0 -0
- {componentsv2-0.2.3 → componentsv2-0.3.0}/componentsv2.egg-info/requires.txt +0 -0
- {componentsv2-0.2.3 → componentsv2-0.3.0}/componentsv2.egg-info/top_level.txt +0 -0
- {componentsv2-0.2.3 → componentsv2-0.3.0}/setup.cfg +0 -0
|
@@ -100,9 +100,7 @@ class ComponentHolder():
|
|
|
100
100
|
return child
|
|
101
101
|
|
|
102
102
|
class ModalV2():
|
|
103
|
-
def __init__(self,
|
|
104
|
-
if custom_id == None:
|
|
105
|
-
raise ValueError("With this wrapper, custom_ids for modals are required!")
|
|
103
|
+
def __init__(self, title: str, custom_id: str = None):
|
|
106
104
|
|
|
107
105
|
self.custom_id = custom_id
|
|
108
106
|
self.title = title
|
|
@@ -138,6 +136,9 @@ class ModalV2():
|
|
|
138
136
|
if initial == True:
|
|
139
137
|
await self.on_form_submit(interaction)
|
|
140
138
|
|
|
139
|
+
def on_submit_decorator(self, func):
|
|
140
|
+
self.on_form_submit = func
|
|
141
|
+
|
|
141
142
|
async def on_form_submit(self, interaction):
|
|
142
143
|
pass
|
|
143
144
|
|
|
@@ -12,11 +12,11 @@ class ActionRow(ComponentV2):
|
|
|
12
12
|
8: 1,
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
-
def __init__(self, id: Optional[int] = None):
|
|
15
|
+
def __init__(self, components: list[ComponentV2] = [], id: Optional[int] = None):
|
|
16
16
|
super().__init__(1, id)
|
|
17
17
|
|
|
18
18
|
self.component_type: Optional[int] = None
|
|
19
|
-
self.components: list[ComponentV2] =
|
|
19
|
+
self.components: list[ComponentV2] = components
|
|
20
20
|
|
|
21
21
|
self.__container_compatible__ = True
|
|
22
22
|
|
|
@@ -41,4 +41,11 @@ class ActionRow(ComponentV2):
|
|
|
41
41
|
if len(self.components) >= max:
|
|
42
42
|
raise ValueError(f"Cannot add more components to this action row! Max: {max}")
|
|
43
43
|
|
|
44
|
-
self.components.append(component)
|
|
44
|
+
self.components.append(component)
|
|
45
|
+
return self
|
|
46
|
+
|
|
47
|
+
def append_components(self, *args: ComponentV2):
|
|
48
|
+
components = list(args)
|
|
49
|
+
|
|
50
|
+
for component in components:
|
|
51
|
+
self.append_component(component)
|
|
@@ -30,6 +30,8 @@ class ButtonV2(ComponentV2):
|
|
|
30
30
|
self.callback = None
|
|
31
31
|
self.registered = False
|
|
32
32
|
|
|
33
|
+
self.__has_holder = None
|
|
34
|
+
|
|
33
35
|
def __call__(self, func):
|
|
34
36
|
if self.registered == True:
|
|
35
37
|
raise ValueError("Buttons cannot be registered to multiple callbacks!")
|
|
@@ -38,6 +40,17 @@ class ButtonV2(ComponentV2):
|
|
|
38
40
|
self.registered = True
|
|
39
41
|
|
|
40
42
|
return self
|
|
43
|
+
|
|
44
|
+
def on_callback(self, func):
|
|
45
|
+
if self.registered == True:
|
|
46
|
+
raise ValueError("Buttons cannot be registered to multiple callbacks!")
|
|
47
|
+
|
|
48
|
+
self.callback = func
|
|
49
|
+
self.registered = True
|
|
50
|
+
|
|
51
|
+
self.__has_holder = False
|
|
52
|
+
|
|
53
|
+
return self
|
|
41
54
|
|
|
42
55
|
def serialize(self):
|
|
43
56
|
base_dict: dict = super(ButtonV2, self).serialize()
|
|
@@ -63,17 +76,7 @@ class ButtonV2(ComponentV2):
|
|
|
63
76
|
if self.registered == False:
|
|
64
77
|
raise ValueError("Attempted to activate button, but it is not registered to a callback!")
|
|
65
78
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
super().__init__(style, label, custom_id, url, disabled, emoji, row, id)
|
|
71
|
-
|
|
72
|
-
async def activated(self, interaction):
|
|
73
|
-
if self.disabled == True:
|
|
74
|
-
return
|
|
75
|
-
|
|
76
|
-
await self.ui_callback(interaction)
|
|
77
|
-
|
|
78
|
-
async def ui_callback(self, interaction):
|
|
79
|
-
pass
|
|
79
|
+
if self.__has_holder != False:
|
|
80
|
+
await self.callback(self.parent_holder, self, interaction)
|
|
81
|
+
else:
|
|
82
|
+
await self.callback(interaction)
|
|
@@ -2,6 +2,7 @@ from .nestable import Nestable
|
|
|
2
2
|
from ..base import ComponentV2
|
|
3
3
|
|
|
4
4
|
from ..action_row import ActionRow
|
|
5
|
+
from ..text_display import TextDisplay
|
|
5
6
|
|
|
6
7
|
from typing import Optional
|
|
7
8
|
|
|
@@ -45,6 +46,13 @@ class Container(Nestable):
|
|
|
45
46
|
self.components.append(component)
|
|
46
47
|
|
|
47
48
|
return self
|
|
49
|
+
|
|
50
|
+
def add_field(self, title: str, content: str):
|
|
51
|
+
return self.append_component(
|
|
52
|
+
TextDisplay(
|
|
53
|
+
f"**{title}**\n{content}"
|
|
54
|
+
)
|
|
55
|
+
)
|
|
48
56
|
|
|
49
57
|
def serialize(self):
|
|
50
58
|
base_dict = super().serialize()
|
|
@@ -53,6 +53,15 @@ class SelectObject(ComponentV2):
|
|
|
53
53
|
self.callback = func
|
|
54
54
|
|
|
55
55
|
return self
|
|
56
|
+
|
|
57
|
+
def on_submit(self, func):
|
|
58
|
+
if self.registered == True:
|
|
59
|
+
raise ValueError("Cannot register a Select component to multiple callbacks!")
|
|
60
|
+
|
|
61
|
+
self.registered = True
|
|
62
|
+
self.callback = func
|
|
63
|
+
|
|
64
|
+
return self
|
|
56
65
|
|
|
57
66
|
class StringSelect(SelectObject):
|
|
58
67
|
class SelectOption():
|
|
@@ -265,38 +274,4 @@ class ChannelSelect(SelectObject):
|
|
|
265
274
|
raise ValueError("Attempted to activate Select component, but it is not registered to a callback!")
|
|
266
275
|
|
|
267
276
|
values = interaction.data.get("values")
|
|
268
|
-
await self.callback(self.parent_holder, self, interaction, values) ## due to a nextcord limitation, i am only able to send the list of values, not user objects.
|
|
269
|
-
|
|
270
|
-
## UI SELECTS
|
|
271
|
-
class UISelectObject(SelectObject):
|
|
272
|
-
def __init__(self, type: int, custom_id: str, placeholder: str = None, min_values: int = None, max_values: int = None, required: int = True, disabled: int = False):
|
|
273
|
-
super().__init__(type, custom_id, placeholder, min_values, max_values, required, disabled)
|
|
274
|
-
|
|
275
|
-
async def activated(self, interaction):
|
|
276
|
-
if self.disabled == True:
|
|
277
|
-
return
|
|
278
|
-
|
|
279
|
-
await self.ui_callback(interaction)
|
|
280
|
-
|
|
281
|
-
async def ui_callback(self, interaction: Interaction):
|
|
282
|
-
pass
|
|
283
|
-
|
|
284
|
-
class UIStringSelect(UISelectObject, StringSelect):
|
|
285
|
-
def __init__(self, custom_id: str, options: list[StringSelect.SelectOption], placeholder: str = None, min_values: int = None, max_values: int = None, required: bool = True, disabled: bool = False):
|
|
286
|
-
StringSelect.__init__(self, custom_id, options, placeholder, min_values, max_values, required, disabled)
|
|
287
|
-
|
|
288
|
-
class UIUserSelect(UISelectObject, UserSelect):
|
|
289
|
-
def __init__(self, custom_id: str, default_values: list[DefaultValue] = None, placeholder: str = None, min_values: int = None, max_values: int = None, required: bool = True, disabled: bool = False):
|
|
290
|
-
UserSelect.__init__(self, custom_id, default_values, placeholder, min_values, max_values, required, disabled)
|
|
291
|
-
|
|
292
|
-
class UIRoleSelect(UISelectObject, RoleSelect):
|
|
293
|
-
def __init__(self, custom_id: str, default_values: list[DefaultValue] = None, placeholder: str = None, min_values: int = None, max_values: int = None, required: bool = True, disabled: bool = False):
|
|
294
|
-
RoleSelect.__init__(self, custom_id, default_values, placeholder, min_values, max_values, required, disabled)
|
|
295
|
-
|
|
296
|
-
class UIChannelSelect(UISelectObject, ChannelSelect):
|
|
297
|
-
def __init__(self, custom_id: str, default_values: list[DefaultValue] = None, placeholder: str = None, min_values: int = None, max_values: int = None, required: bool = True, disabled: bool = False):
|
|
298
|
-
ChannelSelect.__init__(self, custom_id, default_values, placeholder, min_values, max_values, required, disabled)
|
|
299
|
-
|
|
300
|
-
class UIMentionableSelect(UISelectObject, MentionableSelect):
|
|
301
|
-
def __init__(self, custom_id: str, default_values: list[DefaultValue] = None, placeholder: str = None, min_values: int = None, max_values: int = None, required: bool = True, disabled: bool = False):
|
|
302
|
-
MentionableSelect.__init__(self, custom_id, default_values, placeholder, min_values, max_values, required, disabled)
|
|
277
|
+
await self.callback(self.parent_holder, self, interaction, values) ## due to a nextcord limitation, i am only able to send the list of values, not user objects.
|
|
@@ -37,13 +37,39 @@ class NextcordAPIWrapperV2():
|
|
|
37
37
|
if interaction.type == nextcord.InteractionType.component:
|
|
38
38
|
holder: ComponentHolder = self.active_holders.get(str(interaction.message.id))
|
|
39
39
|
if holder != None:
|
|
40
|
-
|
|
40
|
+
id = interaction.data.get("custom_id")
|
|
41
|
+
component = holder.get_component(id) if isinstance(holder, ComponentHolder) else self.__get_list_component(holder, id)
|
|
42
|
+
|
|
41
43
|
if component != None:
|
|
42
44
|
await component.activated(interaction)
|
|
43
45
|
elif interaction.type == nextcord.InteractionType.modal_submit:
|
|
44
46
|
modal: ModalV2 = self.active_modals.get(interaction.user.id)
|
|
45
47
|
if modal != None:
|
|
46
48
|
await modal.submitted(interaction, interaction.data.get("components"))
|
|
49
|
+
|
|
50
|
+
def __get_list_component(self, comps: list[ComponentV2], id: str):
|
|
51
|
+
if id is None:
|
|
52
|
+
return
|
|
53
|
+
|
|
54
|
+
for component in comps:
|
|
55
|
+
if hasattr(component, "custom_id") and component.custom_id == id:
|
|
56
|
+
return component
|
|
57
|
+
|
|
58
|
+
if hasattr(component, "components"):
|
|
59
|
+
found = self.__get_list_component(component.components, id)
|
|
60
|
+
if found is not None:
|
|
61
|
+
return found
|
|
62
|
+
|
|
63
|
+
inner = getattr(component, "component", None)
|
|
64
|
+
if inner is not None:
|
|
65
|
+
if getattr(inner, "custom_id", None) == id:
|
|
66
|
+
return inner
|
|
67
|
+
|
|
68
|
+
found = self.__get_list_component([inner], id)
|
|
69
|
+
if found is not None:
|
|
70
|
+
return found
|
|
71
|
+
|
|
72
|
+
return None
|
|
47
73
|
|
|
48
74
|
def __message_interaction_payload(self, components: list[ComponentV2], content: str = None, flags: int = None) -> dict[str]:
|
|
49
75
|
return {
|
|
@@ -63,30 +89,60 @@ class NextcordAPIWrapperV2():
|
|
|
63
89
|
"components": components
|
|
64
90
|
}
|
|
65
91
|
}
|
|
92
|
+
|
|
93
|
+
def __serialize_components(self, components: list[ComponentV2]):
|
|
94
|
+
serialized = []
|
|
95
|
+
|
|
96
|
+
for component in components:
|
|
97
|
+
serialized.append(component.serialize())
|
|
98
|
+
|
|
99
|
+
return serialized
|
|
100
|
+
|
|
101
|
+
def __serialize_modal(self, components: list[ComponentV2], title: str, custom_id: str = None):
|
|
102
|
+
serialized = []
|
|
103
|
+
|
|
104
|
+
for component in components:
|
|
105
|
+
serialized.append(component.serialize())
|
|
106
|
+
|
|
107
|
+
return {
|
|
108
|
+
"type": 9,
|
|
109
|
+
|
|
110
|
+
"data": {
|
|
111
|
+
"title": title,
|
|
112
|
+
"custom_id": custom_id,
|
|
113
|
+
"components": serialized,
|
|
114
|
+
}
|
|
115
|
+
}
|
|
66
116
|
|
|
67
117
|
async def send_modal(self, interaction: Interaction, modal: ModalV2):
|
|
68
118
|
self.active_modals[interaction.user.id] = modal
|
|
119
|
+
|
|
120
|
+
payload = modal.serialize()
|
|
69
121
|
|
|
70
122
|
await self.bot.http.request(
|
|
71
123
|
nextcord.http.Route("POST", f"/interactions/{interaction.id}/{interaction.token}/callback"),
|
|
72
|
-
json =
|
|
124
|
+
json = payload
|
|
73
125
|
)
|
|
74
126
|
|
|
75
|
-
async def send_message(self, interaction: Interaction, component_holder: ComponentHolder, content: str = None, *, ephemeral: bool = False, is_components_v2: bool = False):
|
|
127
|
+
async def send_message(self, interaction: Interaction, component_holder: ComponentHolder | list[ComponentV2], content: str = None, *, ephemeral: bool = False, is_components_v2: bool = False):
|
|
76
128
|
if is_components_v2 == True and content != None:
|
|
77
129
|
raise TypeError("ComponentsV2 messages cannot contain content!")
|
|
78
130
|
|
|
131
|
+
payload = component_holder.serialize if isinstance(component_holder, ComponentHolder) else self.__serialize_components(component_holder)
|
|
132
|
+
|
|
79
133
|
flags = MessageFlags(ephemeral=ephemeral, is_components_v2=is_components_v2).value
|
|
80
134
|
response = await self.bot.http.request(
|
|
81
135
|
nextcord.http.Route("POST", f"/interactions/{interaction.id}/{interaction.token}/callback?with_response=true"),
|
|
82
|
-
json=self.__message_interaction_payload(
|
|
136
|
+
json=self.__message_interaction_payload(payload, content=content, flags=flags)
|
|
83
137
|
)
|
|
84
138
|
|
|
85
139
|
self.active_holders[response["interaction"]["response_message_id"]] = component_holder
|
|
86
140
|
|
|
87
|
-
async def send_followup(self, interaction: Interaction, component_holder: ComponentHolder, content: str = None, *, ephemeral: bool = False, is_components_v2: bool = False):
|
|
141
|
+
async def send_followup(self, interaction: Interaction, component_holder: ComponentHolder | list[ComponentV2], content: str = None, *, ephemeral: bool = False, is_components_v2: bool = False):
|
|
88
142
|
if is_components_v2 == True and content != None:
|
|
89
143
|
raise TypeError("ComponentsV2 messages cannot contain content!")
|
|
144
|
+
|
|
145
|
+
payload = component_holder.serialize if isinstance(component_holder, ComponentHolder) else self.__serialize_components(component_holder)
|
|
90
146
|
|
|
91
147
|
flags = MessageFlags(ephemeral=ephemeral, is_components_v2=is_components_v2).value
|
|
92
148
|
response = await self.bot.http.request(
|
|
@@ -96,8 +152,10 @@ class NextcordAPIWrapperV2():
|
|
|
96
152
|
|
|
97
153
|
self.active_holders[response["id"]] = component_holder
|
|
98
154
|
|
|
99
|
-
async def edit_message(self, interaction: Interaction, component_holder: ComponentHolder, content: str = None):
|
|
155
|
+
async def edit_message(self, interaction: Interaction, component_holder: ComponentHolder | list[ComponentV2], content: str = None):
|
|
156
|
+
payload = component_holder.serialize if isinstance(component_holder, ComponentHolder) else self.__serialize_components(component_holder)
|
|
157
|
+
|
|
100
158
|
await self.bot.http.request(
|
|
101
159
|
nextcord.http.Route("POST", f"/interactions/{interaction.id}/{interaction.token}/callback"),
|
|
102
|
-
json=self.__edit_interaction_payload(components=
|
|
160
|
+
json=self.__edit_interaction_payload(components=payload, content=content)
|
|
103
161
|
)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|