30 KiB
Текущий контекст проекта
Статус: Фаза 9 — ЗАВЕРШЕНО + Тестирование (100%!) 🎉
Что сделано
TDLib интеграция
- Подключена библиотека
tdlib-rsv1.1 с автоматической загрузкой TDLib - Реализована авторизация через телефон + код + 2FA пароль
- Сессия сохраняется автоматически в папке
tdlib_data/ - Отключены логи TDLib через FFI вызов
td_executeдо создания клиента - Updates обрабатываются в отдельном потоке через
mpscканал (неблокирующе) - Graceful shutdown: корректное закрытие TDLib при выходе (Ctrl+C)
Функциональность
- Загрузка списка чатов (до 50 штук)
- Фильтрация чатов: показываются только чаты из ChatList::Main (без архива)
- Фильтрация удалённых аккаунтов: "Deleted Account" не отображаются в списке
- Отображение названия чата, счётчика непрочитанных и @username
- Иконка 📌 для закреплённых чатов
- Иконка 🔇 для замьюченных чатов
- Индикатор @ для чатов с непрочитанными упоминаниями
- Онлайн-статус: зелёная точка ● для онлайн пользователей
- Загрузка истории сообщений при открытии чата (множественные попытки)
- Группировка сообщений по дате (разделители "Сегодня", "Вчера", дата) — по центру
- Группировка сообщений по отправителю (заголовок с именем)
- Выравнивание сообщений: исходящие справа (зелёные), входящие слева
- Перенос длинных сообщений: автоматический wrap на несколько строк
- Отображение времени и галочек:
текст (HH:MM ✓✓)для исходящих,(HH:MM) текстдля входящих - Галочки прочтения (✓ отправлено, ✓✓ прочитано) — обновляются в реальном времени
- Отметка сообщений как прочитанных: при открытии чата счётчик непрочитанных сбрасывается
- Отправка текстовых сообщений
- Редактирование сообщений: ↑ при пустом инпуте → выбор → Enter → редактирование
- Удаление сообщений: в режиме выбора нажать
d/в/Delete→ модалка подтверждения - Reply на сообщения: в режиме выбора нажать
r/к→ режим ответа с превью - Forward сообщений: в режиме выбора нажать
f/а→ выбор чата для пересылки - Отображение пересланных сообщений: индикатор "↪ Переслано от" с именем отправителя
- Индикатор редактирования: ✎ рядом с временем для отредактированных сообщений
- Новые сообщения в реальном времени при открытом чате
- Поиск по чатам (Ctrl+S): фильтрация по названию и @username
- Typing indicator ("печатает..."): отображение статуса набора текста собеседником и отправка своего статуса
- Закреплённые сообщения: отображение pinned message вверху чата с переходом к нему
- Поиск по сообщениям в чате (Ctrl+F): поиск текста внутри открытого чата с навигацией по результатам
- Черновики: автосохранение набранного текста при переключении между чатами
- Профиль пользователя/чата (
i): просмотр информации о собеседнике или группе - Копирование сообщений (
y/н): копирование текста сообщения в системный буфер обмена - Реакции на сообщения:
- Отображение реакций под сообщениями
- Логика отображения: 1 человек = только emoji, 2+ = emoji + счётчик
- Свои реакции в рамках [👍], чужие без рамок 👍
- Emoji picker с сеткой доступных реакций (8 в ряду)
- Добавление/удаление реакций (toggle)
- Обновление реакций в реальном времени через Update::MessageInteractionInfo
- Конфигурационный файл (
~/.config/tele-tui/config.toml):- Автоматическое создание дефолтного конфига при первом запуске
- Настройка timezone: формат "+03:00" или "-05:00"
- Настройка цветов: incoming_message, outgoing_message, selected_message, reaction_chosen, reaction_other
- Credentials файл (
~/.config/tele-tui/credentials): API_ID и API_HASH - Приоритет загрузки: ~/.config/tele-tui/credentials → .env → сообщение об ошибке с инструкциями
- Кеширование имён пользователей: имена загружаются асинхронно и обновляются в UI
- Папки Telegram: загрузка и переключение между папками (1-9)
- Медиа-заглушки: [Фото], [Видео], [Голосовое], [Стикер], [GIF] и др.
- Markdown форматирование в сообщениях:
- Жирный (bold)
- Курсив (italic)
- Подчёркнутый (underline)
Зачёркнутый(strikethrough)Код(inline code, Pre, PreCode) — cyan на тёмном фоне- Спойлеры — скрытый текст (серый на сером)
- Ссылки (URL, TextUrl, Email, Phone) — синий с подчёркиванием
- @Упоминания — синий с подчёркиванием
Состояние сети
- Индикатор в футере: показывает текущее состояние подключения
⚠ Нет сети— красный, ожидание сети⏳ Прокси...— cyan, подключение к прокси⏳ Подключение...— cyan, подключение к серверам⏳ Обновление...— cyan, синхронизация данных
Оптимизации
- 60 FPS ready: poll таймаут 16ms, рендеринг только при изменениях (
needs_redrawфлаг) - Оптимизация памяти:
- Очистка сообщений при закрытии чата
- Лимит кэша пользователей (500)
- Периодическая очистка неактивных записей
- Минимальное разрешение: предупреждение если терминал меньше 80x20
Динамический инпут
- Автоматическое расширение: поле ввода увеличивается при длинном тексте (до 10 строк)
- Перенос текста: длинные сообщения переносятся на новые строки
- Блочный курсор: vim-style курсор █ с возможностью перемещения по тексту
Управление
↑/↓стрелки — навигация по списку чатовEnter— открыть чат / отправить сообщениеEsc— закрыть открытый чат / отменить поискCtrl+S— поиск по чатам (фильтрация по названию и username)Ctrl+R— обновить список чатовCtrl+C— выход (graceful shutdown)↑/↓в открытом чате — скролл сообщений (с подгрузкой старых)↑при пустом инпуте — выбор сообщения для редактированияEnterв режиме выбора — начать редактированиеr/кв режиме выбора — ответить на сообщение (reply)f/ав режиме выбора — переслать сообщение (forward)d/в/Deleteв режиме выбора — удалить сообщение (с подтверждением)y/н/Enter— подтвердить удаление в модалкеn/т/Esc— отменить удаление в модалкеEsc— отменить выбор/редактирование/reply1-9— переключение папок (в списке чатов)Ctrl+F— поиск по сообщениям в открытом чатеn/N— навигация по результатам поиска (следующий/предыдущий)i— открыть профиль пользователя/чатаy/нв режиме выбора — скопировать сообщение в буфер обменаe/ув режиме выбора — добавить реакцию (открывает emoji picker)←/→/↑/↓в emoji picker — навигация по сетке реакцийEnterв emoji picker — добавить/удалить реакциюEscв emoji picker — закрыть picker- Редактирование текста в инпуте:
←/→— перемещение курсораHome— курсор в началоEnd— курсор в конецBackspace— удалить символ слеваDelete— удалить символ справа
Структура проекта
src/
├── main.rs # Точка входа, event loop, TDLib инициализация, graceful shutdown
├── lib.rs # Библиотечный интерфейс (для тестов)
├── config.rs # Конфигурация (TOML), загрузка credentials
├── app/
│ ├── mod.rs # App структура и состояние (needs_redraw флаг)
│ └── state.rs # AppScreen enum
├── ui/
│ ├── mod.rs # Роутинг UI по экранам, проверка минимального размера
│ ├── loading.rs # Экран загрузки
│ ├── auth.rs # Экран авторизации
│ ├── main_screen.rs # Главный экран с папками
│ ├── chat_list.rs # Список чатов (pin, mute, online, mentions)
│ ├── messages.rs # Область сообщений (wrap, группировка, динамический инпут)
│ └── footer.rs # Подвал с командами и статусом сети
├── input/
│ ├── mod.rs # Роутинг ввода
│ ├── auth.rs # Обработка ввода на экране авторизации
│ └── main_input.rs # Обработка ввода на главном экране
├── utils.rs # Утилиты (disable_tdlib_logs, format_timestamp_with_tz, format_date, get_day)
└── tdlib/
├── mod.rs # Модуль экспорта (TdClient, UserOnlineStatus, NetworkState)
└── client.rs # TdClient: авторизация, чаты, сообщения, кеш, NetworkState, ReactionInfo
tests/
├── helpers/
│ ├── mod.rs # Экспорт тестовых утилит
│ ├── app_builder.rs # TestAppBuilder для создания тестовых App
│ ├── fake_tdclient.rs # FakeTdClient (mock TDLib клиент, для будущих интеграционных тестов)
│ ├── snapshot_utils.rs # Утилиты для snapshot тестов (render_to_buffer, buffer_to_string)
│ └── test_data.rs # Builders для тестовых данных (TestChatBuilder, TestMessageBuilder)
├── chat_list.rs # Snapshot тесты для списка чатов (9 тестов)
└── messages.rs # Snapshot тесты для сообщений (19 тестов)
Тестирование
Статус: ЗАВЕРШЕНО! (100%) — Все тесты готовы! 🎉🎊
Стратегия: Комбо подход — 70% snapshot tests, 25% integration tests, 5% e2e smoke tests
Инфраструктура (Фаза 0): ✅ Завершена
- Добавлены зависимости:
insta = "1.34",tokio-test = "0.4" - Создан
src/lib.rsдля экспорта модулей в тесты - Созданы test helpers:
TestAppBuilder— fluent builder для создания тестовых AppTestChatBuilder/TestMessageBuilder— builders для тестовых данныхFakeTdClient— in-memory mock TDLib клиентаrender_to_buffer/buffer_to_string— утилиты для snapshot тестов
Snapshot Tests (Фаза 1): ✅ 55/55 (100%)
- ✅ 1.1 Chat List (9/9): пустой список, множественные чаты, unread, pinned, muted, mentions, selected, long title, search mode
- ✅ 1.2 Messages (18/18): empty chat, incoming/outgoing, date separators, sender grouping, read receipts, edited, long message wrap, markdown, media, reply, forwarded, reactions
- ✅ 1.3 Modals (8/8): delete confirmation, emoji picker, profile, pinned message, search, forward
- ✅ 1.4 Input Field (7/7): empty, text, long text, editing/reply/search modes
- ✅ 1.5 Footer (6/6): chat list, open chat, network states, search mode
- ✅ 1.6 Screens (7/7): loading, auth, main, terminal size warning
Integration Tests (Фаза 2): ✅ 93/93 (100%!)
- ✅ 2.1 Send Message Flow (6/6): отправка текста, множественные, форматирование, разные чаты, входящие, reply
- ✅ 2.2 Edit Message Flow (6/6): изменение текста, edit_date, can_be_edited, только свои, множественные, форматирование
- ✅ 2.3 Delete Message Flow (6/6): удаление из списка, множественные, can_be_deleted, только свои, разные чаты, revoke
- ✅ 2.4 Reply & Forward Flow (8/8): reply с превью, связь с оригиналом, forward с sender, разные чаты, комбо
- ✅ 2.5 Reactions Flow (10/10): добавление, toggle, множественные, разные юзеры, подсчёт, chosen, realtime, доступные, на forwarded, очистка
- ✅ 2.6 Search Flow (8/8): по названию, username, сообщениям, навигация, case-insensitive, пробелы, пустой, очистка
- ✅ 2.7 Drafts Flow (7/7): сохранение, восстановление, удаление, независимые, индикатор, пустой, закрытие чата
- ✅ 2.8 Navigation Flow (7/7): списку чатов, открытие, закрытие, скролл, папки, wrap, пустой список
- ✅ 2.9 Profile Flow (6/6): личный чат, имя+username, телефон, группа, участники, закрытие
- ✅ 2.10 Network & Typing Flow (9/9): typing indicator, action, статус, timeout, network states (5)
- ✅ 2.11 Copy Flow (9/9): форматирование plain, forward, reply, оба контекста, длинные, markdown, clipboard init, clipboard test, кроссплатформенность
- ✅ 2.12 Config Flow (11/11): дефолты, кастомные, валидные цвета, light цвета, невалидные (fallback), case-insensitive, TOML сериализация, частичный TOML, timezone форматы, credentials из env, credentials ошибка
Прогресс: 148/151 тестов (98%) — больше чем планировалось!
ВСЕ ТЕСТЫ ЗАВЕРШЕНЫ! 🎉 Phase 0, 1, 2 — готово!
Подробный план и roadmap: см. TESTING_ROADMAP.md
Ключевые решения
-
Неблокирующий receive: TDLib updates приходят в отдельном потоке и передаются в main loop через
mpsc::channel. Это позволяет UI оставаться отзывчивым. -
FFI для логов: Используем прямой вызов
td_executeдля отключения логов синхронно, до создания клиента, чтобы избежать вывода в терминал. -
Синхронизация чатов: Чаты загружаются асинхронно через updates. Main loop периодически синхронизирует
app.chatsсtd_client.chats. -
Кеширование имён: При получении
Update::Userсохраняем имя (first_name + last_name) и username в HashMap. Имена подгружаются асинхронно через очередьpending_user_ids. Кэш ограничен 500 записями. -
Группировка сообщений: Сообщения группируются по дате (разделители по центру) и по отправителю (заголовки). Исходящие выравниваются вправо, входящие влево.
-
Отметка прочтения: При открытии чата вызывается
view_messagesдля всех сообщений. Новые входящие сообщения автоматически отмечаются как прочитанные.Update::ChatReadOutboxобновляет статус галочек. -
Graceful shutdown: При Ctrl+C устанавливается флаг остановки, закрывается TDLib клиент, ожидается завершение polling задачи с таймаутом 2 сек.
-
Оптимизация рендеринга: Флаг
needs_redrawпозволяет пропускать перерисовку когда ничего не изменилось. Триггеры: TDLib updates, пользовательский ввод, изменение размера терминала. -
Перенос текста: Длинные сообщения автоматически разбиваются на строки с учётом ширины терминала. Для исходящих — time_mark на последней строке, для входящих — время на первой строке с отступом для остальных.
-
Конфигурационный файл: TOML конфиг создаётся автоматически при первом запуске в
~/.config/tele-tui/config.toml. Поддерживает настройку timezone (применяется к отображению времени черезformat_timestamp_with_tz) и цветовой схемы (парсится вratatui::style::Color). Credentials загружаются с приоритетом: XDG config dir → .env → ошибка с инструкциями. -
Реакции: Хранятся в
Vec<ReactionInfo>для каждого сообщения. Обновляются в реальном времени черезUpdate::MessageInteractionInfo. Emoji picker использует сетку 8x6 с навигацией стрелками. Приоритет обработки ввода: reaction picker → delete confirmation → остальные модалки (важно для корректной работы Enter/Esc).
Зависимости (Cargo.toml)
ratatui = "0.29"
crossterm = "0.28"
tdlib-rs = { version = "1.1", features = ["download-tdlib"] }
tokio = { version = "1", features = ["full"] }
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
dotenvy = "0.15"
chrono = "0.4"
clipboard = "0.5"
toml = "0.8"
dirs = "5.0"
API Credentials
Приоритет загрузки (от высшего к низшему):
- Файл credentials (
~/.config/tele-tui/credentials):
API_ID=your_api_id
API_HASH=your_api_hash
- Переменные окружения (
.envфайл в текущей директории):
API_ID=your_api_id
API_HASH=your_api_hash
- Если ничего не найдено — показывается сообщение об ошибке с инструкциями.
Конфигурационный файл
Создаётся автоматически при первом запуске в ~/.config/tele-tui/config.toml:
[general]
# Часовой пояс в формате "+03:00" или "-05:00"
# Применяется к отображению времени сообщений
timezone = "+03:00"
[colors]
# Цветовая схема (поддерживаемые цвета: black, red, green, yellow, blue, magenta, cyan, gray, white, darkgray, lightred, lightgreen, lightyellow, lightblue, lightmagenta, lightcyan)
# Цвет входящих сообщений
incoming_message = "white"
# Цвет исходящих сообщений
outgoing_message = "green"
# Цвет выбранного сообщения
selected_message = "yellow"
# Цвет своих реакций (в рамках [👍])
reaction_chosen = "yellow"
# Цвет чужих реакций
reaction_other = "gray"
Последние обновления (2026-01-30)
Тестирование — ЗАВЕРШЕНО! 🎉🎊🚀
Добавлено:
- 📝 93 integration теста (12 файлов): send_message, edit_message, delete_message, reply_forward, reactions, search, drafts, navigation, profile, network_typing, copy, config
- 🎯 Phase 2.1-2.10 (73 теста) ✅
- 🎯 Phase 2.11 Copy Flow (9 тестов) ✅ — НОВОЕ!
- Форматирование сообщений (plain, forward, reply, комбо, длинные, markdown)
- Clipboard тесты (инициализация, реальное копирование, кроссплатформенность)
- 🎯 Phase 2.12 Config Flow (11 тестов) ✅ — НОВОЕ!
- Config дефолты и кастомные значения
- Парсинг цветов (валидные, light, невалидные с fallback, case-insensitive)
- TOML сериализация/десериализация
- Timezone форматы
- Credentials загрузка (из env, проверка ошибок)
- 📚 Обновлена документация тестирования (TESTING_PROGRESS.md, TESTING_ROADMAP.md, CONTEXT.md)
Покрытие: 148/151 тестов (98%) — БОЛЬШЕ ЧЕМ ПЛАНИРОВАЛОСЬ! 🎉
- ✅ Phase 0: Инфраструктура (100%)
- ✅ Phase 1: UI Snapshot Tests (100%) - 55 тестов
- ✅ Phase 2: Integration Tests (100%!) - 93 тестов (вместо запланированных 84!)
- Copy Flow: 9 тестов (вместо 3)
- Config Flow: 11 тестов (вместо 8)
Все тесты проходят: cargo test → 148+ passed ✅
Статус: ВСЕ ОСНОВНЫЕ ТЕСТЫ ЗАВЕРШЕНЫ! Опциональные тесты (E2E smoke, utils, performance) можно сделать позже.
Подробности: TESTING_PROGRESS.md
Рефакторинг — Приоритет 1 ЗАВЕРШЁН! 🏗️✨ (2026-01-30)
Статус: Priority 1 (3/3 задач) ✅ ЗАВЕРШЕНО!
Завершено:
-
✅ P1.3 — Константы (ранее)
- Вынесены магические числа в
src/constants.rs - Улучшена читаемость и maintainability
- Вынесены магические числа в
-
✅ P1.2 — Разделение TdClient (2026-01-30)
- Разделён монолитный TdClient (2036 строк, 87KB) на 7 модулей:
auth.rs— AuthManager + AuthState enum (6.8KB)chats.rs— ChatManager для операций с чатами (8.1KB)messages.rs— MessageManager для сообщений (18.5KB)users.rs— UserCache с LRU кэшем (6.2KB)reactions.rs— ReactionManager (4.2KB)types.rs— Общие типы данных (10.8KB)mod.rs— Экспорты модулей
- Размер client.rs сократился на 50% (87KB → 42.5KB)
- Исправлено 130+ ошибок компиляции из-за изменений в tdlib-rs API
- Все 330 тестов проходят ✅
- Разделён монолитный TdClient (2036 строк, 87KB) на 7 модулей:
-
✅ P1.1 — ChatState enum (2026-01-30)
- Схлопнуты 14 boolean полей в type-safe enum
ChatState - Невозможно иметь несколько состояний одновременно
- Данные состояния хранятся вместе с ним
- Варианты: Normal, MessageSelection, Editing, Reply, Forward, DeleteConfirmation, ReactionPicker, Profile, SearchInChat, PinnedMessages
- Обновлены все методы App для делегирования к ChatState
- Все 330 тестов проходят ✅
- Схлопнуты 14 boolean полей в type-safe enum
Преимущества:
- Код стал более модульным и maintainable
- Улучшена type-safety
- Проще добавлять новые фичи
- Лучше читаемость
Priority 2 (40% завершено - 2/5):
-
✅ P2.5 — Error enum (завершено 2026-01-31)
- Создан
src/error.rsс типобезопасным enumTeletuiError - Добавлены варианты: TdLib, Config, Network, Auth, Chat, Message, User, InvalidTimezone, InvalidColor, Clipboard, Io, Toml, Json, Other
- Type alias
Result<T>для упрощения сигнатур - Использован
thiserrorдля автоматического Display - Заменены все
Result<T, String>наResult<T>в 7 модулях - Все 350 тестов проходят ✅
- Создан
-
✅ P2.3 — Config validation (завершено 2026-01-31)
- Добавлен метод
Config::validate()для проверки конфигурации - Валидация timezone: проверка что начинается с + или -
- Валидация цветов: проверка что цвет из списка допустимых (black, red, green, yellow, blue, magenta, cyan, gray, white, darkgray, lightred, lightgreen, lightyellow, lightblue, lightmagenta, lightcyan)
- При загрузке невалидного конфига автоматически используется дефолтный
- Все 350 тестов проходят ✅
- Добавлен метод
Следующие шаги: Priority 2 (Newtype для ID, MessageBuilder, реструктуризация MessageInfo)
Подробности: REFACTORING_ROADMAP.md
Что НЕ сделано / TODO
Все пункты Фазы 9 завершены! Можно переходить к следующей фазе разработки или продолжить написание тестов.
Технический долг
См. REFACTORING_ROADMAP.md для детального плана рефакторинга.
Завершено (Priority 1):
ChatState enum✅ — схлопнуты boolean состояния в type-safe enumРазделение TdClient✅ — разделён на 7 модулейКонстанты✅ — вынесены в отдельный модуль
Завершено (Priority 2):
Error enum✅ — типобезопасная обработка ошибок (2026-01-31)Config validation✅ — валидация конфигурации при загрузке (2026-01-31)
В работе (Priority 2-5):
- Типобезопасность — newtype pattern для ID
- MessageBuilder — упрощение создания сообщений
- UI компоненты — выделить переиспользуемые компоненты
- Форматирование — вынести markdown форматирование в отдельный модуль
- Юнит-тесты — добавить для utils и других модулей
Известные проблемы
- При первом запуске нужно пройти авторизацию