31
31
"Paginator" ,
32
32
"PageGroup" ,
33
33
"PaginatorMenu" ,
34
+ "Page" ,
34
35
)
35
36
36
37
@@ -104,6 +105,48 @@ async def callback(self, interaction: discord.Interaction):
104
105
await self .paginator .goto_page (page_number = self .paginator .current_page )
105
106
106
107
108
+ class Page :
109
+ """Represents a page shown in the paginator.
110
+
111
+ Allows for directly referencing and modifying each page as a class instance.
112
+
113
+ Parameters
114
+ ----------
115
+ content: :class:`str`
116
+ The content of the page. Corresponds to the :class:`discord.Message.content` attribute.
117
+ embeds: Optional[List[Union[List[:class:`discord.Embed`], :class:`discord.Embed`]]]
118
+ The embeds of the page. Corresponds to the :class:`discord.Message.embeds` attribute.
119
+ """
120
+
121
+ def __init__ (
122
+ self , content : Optional [str ] = None , embeds : Optional [List [Union [List [discord .Embed ], discord .Embed ]]] = None
123
+ ):
124
+ if content is None and embeds is None :
125
+ raise discord .InvalidArgument ("A page cannot have both content and embeds equal to None." )
126
+ self ._content = content
127
+ self ._embeds = embeds
128
+
129
+ @property
130
+ def content (self ) -> Optional [str ]:
131
+ """Gets the content for the page."""
132
+ return self ._content
133
+
134
+ @content .setter
135
+ def content (self , value : Optional [str ]):
136
+ """Sets the content for the page."""
137
+ self ._content = value
138
+
139
+ @property
140
+ def embeds (self ) -> Optional [List [Union [List [discord .Embed ], discord .Embed ]]]:
141
+ """Gets the embeds for the page."""
142
+ return self ._embeds
143
+
144
+ @embeds .setter
145
+ def embeds (self , value : Optional [List [Union [List [discord .Embed ], discord .Embed ]]]):
146
+ """Sets the embeds for the page."""
147
+ self ._embeds = value
148
+
149
+
107
150
class PageGroup :
108
151
"""Creates a group of pages which the user can switch between.
109
152
@@ -116,8 +159,8 @@ class PageGroup:
116
159
117
160
Parameters
118
161
----------
119
- pages: Union[List[:class:`str`], List[Union[List[:class:`discord.Embed`], :class:`discord.Embed]]]
120
- The list of strings, embeds, or list of embeds to include in the page group.
162
+ pages: Union[List[:class:`str`], List[:class:`Page`], List[ Union[List[:class:`discord.Embed`], :class:`discord.Embed]]]
163
+ The list of :class:`Page` objects, strings, embeds, or list of embeds to include in the page group.
121
164
label: :class:`str`
122
165
The label shown on the corresponding PaginatorMenu dropdown option.
123
166
Also used as the SelectOption value.
@@ -150,7 +193,7 @@ class PageGroup:
150
193
151
194
def __init__ (
152
195
self ,
153
- pages : Union [List [str ], List [Union [List [discord .Embed ], discord .Embed ]]],
196
+ pages : Union [List [str ], List [Page ], List [ Union [List [discord .Embed ], discord .Embed ]]],
154
197
label : str ,
155
198
description : str ,
156
199
emoji : Union [str , discord .Emoji , discord .PartialEmoji ] = None ,
@@ -186,8 +229,8 @@ class Paginator(discord.ui.View):
186
229
187
230
Parameters
188
231
----------
189
- pages: Union[List[:class:`PageGroup`], List[:class:`str`], List[Union[List[:class:`discord.Embed`], :class:`discord.Embed`]]]
190
- The list of :class:`PageGroup` objects, strings, embeds, or list of embeds to paginate.
232
+ pages: Union[List[:class:`PageGroup`], List[:class:`Page`], List[:class:` str`], List[Union[List[:class:`discord.Embed`], :class:`discord.Embed`]]]
233
+ The list of :class:`PageGroup` objects, :class:`Page` objects, strings, embeds, or list of embeds to paginate.
191
234
If a list of :class:`PageGroup` objects is provided and `show_menu` is ``False``, only the first page group will be displayed.
192
235
show_disabled: :class:`bool`
193
236
Whether to show disabled buttons.
@@ -233,7 +276,7 @@ class Paginator(discord.ui.View):
233
276
234
277
def __init__ (
235
278
self ,
236
- pages : Union [List [PageGroup ], List [str ], List [Union [List [discord .Embed ], discord .Embed ]]],
279
+ pages : Union [List [PageGroup ], List [Page ], List [ str ], List [Union [List [discord .Embed ], discord .Embed ]]],
237
280
show_disabled : bool = True ,
238
281
show_indicator = True ,
239
282
show_menu = False ,
@@ -248,15 +291,19 @@ def __init__(
248
291
) -> None :
249
292
super ().__init__ (timeout = timeout )
250
293
self .timeout : float = timeout
251
- self .pages : Union [List [PageGroup ], List [str ], List [Union [List [discord .Embed ], discord .Embed ]]] = pages
294
+ self .pages : Union [
295
+ List [PageGroup ], List [str ], List [Page ], List [Union [List [discord .Embed ], discord .Embed ]]
296
+ ] = pages
252
297
self .current_page = 0
253
298
self .menu : Optional [PaginatorMenu ] = None
254
299
self .show_menu = show_menu
255
300
self .page_groups : Optional [List [PageGroup ]] = None
256
301
257
302
if all (isinstance (pg , PageGroup ) for pg in pages ):
258
303
self .page_groups = self .pages if show_menu else None
259
- self .pages : Union [List [str ], List [Union [List [discord .Embed ], discord .Embed ]]] = self .page_groups [0 ].pages
304
+ self .pages : Union [
305
+ List [str ], List [Page ], List [Union [List [discord .Embed ], discord .Embed ]]
306
+ ] = self .page_groups [0 ].pages
260
307
261
308
self .page_count = len (self .pages ) - 1
262
309
self .buttons = {}
@@ -284,7 +331,7 @@ def __init__(
284
331
285
332
async def update (
286
333
self ,
287
- pages : Optional [Union [List [str ], List [Union [List [discord .Embed ], discord .Embed ]]]] = None ,
334
+ pages : Optional [Union [List [str ], List [Page ], List [ Union [List [discord .Embed ], discord .Embed ]]]] = None ,
288
335
show_disabled : Optional [bool ] = None ,
289
336
show_indicator : Optional [bool ] = None ,
290
337
author_check : Optional [bool ] = None ,
@@ -300,8 +347,8 @@ async def update(
300
347
301
348
Parameters
302
349
----------
303
- pages: Optional[Union[List[:class:`PageGroup`], List[:class:`str`], List[Union[List[:class:`discord.Embed`], :class:`discord.Embed]]]]
304
- The list of :class:`PageGroup` objects, strings, embeds, or list of embeds to paginate.
350
+ pages: Optional[Union[List[:class:`PageGroup`], List[:class:`Page`], List[:class:` str`], List[Union[List[:class:`discord.Embed`], :class:`discord.Embed]]]]
351
+ The list of :class:`PageGroup` objects, :class:`Page` objects, strings, embeds, or list of embeds to paginate.
305
352
show_disabled: :class:`bool`
306
353
Whether to show disabled buttons.
307
354
show_indicator: :class:`bool`
@@ -326,7 +373,7 @@ async def update(
326
373
"""
327
374
328
375
# Update pages and reset current_page to 0 (default)
329
- self .pages : Union [List [PageGroup ], List [str ], List [Union [List [discord .Embed ], discord .Embed ]]] = (
376
+ self .pages : Union [List [PageGroup ], List [str ], List [Page ], List [ Union [List [discord .Embed ], discord .Embed ]]] = (
330
377
pages if pages is not None else self .pages
331
378
)
332
379
self .page_count = len (self .pages ) - 1
@@ -361,7 +408,7 @@ async def on_timeout(self) -> None:
361
408
async def disable (
362
409
self ,
363
410
include_custom : bool = False ,
364
- page : Optional [Union [str , Union [List [discord .Embed ], discord .Embed ]]] = None ,
411
+ page : Optional [Union [str , Page , Union [List [discord .Embed ], discord .Embed ]]] = None ,
365
412
) -> None :
366
413
"""Stops the paginator, disabling all of its components.
367
414
@@ -378,8 +425,8 @@ async def disable(
378
425
item .disabled = True
379
426
if page :
380
427
await self .message .edit (
381
- content = page if isinstance ( page , str ) else None ,
382
- embeds = [] if isinstance ( page , str ) else page ,
428
+ content = page . content ,
429
+ embeds = page . embeds ,
383
430
view = self ,
384
431
)
385
432
else :
@@ -388,7 +435,7 @@ async def disable(
388
435
async def cancel (
389
436
self ,
390
437
include_custom : bool = False ,
391
- page : Optional [Union [str , Union [List [discord .Embed ], discord .Embed ]]] = None ,
438
+ page : Optional [Union [str , Page , Union [List [discord .Embed ], discord .Embed ]]] = None ,
392
439
) -> None :
393
440
"""Cancels the paginator, removing all of its components from the message.
394
441
@@ -406,8 +453,8 @@ async def cancel(
406
453
self .remove_item (item )
407
454
if page :
408
455
await self .message .edit (
409
- content = page if isinstance ( page , str ) else None ,
410
- embeds = [] if isinstance ( page , str ) else page ,
456
+ content = page . content ,
457
+ embeds = page . embeds ,
411
458
view = self ,
412
459
)
413
460
else :
@@ -439,8 +486,8 @@ async def goto_page(self, page_number=0) -> discord.Message:
439
486
page = self .get_page_content (page )
440
487
441
488
return await self .message .edit (
442
- content = page if isinstance ( page , str ) else None ,
443
- embeds = [] if isinstance ( page , str ) else page ,
489
+ content = page . content ,
490
+ embeds = page . embeds ,
444
491
view = self ,
445
492
)
446
493
@@ -588,17 +635,19 @@ def update_buttons(self) -> Dict:
588
635
return self .buttons
589
636
590
637
@staticmethod
591
- def get_page_content (page : Union [str , discord .Embed , List [discord .Embed ]]):
638
+ def get_page_content (page : Union [Page , str , discord .Embed , List [discord .Embed ]]) -> Page :
592
639
"""Returns the correct content type for a page based on its content."""
593
- if isinstance (page , discord .Embed ):
594
- return [page ]
640
+ if isinstance (page , Page ):
641
+ return page
642
+ elif isinstance (page , str ):
643
+ return Page (content = page , embeds = [])
644
+ elif isinstance (page , discord .Embed ):
645
+ return Page (content = None , embeds = [page ])
595
646
elif isinstance (page , List ):
596
647
if all (isinstance (x , discord .Embed ) for x in page ):
597
- return page
648
+ return Page ( content = None , embeds = page )
598
649
else :
599
650
raise TypeError ("All list items must be embeds." )
600
- elif isinstance (page , str ):
601
- return page
602
651
603
652
async def send (
604
653
self ,
@@ -658,7 +707,7 @@ async def send(
658
707
659
708
self .update_buttons ()
660
709
page = self .pages [self .current_page ]
661
- page = self .get_page_content (page )
710
+ page_content = self .get_page_content (page )
662
711
663
712
self .user = ctx .author
664
713
@@ -673,8 +722,8 @@ async def send(
673
722
ctx = target
674
723
675
724
self .message = await ctx .send (
676
- content = page if isinstance ( page , str ) else None ,
677
- embeds = [] if isinstance ( page , str ) else page ,
725
+ content = page_content . content ,
726
+ embeds = page_content . embeds ,
678
727
view = self ,
679
728
reference = reference ,
680
729
allowed_mentions = allowed_mentions ,
@@ -718,31 +767,31 @@ async def respond(
718
767
719
768
self .update_buttons ()
720
769
721
- page = self .pages [self .current_page ]
722
- page = self .get_page_content (page )
770
+ page : Union [ Page , str , discord . Embed , List [ discord . Embed ]] = self .pages [self .current_page ]
771
+ page_content : Page = self .get_page_content (page )
723
772
724
773
self .user = interaction .user
725
774
if target :
726
775
await interaction .response .send_message (target_message , ephemeral = ephemeral )
727
776
self .message = await target .send (
728
- content = page if isinstance ( page , str ) else None ,
729
- embeds = [] if isinstance ( page , str ) else page ,
777
+ content = page_content . content ,
778
+ embeds = page_content . embeds ,
730
779
view = self ,
731
780
)
732
781
else :
733
782
if interaction .response .is_done ():
734
783
msg = await interaction .followup .send (
735
- content = page if isinstance ( page , str ) else None ,
736
- embeds = [] if isinstance ( page , str ) else page ,
784
+ content = page_content . content ,
785
+ embeds = page_content . embeds ,
737
786
view = self ,
738
787
ephemeral = ephemeral ,
739
788
)
740
789
# convert from WebhookMessage to Message reference to bypass 15min webhook token timeout
741
790
msg = await msg .channel .fetch_message (msg .id )
742
791
else :
743
792
msg = await interaction .response .send_message (
744
- content = page if isinstance ( page , str ) else None ,
745
- embeds = [] if isinstance ( page , str ) else page ,
793
+ content = page_content . content ,
794
+ embeds = page_content . embeds ,
746
795
view = self ,
747
796
ephemeral = ephemeral ,
748
797
)
0 commit comments