Some checks failed
CI / Check (pull_request) Has been cancelled
CI / Format (pull_request) Has been cancelled
CI / Clippy (pull_request) Has been cancelled
CI / Build (macos-latest) (pull_request) Has been cancelled
CI / Build (ubuntu-latest) (pull_request) Has been cancelled
CI / Build (windows-latest) (pull_request) Has been cancelled
11 KiB
11 KiB
Roadmap
Завершённые фазы
| Фаза | Описание | Ключевые результаты |
|---|---|---|
| 1 | Базовая инфраструктура | ratatui + crossterm, vim-навигация, русская раскладка |
| 2 | TDLib интеграция | tdlib-rs, авторизация, загрузка чатов и сообщений |
| 3 | Улучшение UX | Отправка, поиск, скролл, realtime обновления |
| 4 | Папки и фильтрация | Загрузка папок из Telegram, переключение 1-9 |
| 5 | Расширенный функционал | Онлайн-статус, галочки прочтения, медиа-заглушки, muted |
| 6 | Полировка | 60 FPS, оптимизация памяти, graceful shutdown, динамический инпут |
| 7 | Рефакторинг памяти | Единый источник данных, LRU-кэш (500 users), lazy loading |
| 8 | Дополнительные фичи | Markdown, edit/delete, reply/forward, блочный курсор |
| 9 | Расширенные возможности | Typing, pinned, поиск в чате, черновики, профиль, копирование, реакции, конфиг |
| 10 | Desktop уведомления (83%) | notify-rust, muted фильтр, mentions, медиа. TODO: кастомные звуки |
| 11 | Inline просмотр фото | Dual renderer (Halfblocks + iTerm2/Sixel), throttling 15 FPS, modal viewer, lazy loading, auto-download |
| 12 | Голосовые сообщения | ffplay player, pause/resume with seek, VoiceCache, AudioConfig, progress bar + waveform UI |
| 13 | Глубокий рефакторинг | 5 файлов (4582->модули), 5 traits, shared components, docs |
Фаза 11: Inline просмотр фото в чате [DONE]
UX: Always-show inline preview (50 chars, Halfblocks) -> v/м открывает fullscreen modal (iTerm2/Sixel) -> ←/→ навигация между фото.
Реализовано:
- Dual renderer архитектура:
inline_image_renderer: Halfblocks (быстро, Unicode блоки) для навигацииmodal_image_renderer: iTerm2/Sixel (медленно, высокое качество) для просмотра
- Performance optimizations:
- Frame throttling: inline 15 FPS, текст 60 FPS
- Lazy loading: только видимые изображения
- LRU cache: max 100 протоколов
- Skip partial rendering (no flickering)
- UX улучшения:
- Always-show inline preview (фикс. ширина 50 chars)
- Fullscreen modal на
v/мс aspect ratio - Loading indicator в модалке
- Navigation hotkeys:
←/→между фото,Esc/qзакрыть
- Типы и API:
MediaInfo,PhotoInfo,PhotoDownloadState,ImageModalStateImagesConfigв config.toml- Feature flag
imagesдля зависимостей
- Media модуль:
cache.rs: ImageCache (LRU)image_renderer.rs: new() + new_fast()
- UI модули:
modals/image_viewer.rs: fullscreen modalmessages.rs: throttled second-pass rendering
- Авто-загрузка фото (bugfix):
- Auto-download последних 30 фото при открытии чата (
open_chat_and_load_data) - Download on demand по
v(вместо "Фото не загружено") - Retry при ошибке загрузки
- Конфиг:
auto_download_images+show_imagesв[images]
- Auto-download последних 30 фото при открытии чата (
Фаза 12: Прослушивание голосовых сообщений [DONE]
Этап 1: Инфраструктура аудио [DONE]
- Модуль
src/audio/player.rs— AudioPlayer на ffplay (subprocess)cache.rs— VoiceCache (LRU, configurable size,~/.cache/tele-tui/voice/)
- AudioPlayer API: play(), play_from(ss), pause() (SIGSTOP), resume(), resume_from(ss), stop()
- Race condition fix:
startingflag + pid ownership guard в потоках - Drop impl для AudioPlayer (убивает ffplay при выходе)
Этап 2: Интеграция с TDLib [DONE]
- Типы:
VoiceInfo,VoiceDownloadState,PlaybackState,PlaybackStatus - Конвертация
MessageVoiceNoteвmessage_conversion.rs download_voice_note()в TdClientTrait + client_impl + fake- Методы
has_voice(),voice_info(),voice_info_mut()наMessageInfo
Этап 3: UI для воспроизведения [DONE]
- Progress bar (━●─) с позицией и длительностью
- Waveform визуализация (▁▂▃▄▅▆▇█) из base64-encoded TDLib данных
- Иконки статуса: ▶ Playing, ⏸ Paused, ⏹ Stopped
- Throttled redraw: обновление UI только при смене секунды (не 60 FPS)
Этап 4: Хоткеи [DONE]
- Space — play/pause toggle (запуск + пауза/возобновление с откатом 1s)
- ←/→ — seek ±5 сек (через
resume_from()— перезапуск ffplay с-ss) - Seek работает и при воспроизведении, и на паузе (на паузе двигает позицию, при resume стартует с неё)
- MoveLeft/MoveRight как alias для SeekBackward/SeekForward (HashMap non-deterministic order fix)
- Автоматическая остановка при навигации на другое сообщение
- Остановка ffplay при выходе из приложения (Ctrl+C)
Этап 5: Конфигурация и кэш [DONE]
AudioConfigв config.toml (cache_size_mb,auto_download_voice)DEFAULT_AUDIO_CACHE_SIZE_MBконстанта (100 MB)- Ticker для progress bar в event loop (delta-based position tracking)
- VoiceCache интеграция: проверка кэша перед загрузкой, кэширование после download
Технические детали
- Аудио: ffplay (subprocess), resume/seek через перезапуск с
-ssoffset - Race conditions:
startingflag предотвращает falseis_stopped()при старте ffplay; pid ownership guard в потоках предотвращает затирание pid нового процесса старым - Keybinding conflict: Left/Right привязаны к MoveLeft/MoveRight и SeekBackward/SeekForward; HashMap iteration order не гарантирован → оба варианта обрабатываются как seek в режиме выбора сообщения
- Платформы: macOS, Linux (везде где есть ffmpeg)
- Хоткеи: Space (play/pause), ←/→ (seek ±5s)
Фаза 14: Мультиаккаунт
Цель: поддержка нескольких Telegram-аккаунтов с мгновенным переключением внутри приложения.
UI: Индикатор в footer + хоткеи
┌──────────────┬───────────────────────────┐
│ Saved Msgs │ Привет! │
│ Иван Петров │ Как дела? │
│ Работа чат │ │
├──────────────┴───────────────────────────┤
│ [NORMAL] Михаил ⟨1/2⟩ Work(3) │ Ctrl+A │
└──────────────────────────────────────────┘
- Footer: текущий аккаунт + номер
⟨1/2⟩+ бейджи непрочитанных с других аккаунтов - Быстрое переключение:
Ctrl+1..Ctrl+9— мгновенный switch без модалки - Модалка управления (
Ctrl+A): список аккаунтов, добавление/удаление, выбор активного
Модалка переключения аккаунтов
┌──────────────────────────────────┐
│ Аккаунты │
│ │
│ 1. Михаил (+7 900 ...) ● │ ← активный
│ 2. Work (+7 911 ...) (3) │ ← 3 непрочитанных
│ 3. + Добавить аккаунт │
│ │
│ [j/k навигация, Enter выбор] │
│ [d — удалить аккаунт] │
└──────────────────────────────────┘
Техническая реализация: все клиенты одновременно
- Несколько TdClient: каждый аккаунт — отдельный
TdClientсо своимdatabase_directory- Аккаунт 1:
~/.local/share/tele-tui/accounts/1/tdlib_data/ - Аккаунт 2:
~/.local/share/tele-tui/accounts/2/tdlib_data/
- Аккаунт 1:
- Все клиенты активны: polling updates со всех аккаунтов одновременно (уведомления, непрочитанные)
- Мгновенное переключение: swap активного
App.td_client— чаты и сообщения уже загружены - Общий конфиг:
~/.config/tele-tui/config.toml(один для всех аккаунтов) - Профили аккаунтов:
~/.config/tele-tui/accounts.toml— список аккаунтов (имя, путь к БД)
Этапы
-
Этап 1: Инфраструктура профилей (DONE)
- Структура
AccountProfile(name, display_name, db_path) accounts.toml— хранение списка аккаунтов- Миграция
tdlib_data/→accounts/default/tdlib_data/(обратная совместимость) - CLI:
--account <name>для запуска конкретного аккаунта
- Структура
-
Этап 2+3: Account Switcher Modal + Переключение (DONE)
- Подход: single-client reinit (close TDLib → new TdClient → auth)
- Модалка
Ctrl+A— глобальный оверлей с навигацией j/k - Footer индикатор
[account_name]если не "default" AccountSwitcherStateenum (SelectAccount / AddAccount)recreate_client()метод в TdClientTrait (close → new → set_tdlib_parameters)add_account()— создание нового аккаунта из модалкиpending_account_switchфлаг → обработка в main loop
-
Этап 4: Расширенные возможности мультиаккаунта
- Удаление аккаунта из модалки
- Хоткеи
Ctrl+1..Ctrl+9— быстрое переключение - Бейджи непрочитанных с других аккаунтов (требует множественных TdClient)
- Параллельный polling updates со всех аккаунтов