Skip to content
This repository was archived by the owner on Mar 1, 2022. It is now read-only.

Commit 05c1502

Browse files
authored
Add positions to buttons
1 parent 68c08b9 commit 05c1502

File tree

1 file changed

+37
-20
lines changed

1 file changed

+37
-20
lines changed

discord/ext/buttons/buttons.py

Lines changed: 37 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ class Session:
1515
A bool indicating whether or not the session should try to remove reactions after they have been pressed.
1616
"""
1717

18-
def __init__(self,*, timeout: int=180, try_remove: bool=True):
18+
def __init__(self, *, timeout: int = 180, try_remove: bool = True):
1919
self._buttons = {}
2020
self._gather_buttons()
2121

@@ -32,8 +32,14 @@ def __init_subclass__(cls, **kwargs):
3232

3333
def _gather_buttons(self):
3434
for _, member in inspect.getmembers(self):
35-
if hasattr(member, '__button__'):
36-
self._buttons[member.__button__[0]] = member.__button__[1]
35+
if hasattr(member, '__button__'): # Check if the member is a button...
36+
self._buttons[member.__button__[2], member.__button__[0]] = member.__button__[1] # pos, key, value
37+
38+
def sort_buttons(self, *, buttons: dict = None):
39+
if not buttons:
40+
buttons = self.buttons
41+
42+
return {k[1]: v for k, v in sorted(buttons.items(), key=lambda t: t[0])}
3743

3844
async def start(self, ctx, page=None):
3945
"""Start the session with the given page.
@@ -57,14 +63,17 @@ async def start(self, ctx, page=None):
5763
self._session_task = ctx.bot.loop.create_task(self._session(ctx))
5864

5965
async def _session(self, ctx):
66+
self.buttons = self.sort_buttons()
67+
6068
for reaction in self.buttons.keys():
6169
ctx.bot.loop.create_task(self._add_reaction(reaction))
6270

6371
while True:
6472
try:
65-
payload = await ctx.bot.wait_for('raw_reaction_add', timeout=self.timeout, check=lambda _: self.check(_)(ctx))
73+
payload = await ctx.bot.wait_for('raw_reaction_add', timeout=self.timeout,
74+
check=lambda _: self.check(_)(ctx))
6675
except asyncio.TimeoutError:
67-
return await self.cancel(ctx)
76+
return ctx.bot.loop.create_task(self.cancel(ctx))
6877

6978
if self._try_remove:
7079
try:
@@ -110,6 +119,7 @@ def inner(ctx):
110119
elif payload.user_id != ctx.author.id:
111120
return False
112121
return True
122+
113123
return inner
114124

115125

@@ -145,17 +155,17 @@ class Paginator(Session):
145155
Only available when embed=True. The thumbnail URL to set for the embeded pages.
146156
"""
147157

148-
def __init__(self, *, title: str='', length: int=10, entries: list=None,
149-
extra_pages: list=None, prefix: str='', suffix: str='', format: str='',
150-
colour: Union[int, discord.Colour]=discord.Embed.Empty,
151-
color: Union[int, discord.Colour]=discord.Embed.Empty, use_defaults: bool=True, embed: bool=True,
152-
joiner: str='\n', timeout: int=180, thumbnail: str=None):
158+
def __init__(self, *, title: str = '', length: int = 10, entries: list = None,
159+
extra_pages: list = None, prefix: str = '', suffix: str = '', format: str = '',
160+
colour: Union[int, discord.Colour] = discord.Embed.Empty,
161+
color: Union[int, discord.Colour] = discord.Embed.Empty, use_defaults: bool = True, embed: bool = True,
162+
joiner: str = '\n', timeout: int = 180, thumbnail: str = None):
153163
super().__init__()
154-
self._defaults = {'⏮': partial(self._default_indexer, 'start'),
155-
'◀': partial(self._default_indexer, -1),
156-
'⏹': partial(self._default_indexer, 'stop'),
157-
'▶': partial(self._default_indexer, +1),
158-
'⏭': partial(self._default_indexer, 'end')}
164+
self._defaults = {(0, '⏮'): partial(self._default_indexer, 'start'),
165+
(1, '◀'): partial(self._default_indexer, -1),
166+
(2, '⏹'): partial(self._default_indexer, 'stop'),
167+
(3, '▶'): partial(self._default_indexer, +1),
168+
(4, '⏭'): partial(self._default_indexer, 'end')}
159169

160170
self.buttons = {}
161171

@@ -233,14 +243,17 @@ async def _session(self, ctx):
233243
else:
234244
self.buttons = self._buttons
235245

246+
self.buttons = self.sort_buttons()
247+
236248
for reaction in self.buttons.keys():
237249
ctx.bot.loop.create_task(self._add_reaction(reaction))
238250

239251
while True:
240252
try:
241-
payload = await ctx.bot.wait_for('raw_reaction_add', timeout=self.timeout, check=lambda _: self.check(_)(ctx))
253+
payload = await ctx.bot.wait_for('raw_reaction_add', timeout=self.timeout,
254+
check=lambda _: self.check(_)(ctx))
242255
except asyncio.TimeoutError:
243-
return await self.cancel(ctx)
256+
return ctx.bot.loop.create_task(self.cancel(ctx))
244257

245258
if self._try_remove:
246259
try:
@@ -281,24 +294,28 @@ async def _default_indexer(self, control, ctx):
281294
await self.page.edit(content=self._pages[self._index])
282295

283296

284-
def button(emoji: str):
297+
def button(emoji: str, *, position: int = 666):
285298
"""A decorator that adds a button to your interactive session class.
286299
287300
Parameters
288301
-----------
289302
emoji: str
290303
The emoji to use as a button. This could be a unicode endpoint or in name:id format,
291-
for custom emojis
304+
for custom emojis.
305+
position: int
306+
The position to inject the button into.
292307
293308
Raises
294309
-------
295310
TypeError
296311
The button callback is not a coroutine.
297312
"""
313+
298314
def deco(func):
299315
if not asyncio.iscoroutinefunction(func):
300316
raise TypeError('Button callback must be a coroutine.')
301317

302-
func.__button__ = (emoji, func)
318+
func.__button__ = (emoji, func, position)
303319
return func
320+
304321
return deco

0 commit comments

Comments
 (0)