Skip to main content

A reactive declarative UI and threading utility library for exteraGram / Telegram plugins.

Project description

exteragram-alib 🚀

Мощная библиотека реактивного декларативного UI и утилит управления потоками для разработки плагинов exteraGram (Android-клиент Telegram).

A powerful reactive declarative UI and threading utility library for writing exteraGram (Android Telegram client) plugins.


Содержание / Table of Contents

  1. Установка / Installation
  2. Реактивное состояние / Reactive States (State)
  3. Декларативный UI / Declarative UI
  4. Интерактивные виджеты / Interactive Widgets
  5. Контейнеры разметки / Layout Containers
  6. Экран настроек / Settings Wrapper (to_setting)
  7. Всплывающие экраны / Bottom Sheets
  8. Управление потоками / Threading & Dispatching

1. Установка / Installation

Укажите библиотеку в списке внешних зависимостей вашего плагина в переменной __requirements__ (exteraGram автоматически скачает её при установке плагина): Add the library to the __requirements__ metadata list in your exteraGram plugin:

__requirements__ = ["exteragram-alib"]

2. Реактивное состояние / Reactive States (State)

Класс State связывает переменные с UI-компонентами. При обновлении значения через .set(), все подписанные элементы интерфейса автоматически перерисовываются на Android-устройстве.

from alib import State

# Инициализация состояния
my_state = State("Начальный текст")

# Получение значения
current_val = my_state.get()

# Обновление значения (вызывает автоматическую перерисовку привязанных UI-элементов)
my_state.set("Новый реактивный текст")

# Подписка на изменение вручную (если необходимо)
def on_change(val):
    print(f"Значение изменилось на: {val}")

my_state.add_listener(on_change)

3. Декларативный UI / Declarative UI

Каждый виджет наследуется от базового класса Widget и поддерживает следующие настройки макета (layout properties):

  • width"match" (по всей ширине), "wrap" (по размеру содержимого) или числовое значение в dp.
  • height"match", "wrap" или числовое значение в dp.
  • weight — вес элемента в распределении пространства (float, например 1.0).
  • gravity — выравнивание (используется из android.view.Gravity).
  • margins — внешние отступы в формате списка [left, top, right, bottom] в dp.
  • padding — внутренние отступы в формате списка [left, top, right, bottom] в dp.

4. Интерактивные виджеты / Interactive Widgets

Label (Текст)

Обычное текстовое поле. Может принимать State в качестве параметра text для реактивного обновления.

from alib import Label

lbl = Label(
    text=my_state,          # Текст или реактивный State
    text_size=15,           # Размер шрифта в sp
    color=0xFF3390EC,       # Цвет текста в формате ARGB/HEX
    bold=True               # Жирный шрифт (True/False)
)

Button (Кнопка)

Простая кликабельная кнопка.

from alib import Button

btn = Button(
    text="Нажми меня",
    on_click=lambda view: print("Кнопка нажата!"),
    padding=[8, 16, 8, 16]
)

Field (Поле ввода)

Поле текстового ввода. Позволяет реактивно синхронизировать текст с State.

from alib import Field

field = Field(
    text=my_text_state,     # Привязанный State для двусторонней синхронизации
    hint="Введите имя..."   # Подсказка
)

Toggle (Переключатель)

Двухпозиционный переключатель (активен/неактивен).

from alib import Toggle

toggle = Toggle(
    value=my_boolean_state, # Привязанный boolean State
    on_change=lambda val: print(f"Новое состояние: {val}")
)

Radio (Радио-кнопка)

Круглая радио-кнопка для выбора из вариантов.

from alib import Radio

# radio_state принимает checked_value при выборе
radio = Radio(
    value=radio_state,       # Общий State выбора
    checked_value=1,         # Значение данного варианта
    on_change=lambda val: print(f"Выбран вариант: {val}")
)

Selector (Выпадающий список)

Строка выбора значения. При нажатии открывает системный AlertDialog со списком вариантов.

from alib import Selector

sel = Selector(
    text="Выбор языка",
    items=["Русский", "English", "Deutsch"],
    value=lang_index_state,   # Реактивный State (хранит индекс выбранного элемента)
    icon="msg_language",      # Иконка Telegram
    on_change=lambda idx: print(f"Выбран индекс: {idx}")
)

Slider (Слайдер)

Слайдер для выбора числового значения.

from alib import Slider

slider = Slider(
    value=num_state,          # Привязанный State (int)
    min_val=12,               # Минимальное значение
    max_val=30,               # Максимальное значение
    to_string=lambda label_type, val: f"Шрифт: {val}sp"  # Форматирование отображения
)

AltSeekbar (Альтернативный слайдер)

Слайдер с отображением заголовка и крайних текстовых значений (слева/справа).

from alib import AltSeekbar

alt_slider = AltSeekbar(
    value=float_state,
    min_val=0,
    max_val=28,
    title="Скругление углов",
    left_text="0%",
    right_text="100%",
    on_change=lambda val: print(f"Значение изменено: {val}")
)

RowItem (Ячейка списка)

Строка в стиле настроек Telegram. Поддерживает иконку, заголовок, описание и правый виджет.

from alib import RowItem, Toggle

row = RowItem(
    title="Оповещения",
    subtext="Включить всплывающие уведомления чатов",
    icon="msg_notifications",
    right_widget=Toggle(value=notif_state)
)

ActionRow (Ячейка действия)

Ячейка со встроенной кнопкой действия справа.

from alib import ActionRow

action = ActionRow(
    title="Счетчик кликов",
    subtext=click_counter_state, # Реактивный текст
    button_text="Кликнуть",      # Текст на кнопке
    icon="msg_folders",          # Иконка слева
    on_button_click=lambda view: click_counter_state.set(click_counter_state.get() + 1)
)

5. Контейнеры разметки / Layout Containers

VBox (Вертикальный контейнер)

Размещает дочерние элементы вертикально один под другим.

from alib import VBox

vbox = VBox(
    padding=[16, 16, 16, 16], # Внутренние отступы
    children=[widget1, widget2]
)

HBox (Горизонтальный контейнер)

Размещает дочерние элементы горизонтально в ряд.

from alib import HBox

hbox = HBox(
    children=[widget1, widget2]
)

Card (Карточка/Секция)

Контейнер со скругленными углами и фоном. По умолчанию автоматически отрисовывает разделительные линии (Divider) между дочерними элементами.

from alib import Card, RowItem, Toggle

card = Card(
    radius=20,               # Радиус скругления углов карточки
    show_dividers=True,      # Показывать разделители между ячейками
    children=[
        RowItem(title="Пункт 1", right_widget=Toggle(value=s1)),
        RowItem(title="Пункт 2", right_widget=Toggle(value=s2)),
    ]
)

6. Экран настроек / Settings Wrapper (to_setting)

Для внедрения кастомных декларативных UI-интерфейсов на стандартный экран настроек плагина в exteraGram, оберните виджет функцией to_setting():

from alib import to_setting, RowItem, Toggle

class MyPlugin(BasePlugin):
    def create_settings(self) -> List[Any]:
        return [
            to_setting(
                RowItem(title="Включить хуки", right_widget=Toggle(value=self.state))
            )
        ]

[!IMPORTANT] Важно: На стандартном экране настроек плагина (create_settings) exteraGram автоматически группирует возвращаемые элементы в системные карточки. Не оборачивайте элементы в контейнер Card внутри create_settings вручную, иначе это приведет к двойному вложению карточек.

Класс Card предназначен главным образом для использования внутри всплывающих окон (show_bottom_sheet), где группировка по умолчанию отсутствует и карточки нужно собирать вручную.


7. Всплывающие экраны / Bottom Sheets

Функция show_bottom_sheet() позволяет отобразить кастомный диалог в стиле BottomSheet Telegram поверх любого экрана приложения. Она автоматически обрабатывает жесты смахивания вниз для закрытия с учетом состояния прокрутки.

from alib import show_bottom_sheet, VBox, Header, Card, Button

def open_my_sheet(fragment):
    sheet_layout = VBox(
        padding=[0, 0, 0, 16],
        children=[
            Header(text="Кастомное меню"),
            Card(children=[...])
        ]
    )
    
    # Возвращает экземпляр BottomSheet диалога
    sheet = show_bottom_sheet(
        fragment=fragment,      # Контекст/фрагмент Telegram
        title="Мой Заголовок",   # Текст заголовка
        content_layout=sheet_layout, # Корневой декларативный виджет
        center_header=True,     # Центрировать ли заголовок
        height_pct=0.8          # Высота экрана (80% от высоты экрана)
    )

8. Управление потоками / Threading & Dispatching

Упрощает асинхронное выполнение задач и потокобезопасную работу с интерфейсом.

@main_thread (алиас @run_on_ui)

Декоратор перенаправляет выполнение функции в главный (UI) поток Android для безопасного взаимодействия с интерфейсом.

from alib import main_thread

@main_thread
def update_status(message: str):
    # Этот код гарантированно выполнится на UI-потоке Android
    status_label.set(message)

@background_thread (алиас @run_on_background)

Декоратор запускает функцию асинхронно в одной из фоновых очередей Telegram с возможностью задержки.

  • queue — имя очереди: "plugins" (по умолчанию), "global", "network", "search".
  • delay — задержка запуска в миллисекундах (по умолчанию 0).
from alib import background_thread

@background_thread(queue="network", delay=1500)
def load_web_data():
    # Запустится через 1.5 секунды в фоне на сетевом потоке
    result = make_api_request()
    update_status(result) # Отправляем результат обратно на UI-поток

Запуск анонимных функций (run_main и run_bg)

Если не нужно создавать именованную функцию с декоратором, используйте хелперы:

from alib import run_main, run_bg

# Выполнить в фоне
run_bg(lambda: save_cache_to_disk(), queue="plugins", delay=500)

# Вернуть управление на UI
run_main(lambda: show_success_toast())

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

exteragram_alib-1.0.2.tar.gz (23.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

exteragram_alib-1.0.2-py3-none-any.whl (19.0 kB view details)

Uploaded Python 3

File details

Details for the file exteragram_alib-1.0.2.tar.gz.

File metadata

  • Download URL: exteragram_alib-1.0.2.tar.gz
  • Upload date:
  • Size: 23.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.5

File hashes

Hashes for exteragram_alib-1.0.2.tar.gz
Algorithm Hash digest
SHA256 645e0a2e062c4ab7ac0c0dc2594f2b0e5c15a7a611396209f22c5e7d2f0b9a63
MD5 bd7d93b84504cb916e3f315a11205d96
BLAKE2b-256 fced07c600e62c57534cf3965e215c928c4dfff515fa1a8878913e2b9aeda8c9

See more details on using hashes here.

File details

Details for the file exteragram_alib-1.0.2-py3-none-any.whl.

File metadata

File hashes

Hashes for exteragram_alib-1.0.2-py3-none-any.whl
Algorithm Hash digest
SHA256 ba1b4f5d7ddc0ca647b9ded3d6754b4d5de504827300a19dccd531c83e8ccb7a
MD5 ef02a96cb85f6473eb345b9531263b1a
BLAKE2b-256 dc048e42cd992738e381603e447b5594d4a40b95f038282803904e8f0098adc2

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page