31
31
JUMP_LAST_LABEL = " \u276f \u276f " # >>
32
32
STOP_PAGINATE_EMOJI = "\u274c " # [:x:] This is an emoji, which is treated differently from the above
33
33
34
+ NO_EMBED_FOOTER_BUMP = 15
35
+
36
+ _AUTOGENERATE = object ()
37
+
38
+
34
39
logger : ModmailLogger = logging .getLogger (__name__ )
35
40
36
41
@@ -57,13 +62,14 @@ def __init__(
57
62
contents : Union [List [str ], str ],
58
63
/ ,
59
64
source_message : Optional [discord .Message ] = None ,
60
- embed : Embed = None ,
65
+ embed : Union [ Embed , bool , None ] = _AUTOGENERATE ,
61
66
timeout : float = 180 ,
62
67
* ,
63
68
footer_text : str = None ,
64
69
prefix : str = "```" ,
65
70
suffix : str = "```" ,
66
71
max_size : int = 2000 ,
72
+ title : str = None ,
67
73
linesep : str = "\n " ,
68
74
only_users : Optional [List [Union [discord .Object , discord .abc .User ]]] = None ,
69
75
only_roles : Optional [List [Union [discord .Object , discord .Role ]]] = None ,
@@ -75,14 +81,33 @@ def __init__(
75
81
If source message is provided and only_users is NOT provided, the paginator will respond
76
82
to the author of the source message. To override this, pass an empty list to `only_users`.
77
83
84
+ By default, an embed is created. However, a custom embed can
85
+ be passed, or None can be passed to not use an embed.
78
86
"""
79
87
self .index = 0
80
88
self ._pages : List [str ] = []
81
89
self .prefix = prefix
82
90
self .suffix = suffix
83
91
self .max_size = max_size
84
92
self .linesep = linesep
85
- self .embed = embed or Embed ()
93
+ if embed is _AUTOGENERATE or embed is True :
94
+ self .embed = Embed ()
95
+ else :
96
+ if embed is False :
97
+ embed = None
98
+ self .embed = embed
99
+
100
+ # used if embed is None
101
+ self .content = ""
102
+ if self .embed is None :
103
+ self .title = title
104
+ # need to set the max_size down a few to be able to set a "footer"
105
+ # page indicator is "page xx of xx"
106
+ self .max_size -= NO_EMBED_FOOTER_BUMP + len (self .title or "" )
107
+ if self .title is not None :
108
+ self .max_size -= len (title )
109
+ if footer_text is not None :
110
+ self .max_size -= len (footer_text ) + 1
86
111
87
112
# temporary to support strings as contents. This will be changed when we added wrapping.
88
113
if isinstance (contents , str ):
@@ -116,8 +141,8 @@ def __init__(
116
141
117
142
# set footer to embed.footer if embed is set
118
143
# this is because we will be modifying the footer of this embed
119
- if embed is not None :
120
- if not isinstance (embed .footer , EmbedProxy ) and footer_text is None :
144
+ if self . embed is not None :
145
+ if not isinstance (self . embed .footer , EmbedProxy ) and footer_text is None :
121
146
footer_text = embed .footer
122
147
self .footer_text = footer_text
123
148
self .clear ()
@@ -140,7 +165,7 @@ async def paginate(
140
165
source_message : discord .Message = None ,
141
166
/ ,
142
167
timeout : float = 180 ,
143
- embed : Embed = None ,
168
+ embed : Embed = _AUTOGENERATE ,
144
169
* ,
145
170
footer_text : str = None ,
146
171
only : Optional [discord .abc .User ] = None ,
@@ -149,6 +174,7 @@ async def paginate(
149
174
prefix : str = "" ,
150
175
suffix : str = "" ,
151
176
max_size : int = 4000 ,
177
+ title : str = None ,
152
178
linesep : str = "\n " ,
153
179
only_users : Optional [List [Union [discord .Object , discord .abc .User ]]] = None ,
154
180
only_roles : Optional [List [Union [discord .Object , discord .abc .Role ]]] = None ,
@@ -167,6 +193,7 @@ async def paginate(
167
193
prefix = prefix ,
168
194
suffix = suffix ,
169
195
max_size = max_size ,
196
+ title = title ,
170
197
linesep = linesep ,
171
198
only_users = only_users ,
172
199
only_roles = only_roles ,
@@ -178,18 +205,24 @@ async def paginate(
178
205
channel = source_message .channel
179
206
180
207
paginator .update_states ()
181
- paginator .embed .description = paginator .pages [paginator .index ]
182
208
# if there's only one page, don't send the view
183
209
if len (paginator .pages ) < 2 :
184
- await channel .send (embeds = [paginator .embed ])
210
+ if paginator .embed :
211
+ await channel .send (embeds = [paginator .embed ])
212
+ else :
213
+ await channel .send (content = paginator .content )
214
+
185
215
return
186
216
187
217
if len (paginator .pages ) < (show_jump_buttons_min_pages or 3 ):
188
218
for item in paginator .children :
189
219
if getattr (item , "custom_id" , None ) in ["pag_jump_first" , "pag_jump_last" ]:
190
220
paginator .remove_item (item )
191
221
192
- msg : discord .Message = await channel .send (embeds = [paginator .embed ], view = paginator )
222
+ if paginator .embed is None :
223
+ msg : discord .Message = await channel .send (content = paginator .content , view = paginator )
224
+ else :
225
+ msg : discord .Message = await channel .send (embeds = [paginator .embed ], view = paginator )
193
226
194
227
await paginator .wait ()
195
228
await msg .edit (view = None )
@@ -212,15 +245,6 @@ async def interaction_check(self, interaction: Interaction) -> bool:
212
245
)
213
246
return False
214
247
215
- def get_footer (self ) -> str :
216
- """Returns the footer text."""
217
- self .embed .description = self ._pages [self .index ]
218
- page_indicator = f"Page { self .index + 1 } /{ len (self ._pages )} "
219
- footer_txt = (
220
- f"{ self .footer_text } ({ page_indicator } )" if self .footer_text is not None else page_indicator
221
- )
222
- return footer_txt
223
-
224
248
def update_states (self ) -> None :
225
249
"""
226
250
Disable specific components depending on paginator page and length.
@@ -230,7 +254,20 @@ def update_states(self) -> None:
230
254
if the paginator is on the last page, the jump last/move forward buttons will be disabled.
231
255
"""
232
256
# update the footer
233
- self .embed .set_footer (text = self .get_footer ())
257
+ page_indicator = f"Page { self .index + 1 } /{ len (self ._pages )} "
258
+ if self .footer_text :
259
+ footer_text = f"{ self .footer_text } ({ page_indicator } )"
260
+ else :
261
+ footer_text = page_indicator
262
+
263
+ if self .embed is None :
264
+ self .content = (self .title or "" ) + "\n "
265
+ self .content += self ._pages [self .index ]
266
+ self .content += "\n " + footer_text
267
+
268
+ else :
269
+ self .embed .description = self ._pages [self .index ]
270
+ self .embed .set_footer (text = footer_text )
234
271
235
272
# determine if the jump buttons should be enabled
236
273
more_than_two_pages = len (self ._pages ) > 2
@@ -264,7 +301,10 @@ async def send_page(self, interaction: Interaction) -> None:
264
301
"""Send new page to discord, after updating the view to have properly disabled buttons."""
265
302
self .update_states ()
266
303
267
- await interaction .message .edit (embed = self .embed , view = self )
304
+ if self .embed :
305
+ await interaction .message .edit (embed = self .embed , view = self )
306
+ else :
307
+ await interaction .message .edit (content = self .content , view = self )
268
308
269
309
@ui .button (label = JUMP_FIRST_LABEL , custom_id = "pag_jump_first" , style = ButtonStyle .primary )
270
310
async def go_first (self , _ : Button , interaction : Interaction ) -> None :
0 commit comments