Files
telegram-tui/ROADMAP.md
Mikhail Kilin ffd52d2384 refactor: complete Phase 13 deep architecture refactoring (etaps 3-7)
Split monolithic files into modular architecture:
- ui/messages.rs (893→365 lines): extract modals/, compose_bar.rs
- tdlib/messages.rs (836→3 files): split into messages/mod, convert, operations
- config/mod.rs (642→3 files): extract validation.rs, loader.rs
- Code duplication cleanup: shared components, ~220 lines removed
- Documentation: PROJECT_STRUCTURE.md rewrite, 16 files got //! docs

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-06 15:28:11 +03:00

675 lines
35 KiB
Markdown
Raw 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.
# Roadmap
## Фаза 1: Базовая инфраструктура [DONE]
- [x] Настройка проекта (Cargo.toml)
- [x] TUI фреймворк (ratatui + crossterm)
- [x] Базовый layout (папки, список чатов, область сообщений)
- [x] Vim-style навигация (hjkl, стрелки)
- [x] Русская раскладка (ролд)
## Фаза 2: TDLib интеграция [DONE]
- [x] Подключение tdlib-rs
- [x] Авторизация (телефон + код + 2FA)
- [x] Сохранение сессии
- [x] Загрузка списка чатов
- [x] Загрузка истории сообщений
- [x] Отключение логов TDLib
## Фаза 3: Улучшение UX [DONE]
- [x] Отправка сообщений
- [x] Фильтрация чатов (только Main, без архива)
- [x] Поиск по чатам (Ctrl+S)
- [x] Скролл истории сообщений
- [x] Загрузка имён пользователей (вместо User_ID)
- [x] Отметка сообщений как прочитанные
- [x] Реальное время: новые сообщения
## Фаза 4: Папки и фильтрация [DONE]
- [x] Загрузка папок из Telegram
- [x] Переключение между папками (1-9)
- [x] Фильтрация чатов по папке
## Фаза 5: Расширенный функционал [DONE]
- [x] Отображение онлайн-статуса (зелёная точка ●)
- [x] Статус доставки/прочтения (✓, ✓✓)
- [x] Поддержка медиа-заглушек (фото, видео, голосовые, стикеры и др.)
- [x] Mentions (@) — индикатор непрочитанных упоминаний
- [x] Muted чаты (иконка 🔇)
## Фаза 6: Полировка [DONE]
- [x] Оптимизация использования памяти (базовая)
- Очистка сообщений при закрытии чата
- Лимит кэша пользователей (500)
- Периодическая очистка неактивных записей
- [x] Оптимизация 60 FPS
- Poll таймаут 16ms
- Флаг `needs_redraw` — рендеринг только при изменениях
- Обработка Event::Resize для перерисовки при изменении размера
- [x] Минимальное разрешение (80x20)
- Предупреждение если терминал слишком мал
- [x] Обработка ошибок сети
- NetworkState enum (WaitingForNetwork, Connecting, etc.)
- Индикатор в футере с цветовой индикацией
- [x] Graceful shutdown
- AtomicBool флаг для остановки polling
- Корректное закрытие TDLib клиента
- Таймаут ожидания завершения задач
- [x] Динамический инпут
- Автоматическое расширение до 10 строк
- Wrap для длинного текста
- [x] Перенос длинных сообщений
- Автоматический wrap на несколько строк
- Правильное выравнивание для исходящих/входящих
## Фаза 7: Глубокий рефакторинг памяти [DONE]
- [x] Удалить дублирование current_messages между App и TdClient
- [x] Использовать единый источник данных для сообщений
- [x] Реализовать LRU-кэш для user_names/user_statuses вместо простого лимита
- [x] Lazy loading для имён пользователей (батчевая загрузка последних 5 за цикл)
- [x] Лимиты памяти:
- MAX_MESSAGES_IN_CHAT = 500
- MAX_CHATS = 200
- MAX_CHAT_USER_IDS = 500
- MAX_USER_CACHE_SIZE = 500 (LRU)
## Фаза 8: Дополнительные фичи [DONE]
- [x] Markdown форматирование в сообщениях
- Bold, Italic, Underline, Strikethrough
- Code (inline, Pre, PreCode)
- Spoiler (скрытый текст)
- URLs, упоминания (@)
- [x] Редактирование сообщений
- ↑ при пустом инпуте → выбор сообщения
- Enter для начала редактирования
- Подсветка выбранного сообщения (▶)
- Esc для отмены
- [x] Удаление сообщений
- d / в / Delete в режиме выбора
- Модалка подтверждения (y/n)
- Удаление для всех если возможно
- [x] Индикатор редактирования (✎)
- Отображается рядом с временем для отредактированных сообщений
- [x] Блочный курсор в поле ввода
- Vim-style курсор █
- Перемещение ←/→, Home/End
- Редактирование в любой позиции
- [x] Reply на сообщения
- `r` / `к` в режиме выбора → режим ответа
- Превью сообщения в поле ввода
- Esc для отмены
- [x] Forward сообщений
- `f` / `а` в режиме выбора → режим пересылки
- Превью сообщения в поле ввода
- Выбор чата стрелками, Enter для пересылки
- Esc для отмены
- Отображение "↪ Переслано от" для пересланных сообщений
## Фаза 9: Расширенные возможности [DONE]
- [x] Typing indicator ("печатает...")
- Показывать когда собеседник печатает
- Отправлять свой статус печати при наборе текста
- [x] Закреплённые сообщения (Pinned)
- Отображать pinned message вверху открытого чата
- Клик/хоткей для перехода к закреплённому сообщению
- [x] Поиск по сообщениям в чате
- `Ctrl+F` — поиск текста внутри открытого чата
- Навигация по результатам (n/N или стрелки)
- Подсветка найденных совпадений
- [x] Черновики
- Сохранять набранный текст при переключении между чатами
- Индикатор черновика в списке чатов
- Восстановление текста при возврате в чат
- [x] Профиль пользователя/чата
- `Ctrl+i` — открыть информацию о чате/собеседнике
- Для личных чатов: имя, username, телефон, био
- Для групп: название, описание, количество участников
- [x] Копирование сообщений
- `y` / `н` в режиме выбора — скопировать текст в системный буфер обмена
- Использовать clipboard crate для кроссплатформенности
- [x] Реакции
- Отображение реакций под сообщениями
- `e` в режиме выбора — добавить реакцию (emoji picker)
- Список доступных реакций чата
- [x] Конфигурационный файл
- `~/.config/tele-tui/config.toml`
- Настройки: цветовая схема, часовой пояс, хоткеи
- Загрузка конфига при старте
## Фаза 10: Desktop уведомления [DONE - 83%]
### Стадия 1: Базовая реализация [DONE]
- [x] NotificationManager модуль
- notify-rust интеграция (версия 4.11)
- Feature flag "notifications" в Cargo.toml
- Базовая структура с настройками
- [x] Конфигурация уведомлений
- NotificationsConfig в config.toml
- enabled: bool - вкл/выкл уведомлений
- only_mentions: bool - только упоминания
- show_preview: bool - показывать превью текста
- [x] Интеграция с TdClient
- Поле notification_manager в TdClient
- Метод configure_notifications()
- Обработка в handle_new_message_update()
- [x] Базовая отправка уведомлений
- Уведомления для сообщений не из текущего чата
- Форматирование title (имя чата) и body (текст/медиа-заглушка)
- Sender name из MessageInfo
### Стадия 2: Улучшения [IN PROGRESS]
- [x] Синхронизация muted чатов
- Загрузка списка muted чатов из Telegram
- Вызов sync_muted_chats() при инициализации и обновлении (Ctrl+R)
- Muted чаты автоматически фильтруются из уведомлений
- [x] Фильтрация по упоминаниям
- Метод MessageInfo::has_mention() проверяет TextEntityType::Mention и MentionName
- NotificationManager применяет фильтр only_mentions из конфига
- Работает для @username и inline mentions
- [x] Поддержка типов медиа
- Метод beautify_media_labels() заменяет текстовые заглушки на emoji
- Поддержка: 📷 Фото, 🎥 Видео, 🎞️ GIF, 🎤 Голосовое, 🎨 Стикер
- Также: 📎 Файл, 🎵 Аудио, 📹 Видеосообщение, 📍 Локация, 👤 Контакт, 📊 Опрос
- [ ] Кастомизация звуков
- Настройка звуков уведомлений в config.toml
- Разные звуки для разных типов сообщений
### Стадия 3: Полировка [DONE]
- [x] Обработка ошибок
- Graceful fallback если уведомления недоступны (возвращает Ok без паники)
- Логирование ошибок через tracing::warn!
- Детальное логирование причин пропуска уведомлений (debug level)
- [x] Дополнительные настройки
- timeout_ms - продолжительность показа (0 = системное значение)
- urgency - уровень важности: "low", "normal", "critical" (только Linux)
- Красивые эмодзи для типов медиа
- [ ] Опциональные улучшения (не критично)
- Кросс-платформенное тестирование (требует ручного тестирования)
- icon - кастомная иконка приложения
- Actions в уведомлениях (кнопки "Ответить", "Прочитано")
## Фаза 11: Показ изображений в чате [PLANNED]
### Этап 1: Инфраструктура [TODO]
- [ ] Модуль src/media/
- image_cache.rs - LRU кэш для загруженных изображений
- image_loader.rs - Асинхронная загрузка через TDLib
- image_renderer.rs - Рендеринг в ratatui
- [ ] Зависимости
- ratatui-image 1.0 - поддержка изображений в TUI
- Определение протокола терминала (Sixel/Kitty/iTerm2/Halfblocks)
- [ ] ImageCache с лимитами
- LRU кэш с максимальным размером в МБ
- Автоматическая очистка старых изображений
- MAX_IMAGE_CACHE_SIZE = 100 MB (по умолчанию)
### Этап 2: Интеграция с TDLib [TODO]
- [ ] Обработка MessageContentPhoto
- Добавить PhotoInfo в MessageInfo
- Извлечение file_id, width, height из Photo
- Выбор оптимального размера изображения (до 800px)
- [ ] Загрузка файлов
- Метод TdClient::download_photo(file_id)
- Асинхронная загрузка через downloadFile API
- Обработка состояний загрузки (pending/downloading/ready)
- [ ] Кэширование
- Сохранение путей к загруженным файлам
- Повторное использование уже загруженных изображений
### Этап 3: Рендеринг в UI [TODO]
- [ ] Модификация render_messages()
- Определение возможностей терминала при старте
- Рендеринг изображений через ratatui-image
- Автоматическое масштабирование под размер области
- Сохранение aspect ratio
- [ ] Превью в списке сообщений
- Миниатюры размером 20x10 символов
- Lazy loading (загрузка только видимых)
- Placeholder пока изображение грузится
- [ ] Индикатор загрузки
- Текстовая заглушка "[Загрузка фото...]"
- Progress bar для больших файлов
- Процент загрузки
### Этап 4: Полноэкранный просмотр [TODO]
- [ ] Новый режим: ViewImage
- `v` / `м` в режиме выбора - открыть изображение
- Показ на весь экран терминала
- `Esc` для закрытия
- [ ] Информация об изображении
- Размер файла
- Разрешение (width x height)
- Формат (JPEG/PNG/GIF)
- [ ] Навигация
- `←` / `→` - предыдущее/следующее изображение в чате
- Автоматическая загрузка соседних изображений
### Этап 5: Конфигурация и UX [TODO]
- [ ] MediaConfig в config.toml
- show_images: bool - включить/отключить показ изображений
- image_cache_mb: usize - размер кэша в МБ
- preview_quality: "low" | "medium" | "high"
- render_protocol: "auto" | "sixel" | "kitty" | "iterm2" | "halfblocks"
- [ ] Поддержка различных терминалов
- Auto-detection протокола при старте
- Fallback на Unicode halfblocks для любого терминала
- Опция отключения изображений если терминал не поддерживает
- [ ] Оптимизация производительности
- Асинхронная загрузка (не блокирует UI)
- Приоритизация видимых изображений
- Fast resize для превью
- Кэширование отмасштабированных версий
### Этап 6: Обработка ошибок [TODO]
- [ ] Graceful fallback
- Текстовая заглушка "[Фото]" если загрузка не удалась
- Повторная попытка по запросу пользователя
- Логирование проблем через tracing
- [ ] Ограничения
- Таймаут загрузки (30 сек)
- Максимальный размер файла для автозагрузки (10 MB)
- Предупреждение для больших файлов
### Технические детали
- **Поддерживаемые протоколы:**
- Sixel (xterm, WezTerm, mintty)
- Kitty Graphics Protocol (Kitty terminal)
- iTerm2 Inline Images (iTerm2 на macOS)
- Unicode Halfblocks (fallback для всех)
- **Поддерживаемые форматы:**
- JPEG, PNG, GIF, WebP, BMP
- **Новые хоткеи:**
- `v` / `м` - открыть изображение в полном размере (режим выбора)
- `←` / `→` - навигация между изображениями (в режиме просмотра)
- `Esc` - закрыть полноэкранный просмотр
## Фаза 12: Прослушивание голосовых сообщений [PLANNED]
### Этап 1: Инфраструктура аудио [TODO]
- [ ] Модуль src/audio/
- player.rs - AudioPlayer на rodio
- cache.rs - VoiceCache для загруженных файлов
- state.rs - PlaybackState (статус, позиция, громкость)
- [ ] Зависимости
- rodio 0.17 - Pure Rust аудио библиотека
- Feature flag "audio" в Cargo.toml
- [ ] AudioPlayer API
- play() - воспроизведение файла
- pause() / resume() - пауза/возобновление
- stop() - остановка
- seek() - перемотка
- set_volume() - регулировка громкости
- get_position() - текущая позиция
- [ ] VoiceCache
- Кэш загруженных OGG файлов в ~/.cache/tele-tui/voice/
- LRU политика очистки
- MAX_VOICE_CACHE_SIZE = 100 MB
### Этап 2: Интеграция с TDLib [TODO]
- [ ] Обработка MessageContentVoiceNote
- Добавить VoiceNoteInfo в MessageInfo
- Извлечение file_id, duration, mime_type, waveform
- Метка формата (OGG Opus обычно)
- [ ] Загрузка файлов
- Метод TdClient::download_voice_note(file_id)
- Асинхронная загрузка через downloadFile API
- Обработка состояний (pending/downloading/ready)
- [ ] Кэширование
- Сохранение путей к загруженным файлам
- Не перезагружать уже скачанные голосовые
- Проверка существования файла перед воспроизведением
### Этап 3: UI для воспроизведения [TODO]
- [ ] Индикатор в сообщении
- Иконка 🎤 и длительность голосового
- Progress bar во время воспроизведения
- Статус: ▶ (playing), ⏸ (paused), ⏹ (stopped), ⏳ (loading)
- Текущее время / общая длительность (0:08 / 0:15)
- [ ] Модификация render_messages()
- render_voice_note() для голосовых сообщений
- render_progress_bar() для индикатора воспроизведения
- Hint "[Space] Воспроизвести" если не играет
- [ ] Footer с управлением
- Отображение доступных команд при воспроизведении
- "[Space] Play/Pause [s] Stop [←/→] Seek [↑/↓] Volume"
- [ ] Waveform визуализация (опционально)
- Конвертация waveform данных из Telegram в ASCII bars
- Использование символов ▁▂▃▄▅▆▇█ для визуализации
### Этап 4: Хоткеи для управления [TODO]
- [ ] Новые команды
- PlayVoice - Space в режиме выбора голосового
- PauseVoice - Space во время воспроизведения
- StopVoice - s / ы
- SeekBackward - ← (перемотка назад на 5 сек)
- SeekForward - → (перемотка вперед на 5 сек)
- VolumeUp - ↑ (увеличить на 10%)
- VolumeDown - ↓ (уменьшить на 10%)
- [ ] Контекстная обработка
- Space работает как play/pause в зависимости от состояния
- ← / → для seek только во время воспроизведения
- ↑ / ↓ для громкости только во время воспроизведения
- [ ] Поддержка русской раскладки
- s / ы - stop
- Остальные клавиши универсальны (Space, стрелки)
### Этап 5: Конфигурация и UX [TODO]
- [ ] AudioConfig в config.toml
- enabled: bool - включить/отключить аудио
- default_volume: f32 - громкость по умолчанию (0.0 - 1.0)
- seek_step_seconds: i32 - шаг перемотки в секундах
- autoplay: bool - автовоспроизведение при выборе
- cache_size_mb: usize - размер кэша голосовых
- show_waveform: bool - показывать waveform визуализацию
- system_player_fallback: bool - использовать системный плеер
- system_player: String - команда системного плеера (mpv, ffplay)
- [ ] Асинхронная загрузка
- Не блокировать UI во время загрузки файла
- Индикатор загрузки с процентами
- Возможность отмены загрузки
- [ ] Обновление UI
- Ticker для обновления progress bar (каждые 100ms)
- Плавное обновление позиции воспроизведения
- Автоматическая остановка при достижении конца
### Этап 6: Обработка ошибок [TODO]
- [ ] Graceful fallback на системный плеер
- Если rodio не работает - использовать mpv/ffplay
- Логирование ошибок через tracing
- Предупреждение пользователю если аудио недоступно
- [ ] Обработка ошибок загрузки
- Таймаут загрузки (30 сек)
- Повторная попытка по запросу
- Сообщение об ошибке в UI
- [ ] Ограничения
- Максимальный размер файла для кэша
- Автоматическая очистка старых файлов
- Предупреждение для очень длинных голосовых (>5 мин)
### Этап 7: Дополнительные улучшения [TODO]
- [ ] Управление воспроизведением
- Автоматическая остановка при закрытии чата
- Сохранение позиции при паузе
- Автопереход к следующему голосовому (опционально)
- [ ] Оптимизация
- Lazy loading (загрузка только при воспроизведении)
- Префетчинг следующего голосового (опционально)
- Минимальная задержка при нажатии Play
- [ ] Визуальные улучшения
- Анимация progress bar
- Цветовая индикация статуса (зеленый - playing, желтый - paused)
- Иконки в зависимости от статуса
### Технические детали
- **Аудио библиотека:**
- rodio 0.17 (Pure Rust, кроссплатформенная)
- Поддержка OGG Opus (формат голосовых в Telegram)
- Контроль воспроизведения через Sink API
- **Платформы:**
- Linux (ALSA, PulseAudio)
- macOS (CoreAudio)
- Windows (WASAPI)
- **Fallback:**
- mpv --no-video (универсальный плеер)
- ffplay -nodisp (из ffmpeg)
- **Новые хоткеи:**
- `Space` - воспроизвести/пауза (в режиме выбора голосового)
- `s` / `ы` - остановить воспроизведение
- `←` / `→` - перемотка -5с / +5с (во время воспроизведения)
- `↑` / `↓` - громкость +/- 10% (во время воспроизведения)
## Фаза 13: Глубокий рефакторинг архитектуры [DONE]
**Мотивация:** Код вырос до критических размеров - некоторые файлы содержат >1000 строк, что затрудняет поддержку и навигацию. Необходимо разбить монолитные файлы на логические модули.
**Проблемы:**
- `src/input/main_input.rs` - 1199 строк (самый большой файл!)
- `src/app/mod.rs` - 1015 строк, 116 функций (God Object)
- `src/ui/messages.rs` - 893 строки
- `src/tdlib/messages.rs` - 833 строки
- `src/config/mod.rs` - 642 строки
### Этап 1: Разбить input/main_input.rs (1199 → <200 строк) [DONE ✅]
**Текущая проблема:**
- Весь input handling в одном файле
- Функции по 300-400 строк
- Невозможно быстро найти нужный handler
**План:**
- [x] Создать `src/input/handlers/` директорию
- [x] Создать `handlers/chat.rs` - обработка ввода в открытом чате
- Переместить `handle_open_chat_keyboard_input()`
- Обработка скролла, выбора сообщений
- **452 строки** (7 функций)
- [x] Создать `handlers/chat_list.rs` - обработка в списке чатов
- Переместить `handle_chat_list_keyboard_input()`
- Навигация по чатам, папки
- **142 строки** (3 функции)
- [x] Создать `handlers/compose.rs` - режимы edit/reply/forward
- Обработка ввода в режимах редактирования
- Input field управление (курсор, backspace, delete)
- **80 строк** (2 функции)
- [x] Создать `handlers/modal.rs` - модалки
- Delete confirmation
- Emoji picker
- Profile modal
- **316 строк** (5 функций)
- [x] Создать `handlers/search.rs` - поиск
- Search mode в чате
- Search mode в списке чатов
- **140 строк** (3 функций)
- [x] Обновить `main_input.rs` - только роутинг
- Определение текущего режима
- Делегация в нужный handler
- **164 строки** (2 функции)
**Результат:** 1199 строк → **164 строки** (удалено 1035 строк, -86%)
- Создано 5 новых модулей обработки ввода
- Чистый router pattern в main_input.rs
- Каждый handler отвечает за свою область
- **Дополнительно:** Исправлен конфликт Ctrl+I → Ctrl+U для профиля
### Этап 2: Уменьшить app/mod.rs (116 функций → traits) [DONE ✅]
**Текущая проблема:**
- God Object с 116 функциями
- Сложно найти нужный метод
- Нарушение Single Responsibility Principle
**План:**
- [x] Создать `app/methods/` директорию
- [x] Создать trait `NavigationMethods`
- `next_chat()`, `previous_chat()`, `select_current_chat()`, `close_chat()`
- `next_filtered_chat()`, `previous_filtered_chat()`, `select_filtered_chat()`
- **7 методов**
- [x] Создать trait `MessageMethods`
- `start_message_selection()`, `select_previous/next_message()`
- `get_selected_message()`, `start_editing_selected()`, `cancel_editing()`
- `is_editing()`, `is_selecting_message()`
- **8 методов**
- [x] Создать trait `ComposeMethods`
- `start_reply_to_selected()`, `cancel_reply()`, `is_replying()`, `get_replying_to_message()`
- `start_forward_selected()`, `cancel_forward()`, `is_forwarding()`, `get_forwarding_message()`
- `get_current_draft()`, `load_draft()`
- **10 методов**
- [x] Создать trait `SearchMethods`
- Chat search: `start_search()`, `cancel_search()`, `get_filtered_chats()`
- Message search: `enter/exit_message_search_mode()`, `set/get_search_results()`
- Navigation: `select_previous/next_search_result()`, query управление
- **15 методов**
- [x] Создать trait `ModalMethods`
- Delete confirmation: `is_confirm_delete_shown()`
- Pinned: `is/enter/exit_pinned_mode()`, `select_previous/next_pinned()`, getters
- Profile: `is/enter/exit_profile_mode()`, navigation, leave_group confirmation
- Reactions: `is/enter/exit_reaction_picker_mode()`, `select_previous/next_reaction()`
- **27 методов**
- [x] Оставить в `app/mod.rs` только:
- Struct definition
- Constructors (new, with_client)
- Utilities (get_command, get_selected_chat_id, get_selected_chat)
- Getters/setters для всех полей
- **~48 методов**
**Структура:**
```rust
// app/mod.rs - только core
mod methods;
pub use methods::*;
impl<T: TdClientTrait> App<T> {
pub fn new() -> Self { ... }
pub fn get_command(...) -> Option<Command> { ... }
pub fn get_selected_chat_id(&self) -> Option<i64> { ... }
// ... getters/setters ...
}
// app/methods/navigation.rs
pub trait NavigationMethods<T: TdClientTrait> {
fn next_chat(&mut self);
fn previous_chat(&mut self);
}
impl<T: TdClientTrait> NavigationMethods<T> for App<T> { ... }
```
**Результат:** 1015 строк → **371 строка** (удалено 644 строки, -63%)
- 116 функций → 5 trait impl блоков (67 методов в traits + 48 в core)
- Каждый trait отвечает за свою область функциональности
- Соблюдён Single Responsibility Principle ✅
### Этап 3: Разбить ui/messages.rs (893 → 365 строк) [DONE ✅]
**Текущая проблема:**
- Весь UI рендеринг сообщений в одном файле
- Модалки смешаны с основным рендерингом
- Compose bar (input field) в том же файле
**План:**
- [x] Создать `ui/modals/` директорию
- [x] Создать `modals/mod.rs` - экспорты модальных окон
- [x] Создать `modals/delete_confirm.rs`
- Wrapper для компонента подтверждения удаления
- **~8 строк**
- [x] Создать `modals/reaction_picker.rs`
- Wrapper для компонента выбора реакций
- **~13 строк**
- [x] Создать `modals/search.rs`
- Поиск по сообщениям в чате
- Input с курсором, результаты, навигация
- **193 строки**
- [x] Создать `modals/pinned.rs`
- Просмотр закреплённых сообщений
- Header, список сообщений, навигация
- **163 строки**
- [x] Создать `ui/compose_bar.rs`
- Поле ввода с поддержкой 5 режимов
- Режимы: normal, edit, reply, forward, select
- Динамический preview для каждого режима
- **168 строк**
- [x] Обновить `messages.rs`:
- Оставлен только core rendering
- Chat header, pinned bar, message list
- Utility функции (wrap_text_with_offsets, WrappedLine)
- Интеграция через compose_bar::render() и modals::render_*()
- **365 строк**
**Результат:** 893 строки → **365 строк** (удалено 528 строк, -59%)
- Создано 6 новых модулей UI
- Чистое разделение ответственности
- Модальные окна полностью изолированы
- Compose bar - отдельный переиспользуемый компонент
### Этап 4: Разбить tdlib/messages.rs (833 → 3 файла) [DONE ✅]
**Текущая проблема:**
- Смешивается конвертация из TDLib и операции
- Большой файл сложно читать
**План:**
- [x] Создать `tdlib/messages/` директорию
- [x] Создать `messages/convert.rs`
- convert_message(), fetch_missing_reply_info(), fetch_and_update_reply()
- **134 строки**
- [x] Создать `messages/operations.rs`
- 11 TDLib API операций (send, edit, delete, forward, search, etc.)
- **616 строк**
- [x] Обновить `tdlib/messages.rs``tdlib/messages/mod.rs`
- Struct MessageManager, new(), push_message()
- **99 строк**
**Результат:** 836 строк → 3 файла (99 + 134 + 616)
### Этап 5: Разбить config/mod.rs (642 → 3 файла) [DONE ✅]
**Текущая проблема:**
- Много default_* функций (по 1-3 строки каждая)
- Validation logic смешана с определениями
- Сложно найти нужную секцию конфига
**План:**
- [x] Создать `config/validation.rs`
- validate(), parse_color()
- **86 строк**
- [x] Создать `config/loader.rs`
- load(), save(), paths, credentials
- **192 строки**
- [x] Оставить в `config/mod.rs`:
- Structs, defaults, Default impls, tests
- **350 строк**
**Результат:** 642 строки → 3 файла (350 + 86 + 192)
### Этап 6: Code Duplication Cleanup [DONE ✅]
**План:**
- [x] Очистка неиспользуемых импортов в 7 файлах
- [x] Извлечение `format_user_status()` в `ui/chat_list.rs` (удалено ~80 строк дублей)
- [x] Создание `ui/components/message_list.rs` — общие render_message_item, calculate_scroll_offset, render_help_bar (удалено ~120 строк дублей)
- [x] Извлечение `scroll_to_message()` в `input/handlers/mod.rs` (удалено ~20 строк дублей)
- **Итого:** удалено ~220 строк дублированного кода, 0 compiler warnings
### Этап 7: Documentation Update [DONE ✅]
**План:**
- [x] Обновить CONTEXT.md с новой структурой
- [x] Полностью переписать PROJECT_STRUCTURE.md (архитектура, дерево файлов, traits, state machine)
- [x] Добавить module-level документацию (`//!`) к 16 файлам
- [x] Создать architecture diagram (ASCII) в PROJECT_STRUCTURE.md
### Метрики успеха
**До рефакторинга:**
```
input/main_input.rs: 1199 строк
app/mod.rs: 1015 строк (116 функций)
ui/messages.rs: 893 строки
tdlib/messages.rs: 833 строки
config/mod.rs: 642 строки
ИТОГО: 4582 строки в 5 файлах
```
**После рефакторинга:**
```
input/handlers/*.rs: ~6 файлов по <400 строк
app/methods/*.rs: ~6 traits с impl блоками
ui/modals/*.rs: ~4 файла по <150 строк
tdlib/messages/*.rs: 2 файла по <500 строк
config/*.rs: 4 файла по <200 строк
ИТОГО: те же строки, но в ~20+ файлах
```
**Преимущества:**
- ✅ Легче найти нужный код
- ✅ Легче тестировать модули
- ✅ Меньше конфликтов при работе в команде
- ✅ Лучше читаемость и поддерживаемость
- ✅ Соблюдение Single Responsibility Principle