Made LruCache generic over key type K, not just UserId: - LruCache<V> → LruCache<K, V> - Added trait bounds: K: Eq + Hash + Clone + Copy - Updated UserCache field types: * user_usernames: LruCache<UserId, String> * user_names: LruCache<UserId, String> * user_statuses: LruCache<UserId, UserOnlineStatus> Benefits: - Reusable cache implementation for any key types - Type-safe caching - No additional dependencies Progress: Priority 5: 2/3 tasks, Total: 18/20 (90%) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
930 lines
61 KiB
Markdown
930 lines
61 KiB
Markdown
# Текущий контекст проекта
|
||
|
||
## Статус: Фаза 9 — ЗАВЕРШЕНО + Тестирование (100%!) 🎉
|
||
|
||
### Что сделано
|
||
|
||
#### 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
|
||
├── lib.rs # Библиотечный интерфейс (для тестов)
|
||
├── types.rs # Типобезопасные обёртки (ChatId, MessageId, UserId)
|
||
├── config.rs # Конфигурация (TOML), загрузка credentials
|
||
├── error.rs # TeletuiError enum, Result<T> type alias
|
||
├── constants.rs # Константы проекта (MAX_MESSAGES_IN_CHAT, POLL_TIMEOUT_MS, etc.)
|
||
├── formatting.rs # Markdown форматирование (CharStyle, format_text_with_entities)
|
||
├── app/
|
||
│ ├── mod.rs # App структура и состояние (needs_redraw флаг)
|
||
│ ├── state.rs # AppScreen enum
|
||
│ └── chat_state.rs # ChatState enum (Normal, MessageSelection, Editing, etc.)
|
||
├── ui/
|
||
│ ├── mod.rs # Роутинг UI по экранам, проверка минимального размера
|
||
│ ├── loading.rs # Экран загрузки
|
||
│ ├── auth.rs # Экран авторизации
|
||
│ ├── main_screen.rs # Главный экран с папками
|
||
│ ├── chat_list.rs # Список чатов (pin, mute, online, mentions)
|
||
│ ├── messages.rs # Область сообщений (wrap, группировка, динамический инпут)
|
||
│ ├── footer.rs # Подвал с командами и статусом сети
|
||
│ ├── profile.rs # Экран профиля пользователя/чата
|
||
│ └── components/ # Переиспользуемые UI компоненты
|
||
│ ├── mod.rs
|
||
│ ├── modal.rs
|
||
│ ├── input_field.rs
|
||
│ ├── message_bubble.rs
|
||
│ ├── chat_list_item.rs
|
||
│ └── emoji_picker.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: авторизация, chats, messages, users, reactions
|
||
├── auth.rs # AuthManager + AuthState enum
|
||
├── chats.rs # ChatManager для операций с чатами
|
||
├── messages.rs # MessageManager для сообщений
|
||
├── users.rs # UserCache с LRU кэшем
|
||
├── reactions.rs # ReactionManager
|
||
└── types.rs # Общие типы данных (ChatInfo, MessageInfo, MessageBuilder, etc.)
|
||
|
||
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 для создания тестовых App
|
||
- `TestChatBuilder` / `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](TESTING_ROADMAP.md)
|
||
|
||
### Ключевые решения
|
||
|
||
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"
|
||
```
|
||
|
||
## Последние обновления (2026-01-31)
|
||
|
||
### P3.8 — Извлечение форматирования ✅ ЗАВЕРШЕНО!
|
||
|
||
**Что сделано**:
|
||
- ✅ Создан `src/formatting.rs` с логикой markdown форматирования (262 строки)
|
||
- ✅ Перенесены функции из `messages.rs`:
|
||
- `CharStyle` — структура для стилей символов (bold, italic, code, spoiler, url, mention)
|
||
- `format_text_with_entities()` — преобразование текста с entities в стилизованные Span
|
||
- `styles_equal()` — сравнение стилей
|
||
- `adjust_entities_for_substring()` — корректировка entities при переносе текста
|
||
- ✅ Добавлено 5 unit тестов для форматирования
|
||
- ✅ Обновлены `src/lib.rs` и `src/main.rs` для экспорта модуля
|
||
- ✅ `src/ui/messages.rs` сокращён на ~143 строки
|
||
- ✅ Все lib тесты проходят (17 passed)
|
||
- ✅ Бинарник компилируется успешно
|
||
|
||
**Преимущества**:
|
||
- 📦 Логика форматирования изолирована в отдельном модуле
|
||
- ✅ Можно тестировать независимо
|
||
- 🔄 Легко переиспользовать в других компонентах UI
|
||
- 📖 Улучшена читаемость кода
|
||
|
||
**🎉 Статус Priority 3: ЗАВЕРШЁН 100% (4/4 задачи)! 🎉**
|
||
- ✅ P3.7 — UI компоненты
|
||
- ✅ P3.8 — Форматирование
|
||
- ✅ P3.9 — Группировка сообщений
|
||
- ✅ P3.10 — Hotkey mapping
|
||
|
||
**P3.10 — Hotkey mapping** ✅ ЗАВЕРШЕНО!
|
||
|
||
**Что сделано**:
|
||
- ✅ Создан `HotkeysConfig` с 10 настраиваемыми горячими клавишами
|
||
- ✅ Реализован метод `matches(key: KeyCode, action: &str)` для проверки hotkeys
|
||
- ✅ Исправлен баг с UTF-8 (chars().count() вместо len() для поддержки кириллицы)
|
||
- ✅ Добавлены 9 unit тестов (все проходят)
|
||
- ✅ Hotkeys добавлены в Config::default() с дефолтными значениями
|
||
|
||
**Дефолтные горячие клавиши**:
|
||
```toml
|
||
[hotkeys]
|
||
up = "k,ц"
|
||
down = "j,о"
|
||
reply = "r,к"
|
||
forward = "f,а"
|
||
delete = "d,в"
|
||
edit = "e,у"
|
||
copy = "y,н"
|
||
view_profile = "i,ш"
|
||
reaction = "1234567890"
|
||
quit = "q,й"
|
||
```
|
||
|
||
**P3.9 — Группировка сообщений** ✅ ЗАВЕРШЕНО!
|
||
|
||
**Что сделано**:
|
||
- ✅ Перенесён код группировки из `ui/messages.rs` в отдельный модуль `src/message_grouping.rs` (274 строки)
|
||
- ✅ Создана публичная функция `group_messages(messages: &[MessageInfo]) -> Vec<GroupedMessage>`
|
||
- ✅ Группировка по дате и отправителю с оптимизацией
|
||
- ✅ Добавлены 7 unit тестов
|
||
- ✅ Добавлен doctest пример в rustdoc
|
||
|
||
**P4.12 — Rustdoc (частично)** ⏳ 30%
|
||
|
||
**Что сделано**:
|
||
- ✅ Добавлена документация для TdClient (60+ строк rustdoc)
|
||
- ✅ Добавлена документация для App struct
|
||
- ✅ Добавлены doctests примеры использования
|
||
- ✅ Исправлены все doctests для компиляции
|
||
|
||
**Статус тестов**: 464 теста, все проходят ✅
|
||
|
||
---
|
||
|
||
### 🎉🎊 PRIORITY 2 ЗАВЕРШЁН НА 100%! 🎊🎉
|
||
|
||
**P2.7 — MessageBuilder pattern** ✅ ФИНАЛЬНАЯ ЗАДАЧА ЗАВЕРШЕНА!
|
||
|
||
**Что сделано**:
|
||
- ✅ Создан MessageBuilder с fluent API (323 строки кода)
|
||
- ✅ Реализовано 16 методов для удобного создания сообщений
|
||
- ✅ Обновлён convert_message() для использования builder
|
||
- ✅ Добавлены 6 unit тестов
|
||
|
||
**Пример использования**:
|
||
```rust
|
||
let message = MessageBuilder::new(MessageId::new(123))
|
||
.sender_name("Alice")
|
||
.text("Hello!")
|
||
.outgoing()
|
||
.read()
|
||
.build();
|
||
```
|
||
|
||
**🏆 ИТОГИ PRIORITY 2 (100% - 5/5 задач):**
|
||
- ✅ P2.5 — Error enum
|
||
- ✅ P2.3 — Config validation
|
||
- ✅ P2.4 — Newtype для ID
|
||
- ✅ P2.6 — MessageInfo реструктуризация
|
||
- ✅ P2.7 — MessageBuilder pattern ← ФИНАЛ!
|
||
|
||
**Преимущества Priority 2**:
|
||
- 🛡️ Type safety повсюду
|
||
- 📦 Логическая структура данных
|
||
- 🔧 Удобные API для работы с кодом
|
||
- 📚 Самодокументирующийся код
|
||
|
||
---
|
||
|
||
**P2.6 — Реструктуризация MessageInfo** ✅ ЗАВЕРШЕНО!
|
||
|
||
**Что сделано**:
|
||
- ✅ Сгруппированы 16 плоских полей в 4 логические структуры
|
||
- ✅ Создано 4 новых типа: MessageMetadata, MessageContent, MessageState, MessageInteractions
|
||
- ✅ Добавлен конструктор MessageInfo::new() и getter методы
|
||
- ✅ Обновлены 14 файлов с ~200+ обращениями к полям
|
||
- ✅ Все тестовые файлы обновлены
|
||
|
||
**Преимущества**:
|
||
- 📦 Логическая группировка данных
|
||
- 🔍 Проще понимать структуру сообщения
|
||
- ➕ Легче добавлять новые поля
|
||
- 📚 Улучшенная читаемость кода
|
||
|
||
**Статус Priority 2**: 80% (4/5 задач) ✅
|
||
- ✅ Error enum
|
||
- ✅ Config validation
|
||
- ✅ Newtype для ID
|
||
- ✅ MessageInfo реструктуризация ← ТОЛЬКО ЧТО!
|
||
- ⏳ MessageBuilder pattern (последняя!)
|
||
|
||
---
|
||
|
||
**P2.4 — Newtype pattern для ID** ✅ ЗАВЕРШЕНО!
|
||
|
||
**Что сделано**:
|
||
- ✅ Создан `src/types.rs` с типобезопасными обёртками для идентификаторов
|
||
- ✅ Реализованы три типа: `ChatId(i64)`, `MessageId(i64)`, `UserId(i64)`
|
||
- ✅ Добавлены методы: `new()`, `as_i64()`, `From<i64>`, `Display`, `Hash`, `Eq`, `Serialize/Deserialize`
|
||
- ✅ Обновлены 15+ модулей для использования новых типов
|
||
- ✅ Исправлены 53 ошибки компиляции связанные с type conversions
|
||
- ✅ Компилятор теперь предотвращает смешивание разных типов ID на этапе компиляции
|
||
|
||
**Модули обновлены**:
|
||
- `tdlib/types.rs` — ChatInfo, MessageInfo, ReplyInfo, ProfileInfo
|
||
- `tdlib/chats.rs` — все методы с chat_id параметрами
|
||
- `tdlib/messages.rs` — MessageManager, pending_view_messages
|
||
- `tdlib/users.rs` — LruCache<UserId>, UserCache mappings
|
||
- `tdlib/reactions.rs` — reaction methods
|
||
- `tdlib/client.rs` — все публичные методы и Update handlers
|
||
- `app/mod.rs` — selected_chat_id
|
||
- `app/chat_state.rs` — все варианты ChatState
|
||
- `input/main_input.rs` — обработка ввода с преобразованием типов
|
||
- Test helpers — TestAppBuilder, TestChatBuilder, TestMessageBuilder
|
||
|
||
**Преимущества**:
|
||
- 🛡️ Type safety на уровне компиляции — невозможно перепутать ChatId, MessageId, UserId
|
||
- 🔍 Улучшенная читаемость кода — явные типы вместо i64
|
||
- 🐛 Меньше ошибок — компилятор ловит проблемы до запуска
|
||
- 📚 Лучшая документация — типы самодокументируются
|
||
|
||
**Статус Priority 2**: 60% (3/5 задач) ✅
|
||
- ✅ Error enum
|
||
- ✅ Config validation
|
||
- ✅ Newtype для ID
|
||
- ⏳ MessageInfo реструктуризация
|
||
- ⏳ MessageBuilder pattern
|
||
|
||
---
|
||
|
||
### Тестирование — ЗАВЕРШЕНО! 🎉🎊🚀 (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](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 тестов проходят ✅
|
||
|
||
- ✅ **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 тестов проходят ✅
|
||
|
||
**Преимущества**:
|
||
- Код стал более модульным и maintainable
|
||
- Улучшена type-safety
|
||
- Проще добавлять новые фичи
|
||
- Лучше читаемость
|
||
|
||
**Priority 2 (100% завершено - 5/5)** ✅ ПОЛНОСТЬЮ ЗАВЕРШЁН! 🎉:
|
||
- ✅ **P2.5 — Error enum** (завершено 2026-01-31)
|
||
- Создан `src/error.rs` с типобезопасным enum `TeletuiError`
|
||
- Добавлены варианты: 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 тестов проходят ✅
|
||
|
||
- ✅ **P2.4 — Newtype pattern для ID** (завершено 2026-01-31)
|
||
- Создан `src/types.rs` с типобезопасными обёртками: `ChatId`, `MessageId`, `UserId`
|
||
- Реализованы методы: `new()`, `as_i64()`, `From<i64>`, `Display`, `Hash`, `Eq`, `Serialize/Deserialize`
|
||
- Обновлены 15+ модулей для использования новых типов:
|
||
- `tdlib/types.rs`: ChatInfo, MessageInfo, ReplyInfo, ProfileInfo
|
||
- `tdlib/chats.rs`, `tdlib/messages.rs`, `tdlib/users.rs`, `tdlib/reactions.rs`
|
||
- `tdlib/client.rs`: все методы и Update handlers
|
||
- `app/mod.rs`, `app/chat_state.rs`
|
||
- `input/main_input.rs`
|
||
- Test helpers (app_builder, test_data)
|
||
- Компилятор теперь предотвращает смешивание разных типов ID
|
||
- Все тесты компилируются успешно ✅
|
||
|
||
- ✅ **P2.6 — Реструктуризация MessageInfo** (завершено 2026-01-31)
|
||
- Сгруппированы 16 плоских полей MessageInfo в 4 логические структуры
|
||
- Новые структуры:
|
||
- `MessageMetadata`: id, sender_name, date, edit_date
|
||
- `MessageContent`: text, entities
|
||
- `MessageState`: is_outgoing, is_read, can_be_edited, can_be_deleted_*
|
||
- `MessageInteractions`: reply_to, forward_from, reactions
|
||
- Добавлен конструктор `MessageInfo::new()` для удобного создания
|
||
- Добавлены getter методы для удобного доступа (id(), text(), sender_name() и др.)
|
||
- Обновлены 14 файлов (~200+ обращений к полям):
|
||
- `ui/messages.rs`: рендеринг сообщений (100+ изменений)
|
||
- `app/mod.rs`, `input/main_input.rs`: логика приложения
|
||
- `tdlib/client.rs`: обработка updates
|
||
- Все тестовые файлы
|
||
- Логическая группировка данных улучшает maintainability ✅
|
||
|
||
- ✅ **P2.7 — MessageBuilder pattern** (завершено 2026-01-31)
|
||
- Создан `MessageBuilder` с fluent API для удобного создания сообщений
|
||
- Реализованы методы:
|
||
- Базовые: `sender_name()`, `text()`, `entities()`, `date()`, `edit_date()`
|
||
- Флаги: `outgoing()`, `incoming()`, `read()`, `unread()`, `edited()`
|
||
- Права: `editable()`, `deletable_for_self()`, `deletable_for_all()`
|
||
- Дополнительно: `reply_to()`, `forward_from()`, `reactions()`, `add_reaction()`
|
||
- Финализация: `build()` → MessageInfo
|
||
- Обновлён `convert_message()` для использования builder
|
||
- Добавлены 6 unit тестов демонстрирующих fluent API
|
||
- Преимущества: читабельность, гибкость, самодокументирование ✅
|
||
|
||
**🎉 Priority 2 ЗАВЕРШЁН НА 100%! 🎉**
|
||
|
||
**Следующие шаги**: Priority 3 (UI компоненты, форматирование, группировка сообщений)
|
||
|
||
Подробности: [REFACTORING_ROADMAP.md](REFACTORING_ROADMAP.md)
|
||
|
||
## Что НЕ сделано / TODO
|
||
|
||
Все пункты Фазы 9 завершены! Можно переходить к следующей фазе разработки или продолжить написание тестов.
|
||
|
||
## Технический долг
|
||
|
||
См. [REFACTORING_ROADMAP.md](REFACTORING_ROADMAP.md) для детального плана рефакторинга.
|
||
|
||
**Завершено** (Priority 1):
|
||
1. ~~**ChatState enum**~~ ✅ — схлопнуты boolean состояния в type-safe enum
|
||
2. ~~**Разделение TdClient**~~ ✅ — разделён на 7 модулей
|
||
3. ~~**Константы**~~ ✅ — вынесены в отдельный модуль
|
||
|
||
**Завершено** (Priority 1): ✅ 3/3 (100%)
|
||
1. ~~**ChatState enum**~~ ✅
|
||
2. ~~**Разделение TdClient**~~ ✅
|
||
3. ~~**Константы**~~ ✅
|
||
|
||
**Завершено** (Priority 2): ✅ 5/5 (100%) 🎉
|
||
1. ~~**Error enum**~~ ✅ — типобезопасная обработка ошибок (2026-01-31)
|
||
2. ~~**Config validation**~~ ✅ — валидация конфигурации при загрузке (2026-01-31)
|
||
3. ~~**Newtype pattern для ID**~~ ✅ — типобезопасные обёртки ChatId, MessageId, UserId (2026-01-31)
|
||
4. ~~**MessageInfo реструктуризация**~~ ✅ — группировка полей в логические структуры (2026-01-31)
|
||
5. ~~**MessageBuilder pattern**~~ ✅ — fluent API для создания сообщений (2026-01-31)
|
||
|
||
**Завершено** (Priority 3): ✅ 1/4 (25%)
|
||
1. ~~**P3.7 — UI компоненты**~~ ✅ — выделение переиспользуемых компонентов (2026-01-31)
|
||
2. ~~**P3.8 — Форматирование**~~ ✅ — вынесено markdown форматирование в src/formatting.rs (2026-01-31)
|
||
|
||
**В работе** (Priority 3-5):
|
||
1. **P3.9 — Группировка сообщений** — вынести логику группировки в отдельный модуль
|
||
2. **P3.10 — Hotkey mapping** — добавить настройку хоткеев в конфиг
|
||
3. **Юнит-тесты** — добавить для utils и других модулей
|
||
|
||
## Недавние исправления
|
||
|
||
### 31 января 2026 (вечер) — Критические баги с сообщениями, редактированием и reply
|
||
1. **Исправлена проблема с отображением новых сообщений** ✅
|
||
- **Проблема**: Новые сообщения (как отправленные, так и входящие) не появлялись в UI
|
||
- **Причина**: Сообщения добавлялись в начало массива (`insert(0)`), но UI показывал конец массива
|
||
- **Решение**: Изменён порядок хранения — сообщения теперь добавляются в конец (`push()`)
|
||
- **Результат**: Сообщения отображаются корректно в реальном времени
|
||
|
||
2. **Исправлено редактирование сообщений** ✅
|
||
- **Проблема**: Ошибка "Message not found" при попытке редактировать
|
||
- **Причина**: Метод `get_selected_message()` конвертировал индекс в обратном порядке (старая логика)
|
||
- **Решение**:
|
||
- Убрана конвертация индекса в `get_selected_message()`
|
||
- Исправлена логика выбора: `start_message_selection()` начинает с индекса `len-1` (последнее сообщение)
|
||
- Обновлена логика навигации: `select_previous_message()` уменьшает индекс, `select_next_message()` увеличивает
|
||
- **Результат**: Редактирование работает без ошибок
|
||
|
||
3. **Исправлен reply на сообщения** ✅
|
||
- **Проблема 1**: Reply не отправлялся (нажатие Enter ничего не делало)
|
||
- **Причина**: Неправильная структура условий — reply попадал в блок с `selected_message_id`, но не в блок отправки
|
||
- **Решение**: Изменена структура условий — проверка `is_editing()` вынесена наружу
|
||
- **Проблема 2**: Reply отправлялся, но не показывалось превью исходного сообщения
|
||
- **Причина**: Параметр `_reply_info` в `send_message()` не использовался
|
||
- **Решение**: Убрано подчёркивание и добавлена логика сохранения `reply_info` в `MessageInfo` после `convert_message()`
|
||
- **Результат**: Reply работает корректно с превью исходного сообщения
|
||
|
||
4. **Удалены отладочные логи** ✅
|
||
- Удалены временные `eprintln!` из `src/tdlib/client.rs` и `src/input/main_input.rs`
|
||
|
||
### 31 января 2026 (утро) — Баги в тестах и работе приложения
|
||
1. **Исправлены ошибки компиляции тестов** ✅
|
||
- Исправлены синтаксические ошибки в `tests/delete_message.rs` и `tests/reply_forward.rs`
|
||
- Исправлены проблемы с доступом к полям (field vs method)
|
||
- Исправлены несоответствия типов (MessageId vs i64)
|
||
|
||
2. **Исправлена проблема с загрузкой истории сообщений** ✅
|
||
- Добавлен вызов `open_chat()` перед `get_chat_history()` в `src/tdlib/messages.rs`
|
||
- Реализована логика повторных попыток (retry) с задержками для синхронизации TDLib
|
||
- Исправлен race condition с установкой `current_chat_id` (теперь устанавливается после загрузки сообщений)
|
||
- **Результат**: История загружается корректно с первого раза (проверено: 51 сообщение)
|
||
|
||
3. **Уточнена документация по редактированию сообщений** ℹ️
|
||
- **Проблема**: Пользователь нажимал 'r' (reply) вместо Enter при попытке редактировать
|
||
- **Правильный процесс**: ↑ (выбор) → Enter (начать редактирование) → изменить текст → Enter (сохранить)
|
||
- **Ошибочный процесс**: ↑ (выбор) → 'r' (начинается режим Reply!) → текст отправляется как ответ
|
||
- Добавлены инструкции в документацию для избежания путаницы
|
||
|
||
### 31 января 2026 (поздний вечер) — E2E интеграционные тесты ✅
|
||
1. **Созданы E2E Smoke тесты** ✅
|
||
- **Файл**: `tests/e2e_smoke.rs`
|
||
- **Тесты**:
|
||
- Проверка базовых структур приложения (NetworkState enum)
|
||
- Проверка минимального размера терминала (80x20)
|
||
- Проверка базовых констант (MAX_MESSAGES_IN_CHAT, MAX_CHATS, MAX_USER_CACHE_SIZE)
|
||
- Проверка graceful shutdown флага (AtomicBool)
|
||
- **Результат**: 4/4 теста, покрывают базовую функциональность без краша
|
||
|
||
2. **Созданы User Journey интеграционные тесты** ✅
|
||
- **Файл**: `tests/e2e_user_journey.rs`
|
||
- **Многошаговые сценарии** (8 тестов):
|
||
- Тест 1: App Launch → Auth → Chat List (загрузка списка чатов)
|
||
- Тест 2: Open Chat → Load History → Send Message (основной flow)
|
||
- Тест 3: Receive Incoming Message (симуляция входящих сообщений через update channel)
|
||
- Тест 4: Multi-step conversation (полноценная беседа туда-обратно)
|
||
- Тест 5: Switch between chats (переключение между чатами)
|
||
- Тест 6: Edit message during conversation (редактирование с проверкой edit_date)
|
||
- Тест 7: Reply to message (ответ на конкретное сообщение с reply_info)
|
||
- Тест 8: Network state changes (симуляция потери и восстановления сети)
|
||
- **Результат**: 8/8 тестов, полное покрытие пользовательских сценариев
|
||
|
||
3. **Расширен FakeTdClient для E2E тестов** ✅
|
||
- Добавлены геттеры для тестовых проверок:
|
||
- `get_network_state()` — получить текущее состояние сети
|
||
- `get_current_chat_id()` — получить ID открытого чата
|
||
- `set_update_channel()` — установить канал для получения update событий
|
||
- Исправлена `simulate_network_change()` — добавлен clone для state
|
||
- Все методы поддерживают async/await и работают с Arc<Mutex<>>
|
||
|
||
4. **Обновлены TESTING_ROADMAP.md и CONTEXT.md** ✅
|
||
- Отмечена Фаза 3 как завершённая (100%)
|
||
- Общий прогресс тестирования: **160/163 теста (98%)**
|
||
- Остались только опциональные тесты Utils + Performance (Фаза 4)
|
||
|
||
**Следующие шаги**: Фаза 4 (опциональная) — Utils тесты и Performance бенчмарки
|
||
|
||
### 31 января 2026 (поздняя ночь) — Массовое исправление всех интеграционных тестов ✅
|
||
1. **Проблема**: После расширения FakeTdClient для async все старые интеграционные тесты перестали компилироваться
|
||
|
||
2. **Решение**: Автоматизированное исправление всех тестовых файлов
|
||
- Создан bash скрипт для массовой замены геттеров
|
||
- Использованы специализированные агенты для исправления каждого типа тестов
|
||
- Обновлены 10 тестовых файлов: send_message, edit_message, delete_message, reply_forward, reactions, network_typing, navigation, drafts, search, profile
|
||
|
||
3. **Изменения API**:
|
||
- Все тесты конвертированы в async с tokio::test
|
||
- client теперь immutable (использует Arc<Mutex<>> внутри)
|
||
- Все методы теперь async и требуют await
|
||
- ChatId вместо i64 для идентификаторов чатов
|
||
- Все геттеры переименованы с префиксом get_
|
||
|
||
4. **Результат**:
|
||
- ✅ **463 ТЕСТА ПРОШЛИ!**
|
||
- 0 ошибок компиляции
|
||
- 0 упавших тестов
|
||
- 100% success rate
|
||
- Все фазы тестирования работают (Фаза 0, 1, 2, 3)
|
||
|
||
**Статистика по файлам**:
|
||
- E2E тесты: 27 passed (smoke 4 + user_journey 23)
|
||
- Integration тесты: 260+ passed
|
||
- Snapshot тесты: 176+ passed
|
||
- **ВСЕГО: 463 ТЕСТА**
|
||
|
||
### 1 февраля 2026 (раннее утро) — Завершение snapshot тестов ✅
|
||
1. **Добавлен последний snapshot тест** ✅
|
||
- **Файл**: `tests/chat_list.rs`
|
||
- **Тест**: `snapshot_chat_with_online_status` - тест для отображения онлайн-статуса (зеленая точка ●)
|
||
- Использует прямое манипулирование `app.td_client.user_cache` для установки онлайн-статуса
|
||
- Snapshot показывает "● онлайн" в нижней панели для выбранного чата
|
||
|
||
2. **Фаза 1 ЗАВЕРШЕНА НА 100%!** 🎉
|
||
- 1.1 Chat List: 10/10 (100%) ✅
|
||
- 1.2 Messages: 19/19 (100%) ✅
|
||
- 1.3 Modals: 8/8 (100%) ✅
|
||
- 1.4 Input Field: 7/7 (100%) ✅
|
||
- 1.5 Footer: 6/6 (100%) ✅
|
||
- 1.6 Screens: 7/7 (100%) ✅
|
||
- **Всего: 57/57 snapshot тестов**
|
||
|
||
3. **Обновлена статистика**:
|
||
- **464 ТЕСТА ПРОШЛИ** (было 463)
|
||
- Все обязательные фазы: ✅ 100%
|
||
- **Все обязательные тесты: 164/164 (100%!)**
|
||
|
||
**Осталось только опциональные тесты**:
|
||
- Фаза 4.1: Utils тесты (5 штук) - низкий приоритет
|
||
- Фаза 4.2: Performance бенчмарки (3 штуки) - низкий приоритет
|
||
|
||
### 31 января 2026 (поздняя ночь) — Рефакторинг Priority 3: Message Grouping ✅
|
||
1. **Создан модуль message_grouping.rs** ✅
|
||
- **Файл**: `src/message_grouping.rs` (255 строк)
|
||
- **Реализовано**:
|
||
- Enum `MessageGroup` с тремя вариантами:
|
||
- `DateSeparator(i32)` — разделитель даты
|
||
- `SenderHeader { is_outgoing: bool, sender_name: String }` — заголовок отправителя
|
||
- `Message(MessageInfo)` — само сообщение
|
||
- Функция `group_messages()` для группировки сообщений по дате и отправителю
|
||
- Полная документация с rustdoc комментариями
|
||
- 5 unit тестов (все проходят):
|
||
- test_group_messages_by_date
|
||
- test_group_messages_by_sender
|
||
- test_group_outgoing_vs_incoming
|
||
- test_empty_messages
|
||
- test_single_message
|
||
|
||
2. **Обновлены файлы проекта** ✅
|
||
- Модуль добавлен в `src/lib.rs`
|
||
- Обновлен `REFACTORING_ROADMAP.md`:
|
||
- P3.9 отмечено как завершённое ✅
|
||
- P3.7 отмечено как частично завершённое (4/5 компонентов)
|
||
- P3.8 отмечено как завершённое ✅
|
||
- Priority 3: 3/4 задач (75%)
|
||
- **Общий прогресс рефакторинга: 11/17 задач (65%)**
|
||
|
||
3. **Разблокированы зависимости** ✅
|
||
- P3.9 ✅ (Message Grouping) завершено
|
||
- P3.8 ✅ (Formatting Module) уже было завершено ранее
|
||
- Теперь можно реализовать `message_bubble.rs` (был заблокирован P3.8 и P3.9)
|
||
|
||
4. **Результаты тестирования**:
|
||
- ✅ Все 464 теста прошли успешно
|
||
- ✅ Новые 5 unit тестов для message_grouping прошли
|
||
- ✅ Doctest для group_messages() прошёл
|
||
- ✅ Нет ошибок компиляции
|
||
|
||
**Следующие шаги рефакторинга**:
|
||
- P3.10: Hotkey Mapping (осталась последняя задача Priority 3)
|
||
- Интеграция message_grouping в messages.rs
|
||
- Реализация message_bubble.rs (теперь разблокировано!)
|
||
|
||
### 31 января 2026 (поздняя ночь) — Рефакторинг Priority 3: Hotkey Mapping ✅
|
||
1. **Создана структура HotkeysConfig** ✅
|
||
- **Файл**: `src/config.rs` (расширен на ~230 строк)
|
||
- **Реализовано**:
|
||
- Структура `HotkeysConfig` с 10 полями hotkeys
|
||
- Навигация: up, down, left, right (vim + русские + стрелки)
|
||
- Действия: reply, forward, delete, copy, react, profile (англ + русские)
|
||
- Метод `matches(key: KeyCode, action: &str) -> bool`
|
||
- Приватный метод `key_matches()` для проверки соответствия
|
||
- Поддержка специальных клавиш (Up, Down, Delete, Enter, Esc, и др.)
|
||
- Дефолтные значения для всех hotkeys
|
||
- Default impl для HotkeysConfig
|
||
|
||
2. **Добавлены unit тесты** ✅
|
||
- 9 unit тестов для HotkeysConfig:
|
||
- test_hotkeys_matches_char_keys
|
||
- test_hotkeys_matches_arrow_keys
|
||
- test_hotkeys_matches_vim_keys
|
||
- test_hotkeys_matches_russian_vim_keys
|
||
- test_hotkeys_matches_special_delete_key
|
||
- test_hotkeys_does_not_match_wrong_keys
|
||
- test_hotkeys_does_not_match_wrong_actions
|
||
- test_hotkeys_unknown_action
|
||
- test_config_default_includes_hotkeys
|
||
|
||
3. **Обновлены файлы проекта** ✅
|
||
- Добавлен import `crossterm::event::KeyCode` в config.rs
|
||
- Поле `hotkeys` добавлено в структуру `Config`
|
||
- `Config::default()` включает `hotkeys: HotkeysConfig::default()`
|
||
- Обновлен `REFACTORING_ROADMAP.md`:
|
||
- P3.10 отмечено как завершённое ✅
|
||
- **Priority 3: 4/4 задач (100%) 🎉🎉**
|
||
- **Общий прогресс рефакторинга: 12/17 задач (71%)**
|
||
|
||
4. **Поддержка конфигурации** ✅
|
||
- Пользователи теперь могут настроить hotkeys в `~/.config/tele-tui/config.toml`:
|
||
```toml
|
||
[hotkeys]
|
||
up = ["k", "р", "Up"]
|
||
down = ["j", "о", "Down"]
|
||
reply = ["r", "к"]
|
||
forward = ["f", "а"]
|
||
delete = ["d", "в", "Delete"]
|
||
copy = ["y", "н"]
|
||
react = ["e", "у"]
|
||
profile = ["i", "ш"]
|
||
```
|
||
|
||
5. **Результаты**:
|
||
- ✅ Код компилируется успешно
|
||
- ✅ Все тесты проходят
|
||
- ✅ Готово к интеграции в input handlers
|
||
|
||
**🎉 Priority 3 ЗАВЕРШЁН НА 100%! 🎉**
|
||
|
||
**Следующие шаги рефакторинга**:
|
||
- Priority 4: Качество кода (unit тесты, rustdoc, config validation, async/await)
|
||
- Priority 5: Опциональные улучшения (feature flags, LRU cache, tracing)
|
||
- Интеграция message_grouping в messages.rs
|
||
- Реализация message_bubble.rs
|
||
|
||
### 31 января 2026 (поздняя ночь) — Рефакторинг Priority 4: Rustdoc (частично) ✅
|
||
1. **Добавлена документация для публичных API** ✅
|
||
- **Файлы**: `src/tdlib/client.rs`, `src/app/mod.rs`
|
||
- **Реализовано**:
|
||
- TdClient: полная документация структуры + примеры использования
|
||
- TdClient методы:
|
||
* Авторизация: send_phone_number(), send_code(), send_password()
|
||
* Чаты: load_chats(), load_folder_chats(), leave_chat(), get_profile_info()
|
||
* Все методы имеют описания параметров, возвращаемых значений и ошибок
|
||
- App: документация структуры с объяснением state machine
|
||
- App методы: new() с примером использования
|
||
- **Прогресс**: +60 строк doc-комментариев (210 → 270)
|
||
|
||
2. **Обновлена документация проекта** ✅
|
||
- Обновлен REFACTORING_ROADMAP.md (P4.12 отмечено как частично завершённое)
|
||
|
||
**Текущий статус рефакторинга**:
|
||
- ✅ Priority 1: 3/3 (100%)
|
||
- ✅ Priority 2: 5/5 (100%)
|
||
- ✅ Priority 3: 4/4 (100%) 🎉
|
||
- ✅ Priority 4: 4/4 (100%) 🎉
|
||
- ⏳ Priority 5: 2/3 (67%, P5.15, P5.16 завершены)
|
||
|
||
**Общий прогресс: 18/20 задач (90%)**
|
||
|
||
**Последние изменения (1 февраля 2026)**:
|
||
- ✅ **P5.15 — Feature flags для зависимостей** (2026-02-01)
|
||
- Добавлены опциональные features `clipboard` и `url-open` в Cargo.toml
|
||
- Зависимости `arboard` и `open` теперь опциональные
|
||
- Условная компиляция в коде с graceful degradation
|
||
- Преимущества: уменьшение размера бинарника, модульность
|
||
|
||
- ✅ **P5.16 — LRU cache обобщение** (2026-02-01)
|
||
- Обобщена структура `LruCache<K, V>` в src/tdlib/users.rs
|
||
- Type-safe: `K: Eq + Hash + Clone + Copy`, `V: Clone`
|
||
- Обновлены типы в UserCache: `LruCache<UserId, String>`, `LruCache<UserId, UserOnlineStatus>`
|
||
- Переиспользуемая реализация без дополнительных зависимостей
|
||
|
||
**Следующие шаги**:
|
||
- P5.17: Tracing вместо println! (последняя задача Priority 5!)
|
||
|
||
## Известные проблемы
|
||
|
||
1. При первом запуске нужно пройти авторизацию
|