From 231081dd2f5d027813cf41fa5adf190d5a025a93 Mon Sep 17 00:00:00 2001 From: Evgeny Date: Wed, 24 Jun 2026 13:50:10 +0300 Subject: [PATCH] docs: add chatgui animated emoji system and tdesktop-dev reference to AGENTS.md --- AGENTS.md | 137 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 137 insertions(+) diff --git a/AGENTS.md b/AGENTS.md index dbf8822d..9b25af0e 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -211,6 +211,8 @@ SOCKET=14, CONTROL=15, DUMP=16, TRAFFIC=17, DEBUG=18, GENERAL=19, NAT=20 ├── doc/ # Technical Specifications ├── tools/ # Auxiliary tools │ ├── etcpmon/ # GUI монитор ETCP +│ ├── chatgui/ # GUI чат (Qt 5, отдельная сборка через CMake) +│ ├── tdesktop-dev/ # Референс: Telegram Desktop (только для изучения) │ ├── proxy/ # UDP прокси для тестов │ └── bping/ # BPing (bandwidth ping) ├── tinycrypt/ # TinyCrypt crypto library (external) @@ -337,6 +339,141 @@ SOCKET=14, CONTROL=15, DUMP=16, TRAFFIC=17, DEBUG=18, GENERAL=19, NAT=20 - Для каждого отладочного вывода подумай какая из доступной информация будет полезна чтобы можно было наиболее завершенно оценить состояние алгоритма и состояний влияющих на алгоритм. +## chatgui (GUI Chat Client) + +Chatgui — десктопный GUI-чат на Qt 5, отдельный проект внутри репозитория. Не связан с autotools-сборкой utun. + +### Технологии +- **Язык:** C++17 +- **Фреймворк:** Qt 5.15+ (Widgets + Network) +- **Сборка:** CMake 3.16+ +- **БД:** SQLite3 (WAL mode, встроенный `db/sqlite3.c` amalgamation) +- **Анимации:** rlottie (C API) + zlib (gzip-декомпрессия TGS) + +### Сборка +```bash +# Установка зависимостей +sudo apt install librlottie-dev zlib1g-dev qtbase5-dev + +# Сборка +cd tools/chatgui && mkdir -p build && cd build +cmake .. && make -j4 +./chatgui +``` + +### Структура файлов (src/) + +| Файл | Назначение | +|------|-----------| +| `mainwindow.h/cpp` | Главное окно, QSplitter (ChannelList \| MessageList \| AccountList), трей | +| `chatview.h/cpp` | QListView с фоновым изображением, hover-сигнал, drag-to-select | +| `messagelist.h/cpp` | QStandardItemModel, stub-данные, инициализация анимаций, hover→activate | +| `messagedelegate.h/cpp` | QStyledItemDelegate: бабблы, текст, цитаты, реакции, оверлей анимаций | +| `emoji.h/cpp` | EmojiData/EmojiCategory/EmojiType, 4 категории, `g_animatedEmojiMap` | +| `emojipanel.h/cpp` | Эмодзи-пикер: QTabWidget + QGridLayout, EmojiButton с hover-анимацией | +| `emojitabbar.h/cpp` | Кастомный QTabBar для эмодзи-панели | +| `inputbar.h/cpp` | Поле ввода (QTextEdit), вставка эмодзи, отправка по Enter | +| `lottieicon.h/cpp` | Загрузка TGS (gzip→zlib), рендер кадров через `lottie_animation_render` | +| `animtimer.h/cpp` | Синглтон-таймер 30fps, refcount activate/deactivate, сигнал ticked | +| `channellist.h/cpp` `channeldelegate.h/cpp` | Список каналов с аватарами и превью | +| `accountlist.h/cpp` | Список аккаунтов/пользователей | + +### Другие поддиректории +- `db/` — SQLite3 amalgamation (`sqlite3.c/h`), `db_manager.h/cpp` (схема: nodes, channels, messages, keys, addresses) +- `transport/` — TCP-клиент для связи с uTun (`msg_client.h/cpp`, бинарный протокол `[size:2][type:1][id:8][options:1][data...]`) +- `resources/` — `bg.jpg`, `chatgui.qrc` (встраивает 5 TGS в бинарник), `animations/*.tgs` + +### Система анимированных эмодзи + +#### Формат +TGS = gzip-сжатый Lottie JSON. Холст 512×512, 60fps, 90–180 кадров. Декомпрессия через zlib (`inflateInit2` с `16+MAX_WBITS`). + +#### Ключевые компоненты +``` +LottieIcon — загрузка TGS, рендер кадров (rlottie C API) + ↓ +AnimTimer (синглтон) — таймер 33ms, refcount activate/deactivate + ├── в сообщениях: → MessageDelegate::paint() + │ drawAnimatedEmojiOverlay() — QTextLayout → позиции эмодзи → drawImage() + │ drawStatusBar() — анимированные реакции вместо drawText() + │ + ├── в панели: → EmojiButton (наследует QPushButton) + │ per-button QTimer, enterEvent/leaveEvent, собственный paintEvent + │ + └── активация: → ChatView::hoveredIndexChanged + MessageList проверяет текст/реакции сообщения на g_animatedEmojiMap + есть анимация → AnimTimer::activate() / нет → deactivate() +``` + +#### Инициализация +1. `MessageList` конструктор: загружает все `EmojiType::Animation` из `builtinEmojiSet()`, создаёт `LottieIcon`, регистрирует в `AnimTimer` +2. **Должно быть ДО создания `EmojiPanel`** — иначе `EmojiButton` получит `nullptr` +3. `g_animatedEmojiMap` заполняется при старте (Unicode → animPath) + +#### Текущий маппинг (5 эмодзи) +| Unicode | Shortcode | TGS-файл | +|---------|-----------|----------| +| ✨ `U+2728` | `:sparkles:` | `sparkles_emoji.tgs` | +| 🏳️ `U+1F3F3` | `:flag:` | `white_flag_emoji.tgs` | +| 👋 `U+1F44B` | `:wave:` | `greeting.tgs` | +| ✋ `U+270B` | `:raised_hand:` | `stop.tgs` | +| 🤖 `U+1F916` | `:robot:` | `robot.tgs` | + +#### Рендеринг в сообщениях +- Текст рисуется через `QPainter::drawText(Qt::TextWordWrap)` +- `drawAnimatedEmojiOverlay()` повторяет layout через `QTextLayout` с теми же параметрами +- Для каждого эмодзи из `g_animatedEmojiMap` находит пиксельную позицию через `QTextLine::cursorToX()` +- Рендерит кадр через `LottieIcon::renderFrame(currentFrame(), size)` и рисует `drawImage()` +- Размер эмодзи масштабирован ×1.3 относительно высоты строки +- Аналогично для реакций в `drawStatusBar()` + +#### Drag-to-select +- Одиночный клик снимает выделение (если было), не стартует новое +- Движение ≥5px от точки нажатия стартует выделение (`m_selStart`/`m_selEnd`) +- Ctrl+C копирует: для одного сообщения — выделенный фрагмент, для нескольких — `[time] author: text` + +### Важные правила chatgui +- `CMAKE_AUTORCC ON` обязателен для компиляции `.qrc`-ресурсов +- Иконки должны быть зарегистрированы в `AnimTimer` ДО создания `EmojiPanel` +- `EmojiButton` НЕ использует `Q_OBJECT` (в анонимном namespace) — таймер через лямбду, каст через `dynamic_cast` +- Координаты `indexAt()`: `viewport()->mapFrom(this, event->pos())` + +--- + +## tdesktop-dev (референсный проект Telegram Desktop) + +**Расположение:** `tools/tdesktop-dev/` — полный клон [Telegram Desktop](https://github.com/telegramdesktop/tdesktop). + +**Статус:** референс. Не собирается, не модифицируется, в `.gitignore`. + +**Назначение:** +- Источник TGS-анимаций (`Telegram/Resources/animations/` — 99+ файлов) +- Образец использования rlottie/lib_lottie API +- Архитектурный референс для GUI-компонентов + +**Правила:** +- НЕ модифицировать файлы внутри `tdesktop-dev/` +- НЕ коммитить изменения из `tdesktop-dev/` +- НЕ ссылаться в сборке на код/библиотеки из tdesktop-dev +- Можно копировать TGS-файлы в `tools/chatgui/resources/animations/` + +**Полезные поддиректории:** +- `Telegram/Resources/animations/` — TGS-анимации (dice, reactions, emoji, UI) +- `Telegram/lib_lottie/` — C++ обёртка над rlottie (SinglePlayer, MultiPlayer, Icon, FrameGenerator) +- `Telegram/ThirdParty/rlottie/` — submodule rlottie (обычно не выкачан) + +**rlottie C API (ключевые функции):** +```c +Lottie_Animation *lottie_animation_from_data(const char *data, const char *key, const char *resource_path); +void lottie_animation_get_size(const Lottie_Animation *anim, size_t *w, size_t *h); +size_t lottie_animation_get_totalframe(const Lottie_Animation *anim); +double lottie_animation_get_framerate(const Lottie_Animation *anim); +void lottie_animation_render(Lottie_Animation *anim, size_t frame, uint32_t *buf, size_t w, size_t h, size_t stride); +void lottie_animation_destroy(Lottie_Animation *anim); +``` + +--- + ## Key Documentation Files - `/doc/etcp_protocol.txt` - ETCP протокол (формат кодограмм, ACK, handshake, keepalive) - `/doc/etcp_arch.md` - ETCP архитектура