diff --git a/CONTEXT.md b/CONTEXT.md index 877e7cf..a0ec577 100644 --- a/CONTEXT.md +++ b/CONTEXT.md @@ -42,6 +42,43 @@ - `src/app/mod.rs`: вызов configure_notifications() при инициализации - **Тесты**: Компиляция успешна (cargo build --lib ✅, cargo build ✅) +**📸 PLANNED: Показ изображений в чате (Фаза 11)** +- **Описание**: Отображение изображений прямо в терминале вместо текстовых заглушек "[Фото]" +- **Технологии**: + - ratatui-image 1.0 - поддержка изображений в TUI + - Протоколы: Sixel, Kitty Graphics, iTerm2 Inline Images, Unicode Halfblocks + - TDLib downloadFile API для загрузки фото + - LRU кэш для загруженных изображений (лимит 100 MB) +- **Архитектура**: + - `src/media/` - новый модуль (image_cache, image_loader, image_renderer) + - `PhotoInfo` в `MessageInfo` для хранения метаданных изображения + - Асинхронная загрузка в фоне (не блокирует UI) + - Lazy loading - загрузка только видимых изображений +- **UX фичи**: + - Превью в списке сообщений (миниатюры 20x10 символов) + - Индикатор загрузки с progress bar + - Полноэкранный просмотр: `v` в режиме выбора + - Навигация между изображениями: `←` / `→` + - Auto-detection возможностей терминала + - Fallback на Unicode halfblocks для любых терминалов +- **Конфигурация** (config.toml): + - show_images: bool - включить/отключить + - image_cache_mb: usize - размер кэша + - preview_quality: "low" | "medium" | "high" + - render_protocol: "auto" | "sixel" | "kitty" | "iterm2" | "halfblocks" +- **План реализации**: + - Этап 1: Инфраструктура (модуль media, ImageCache, зависимости) + - Этап 2: Интеграция с TDLib (PhotoInfo, download_photo) + - Этап 3: Рендеринг в UI (превью, масштабирование) + - Этап 4: Полноэкранный просмотр (новый режим ViewImage) + - Этап 5: Конфигурация и оптимизация + - Этап 6: Обработка ошибок и fallback +- **Ожидаемый результат**: + - Фото показываются inline в чате с автоматическим масштабированием + - Поддержка всех популярных терминалов (Kitty, WezTerm, iTerm2, и любых других) + - Производительность: кэширование, асинхронность, lazy loading +- **Статус**: PLANNED (документация готова в ROADMAP.md) + **🐛 FIX: HashMap keybindings коллизии - дубликаты клавиш** - **Проблема #1**: `KeyCode::Enter` был привязан к 3 командам (OpenChat, SelectMessage, SubmitMessage) - **Проблема #2**: `KeyCode::Up` был привязан к 2 командам (MoveUp, EditMessage) diff --git a/HOTKEYS.md b/HOTKEYS.md index 99f9db3..83bd31d 100644 --- a/HOTKEYS.md +++ b/HOTKEYS.md @@ -41,8 +41,22 @@ | `d` / `Delete` | `в` | Удалить сообщение | | `y` | `н` | Копировать текст в буфер обмена | | `e` | `у` | Добавить реакцию (Emoji picker) | +| `v` | `м` | Открыть изображение в полном размере | | `Ctrl+i` | `Ctrl+ш` | Открыть профиль чата/пользователя | +## Просмотр изображений + +### Режим просмотра изображения + +| Клавиша | Действие | +|---------|----------| +| `v` / `м` | Открыть изображение (в режиме выбора) | +| `←` | Предыдущее изображение в чате | +| `→` | Следующее изображение в чате | +| `Esc` | Закрыть просмотр изображения | + +**Примечание**: Изображения отображаются inline в чате автоматически. Используйте `v` для просмотра в полном размере. + ## Модалки подтверждения ### Удаление сообщения @@ -103,6 +117,7 @@ - Удалить: `d` / `в` / `Delete` - Копировать: `y` / `н` - Реакция: `e` / `у` +- Просмотр изображения: `v` / `м` (если выбрано сообщение с фото) - Отменить: `Esc` ### Режим редактирования @@ -120,6 +135,10 @@ - Переслать: `Enter` - Отменить: `Esc` +### Режим просмотра изображения +- Навигация: `←/→` (предыдущее/следующее изображение) +- Закрыть: `Esc` + ## Поддержка русской раскладки Все основные vim-клавиши поддерживают русскую раскладку: @@ -135,6 +154,7 @@ | `d` | `в` | Delete | | `y` | `н` | Copy (Yank) | | `e` | `у` | Emoji reaction | +| `v` | `м` | View image | ## Подсказки diff --git a/PROJECT_STRUCTURE.md b/PROJECT_STRUCTURE.md index c469bbf..0369425 100644 --- a/PROJECT_STRUCTURE.md +++ b/PROJECT_STRUCTURE.md @@ -23,6 +23,12 @@ tele-tui/ │ │ ├── mod.rs │ │ ├── auth.rs │ │ └── main_input.rs +│ ├── 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 @@ -102,6 +108,42 @@ tele-tui/ #### state.rs - `AppScreen` enum — текущий экран (Loading, Auth, Main) +### 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 @@ -269,6 +311,7 @@ App { is_delete_confirmation: bool, is_reaction_picker_mode: bool, profile_info: Option, + view_image_mode: Option, // PLANNED - Фаза 11 // Search search_query: String, @@ -276,6 +319,10 @@ App { // Drafts drafts: HashMap, + + // Media (PLANNED - Фаза 11) + image_loader: ImageLoader, + image_protocol: StatefulProtocol, // Terminal capabilities } ``` @@ -302,6 +349,14 @@ App { ### UI - `ratatui` 0.29 — TUI framework - `crossterm` 0.28 — terminal control +- `ratatui-image` 1.0 — отображение изображений в TUI (PLANNED) + +### Media (PLANNED) +- `image` — загрузка и обработка изображений +- `ratatui-image` — рендеринг в ratatui с поддержкой Sixel/Kitty/iTerm2 + +### Notifications +- `notify-rust` 4.11 — desktop уведомления (feature flag) ### Telegram - `tdlib-rs` 1.1 — TDLib bindings diff --git a/ROADMAP.md b/ROADMAP.md index a96d263..f3b3c0f 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -195,3 +195,98 @@ - Кросс-платформенное тестирование (требует ручного тестирования) - 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` - закрыть полноэкранный просмотр