Files
telegram-tui/CONTEXT.md
Mikhail Kilin 051c4a0265
Some checks are pending
CI / Check (pull_request) Waiting to run
CI / Format (pull_request) Waiting to run
CI / Clippy (pull_request) Waiting to run
CI / Build (macos-latest) (pull_request) Waiting to run
CI / Build (ubuntu-latest) (pull_request) Waiting to run
CI / Build (windows-latest) (pull_request) Waiting to run
fixes
2026-01-28 01:29:03 +03:00

246 lines
18 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Текущий контекст проекта
## Статус: Фаза 9 — ЗАВЕРШЕНО
### Что сделано
#### 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) текст` для входящих
- **Галочки прочтения** (✓ отправлено, ✓✓ прочитано) — обновляются в реальном времени
- **Отметка сообщений как прочитанных**: при открытии чата счётчик непрочитанных сбрасывается
- **Отправка текстовых сообщений**
- **Редактирование сообщений**: ↑ при пустом инпуте → выбор → 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` — отменить выбор/редактирование/reply
- `1-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
├── 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
```
### Ключевые решения
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 на последней строке, для входящих — время на первой строке с отступом для остальных.
10. **Конфигурационный файл**: TOML конфиг создаётся автоматически при первом запуске в `~/.config/tele-tui/config.toml`. Поддерживает настройку timezone (применяется к отображению времени через `format_timestamp_with_tz`) и цветовой схемы (парсится в `ratatui::style::Color`). Credentials загружаются с приоритетом: XDG config dir → .env → ошибка с инструкциями.
11. **Реакции**: Хранятся в `Vec<ReactionInfo>` для каждого сообщения. Обновляются в реальном времени через `Update::MessageInteractionInfo`. Emoji picker использует сетку 8x6 с навигацией стрелками. Приоритет обработки ввода: reaction picker → delete confirmation → остальные модалки (важно для корректной работы Enter/Esc).
### Зависимости (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"
clipboard = "0.5"
toml = "0.8"
dirs = "5.0"
```
### API Credentials
Приоритет загрузки (от высшего к низшему):
1. **Файл credentials** (`~/.config/tele-tui/credentials`):
```
API_ID=your_api_id
API_HASH=your_api_hash
```
2. **Переменные окружения** (`.env` файл в текущей директории):
```
API_ID=your_api_id
API_HASH=your_api_hash
```
3. Если ничего не найдено — показывается сообщение об ошибке с инструкциями.
### Конфигурационный файл
Создаётся автоматически при первом запуске в `~/.config/tele-tui/config.toml`:
```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"
```
## Что НЕ сделано / TODO
Все пункты Фазы 9 завершены! Можно переходить к следующей фазе разработки.
## Известные проблемы
1. При первом запуске нужно пройти авторизацию