Files
telegram-tui/CONTEXT.md
Mikhail Kilin 7bc264198f feat: implement Phase 12 — voice message playback with ffplay
Add voice message playback infrastructure:
- AudioPlayer using ffplay subprocess with SIGSTOP/SIGCONT for pause/resume
- VoiceCache with LRU eviction (100 MB limit)
- TDLib integration: VoiceInfo, VoiceDownloadState, PlaybackState types
- download_voice_note() in TdClientTrait
- Keybindings: Space (play/pause), ←/→ (seek ±5s)
- Auto-stop playback on message navigation
- Remove debug_log module
2026-02-09 02:35:49 +03:00

7.6 KiB
Raw Blame History

Текущий контекст проекта

Статус: Фаза 12 — Прослушивание голосовых сообщений (IN PROGRESS)

Завершённые фазы (краткий итог)

Фаза Описание Статус
1 Базовая инфраструктура (ratatui + crossterm, vim-навигация) DONE
2 TDLib интеграция (авторизация, чаты, сообщения) DONE
3 Улучшение UX (отправка, поиск, скролл, realtime) DONE
4 Папки и фильтрация (загрузка папок, переключение 1-9) DONE
5 Расширенный функционал (онлайн-статус, медиа-заглушки, muted) DONE
6 Полировка (60 FPS, память, graceful shutdown, динамический инпут) DONE
7 Рефакторинг памяти (единый источник данных, LRU-кэш) DONE
8 Дополнительные фичи (markdown, edit/delete, reply/forward, блочный курсор) DONE
9 Расширенные возможности (typing, pinned, поиск в чате, черновики, профиль, копирование, реакции, конфиг) DONE
10 Desktop уведомления (notify-rust, muted фильтр, mentions, медиа) DONE (83%)
11 Inline просмотр фото (ratatui-image, кэш, загрузка) DONE
12 Прослушивание голосовых сообщений (ffplay, play/pause, seek) IN PROGRESS
13 Глубокий рефакторинг архитектуры (7 этапов) DONE

Фаза 11: Inline фото + оптимизации (подробности)

Feature-gated (images), 2-tier архитектура:

Базовая реализация:

  1. Типы: MediaInfo, PhotoInfo, PhotoDownloadState, ImageModalState, ImagesConfig
  2. Зависимости: ratatui-image 8.1, image 0.25 (feature-gated)
  3. Media модуль: ImageCache (LRU), dual ImageRenderer (inline + modal)
  4. UX: Always-show inline preview (фикс. ширина 50 chars) + полноэкранная модалка на v/м
  5. Метаданные: extract_media_info() из TDLib MessagePhoto; auto-download visible photos

Оптимизации производительности:

  1. Dual protocol strategy:
    • inline_image_renderer: Halfblocks → быстро (Unicode блоки), для навигации
    • modal_image_renderer: iTerm2/Sixel → медленно (high quality), для просмотра
  2. Frame throttling: inline images 15 FPS (66ms), текст 60 FPS
  3. Lazy loading: загрузка только видимых изображений (не все сразу)
  4. LRU кэш: max 100 протоколов, eviction старых
  5. Loading indicator: " Загрузка..." в модалке при первом открытии
  6. Navigation hotkeys: / между фото, Esc/q закрыть модалку

UI рендеринг:

  • message_bubble.rs: photo status (Downloading/Error/placeholder), inline preview
  • messages.rs: второй проход с render_images() + throttling + только видимые
  • modals/image_viewer.rs: fullscreen modal с aspect ratio + loading state

Фаза 13: Рефакторинг (подробности)

Разбиты 5 монолитных файлов (4582 строк) на модульную архитектуру:

  • input/main_input.rs (1199→164): чистый роутер + 5 handler модулей в handlers/
  • app/mod.rs (1015→371): 5 trait модулей в methods/ (Navigation, Message, Compose, Search, Modal)
  • ui/messages.rs (893→365): модули modals/ (search, pinned, delete, reactions) + compose_bar.rs
  • tdlib/messages.rs (836→3 файла): messages/ (mod, convert, operations)
  • config/mod.rs (642→3 файла): validation.rs, loader.rs
  • Очистка дублей: ~220 строк удалено (shared components, format_user_status, scroll_to_message)
  • Документация: PROJECT_STRUCTURE.md переписан, 16 файлов получили //! docs

Фаза 12: Голосовые сообщения (подробности)

Реализовано:

  • AudioPlayer на ffplay (subprocess): play, pause (SIGSTOP), resume (SIGCONT), stop
  • VoiceCache: LRU кэш OGG файлов в ~/.cache/tele-tui/voice/ (max 100 MB)
  • Типы: VoiceInfo, VoiceDownloadState, PlaybackState, PlaybackStatus
  • TDLib интеграция: download_voice_note(), конвертация MessageVoiceNote
  • Хоткеи: Space (play/pause), ←/→ (seek ±5s)
  • Автостоп: при навигации на другое сообщение воспроизведение останавливается

Не реализовано:

  • UI индикаторы в сообщениях (🎤, progress bar, waveform)
  • AudioConfig в config.toml
  • Ticker для progress bar
  • VoiceCache не интегрирован в handlers

Ключевая архитектура

main.rs → event loop (16ms poll)
├── input/ → роутер + handlers/ (chat, chat_list, compose, modal, search)
├── app/ → App<T: TdClientTrait> + methods/ (5 traits, 67 методов)
├── ui/ → рендеринг (messages, chat_list, modals/, compose_bar, components/)
├── audio/ → player.rs (ffplay), cache.rs (VoiceCache)
├── media/ → [feature=images] cache.rs, image_renderer.rs
└── tdlib/ → TDLib wrapper (client, auth, chats, messages/, users, reactions, types)

Тестирование

500+ тестов (0 failures):

  • Snapshot tests: 57 (UI компоненты)
  • Integration tests: 93 (user flows)
  • E2E tests: 12 (smoke + journey)
  • Utils tests: 18
  • Performance benchmarks: 8

Ключевые решения

  1. Неблокирующий receive: TDLib updates через mpsc::channel в отдельном потоке
  2. Trait-based App: методы разбиты на traits — требуют use import на call site
  3. FakeTdClient: mock для тестов без TDLib (реализует TdClientTrait)
  4. Оптимизация рендеринга: needs_redraw флаг, рендеринг только при изменениях
  5. Конфиг: TOML ~/.config/tele-tui/config.toml, credentials с приоритетом (XDG → .env)
  6. Feature-gated images: images feature flag для ratatui-image + image deps
  7. Dual renderer: inline (Halfblocks, 15 FPS) + modal (iTerm2/Sixel, high quality) для баланса скорости/качества
  8. Audio via ffplay: subprocess с SIGSTOP/SIGCONT для pause/resume, автостоп при навигации

Зависимости (основные)

ratatui = "0.29"           # TUI фреймворк
crossterm = "0.28"          # Терминальный backend
tdlib-rs = "1.1"            # Telegram TDLib binding
tokio = "1"                 # Async runtime
notify-rust = "4.11"        # Desktop уведомления (feature flag)
ratatui-image = "8.1"       # Inline images (feature flag)
image = "0.25"              # Image decoding (feature flag)

Полная структура проекта: см. PROJECT_STRUCTURE.md Подробный план: см. ROADMAP.md