from aiogram.utils.keyboard import InlineKeyboardBuilder, InlineKeyboardButton from aiogram.types import InlineKeyboardMarkup, WebAppInfo from typing import Dict, Optional, List, Tuple from config.settings import Settings def get_main_menu_inline_keyboard( lang: str, i18n_instance, settings: Settings, show_trial_button: bool = False) -> InlineKeyboardMarkup: _ = lambda key, **kwargs: i18n_instance.gettext(lang, key, **kwargs) builder = InlineKeyboardBuilder() if show_trial_button and settings.TRIAL_ENABLED: builder.row( InlineKeyboardButton(text=_(key="menu_activate_trial_button"), callback_data="main_action:request_trial")) builder.row( InlineKeyboardButton(text=_(key="menu_subscribe_inline"), callback_data="main_action:subscribe")) builder.row( InlineKeyboardButton( text=_(key="menu_my_subscription_inline"), callback_data="main_action:my_subscription", ) ) referral_button = InlineKeyboardButton( text=_(key="menu_referral_inline"), callback_data="main_action:referral") promo_button = InlineKeyboardButton( text=_(key="menu_apply_promo_button"), callback_data="main_action:apply_promo") builder.row(referral_button, promo_button) language_button = InlineKeyboardButton( text=_(key="menu_language_settings_inline"), callback_data="main_action:language") status_button_list = [] if settings.SERVER_STATUS_URL: status_button_list.append( InlineKeyboardButton(text=_(key="menu_server_status_button"), url=settings.SERVER_STATUS_URL)) if status_button_list: builder.row(language_button, *status_button_list) else: builder.row(language_button) if settings.SUPPORT_LINK: builder.row( InlineKeyboardButton(text=_(key="menu_support_button"), url=settings.SUPPORT_LINK)) if settings.TERMS_OF_SERVICE_URL: builder.row( InlineKeyboardButton(text=_(key="menu_terms_button"), url=settings.TERMS_OF_SERVICE_URL)) return builder.as_markup() def get_language_selection_keyboard(i18n_instance, current_lang: str) -> InlineKeyboardMarkup: _ = lambda key, **kwargs: i18n_instance.gettext(current_lang, key, **kwargs ) builder = InlineKeyboardBuilder() builder.button(text=f"🇬🇧 English {'✅' if current_lang == 'en' else ''}", callback_data="set_lang_en") builder.button(text=f"🇷🇺 Русский {'✅' if current_lang == 'ru' else ''}", callback_data="set_lang_ru") builder.button(text=_(key="back_to_main_menu_button"), callback_data="main_action:back_to_main") builder.adjust(1) return builder.as_markup() def get_trial_confirmation_keyboard(lang: str, i18n_instance) -> InlineKeyboardMarkup: _ = lambda key, **kwargs: i18n_instance.gettext(lang, key, **kwargs) builder = InlineKeyboardBuilder() builder.button(text=_(key="trial_confirm_activate_button"), callback_data="trial_action:confirm_activate") builder.button(text=_(key="cancel_button"), callback_data="main_action:back_to_main") builder.adjust(1) return builder.as_markup() def get_subscription_options_keyboard(subscription_options: Dict[ int, Optional[int]], currency_symbol_val: str, lang: str, i18n_instance) -> InlineKeyboardMarkup: _ = lambda key, **kwargs: i18n_instance.gettext(lang, key, **kwargs) builder = InlineKeyboardBuilder() if subscription_options: for months, price in subscription_options.items(): if price is not None: button_text = _("subscribe_for_months_button", months=months, price=price, currency_symbol=currency_symbol_val) builder.button(text=button_text, callback_data=f"subscribe_period:{months}") builder.adjust(1) builder.row( InlineKeyboardButton(text=_(key="back_to_main_menu_button"), callback_data="main_action:back_to_main")) return builder.as_markup() def get_payment_method_keyboard(months: int, price: float, tribute_url: Optional[str], stars_price: Optional[int], currency_symbol_val: str, lang: str, i18n_instance, settings: Settings) -> InlineKeyboardMarkup: _ = lambda key, **kwargs: i18n_instance.gettext(lang, key, **kwargs) builder = InlineKeyboardBuilder() if settings.STARS_ENABLED and stars_price is not None: builder.button(text=_("pay_with_stars_button"), callback_data=f"pay_stars:{months}:{stars_price}") if settings.TRIBUTE_ENABLED and tribute_url: builder.button(text=_("pay_with_tribute_button"), url=tribute_url) if settings.YOOKASSA_ENABLED: builder.button(text=_("pay_with_yookassa_button"), callback_data=f"pay_yk:{months}:{price}") if settings.CRYPTOPAY_ENABLED: builder.button(text=_("pay_with_cryptopay_button"), callback_data=f"pay_crypto:{months}:{price}") builder.button(text=_(key="cancel_button"), callback_data="main_action:subscribe") builder.adjust(1) return builder.as_markup() def get_payment_url_keyboard(payment_url: str, lang: str, i18n_instance) -> InlineKeyboardMarkup: _ = lambda key, **kwargs: i18n_instance.gettext(lang, key, **kwargs) builder = InlineKeyboardBuilder() builder.button(text=_(key="pay_button"), url=payment_url) builder.button(text=_(key="back_to_main_menu_button"), callback_data="main_action:back_to_main") builder.adjust(1) return builder.as_markup() def get_referral_link_keyboard(lang: str, i18n_instance) -> InlineKeyboardMarkup: _ = lambda key, **kwargs: i18n_instance.gettext(lang, key, **kwargs) builder = InlineKeyboardBuilder() builder.button(text=_(key="referral_share_message_button"), callback_data="referral_action:share_message") builder.button(text=_(key="back_to_main_menu_button"), callback_data="main_action:back_to_main") builder.adjust(1) return builder.as_markup() def get_back_to_main_menu_markup(lang: str, i18n_instance, callback_data: Optional[str] = None) -> InlineKeyboardMarkup: _ = lambda key, **kwargs: i18n_instance.gettext(lang, key, **kwargs) builder = InlineKeyboardBuilder() if callback_data: builder.button(text=_(key="back_to_main_menu_button"), callback_data=callback_data) else: builder.button(text=_(key="back_to_main_menu_button"), callback_data="main_action:back_to_main") return builder.as_markup() def get_subscribe_only_markup(lang: str, i18n_instance) -> InlineKeyboardMarkup: _ = lambda key, **kwargs: i18n_instance.gettext(lang, key, **kwargs) builder = InlineKeyboardBuilder() builder.button(text=_(key="menu_subscribe_inline"), callback_data="main_action:subscribe") return builder.as_markup() def get_user_banned_keyboard(support_link: Optional[str], lang: str, i18n_instance) -> Optional[InlineKeyboardMarkup]: if not support_link: return None _ = lambda key, **kwargs: i18n_instance.gettext(lang, key, **kwargs) builder = InlineKeyboardBuilder() builder.button(text=_(key="menu_support_button"), url=support_link) return builder.as_markup() def get_connect_and_main_keyboard( lang: str, i18n_instance, settings: Settings, config_link: Optional[str]) -> InlineKeyboardMarkup: """Keyboard with a connect button and a back to main menu button.""" _ = lambda key, **kwargs: i18n_instance.gettext(lang, key, **kwargs) builder = InlineKeyboardBuilder() if settings.SUBSCRIPTION_MINI_APP_URL: builder.row( InlineKeyboardButton( text=_("connect_button"), web_app=WebAppInfo(url=settings.SUBSCRIPTION_MINI_APP_URL), ) ) elif config_link: builder.row( InlineKeyboardButton(text=_("connect_button"), url=config_link) ) else: builder.row( InlineKeyboardButton( text=_("connect_button"), callback_data="main_action:my_subscription", ) ) builder.row( InlineKeyboardButton( text=_("back_to_main_menu_button"), callback_data="main_action:back_to_main", ) ) return builder.as_markup() def get_payment_methods_manage_keyboard(lang: str, i18n_instance, has_card: bool) -> InlineKeyboardMarkup: """Deprecated in favor of get_payment_methods_list_keyboard. Kept for backward compatibility.""" _ = lambda key, **kwargs: i18n_instance.gettext(lang, key, **kwargs) builder = InlineKeyboardBuilder() builder.row( InlineKeyboardButton(text=_(key="payment_method_bind_button"), callback_data="pm:bind") ) builder.row( InlineKeyboardButton(text=_(key="back_to_main_menu_button"), callback_data="main_action:back_to_main") ) return builder.as_markup() def get_payment_methods_list_keyboard( cards: List[Tuple[str, str]], page: int, lang: str, i18n_instance, ) -> InlineKeyboardMarkup: """ Build a paginated list of saved payment methods. cards: list of tuples (payment_method_id, display_title) page: 0-based page index """ _ = lambda key, **kwargs: i18n_instance.gettext(lang, key, **kwargs) builder = InlineKeyboardBuilder() per_page = 5 total = len(cards) start = page * per_page end = start + per_page for pm_id, title in cards[start:end]: builder.row( InlineKeyboardButton(text=title, callback_data=f"pm:view:{pm_id}") ) # Pagination controls if needed nav_buttons: List[InlineKeyboardButton] = [] if start > 0: nav_buttons.append(InlineKeyboardButton(text="⬅️", callback_data=f"pm:list:{page-1}")) if end < total: nav_buttons.append(InlineKeyboardButton(text="➡️", callback_data=f"pm:list:{page+1}")) if nav_buttons: builder.row(*nav_buttons) # Bind new card and back builder.row(InlineKeyboardButton(text=_(key="payment_method_bind_button"), callback_data="pm:bind")) builder.row(InlineKeyboardButton(text=_(key="back_to_main_menu_button"), callback_data="main_action:back_to_main")) return builder.as_markup() def get_payment_method_delete_confirm_keyboard(pm_id: str, lang: str, i18n_instance) -> InlineKeyboardMarkup: _ = lambda key, **kwargs: i18n_instance.gettext(lang, key, **kwargs) builder = InlineKeyboardBuilder() builder.row( InlineKeyboardButton(text=_(key="yes_button"), callback_data=f"pm:delete:{pm_id}"), InlineKeyboardButton(text=_(key="cancel_button"), callback_data=f"pm:view:{pm_id}"), ) return builder.as_markup() def get_payment_method_details_keyboard(pm_id: str, lang: str, i18n_instance) -> InlineKeyboardMarkup: _ = lambda key, **kwargs: i18n_instance.gettext(lang, key, **kwargs) builder = InlineKeyboardBuilder() builder.row( InlineKeyboardButton(text=_(key="payment_method_tx_history_title"), callback_data=f"pm:history:{pm_id}") ) builder.row( InlineKeyboardButton(text=_(key="payment_method_delete_button"), callback_data=f"pm:delete_confirm:{pm_id}") ) builder.row( InlineKeyboardButton(text=_(key="back_to_main_menu_button"), callback_data="pm:list:0") ) return builder.as_markup() def get_bind_url_keyboard(bind_url: str, lang: str, i18n_instance) -> InlineKeyboardMarkup: _ = lambda key, **kwargs: i18n_instance.gettext(lang, key, **kwargs) builder = InlineKeyboardBuilder() builder.button(text=_(key="payment_method_bind_button"), url=bind_url) builder.button(text=_(key="back_to_main_menu_button"), callback_data="pm:manage") builder.adjust(1) return builder.as_markup() def get_back_to_payment_methods_keyboard(lang: str, i18n_instance) -> InlineKeyboardMarkup: _ = lambda key, **kwargs: i18n_instance.gettext(lang, key, **kwargs) builder = InlineKeyboardBuilder() builder.row(InlineKeyboardButton(text=_(key="back_to_main_menu_button"), callback_data="pm:list:0")) return builder.as_markup() def get_back_to_payment_method_details_keyboard(pm_id: str, lang: str, i18n_instance) -> InlineKeyboardMarkup: _ = lambda key, **kwargs: i18n_instance.gettext(lang, key, **kwargs) builder = InlineKeyboardBuilder() # Back one step: return to specific payment method details builder.row(InlineKeyboardButton(text=_(key="back_to_main_menu_button"), callback_data=f"pm:view:{pm_id}")) return builder.as_markup() def get_autorenew_cancel_keyboard(lang: str, i18n_instance) -> InlineKeyboardMarkup: _ = lambda key, **kwargs: i18n_instance.gettext(lang, key, **kwargs) builder = InlineKeyboardBuilder() builder.row( InlineKeyboardButton(text=_(key="autorenew_disable_button"), callback_data="autorenew:cancel") ) builder.row( InlineKeyboardButton(text=_(key="menu_my_subscription_inline"), callback_data="main_action:my_subscription") ) return builder.as_markup() def get_autorenew_confirm_keyboard(enable: bool, sub_id: int, lang: str, i18n_instance) -> InlineKeyboardMarkup: _ = lambda key, **kwargs: i18n_instance.gettext(lang, key, **kwargs) builder = InlineKeyboardBuilder() builder.row( InlineKeyboardButton(text=_(key="yes_button"), callback_data=f"autorenew:confirm:{sub_id}:{1 if enable else 0}"), InlineKeyboardButton(text=_(key="no_button"), callback_data="main_action:my_subscription"), ) return builder.as_markup()