Documented new feature for playing voice messages directly from TUI with full playback controls and visual feedback. Documentation Changes: - ROADMAP.md: Added Phase 12 with 7 stages - Stage 1: Audio infrastructure (audio module, AudioPlayer, VoiceCache) - Stage 2: TDLib integration (VoiceNoteInfo, download_voice_note) - Stage 3: UI for playback (progress bar, status indicators, footer) - Stage 4: Hotkeys (play/pause, stop, seek, volume control) - Stage 5: Configuration and UX (AudioConfig, ticker updates) - Stage 6: Error handling and fallback (system player) - Stage 7: Additional improvements (prefetching, animations) - CONTEXT.md: Added PLANNED section for Phase 12 - Technical stack: rodio 0.17, TDLib downloadFile - Platforms: Linux (ALSA/PulseAudio), macOS (CoreAudio), Windows (WASAPI) - Architecture: src/audio/ module with 3 submodules - LRU cache (100 MB limit) - Async loading, ticker for progress updates - Configuration options in config.toml - Fallback to system players (mpv, ffplay) - HOTKEYS.md: Added new hotkeys - `Space` - play/pause (in voice message selection mode) - `s` / `ы` - stop playback - `←` / `→` - seek -5s/+5s (during playback) - `↑` / `↓` - volume +/-10% (during playback) - Added new "Voice Playback" section - Added new "Voice Playback Mode" section - PROJECT_STRUCTURE.md: Added audio/ module documentation - player.rs - AudioPlayer with rodio - cache.rs - VoiceCache for downloaded OGG files - state.rs - PlaybackState (status, position, duration, volume) - Updated dependencies section (rodio 0.17) - Updated App state with audio fields Technical Details: - rodio 0.17 Pure Rust audio library (cross-platform) - OGG Opus support (Telegram voice message format) - Visual progress bar: ▶ ████████░░░░░░ 0:08 / 0:15 - Status indicators: ▶ (playing), ⏸ (paused), ⏹ (stopped), ⏳ (loading) - Smart caching with size limits - Async non-blocking file download - Ticker for smooth progress updates (100ms) - Graceful fallback to system players New Configuration (config.toml): - enabled: bool - enable/disable audio playback - default_volume: f32 - volume (0.0 - 1.0) - seek_step_seconds: i32 - seek step in seconds (default 5) - autoplay: bool - autoplay on selection - cache_size_mb: usize - cache size limit in MB - show_waveform: bool - show waveform visualization - system_player_fallback: bool - use system player fallback - system_player: String - system player command (mpv, ffplay) Status: PLANNED (documentation complete, implementation pending) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
454 lines
18 KiB
Markdown
454 lines
18 KiB
Markdown
# Структура проекта
|
||
|
||
## Обзор директорий
|
||
|
||
```
|
||
tele-tui/
|
||
├── .github/ # GitHub конфигурация
|
||
│ ├── ISSUE_TEMPLATE/ # Шаблоны для issue
|
||
│ │ ├── bug_report.md
|
||
│ │ └── feature_request.md
|
||
│ ├── workflows/ # GitHub Actions CI/CD
|
||
│ │ └── ci.yml
|
||
│ └── pull_request_template.md
|
||
│
|
||
├── docs/ # Дополнительная документация
|
||
│ └── TDLIB_INTEGRATION.md
|
||
│
|
||
├── src/ # Исходный код
|
||
│ ├── app/ # Состояние приложения
|
||
│ │ ├── mod.rs
|
||
│ │ └── state.rs
|
||
│ ├── input/ # Обработка пользовательского ввода
|
||
│ │ ├── mod.rs
|
||
│ │ ├── auth.rs
|
||
│ │ └── main_input.rs
|
||
│ ├── audio/ # Прослушивание голосовых (PLANNED)
|
||
│ │ ├── mod.rs # Экспорт публичных типов
|
||
│ │ ├── player.rs # AudioPlayer на rodio
|
||
│ │ ├── cache.rs # VoiceCache для OGG файлов
|
||
│ │ └── state.rs # PlaybackState
|
||
│ ├── media/ # Работа с изображениями (PLANNED)
|
||
│ │ ├── mod.rs # Экспорт публичных типов
|
||
│ │ ├── image_cache.rs # LRU кэш для загруженных изображений
|
||
│ │ ├── image_loader.rs # Асинхронная загрузка через TDLib
|
||
│ │ └── image_renderer.rs # Рендеринг изображений в ratatui
|
||
│ ├── notifications.rs # Desktop уведомления
|
||
│ ├── tdlib/ # TDLib интеграция
|
||
│ │ ├── mod.rs
|
||
│ │ └── client.rs
|
||
│ ├── ui/ # Рендеринг интерфейса
|
||
│ │ ├── mod.rs
|
||
│ │ ├── auth.rs
|
||
│ │ ├── chat_list.rs
|
||
│ │ ├── footer.rs
|
||
│ │ ├── loading.rs
|
||
│ │ ├── main_screen.rs
|
||
│ │ └── messages.rs
|
||
│ ├── config.rs # Конфигурация приложения
|
||
│ ├── main.rs # Точка входа
|
||
│ └── utils.rs # Утилиты
|
||
│
|
||
├── tdlib_data/ # TDLib сессия (НЕ коммитится)
|
||
├── target/ # Артефакты сборки (НЕ коммитится)
|
||
│
|
||
├── .editorconfig # EditorConfig для IDE
|
||
├── .gitignore # Git ignore правила
|
||
├── Cargo.lock # Зависимости (точные версии)
|
||
├── Cargo.toml # Манифест проекта
|
||
├── rustfmt.toml # Конфигурация форматирования
|
||
│
|
||
├── config.toml.example # Пример конфигурации
|
||
├── credentials.example # Пример credentials
|
||
│
|
||
├── CHANGELOG.md # История изменений
|
||
├── CLAUDE.md # Инструкции для Claude AI
|
||
├── CONTRIBUTING.md # Гайд по контрибуции
|
||
├── CONTEXT.md # Текущий статус разработки
|
||
├── DEVELOPMENT.md # Правила разработки
|
||
├── FAQ.md # Часто задаваемые вопросы
|
||
├── HOTKEYS.md # Список горячих клавиш
|
||
├── INSTALL.md # Инструкция по установке
|
||
├── LICENSE # MIT лицензия
|
||
├── PROJECT_STRUCTURE.md # Этот файл
|
||
├── README.md # Главная документация
|
||
├── REQUIREMENTS.md # Функциональные требования
|
||
├── ROADMAP.md # План развития
|
||
└── SECURITY.md # Политика безопасности
|
||
```
|
||
|
||
## Исходный код (src/)
|
||
|
||
### main.rs
|
||
**Точка входа приложения**
|
||
- Инициализация TDLib клиента
|
||
- Event loop (60 FPS)
|
||
- Обработка Ctrl+C (graceful shutdown)
|
||
- Координация между UI, input и TDLib
|
||
|
||
### config.rs
|
||
**Конфигурация приложения**
|
||
- Загрузка/сохранение TOML конфига
|
||
- Парсинг timezone и цветов
|
||
- Загрузка credentials (приоритетная система)
|
||
- XDG directory support
|
||
|
||
### utils.rs
|
||
**Утилитарные функции**
|
||
- `disable_tdlib_logs()` — отключение TDLib логов через FFI
|
||
- `format_timestamp_with_tz()` — форматирование времени с учётом timezone
|
||
- `format_date()` — форматирование дат для разделителей
|
||
- `format_datetime()` — полное форматирование даты и времени
|
||
- `format_was_online()` — "был(а) X мин. назад"
|
||
|
||
### app/ — Состояние приложения
|
||
|
||
#### mod.rs
|
||
- `App` struct — главная структура состояния
|
||
- `needs_redraw` — флаг для оптимизации рендеринга
|
||
- Состояние модалок (delete confirm, reaction picker, profile)
|
||
- Состояние поиска и черновиков
|
||
- Методы для работы с UI state
|
||
|
||
#### state.rs
|
||
- `AppScreen` enum — текущий экран (Loading, Auth, Main)
|
||
|
||
### audio/ — Прослушивание голосовых сообщений (PLANNED - Фаза 12)
|
||
|
||
#### player.rs
|
||
- `AudioPlayer` — управление воспроизведением голосовых сообщений
|
||
- Использует rodio для кроссплатформенного аудио
|
||
- API методы: play(), pause(), resume(), stop(), seek(), set_volume()
|
||
- Обработка OGG Opus файлов (формат голосовых в Telegram)
|
||
- Отдельный поток для воспроизведения (через rodio Sink)
|
||
|
||
#### cache.rs
|
||
- `VoiceCache` — LRU кэш для загруженных голосовых файлов
|
||
- Хранение в ~/.cache/tele-tui/voice/
|
||
- Лимит по размеру (MB) с автоматической очисткой
|
||
- MAX_VOICE_CACHE_SIZE = 100 MB (настраивается в config)
|
||
- Проверка существования файла перед воспроизведением
|
||
|
||
#### state.rs
|
||
- `PlaybackState` — текущее состояние воспроизведения
|
||
- Поля: message_id, status, position, duration, volume
|
||
- `PlaybackStatus` enum — Stopped, Playing, Paused, Loading
|
||
- Ticker для обновления позиции (каждые 100ms)
|
||
|
||
#### mod.rs
|
||
- Экспорт публичных типов
|
||
- `VoiceNoteInfo` struct — метаданные голосового (file_id, duration, waveform)
|
||
- `AudioConfig` — конфигурация из config.toml
|
||
- Fallback на системный плеер (mpv, ffplay)
|
||
|
||
### media/ — Работа с изображениями (PLANNED - Фаза 11)
|
||
|
||
#### image_cache.rs
|
||
- `ImageCache` — LRU кэш для загруженных изображений
|
||
- Лимит по размеру (MB) с автоматической очисткой
|
||
- Хранение как в памяти (DynamicImage), так и на диске (PathBuf)
|
||
- MAX_IMAGE_CACHE_SIZE = 100 MB (настраивается в config)
|
||
|
||
#### image_loader.rs
|
||
- `ImageLoader` — асинхронная загрузка изображений через TDLib
|
||
- Метод `load_photo(file_id)` — получить изображение из кэша или загрузить
|
||
- Метод `download_and_cache(file)` — загрузка через TDLib downloadFile API
|
||
- Обработка состояний загрузки (pending/downloading/ready)
|
||
- Приоритизация видимых изображений
|
||
|
||
#### image_renderer.rs
|
||
- `ImageRenderer` — рендеринг изображений в ratatui
|
||
- Auto-detection протокола терминала (Sixel/Kitty/iTerm2/Halfblocks)
|
||
- Автоматическое масштабирование под размер области
|
||
- Сохранение aspect ratio
|
||
- Fast resize для превью
|
||
- Fallback на текстовую заглушку
|
||
|
||
#### mod.rs
|
||
- Экспорт публичных типов
|
||
- `PhotoInfo` struct — метаданные изображения (file_id, width, height)
|
||
- `TerminalProtocol` enum — поддерживаемые протоколы отображения
|
||
|
||
### notifications.rs — Desktop уведомления
|
||
|
||
- `NotificationManager` — управление desktop уведомлениями
|
||
- Интеграция с notify-rust для кроссплатформенных уведомлений
|
||
- Фильтрация по muted чатам и mentions
|
||
- Beautification медиа-типов с emoji
|
||
- Настраиваемый timeout и urgency (Linux)
|
||
|
||
### tdlib/ — Telegram интеграция
|
||
|
||
#### client.rs
|
||
- `TdClient` — обёртка над TDLib
|
||
- Авторизация (телефон, код, 2FA)
|
||
- Загрузка чатов и сообщений
|
||
- Отправка/редактирование/удаление сообщений
|
||
- Reply, Forward
|
||
- Реакции (`ReactionInfo`)
|
||
- LRU кеши (users, statuses)
|
||
- `NetworkState` enum
|
||
|
||
#### mod.rs
|
||
- Экспорт публичных типов
|
||
|
||
### ui/ — Рендеринг интерфейса
|
||
|
||
#### mod.rs
|
||
- `render()` — роутинг по экранам
|
||
- Проверка минимального размера терминала (80x20)
|
||
|
||
#### loading.rs
|
||
- Экран "Loading..."
|
||
|
||
#### auth.rs
|
||
- Экран авторизации (ввод телефона, кода, пароля)
|
||
|
||
#### main_screen.rs
|
||
- Главный экран
|
||
- Отображение папок сверху
|
||
|
||
#### chat_list.rs
|
||
- Список чатов
|
||
- Индикаторы: 📌, 🔇, @, (N)
|
||
- Онлайн-статус (●)
|
||
- Поиск по чатам
|
||
|
||
#### messages.rs
|
||
- Область сообщений
|
||
- Группировка по дате и отправителю
|
||
- Markdown форматирование
|
||
- Реакции под сообщениями
|
||
- Emoji picker modal
|
||
- Profile modal
|
||
- Delete confirmation modal
|
||
- Pinned message
|
||
- Динамический инпут
|
||
- Блочный курсор
|
||
|
||
#### footer.rs
|
||
- Футер с командами
|
||
- Индикатор состояния сети
|
||
|
||
### input/ — Обработка ввода
|
||
|
||
#### mod.rs
|
||
- Роутинг ввода по экранам
|
||
|
||
#### auth.rs
|
||
- Обработка ввода на экране авторизации
|
||
|
||
#### main_input.rs
|
||
- Обработка ввода на главном экране
|
||
- **Важно**: порядок обработчиков имеет значение!
|
||
1. Reaction picker (Enter/Esc)
|
||
2. Delete confirmation
|
||
3. Profile modal
|
||
4. Search в чате
|
||
5. Forward mode
|
||
6. Edit/Reply mode
|
||
7. Message selection
|
||
8. Chat list
|
||
- Поддержка русской раскладки
|
||
|
||
## Конфигурационные файлы
|
||
|
||
### Cargo.toml
|
||
Манифест проекта:
|
||
- Metadata (name, version, authors, license)
|
||
- Dependencies
|
||
- Build dependencies (tdlib-rs)
|
||
|
||
### rustfmt.toml
|
||
Конфигурация `cargo fmt`:
|
||
- max_width = 100
|
||
- imports_granularity = "Crate"
|
||
- Стиль комментариев
|
||
|
||
### .editorconfig
|
||
Универсальные настройки для IDE:
|
||
- Unix line endings (LF)
|
||
- UTF-8 encoding
|
||
- Отступы (4 spaces для Rust)
|
||
|
||
## Рантайм файлы
|
||
|
||
### tdlib_data/
|
||
Создаётся автоматически TDLib:
|
||
- Токены авторизации
|
||
- Кеш сообщений и файлов
|
||
- **НЕ коммитится** (в .gitignore)
|
||
- **НЕ делиться** (содержит чувствительные данные)
|
||
|
||
### ~/.config/tele-tui/
|
||
XDG config directory:
|
||
- `config.toml` — пользовательская конфигурация
|
||
- `credentials` — API_ID и API_HASH
|
||
|
||
## Документация
|
||
|
||
### Пользовательская
|
||
- **README.md** — главная страница, overview
|
||
- **INSTALL.md** — установка и настройка
|
||
- **HOTKEYS.md** — все горячие клавиши
|
||
- **FAQ.md** — часто задаваемые вопросы
|
||
|
||
### Разработчика
|
||
- **CONTRIBUTING.md** — как внести вклад
|
||
- **DEVELOPMENT.md** — правила разработки
|
||
- **PROJECT_STRUCTURE.md** — этот файл
|
||
- **ROADMAP.md** — план развития
|
||
- **REFACTORING_ROADMAP.md** — план рефакторинга
|
||
- **TESTING_ROADMAP.md** — план покрытия тестами
|
||
- **CONTEXT.md** — текущий статус, архитектурные решения
|
||
|
||
### Спецификации
|
||
- **REQUIREMENTS.md** — функциональные требования
|
||
- **CHANGELOG.md** — история изменений
|
||
- **SECURITY.md** — политика безопасности
|
||
|
||
### Внутренняя
|
||
- **CLAUDE.md** — инструкции для AI ассистента
|
||
- **docs/TDLIB_INTEGRATION.md** — детали интеграции TDLib
|
||
|
||
## Ключевые концепции
|
||
|
||
### Архитектура
|
||
- **Event-driven**: TDLib updates → mpsc channel → main loop
|
||
- **Unidirectional data flow**: TDLib → App state → UI rendering
|
||
- **Modal stacking**: приоритет обработки ввода для модалок
|
||
|
||
### Оптимизации
|
||
- **needs_redraw**: рендеринг только при изменениях
|
||
- **LRU caches**: user_names, user_statuses (500 записей)
|
||
- **Limits**: 500 messages/chat, 200 chats
|
||
- **Lazy loading**: users загружаются батчами (5 за цикл)
|
||
|
||
### Состояние
|
||
```
|
||
App {
|
||
screen: AppScreen,
|
||
config: Config,
|
||
needs_redraw: bool,
|
||
|
||
// TDLib state
|
||
chats: Vec<Chat>,
|
||
folders: Vec<Folder>,
|
||
|
||
// UI state
|
||
selected_chat_id: Option<i64>,
|
||
input_text: String,
|
||
cursor_position: usize,
|
||
|
||
// Modals
|
||
is_delete_confirmation: bool,
|
||
is_reaction_picker_mode: bool,
|
||
profile_info: Option<ProfileInfo>,
|
||
view_image_mode: Option<ViewImageState>, // PLANNED - Фаза 11
|
||
|
||
// Search
|
||
search_query: String,
|
||
search_results: Vec<i64>,
|
||
|
||
// Drafts
|
||
drafts: HashMap<i64, String>,
|
||
|
||
// Audio (PLANNED - Фаза 12)
|
||
audio_player: Option<AudioPlayer>,
|
||
playback_state: Option<PlaybackState>,
|
||
voice_cache: VoiceCache,
|
||
|
||
// Media (PLANNED - Фаза 11)
|
||
image_loader: ImageLoader,
|
||
image_protocol: StatefulProtocol, // Terminal capabilities
|
||
}
|
||
```
|
||
|
||
## Потоки выполнения
|
||
|
||
### Main thread
|
||
- Event loop (16ms tick для 60 FPS)
|
||
- UI rendering
|
||
- Input handling
|
||
- App state updates
|
||
|
||
### TDLib thread
|
||
- `td_client.receive()` в отдельном Tokio task
|
||
- Updates отправляются через `mpsc::channel`
|
||
- Неблокирующий для main thread
|
||
|
||
### Blocking operations
|
||
- Загрузка конфига (при запуске)
|
||
- Авторизация (блокирует до ввода кода)
|
||
- Graceful shutdown (2 sec timeout)
|
||
|
||
## Зависимости
|
||
|
||
### UI
|
||
- `ratatui` 0.29 — TUI framework
|
||
- `crossterm` 0.28 — terminal control
|
||
- `ratatui-image` 1.0 — отображение изображений в TUI (PLANNED)
|
||
|
||
### Audio (PLANNED)
|
||
- `rodio` 0.17 — Pure Rust аудио библиотека (кроссплатформенная)
|
||
|
||
### Media (PLANNED)
|
||
- `image` — загрузка и обработка изображений
|
||
- `ratatui-image` — рендеринг в ratatui с поддержкой Sixel/Kitty/iTerm2
|
||
|
||
### Notifications
|
||
- `notify-rust` 4.11 — desktop уведомления (feature flag)
|
||
|
||
### Telegram
|
||
- `tdlib-rs` 1.1 — TDLib bindings
|
||
- `tokio` 1.x — async runtime
|
||
|
||
### Data
|
||
- `serde` + `serde_json` 1.0 — serialization
|
||
- `toml` 0.8 — config parsing
|
||
- `chrono` 0.4 — date/time
|
||
|
||
### System
|
||
- `dirs` 5.0 — XDG directories
|
||
- `arboard` 3.4 — clipboard
|
||
- `open` 5.0 — открытие URL/файлов
|
||
- `dotenvy` 0.15 — .env файлы
|
||
|
||
## Workflow разработки
|
||
|
||
1. Изучить [ROADMAP.md](ROADMAP.md) — понять текущую фазу
|
||
2. Прочитать [DEVELOPMENT.md](DEVELOPMENT.md) — правила работы
|
||
3. Изучить [CONTEXT.md](CONTEXT.md) — архитектурные решения
|
||
4. Найти issue или создать новую фичу
|
||
5. Создать feature branch
|
||
6. Внести изменения
|
||
7. `cargo fmt` + `cargo clippy`
|
||
8. Протестировать вручную
|
||
9. Создать PR с описанием
|
||
|
||
## CI/CD
|
||
|
||
### GitHub Actions (.github/workflows/ci.yml)
|
||
- **Check**: `cargo check`
|
||
- **Format**: `cargo fmt --check`
|
||
- **Clippy**: `cargo clippy`
|
||
- **Build**: для Ubuntu, macOS, Windows
|
||
|
||
Запускается на:
|
||
- Push в `main` или `develop`
|
||
- Pull requests
|
||
|
||
## Безопасность
|
||
|
||
### Чувствительные файлы (в .gitignore)
|
||
- `.env`
|
||
- `credentials`
|
||
- `config.toml` (если в корне проекта)
|
||
- `tdlib_data/`
|
||
- `target/`
|
||
|
||
### Рекомендации
|
||
- Credentials в `~/.config/tele-tui/credentials`
|
||
- Права доступа: `chmod 600 ~/.config/tele-tui/credentials`
|
||
- Никогда не коммитить `tdlib_data/`
|