Compare commits
	
		
			7 Commits
		
	
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | 3201026242 | ||
|  | f7398c9acd | ||
|  | d06bfce837 | ||
|  | cb782ce3d8 | ||
|  | fae85d072f | ||
|  | c74fd90a9c | ||
|  | 7228ef64a5 | 
							
								
								
									
										210
									
								
								examples/views/paginator.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										210
									
								
								examples/views/paginator.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,210 @@ | |||||||
|  | import discord | ||||||
|  | from discord.ext import commands | ||||||
|  | from discord import ButtonStyle, Embed, Interaction | ||||||
|  | from discord.ui import Button, View | ||||||
|  |  | ||||||
|  |  | ||||||
|  | class Bot(commands.Bot): | ||||||
|  |     def __init__(self): | ||||||
|  |         super().__init__( | ||||||
|  |             command_prefix=commands.when_mentioned_or("$"), intents=discord.Intents(guilds=True, messages=True) | ||||||
|  |         ) | ||||||
|  |  | ||||||
|  |     async def on_ready(self): | ||||||
|  |         print(f"Logged in as {self.user} (ID: {self.user.id})") | ||||||
|  |         print("------") | ||||||
|  |  | ||||||
|  |  | ||||||
|  | # Define 3 View subclasses that we will switch between depending on if we are viewing the first page, a page in the middle, or the last page. | ||||||
|  | # The first page has the "left" button disabled, because there is no left page to go to | ||||||
|  | class FirstPageComps(View): | ||||||
|  |     def __init__( | ||||||
|  |         self, | ||||||
|  |         author_id: int, | ||||||
|  |     ): | ||||||
|  |         super().__init__() | ||||||
|  |         self.value = None | ||||||
|  |         self.author_id = author_id | ||||||
|  |  | ||||||
|  |     async def interaction_check( | ||||||
|  |         self, | ||||||
|  |         interaction: Interaction, | ||||||
|  |     ): | ||||||
|  |         return interaction.user.id == self.author_id | ||||||
|  |  | ||||||
|  |     @discord.ui.button( | ||||||
|  |         style=ButtonStyle.primary, | ||||||
|  |         disabled=True, | ||||||
|  |         label="Left", | ||||||
|  |     ) | ||||||
|  |     async def left( | ||||||
|  |         self, | ||||||
|  |         button: discord.ui.Button, | ||||||
|  |         interaction: Interaction, | ||||||
|  |     ): | ||||||
|  |         self.value = "left" | ||||||
|  |         self.stop() | ||||||
|  |  | ||||||
|  |     @discord.ui.button( | ||||||
|  |         style=ButtonStyle.primary, | ||||||
|  |         label="Right", | ||||||
|  |     ) | ||||||
|  |     async def right( | ||||||
|  |         self, | ||||||
|  |         button: discord.ui.Button, | ||||||
|  |         interaction: Interaction, | ||||||
|  |     ): | ||||||
|  |         self.value = "right" | ||||||
|  |         self.stop() | ||||||
|  |  | ||||||
|  |  | ||||||
|  | # The middle pages have both left and right buttons available | ||||||
|  | class MiddlePageComps(View): | ||||||
|  |     def __init__( | ||||||
|  |         self, | ||||||
|  |         author_id: int, | ||||||
|  |     ): | ||||||
|  |         super().__init__() | ||||||
|  |         self.value = None | ||||||
|  |         self.author_id = author_id | ||||||
|  |  | ||||||
|  |     async def interaction_check( | ||||||
|  |         self, | ||||||
|  |         interaction: Interaction, | ||||||
|  |     ): | ||||||
|  |         return interaction.user.id == self.author_id | ||||||
|  |  | ||||||
|  |     @discord.ui.button( | ||||||
|  |         style=ButtonStyle.primary, | ||||||
|  |         label="Left", | ||||||
|  |     ) | ||||||
|  |     async def left( | ||||||
|  |         self, | ||||||
|  |         button: discord.ui.Button, | ||||||
|  |         interaction: Interaction, | ||||||
|  |     ): | ||||||
|  |         self.value = "left" | ||||||
|  |         self.stop() | ||||||
|  |  | ||||||
|  |     @discord.ui.button( | ||||||
|  |         style=ButtonStyle.primary, | ||||||
|  |         label="Right", | ||||||
|  |     ) | ||||||
|  |     async def right( | ||||||
|  |         self, | ||||||
|  |         button: discord.ui.Button, | ||||||
|  |         interaction: Interaction, | ||||||
|  |     ): | ||||||
|  |         self.value = "right" | ||||||
|  |         self.stop() | ||||||
|  |  | ||||||
|  |  | ||||||
|  | # The last page has the right button disabled, because there's no right page to go to | ||||||
|  | class LastPageComps(View): | ||||||
|  |     def __init__( | ||||||
|  |         self, | ||||||
|  |         author_id: int, | ||||||
|  |     ): | ||||||
|  |         super().__init__() | ||||||
|  |         self.value = None | ||||||
|  |         self.author_id = author_id | ||||||
|  |  | ||||||
|  |     async def interaction_check( | ||||||
|  |         self, | ||||||
|  |         interaction: Interaction, | ||||||
|  |     ): | ||||||
|  |         return interaction.user.id == self.author_id | ||||||
|  |  | ||||||
|  |     @discord.ui.button( | ||||||
|  |         style=ButtonStyle.primary, | ||||||
|  |         label="Left", | ||||||
|  |     ) | ||||||
|  |     async def left( | ||||||
|  |         self, | ||||||
|  |         button: discord.ui.Button, | ||||||
|  |         interaction: Interaction, | ||||||
|  |     ): | ||||||
|  |         self.value = "left" | ||||||
|  |         self.stop() | ||||||
|  |  | ||||||
|  |     @discord.ui.button( | ||||||
|  |         style=ButtonStyle.primary, | ||||||
|  |         label="Right", | ||||||
|  |         disabled=True, | ||||||
|  |     ) | ||||||
|  |     async def right( | ||||||
|  |         self, | ||||||
|  |         button: discord.ui.Button, | ||||||
|  |         interaction: Interaction, | ||||||
|  |     ): | ||||||
|  |         self.value = "right" | ||||||
|  |         self.stop() | ||||||
|  |  | ||||||
|  |  | ||||||
|  | # Now we define the function that will take care of the pagination for us. It will take a list of Embeds and allow the user to cycle between them using left/right buttons | ||||||
|  | # There is also an optional title parameter in case you want to give your paginator a title, it will display in the embed title, for example if the title is Book | ||||||
|  | # then the title will look like "Book | Page 1/2". This is very optional and can be removed | ||||||
|  | async def paginate( | ||||||
|  |     ctx, | ||||||
|  |     pages: list, | ||||||
|  |     title: str = None, | ||||||
|  | ): | ||||||
|  |  | ||||||
|  |     total_pages = len(pages) | ||||||
|  |     first_page = pages[0] | ||||||
|  |     last_page = pages[-1] | ||||||
|  |     current_page = first_page | ||||||
|  |     index = 0 | ||||||
|  |  | ||||||
|  |     embed = first_page | ||||||
|  |     if title: | ||||||
|  |         embed.title = f"{title} | Page {index+1}/{total_pages}" | ||||||
|  |  | ||||||
|  |     view = FirstPageComps(ctx.author.id) | ||||||
|  |     # Here we send the message with the view of the first page and the FirstPageComps buttons | ||||||
|  |     msg = await ctx.send( | ||||||
|  |         embed=embed, | ||||||
|  |         view=view, | ||||||
|  |     ) | ||||||
|  |  | ||||||
|  |     # The default timeout for Views is 3 minutes, but if a user selects to scroll between pages the timer will be reset. | ||||||
|  |     # If the timer reaches 0, though, the loop will just silently stop. | ||||||
|  |     while True: | ||||||
|  |         wait = await view.wait() | ||||||
|  |         if wait: | ||||||
|  |             return | ||||||
|  |  | ||||||
|  |         if view.value == "right": | ||||||
|  |             index += 1 | ||||||
|  |             current_page = pages[index] | ||||||
|  |             view = MiddlePageComps(ctx.author.id) if current_page != last_page else LastPageComps(ctx.author.id) | ||||||
|  |             embed = current_page | ||||||
|  |             if title: | ||||||
|  |                 embed.title = f"{title} | Page {index+1}/{total_pages}" | ||||||
|  |  | ||||||
|  |         elif view.value == "left": | ||||||
|  |             index -= 1 | ||||||
|  |             current_page = pages[index] | ||||||
|  |             view = MiddlePageComps(ctx.author.id) if current_page != first_page else FirstPageComps(ctx.author.id) | ||||||
|  |             embed = current_page | ||||||
|  |             if title: | ||||||
|  |                 embed.title = f"{title} | Page {index+1}/{total_pages}" | ||||||
|  |  | ||||||
|  |         await msg.edit( | ||||||
|  |             embed=embed, | ||||||
|  |             view=view, | ||||||
|  |         ) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | bot = Bot() | ||||||
|  |  | ||||||
|  | # To test our new function, let's create a list of a couple Embeds and let our paginator deal with the sending and buttons | ||||||
|  | @bot.command() | ||||||
|  | async def sendpages(ctx): | ||||||
|  |     page1 = Embed(description="This is page 1") | ||||||
|  |     page2 = Embed(description="This is page 2") | ||||||
|  |     page3 = Embed(description="This is page 3") | ||||||
|  |     await paginate(ctx, [page1, page2, page3]) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | bot.run("token") | ||||||
		Reference in New Issue
	
	Block a user