discordcn 0.0.1a3__py3-none-any.whl → 0.0.1a4__py3-none-any.whl
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.
- discordcn/_version.py +2 -2
- discordcn/pycord/__init__.py +2 -0
- discordcn/pycord/interfaces/__init__.py +2 -0
- discordcn/pycord/interfaces/paginator.py +150 -50
- {discordcn-0.0.1a3.dist-info → discordcn-0.0.1a4.dist-info}/METADATA +2 -2
- {discordcn-0.0.1a3.dist-info → discordcn-0.0.1a4.dist-info}/RECORD +8 -8
- {discordcn-0.0.1a3.dist-info → discordcn-0.0.1a4.dist-info}/WHEEL +0 -0
- {discordcn-0.0.1a3.dist-info → discordcn-0.0.1a4.dist-info}/licenses/LICENSE +0 -0
discordcn/_version.py
CHANGED
|
@@ -28,7 +28,7 @@ version_tuple: VERSION_TUPLE
|
|
|
28
28
|
commit_id: COMMIT_ID
|
|
29
29
|
__commit_id__: COMMIT_ID
|
|
30
30
|
|
|
31
|
-
__version__ = version = '0.0.
|
|
32
|
-
__version_tuple__ = version_tuple = (0, 0, 1, '
|
|
31
|
+
__version__ = version = '0.0.1a4'
|
|
32
|
+
__version_tuple__ = version_tuple = (0, 0, 1, 'a4')
|
|
33
33
|
|
|
34
34
|
__commit_id__ = commit_id = None
|
discordcn/pycord/__init__.py
CHANGED
|
@@ -12,6 +12,7 @@ from .interfaces import (
|
|
|
12
12
|
PageIndicatorButton,
|
|
13
13
|
PaginatorControls,
|
|
14
14
|
PaginatorControlsBase,
|
|
15
|
+
PaginatorIndicatorModal,
|
|
15
16
|
PaginatorInterface,
|
|
16
17
|
PaginatorInterfaceBase,
|
|
17
18
|
)
|
|
@@ -23,6 +24,7 @@ __all__ = (
|
|
|
23
24
|
"PageIndicatorButton",
|
|
24
25
|
"PaginatorControls",
|
|
25
26
|
"PaginatorControlsBase",
|
|
27
|
+
"PaginatorIndicatorModal",
|
|
26
28
|
"PaginatorInterface",
|
|
27
29
|
"PaginatorInterfaceBase",
|
|
28
30
|
)
|
|
@@ -7,6 +7,7 @@ from .paginator import (
|
|
|
7
7
|
PageIndicatorButton,
|
|
8
8
|
PaginatorControls,
|
|
9
9
|
PaginatorControlsBase,
|
|
10
|
+
PaginatorIndicatorModal,
|
|
10
11
|
PaginatorInterface,
|
|
11
12
|
PaginatorInterfaceBase,
|
|
12
13
|
)
|
|
@@ -18,6 +19,7 @@ __all__ = (
|
|
|
18
19
|
"PageIndicatorButton",
|
|
19
20
|
"PaginatorControls",
|
|
20
21
|
"PaginatorControlsBase",
|
|
22
|
+
"PaginatorIndicatorModal",
|
|
21
23
|
"PaginatorInterface",
|
|
22
24
|
"PaginatorInterfaceBase",
|
|
23
25
|
)
|
|
@@ -11,6 +11,7 @@ from collections.abc import Sequence
|
|
|
11
11
|
from typing import Any, Generic, TypeVar
|
|
12
12
|
|
|
13
13
|
import discord
|
|
14
|
+
from discord import Interaction
|
|
14
15
|
from typing_extensions import Self, override
|
|
15
16
|
|
|
16
17
|
from discordcn.pycord._utils import maybe_awaitable
|
|
@@ -23,12 +24,12 @@ T = TypeVar("T", bound="PaginatorInterfaceBase")
|
|
|
23
24
|
class PaginatorInterfaceBase(ABC, discord.ui.DesignerView):
|
|
24
25
|
"""ABC defining the interface for paginator views.
|
|
25
26
|
|
|
26
|
-
This ABC specifies the minimum requirements for a view to be
|
|
27
|
-
|
|
28
|
-
|
|
27
|
+
This ABC specifies the minimum requirements for a view to be compatible
|
|
28
|
+
with paginator controls, ensuring consistent behavior across different
|
|
29
|
+
paginator implementations.
|
|
29
30
|
|
|
30
31
|
Attributes:
|
|
31
|
-
page: The current page index (0-based).
|
|
32
|
+
page (int): The current page index (0-based).
|
|
32
33
|
"""
|
|
33
34
|
|
|
34
35
|
page: int
|
|
@@ -65,12 +66,10 @@ class PaginatorControlsBase(ABC, discord.ui.ActionRow[T], Generic[T]):
|
|
|
65
66
|
class PageButton(discord.ui.Button[PaginatorInterfaceBase]):
|
|
66
67
|
"""Navigation button for jumping to a specific page.
|
|
67
68
|
|
|
68
|
-
|
|
69
|
-
when clicked. It is designed to work with any view implementing
|
|
70
|
-
PaginatorInterfaceBase.
|
|
69
|
+
Updates the parent view's page index and refreshes the UI when clicked.
|
|
71
70
|
|
|
72
71
|
Attributes:
|
|
73
|
-
page: The target page index this button navigates to.
|
|
72
|
+
page (int): The target page index this button navigates to.
|
|
74
73
|
"""
|
|
75
74
|
|
|
76
75
|
def __init__(self, page: int, **kwargs: Any) -> None:
|
|
@@ -78,9 +77,8 @@ class PageButton(discord.ui.Button[PaginatorInterfaceBase]):
|
|
|
78
77
|
|
|
79
78
|
Args:
|
|
80
79
|
page: The target page index (0-based) to navigate to when clicked.
|
|
81
|
-
**kwargs: Additional keyword arguments passed to
|
|
82
|
-
|
|
83
|
-
``disabled``).
|
|
80
|
+
**kwargs: Additional keyword arguments passed to discord.ui.Button
|
|
81
|
+
(e.g., ``emoji``, ``style``, ``disabled``).
|
|
84
82
|
"""
|
|
85
83
|
super().__init__(**kwargs)
|
|
86
84
|
self.page: int = page
|
|
@@ -94,6 +92,9 @@ class PageButton(discord.ui.Button[PaginatorInterfaceBase]):
|
|
|
94
92
|
|
|
95
93
|
Args:
|
|
96
94
|
interaction: The interaction object from the button click.
|
|
95
|
+
|
|
96
|
+
Raises:
|
|
97
|
+
TypeError: If the button is not attached to a view.
|
|
97
98
|
"""
|
|
98
99
|
if self.view is None:
|
|
99
100
|
msg = "This button is not attached to a view."
|
|
@@ -107,54 +108,143 @@ class PageButton(discord.ui.Button[PaginatorInterfaceBase]):
|
|
|
107
108
|
await interaction.response.edit_message(view=v)
|
|
108
109
|
|
|
109
110
|
|
|
111
|
+
class PaginatorIndicatorModal(discord.ui.DesignerModal):
|
|
112
|
+
"""Modal for direct page navigation input.
|
|
113
|
+
|
|
114
|
+
Allows users to jump to a specific page by entering a page number.
|
|
115
|
+
|
|
116
|
+
Attributes:
|
|
117
|
+
view (PaginatorInterfaceBase): The parent paginator view.
|
|
118
|
+
input (discord.ui.TextInput): The text input field for page number.
|
|
119
|
+
invalid (str): Error message shown for invalid page numbers.
|
|
120
|
+
"""
|
|
121
|
+
|
|
122
|
+
def __init__(
|
|
123
|
+
self, modal_title: str, label_title: str, label_description: str, invalid: str, view: PaginatorInterfaceBase
|
|
124
|
+
) -> None:
|
|
125
|
+
"""Initialize the page navigation modal.
|
|
126
|
+
|
|
127
|
+
Args:
|
|
128
|
+
modal_title: The title displayed at the top of the modal.
|
|
129
|
+
label_title: The label text for the input field.
|
|
130
|
+
label_description: The description text for the input field.
|
|
131
|
+
invalid: Error message shown when an invalid page number is entered.
|
|
132
|
+
view: The parent paginator view.
|
|
133
|
+
"""
|
|
134
|
+
self.view: PaginatorInterfaceBase = view
|
|
135
|
+
self.input: discord.ui.TextInput = discord.ui.TextInput(
|
|
136
|
+
style=discord.InputTextStyle.short, max_length=len(str(view.max_page))
|
|
137
|
+
)
|
|
138
|
+
self.invalid: str = invalid
|
|
139
|
+
label: discord.ui.Label[Self] = discord.ui.Label(
|
|
140
|
+
label=label_title, description=label_description, item=self.input
|
|
141
|
+
)
|
|
142
|
+
super().__init__(label, title=modal_title)
|
|
143
|
+
|
|
144
|
+
@override
|
|
145
|
+
async def callback(self, interaction: Interaction) -> None:
|
|
146
|
+
"""Handle modal submission.
|
|
147
|
+
|
|
148
|
+
Validates the page number and navigates to the specified page if valid.
|
|
149
|
+
|
|
150
|
+
Args:
|
|
151
|
+
interaction: The interaction object from the modal submission.
|
|
152
|
+
"""
|
|
153
|
+
await interaction.response.defer()
|
|
154
|
+
page = self.input.value
|
|
155
|
+
if not page or not page.isdigit() or (int_page := int(page) - 1) > self.view.max_page:
|
|
156
|
+
await interaction.respond(self.invalid, ephemeral=True)
|
|
157
|
+
return
|
|
158
|
+
self.view.page = int_page
|
|
159
|
+
await maybe_awaitable(self.view.update())
|
|
160
|
+
await interaction.edit(view=self.view)
|
|
161
|
+
|
|
162
|
+
|
|
110
163
|
class PageIndicatorButton(discord.ui.Button[PaginatorInterfaceBase]):
|
|
111
|
-
"""
|
|
164
|
+
"""Button displaying the current page number.
|
|
165
|
+
|
|
166
|
+
Shows the current page position in the format "X/Y". Can optionally be
|
|
167
|
+
made interactable to open a modal for direct page navigation.
|
|
112
168
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
169
|
+
Attributes:
|
|
170
|
+
disabled (bool): Whether the button is disabled.
|
|
171
|
+
modal_title (str): Title for the page navigation modal.
|
|
172
|
+
label_title (str): Label title for the modal input field.
|
|
173
|
+
label_description (str): Description for the modal input field.
|
|
174
|
+
invalid (str): Error message for invalid page input.
|
|
116
175
|
"""
|
|
117
176
|
|
|
118
|
-
def __init__(
|
|
177
|
+
def __init__(
|
|
178
|
+
self,
|
|
179
|
+
*,
|
|
180
|
+
label: str,
|
|
181
|
+
interactable: bool,
|
|
182
|
+
modal_title: str,
|
|
183
|
+
label_title: str,
|
|
184
|
+
label_description: str,
|
|
185
|
+
invalid: str,
|
|
186
|
+
) -> None:
|
|
119
187
|
"""Initialize a page indicator button.
|
|
120
188
|
|
|
121
189
|
Args:
|
|
122
|
-
label: The text to display on the button (typically "
|
|
190
|
+
label: The text to display on the button (typically "X/Y" format).
|
|
191
|
+
interactable: Whether clicking the button should open a navigation modal.
|
|
192
|
+
modal_title: Title for the page navigation modal.
|
|
193
|
+
label_title: Label for the modal's input field.
|
|
194
|
+
label_description: Description for the modal's input field.
|
|
195
|
+
invalid: Error message shown for invalid page numbers.
|
|
123
196
|
"""
|
|
124
197
|
super().__init__(style=discord.ButtonStyle.secondary, label=label)
|
|
125
|
-
self.disabled: bool =
|
|
198
|
+
self.disabled: bool = not interactable
|
|
199
|
+
self.modal_title: str = modal_title
|
|
200
|
+
self.label_title: str = label_title
|
|
201
|
+
self.label_description: str = label_description
|
|
202
|
+
self.invalid: str = invalid
|
|
126
203
|
|
|
127
204
|
@override
|
|
128
205
|
async def callback(self, interaction: discord.Interaction) -> None:
|
|
129
|
-
"""Handle button click interactions
|
|
206
|
+
"""Handle button click interactions.
|
|
130
207
|
|
|
131
|
-
|
|
132
|
-
disabled and should never be clicked.
|
|
208
|
+
Opens a modal for direct page navigation when clicked.
|
|
133
209
|
|
|
134
210
|
Args:
|
|
135
211
|
interaction: The interaction object from the button click.
|
|
212
|
+
|
|
213
|
+
Raises:
|
|
214
|
+
TypeError: If the button is not attached to a view.
|
|
136
215
|
"""
|
|
137
|
-
|
|
216
|
+
if self.view is None:
|
|
217
|
+
msg = "This button is not attached to a view."
|
|
218
|
+
raise TypeError(msg)
|
|
219
|
+
|
|
220
|
+
await interaction.response.send_modal(
|
|
221
|
+
PaginatorIndicatorModal( # pyright: ignore[reportArgumentType]
|
|
222
|
+
modal_title=self.modal_title,
|
|
223
|
+
label_title=self.label_title,
|
|
224
|
+
label_description=self.label_description,
|
|
225
|
+
invalid=self.invalid,
|
|
226
|
+
view=self.view,
|
|
227
|
+
)
|
|
228
|
+
)
|
|
138
229
|
|
|
139
230
|
|
|
140
231
|
class PaginatorControls(PaginatorControlsBase[T], Generic[T]):
|
|
141
232
|
"""Navigation controls row for paginator interfaces.
|
|
142
233
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
LAST_EMOJI: The emoji to use for the "last page" button.
|
|
234
|
+
Provides five navigation elements: first page, previous page, page indicator,
|
|
235
|
+
next page, and last page. Buttons are automatically disabled when they would
|
|
236
|
+
navigate beyond valid page boundaries.
|
|
237
|
+
|
|
238
|
+
Class Attributes:
|
|
239
|
+
FIRST_EMOJI (EmojiType): Emoji for the "first page" button.
|
|
240
|
+
LEFT_EMOJI (EmojiType): Emoji for the "previous page" button.
|
|
241
|
+
RIGHT_EMOJI (EmojiType): Emoji for the "next page" button.
|
|
242
|
+
LAST_EMOJI (EmojiType): Emoji for the "last page" button.
|
|
243
|
+
INTERACTABLE_INDICATOR (bool): Whether the page indicator opens a navigation modal.
|
|
244
|
+
MODAL_TITLE (str): Title for the page navigation modal.
|
|
245
|
+
MODAL_LABEL_TITLE (str): Label for the modal's input field.
|
|
246
|
+
MODAL_LABEL_DESCRIPTION (str): Description for the modal's input field.
|
|
247
|
+
MODAL_INVALID (str): Error message for invalid page input.
|
|
158
248
|
"""
|
|
159
249
|
|
|
160
250
|
FIRST_EMOJI: EmojiType = discord.PartialEmoji(name="⏮️")
|
|
@@ -162,6 +252,12 @@ class PaginatorControls(PaginatorControlsBase[T], Generic[T]):
|
|
|
162
252
|
RIGHT_EMOJI: EmojiType = discord.PartialEmoji(name="▶️")
|
|
163
253
|
LAST_EMOJI: EmojiType = discord.PartialEmoji(name="⏭️")
|
|
164
254
|
|
|
255
|
+
INTERACTABLE_INDICATOR: bool = True
|
|
256
|
+
MODAL_TITLE: str = "Page Navigation"
|
|
257
|
+
MODAL_LABEL_TITLE: str = "Page Number:"
|
|
258
|
+
MODAL_LABEL_DESCRIPTION: str = "Input a page number to jump to that page."
|
|
259
|
+
MODAL_INVALID: str = "Please input a valid page number."
|
|
260
|
+
|
|
165
261
|
def __init__(
|
|
166
262
|
self,
|
|
167
263
|
view: T,
|
|
@@ -194,6 +290,11 @@ class PaginatorControls(PaginatorControlsBase[T], Generic[T]):
|
|
|
194
290
|
self.add_item(
|
|
195
291
|
PageIndicatorButton(
|
|
196
292
|
label=f"{view.page + 1}/{view.max_page + 1}",
|
|
293
|
+
interactable=self.INTERACTABLE_INDICATOR,
|
|
294
|
+
modal_title=self.MODAL_TITLE,
|
|
295
|
+
label_title=self.MODAL_LABEL_TITLE,
|
|
296
|
+
label_description=self.MODAL_LABEL_DESCRIPTION,
|
|
297
|
+
invalid=self.MODAL_INVALID,
|
|
197
298
|
),
|
|
198
299
|
)
|
|
199
300
|
self.add_item(
|
|
@@ -217,19 +318,16 @@ class PaginatorControls(PaginatorControlsBase[T], Generic[T]):
|
|
|
217
318
|
class PaginatorInterface(PaginatorInterfaceBase):
|
|
218
319
|
"""Multi-page view with automatic navigation controls.
|
|
219
320
|
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
selects, etc.) that are dynamically loaded when navigating between pages.
|
|
224
|
-
|
|
225
|
-
The paginator automatically appends navigation controls to the bottom of
|
|
226
|
-
each page, allowing users to move between pages using first/previous/next/last
|
|
227
|
-
buttons and see their current position.
|
|
321
|
+
Manages navigation between multiple pages of UI components, automatically
|
|
322
|
+
displaying the appropriate page content and navigation controls. Each page
|
|
323
|
+
is dynamically loaded when navigating between pages.
|
|
228
324
|
|
|
229
325
|
Attributes:
|
|
230
|
-
pages
|
|
231
|
-
|
|
232
|
-
|
|
326
|
+
pages (Sequence[Sequence[discord.ui.ViewItem[discord.ui.DesignerView]]]):
|
|
327
|
+
The sequence of pages, where each page is a sequence of view items.
|
|
328
|
+
page (int): The current page index (0-based).
|
|
329
|
+
controls (type[PaginatorControlsBase[Self]]): The paginator controls
|
|
330
|
+
class to use for navigation.
|
|
233
331
|
"""
|
|
234
332
|
|
|
235
333
|
def __init__(
|
|
@@ -258,7 +356,7 @@ class PaginatorInterface(PaginatorInterfaceBase):
|
|
|
258
356
|
"""The maximum page index (0-based).
|
|
259
357
|
|
|
260
358
|
Returns:
|
|
261
|
-
The index of the last page
|
|
359
|
+
The index of the last page.
|
|
262
360
|
"""
|
|
263
361
|
return len(self.pages) - 1
|
|
264
362
|
|
|
@@ -273,7 +371,8 @@ class PaginatorInterface(PaginatorInterfaceBase):
|
|
|
273
371
|
self.clear_items()
|
|
274
372
|
for item in self.pages[self.page]:
|
|
275
373
|
self.add_item(item)
|
|
276
|
-
|
|
374
|
+
if len(self.pages) > 1:
|
|
375
|
+
self.add_item(self.controls(self))
|
|
277
376
|
|
|
278
377
|
|
|
279
378
|
__all__ = (
|
|
@@ -281,6 +380,7 @@ __all__ = (
|
|
|
281
380
|
"PageIndicatorButton",
|
|
282
381
|
"PaginatorControls",
|
|
283
382
|
"PaginatorControlsBase",
|
|
383
|
+
"PaginatorIndicatorModal",
|
|
284
384
|
"PaginatorInterface",
|
|
285
385
|
"PaginatorInterfaceBase",
|
|
286
386
|
)
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: discordcn
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.1a4
|
|
4
4
|
Summary: An unofficial, community-driven implementation for Discord app interface patterns.
|
|
5
5
|
Project-URL: Homepage, https://github.com/nicebots-xyz/discordcn-py
|
|
6
|
-
Project-URL: source_archive, https://github.com/nicebots-xyz/discordcn-py/archive/
|
|
6
|
+
Project-URL: source_archive, https://github.com/nicebots-xyz/discordcn-py/archive/b4a168d863738ba6dfaa0f6dfa823336eebd447f.zip
|
|
7
7
|
Author-email: Paillat-dev <me@paillat.dev>
|
|
8
8
|
License-Expression: MIT
|
|
9
9
|
License-File: LICENSE
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
discordcn/__init__.py,sha256=M-tPvQrNqMrw6MX2TX2v8XMEc_nnaF_PUdkjAUEnWEA,30
|
|
2
|
-
discordcn/_version.py,sha256=
|
|
2
|
+
discordcn/_version.py,sha256=wvECKgt5TpWmMZcvP9PJmnR2v91tADC9a9ydpd1BOlM,712
|
|
3
3
|
discordcn/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
4
4
|
discordcn/_utils/__init__.py,sha256=Kjk4SSBNj8W1tez3WFgBGcCXiOCF_k5rUw_u42hzkyk,70
|
|
5
5
|
discordcn/_utils/dependencies.py,sha256=ipGc1DYJfbV7zgLwWN9sZnWjJseh0zqHPm-OabGFEKM,5932
|
|
6
|
-
discordcn/pycord/__init__.py,sha256=
|
|
6
|
+
discordcn/pycord/__init__.py,sha256=czJI77-ZYNOZxl2IN7KUmQW6rZqTnvhfguoFtH36nM4,665
|
|
7
7
|
discordcn/pycord/_utils/__init__.py,sha256=qdiz75w8BWBe3Hx_pEjRjLOVIXCLqAesHsf0jERIUQI,228
|
|
8
8
|
discordcn/pycord/_utils/_asyncio.py,sha256=C1mvWsaysEcI-r_c8rVPq-Xqm5vFxjIRaH5o8mNOHyc,756
|
|
9
|
-
discordcn/pycord/interfaces/__init__.py,sha256=
|
|
9
|
+
discordcn/pycord/interfaces/__init__.py,sha256=f1gTnkAFU-Rq2SwxMZKa_MaSedfUixPZhHQqKHljNhg,570
|
|
10
10
|
discordcn/pycord/interfaces/_types.py,sha256=wC30UtEU81qk5_PnVJb8tZIwpQ5LhpoSknlETeuAWmU,353
|
|
11
11
|
discordcn/pycord/interfaces/accordion.py,sha256=VbXM56rmJZvSP4Tg4iG3v2T9rVgxUuHzHVsO9_ZPK6g,17799
|
|
12
12
|
discordcn/pycord/interfaces/confirm.py,sha256=LIXZRVk9wnhv8PDzTY34U3AiwZgOdKG2bnlxS8rfdqs,8194
|
|
13
|
-
discordcn/pycord/interfaces/paginator.py,sha256=
|
|
14
|
-
discordcn-0.0.
|
|
15
|
-
discordcn-0.0.
|
|
16
|
-
discordcn-0.0.
|
|
17
|
-
discordcn-0.0.
|
|
13
|
+
discordcn/pycord/interfaces/paginator.py,sha256=1TtXfXCz1UYzvzEgQtj0kh7hMQhe4DPaixhmxYYudds,13637
|
|
14
|
+
discordcn-0.0.1a4.dist-info/METADATA,sha256=sm_W-5h9U_3FdPCm55iUB1AUEr_FL5eVicfPgriiAro,3187
|
|
15
|
+
discordcn-0.0.1a4.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
|
|
16
|
+
discordcn-0.0.1a4.dist-info/licenses/LICENSE,sha256=GtM5nF4RszKjPj7YvDquoqanaubrF0KhbD8-k6t_648,1069
|
|
17
|
+
discordcn-0.0.1a4.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|