Remove callback parameter from custom.Button

Its behaviour was strange. Removing and adding an event
handler every time a message is sent is not a good idea
and it would just do more harm than good.
This commit is contained in:
Lonami Exo 2018-10-05 20:53:32 +02:00
parent 3dd8b7c6d1
commit 67be6418b6
2 changed files with 33 additions and 52 deletions

View File

@ -37,23 +37,12 @@ class ButtonMethods(UpdateMethods):
for row in buttons: for row in buttons:
current = [] current = []
for button in row: for button in row:
if isinstance(button, custom.MessageButton):
button = button.button
inline = custom.Button._is_inline(button) inline = custom.Button._is_inline(button)
is_inline |= inline is_inline |= inline
is_normal |= not inline is_normal |= not inline
if isinstance(button, custom.Button):
if button.callback:
self.remove_event_handler(
button.callback, events.CallbackQuery)
self.add_event_handler(
button.callback,
events.CallbackQuery(data=getattr(
button.button, 'data', None))
)
button = button.button
elif isinstance(button, custom.MessageButton):
button = button.button
if button.SUBCLASS_OF_ID == 0xbad74a3: if button.SUBCLASS_OF_ID == 0xbad74a3:
# 0xbad74a3 == crc32(b'KeyboardButton') # 0xbad74a3 == crc32(b'KeyboardButton')

View File

@ -18,7 +18,7 @@ class Button:
You should make use of the defined class methods to create button You should make use of the defined class methods to create button
instances instead making them yourself (i.e. don't do ``Button(...)`` instances instead making them yourself (i.e. don't do ``Button(...)``
but instead use methods line `Button.inline(...) <inline>` etc.) but instead use methods line `Button.inline(...) <inline>` etc.
You can use `inline`, `switch_inline` and `url` You can use `inline`, `switch_inline` and `url`
together to create inline buttons (under the message). together to create inline buttons (under the message).
@ -34,36 +34,26 @@ class Button:
to 128 characters and add the ellipsis () character as to 128 characters and add the ellipsis () character as
the 129. the 129.
""" """
def __init__(self, button, callback=None): def __init__(self):
self.button = button raise ValueError('Cannot create instances of this class; '
self.callback = callback 'use the static methods')
self.is_inline = self._is_inline(button)
@classmethod @staticmethod
def _is_inline(cls, button): def _is_inline(button):
""" """
Returns ``True`` if the button belongs to an inline keyboard. Returns ``True`` if the button belongs to an inline keyboard.
""" """
if isinstance(button, cls):
return button.is_inline
elif isinstance(button, MessageButton):
button = button.button
return isinstance(button, ( return isinstance(button, (
types.KeyboardButtonCallback, types.KeyboardButtonCallback,
types.KeyboardButtonSwitchInline, types.KeyboardButtonSwitchInline,
types.KeyboardButtonUrl types.KeyboardButtonUrl
)) ))
@classmethod @staticmethod
def inline(cls, text, callback=None, data=None): def inline(text, data=None):
""" """
Creates a new inline button. Creates a new inline button.
The `callback` parameter should be a function callback accepting
a single parameter (the triggered event on click) if specified.
Otherwise, you should register the event manually.
If `data` is omitted, the given `text` will be used as `data`. If `data` is omitted, the given `text` will be used as `data`.
In any case `data` should be either ``bytes`` or ``str``. In any case `data` should be either ``bytes`` or ``str``.
@ -72,14 +62,16 @@ class Button:
""" """
if not data: if not data:
data = text.encode('utf-8') data = text.encode('utf-8')
elif not isinstance(data, (bytes, bytearray, memoryview)):
data = str(data).encode('utf-8')
if len(data) > 64: if len(data) > 64:
raise ValueError('Too many bytes for the data') raise ValueError('Too many bytes for the data')
return cls(types.KeyboardButtonCallback(text, data), callback) return types.KeyboardButtonCallback(text, data)
@classmethod @staticmethod
def switch_inline(cls, text, query='', same_peer=False): def switch_inline(text, query='', same_peer=False):
""" """
Creates a new button to switch to inline query. Creates a new button to switch to inline query.
@ -90,50 +82,50 @@ class Button:
set under the currently opened chat. Otherwise, the user will set under the currently opened chat. Otherwise, the user will
have to select a different dialog to make the query. have to select a different dialog to make the query.
""" """
return cls(types.KeyboardButtonSwitchInline(text, query, same_peer)) return types.KeyboardButtonSwitchInline(text, query, same_peer)
@classmethod @staticmethod
def url(cls, text, url=None): def url(text, url=None):
""" """
Creates a new button to open the desired URL upon clicking it. Creates a new button to open the desired URL upon clicking it.
If no `url` is given, the `text` will be used as said URL instead. If no `url` is given, the `text` will be used as said URL instead.
""" """
return cls(types.KeyboardButtonUrl(text, url or text)) return types.KeyboardButtonUrl(text, url or text)
@classmethod @staticmethod
def text(cls, text): def text(text):
""" """
Creates a new button with the given text. Creates a new button with the given text.
""" """
return cls(types.KeyboardButton(text)) return types.KeyboardButton(text)
@classmethod @staticmethod
def request_location(cls, text): def request_location(text):
""" """
Creates a new button that will request Creates a new button that will request
the user's location upon being clicked. the user's location upon being clicked.
""" """
return cls(types.KeyboardButtonRequestGeoLocation(text)) return types.KeyboardButtonRequestGeoLocation(text)
@classmethod @staticmethod
def request_phone(cls, text): def request_phone(text):
""" """
Creates a new button that will request Creates a new button that will request
the user's phone number upon being clicked. the user's phone number upon being clicked.
""" """
return cls(types.KeyboardButtonRequestPhone(text)) return types.KeyboardButtonRequestPhone(text)
@classmethod @staticmethod
def clear(cls): def clear():
""" """
Clears all the buttons. When used, no other Clears all the buttons. When used, no other
button should be present or it will be ignored. button should be present or it will be ignored.
""" """
return types.ReplyKeyboardHide() return types.ReplyKeyboardHide()
@classmethod @staticmethod
def force_reply(cls): def force_reply():
""" """
Forces a reply. If used, no other button Forces a reply. If used, no other button
should be present or it will be ignored. should be present or it will be ignored.