# Текущий контекст проекта ## Статус: Фаза 6 завершена — Полировка ### Что сделано #### TDLib интеграция - Подключена библиотека `tdlib-rs` v1.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) текст` для входящих - **Галочки прочтения** (✓ отправлено, ✓✓ прочитано) — обновляются в реальном времени - **Отметка сообщений как прочитанных**: при открытии чата счётчик непрочитанных сбрасывается - **Отправка текстовых сообщений** - **Новые сообщения в реальном времени** при открытом чате - **Поиск по чатам** (Ctrl+S): фильтрация по названию и @username - **Кеширование имён пользователей**: имена загружаются асинхронно и обновляются в UI - **Папки Telegram**: загрузка и переключение между папками (1-9) - **Медиа-заглушки**: [Фото], [Видео], [Голосовое], [Стикер], [GIF] и др. #### Состояние сети - **Индикатор в футере**: показывает текущее состояние подключения - `⚠ Нет сети` — красный, ожидание сети - `⏳ Прокси...` — cyan, подключение к прокси - `⏳ Подключение...` — cyan, подключение к серверам - `⏳ Обновление...` — cyan, синхронизация данных #### Оптимизации - **60 FPS ready**: poll таймаут 16ms, рендеринг только при изменениях (`needs_redraw` флаг) - **Оптимизация памяти**: - Очистка сообщений при закрытии чата - Лимит кэша пользователей (500) - Периодическая очистка неактивных записей - **Минимальное разрешение**: предупреждение если терминал меньше 80x20 #### Динамический инпут - **Автоматическое расширение**: поле ввода увеличивается при длинном тексте (до 10 строк) - **Перенос текста**: длинные сообщения переносятся на новые строки #### Управление - `↑/↓` стрелки — навигация по списку чатов - `Enter` — открыть чат / отправить сообщение - `Esc` — закрыть открытый чат / отменить поиск - `Ctrl+S` — поиск по чатам (фильтрация по названию и username) - `Ctrl+R` — обновить список чатов - `Ctrl+C` — выход (graceful shutdown) - `↑/↓` в открытом чате — скролл сообщений (с подгрузкой старых) - `1-9` — переключение папок (в списке чатов) - Ввод текста в поле сообщения ### Структура проекта ``` src/ ├── main.rs # Точка входа, event loop, TDLib инициализация, graceful shutdown ├── 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, format_date, get_day) └── tdlib/ ├── mod.rs # Модуль экспорта (TdClient, UserOnlineStatus, NetworkState) └── client.rs # TdClient: авторизация, чаты, сообщения, кеш, NetworkState ``` ### Ключевые решения 1. **Неблокирующий receive**: TDLib updates приходят в отдельном потоке и передаются в main loop через `mpsc::channel`. Это позволяет UI оставаться отзывчивым. 2. **FFI для логов**: Используем прямой вызов `td_execute` для отключения логов синхронно, до создания клиента, чтобы избежать вывода в терминал. 3. **Синхронизация чатов**: Чаты загружаются асинхронно через updates. Main loop периодически синхронизирует `app.chats` с `td_client.chats`. 4. **Кеширование имён**: При получении `Update::User` сохраняем имя (first_name + last_name) и username в HashMap. Имена подгружаются асинхронно через очередь `pending_user_ids`. Кэш ограничен 500 записями. 5. **Группировка сообщений**: Сообщения группируются по дате (разделители по центру) и по отправителю (заголовки). Исходящие выравниваются вправо, входящие влево. 6. **Отметка прочтения**: При открытии чата вызывается `view_messages` для всех сообщений. Новые входящие сообщения автоматически отмечаются как прочитанные. `Update::ChatReadOutbox` обновляет статус галочек. 7. **Graceful shutdown**: При Ctrl+C устанавливается флаг остановки, закрывается TDLib клиент, ожидается завершение polling задачи с таймаутом 2 сек. 8. **Оптимизация рендеринга**: Флаг `needs_redraw` позволяет пропускать перерисовку когда ничего не изменилось. Триггеры: TDLib updates, пользовательский ввод, изменение размера терминала. 9. **Перенос текста**: Длинные сообщения автоматически разбиваются на строки с учётом ширины терминала. Для исходящих — time_mark на последней строке, для входящих — время на первой строке с отступом для остальных. ### Зависимости (Cargo.toml) ```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" ``` ### Переменные окружения (.env) ``` API_ID=your_api_id API_HASH=your_api_hash ``` ## Что НЕ сделано / TODO (Фаза 7) - [ ] Удалить дублирование current_messages между App и TdClient - [ ] Использовать единый источник данных для сообщений - [ ] Реализовать LRU-кэш для user_names/user_statuses вместо простого лимита - [ ] Lazy loading для имён пользователей (загружать только видимых) - [ ] Профилирование памяти и устранение утечек - [ ] Markdown форматирование в сообщениях ## Известные проблемы 1. При первом запуске нужно пройти авторизацию 2. Время отображается с фиксированным смещением +3 (MSK)