Skip to content

Instantly share code, notes, and snippets.

@Tishka17
Last active June 20, 2022 08:08
Show Gist options
  • Save Tishka17/ce8b0c8c581a19ba583bb438c9f51f39 to your computer and use it in GitHub Desktop.
Save Tishka17/ce8b0c8c581a19ba583bb438c9f51f39 to your computer and use it in GitHub Desktop.
Counter widget for aiogram_dialog
from typing import List, Dict
from aiogram.types import InlineKeyboardButton, CallbackQuery
from aiogram_dialog.dialog import Dialog
from aiogram_dialog.manager.protocols import DialogManager
from aiogram_dialog.widgets.kbd.base import Keyboard
from aiogram_dialog.widgets.managed import ManagedWidgetAdapter
from aiogram_dialog.widgets.text import Const, Format
from aiogram_dialog.widgets.when import WhenCondition
class Counter(Keyboard):
def __init__(
self, id: str,
plus=Const("+"), minus=Const("-"), text=Format("{value:g}"),
min_value: float = 0, max_value: float = 999999,
increment=1, default=0, number_format="{0:g}",
when: WhenCondition = None,
):
super().__init__(id=id, when=when)
self.plus = plus
self.minus = minus
self.min = min_value
self.max = max_value
self.increment = increment
self.default = default
self.number_format = number_format
self.text = text
def get_value(self, manager: DialogManager) -> float:
return manager.current_context().widget_data.get(
self.widget_id, self.default
)
async def set_value(self, manager: DialogManager, value: float) -> None:
if self.min <= value <= self.max:
manager.current_context().widget_data[self.widget_id] = value
async def _render_keyboard(
self, data: Dict, manager: DialogManager,
) -> List[List[InlineKeyboardButton]]:
plus = await self.plus.render_text(data, manager)
minus = await self.minus.render_text(data, manager)
text = await self.text.render_text(
{"value": self.get_value(manager), "data": data},
manager,
)
return [[
InlineKeyboardButton(text=minus,
callback_data=f"{self.widget_id}:-"),
InlineKeyboardButton(text=text,
callback_data=f"{self.widget_id}:"),
InlineKeyboardButton(text=plus,
callback_data=f"{self.widget_id}:+"),
]]
async def process_callback(self, c: CallbackQuery, dialog: Dialog,
manager: DialogManager) -> bool:
prefix = f"{self.widget_id}:"
if not c.data.startswith(prefix):
return False
cmd = c.data[len(prefix):]
print("cmd", cmd, )
value = self.get_value(manager)
if cmd == "+":
await self.set_value(manager, value + self.increment)
elif cmd == "-":
await self.set_value(manager, value - self.increment)
return True
def get_page(self, manager: DialogManager) -> int:
return manager.current_context().widget_data.get(self.widget_id, 0)
def managed(self, manager: DialogManager):
return ManagedCounterAdapter(self, manager)
class ManagedCounterAdapter(ManagedWidgetAdapter[Counter]):
def get_value(self) -> float:
return self.widget.get_value(self.manager)
async def set_value(self, value: float) -> None:
await self.widget.set_value(self.manager, value)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment