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>
This commit is contained in:
@@ -1,453 +1,328 @@
|
||||
# Структура проекта
|
||||
|
||||
## Архитектура (ASCII)
|
||||
|
||||
```
|
||||
┌─────────────┐
|
||||
│ main.rs │ Event loop (60 FPS)
|
||||
└──────┬──────┘
|
||||
│
|
||||
┌────────────┼────────────┐
|
||||
▼ ▼ ▼
|
||||
┌──────────┐ ┌──────────┐ ┌──────────┐
|
||||
│ input/ │ │ app/ │ │ ui/ │
|
||||
│ handlers │ │ state │ │ render │
|
||||
└────┬─────┘ └────┬─────┘ └────┬─────┘
|
||||
│ │ │
|
||||
│ ┌──────┴──────┐ │
|
||||
│ │ methods/ │ │
|
||||
│ │ (5 traits) │ │
|
||||
│ └──────┬──────┘ │
|
||||
│ │ │
|
||||
▼ ▼ ▼
|
||||
┌─────────────────────────────────┐
|
||||
│ tdlib/ │
|
||||
│ TdClientTrait → TdClient │
|
||||
│ messages/ | auth | chats │
|
||||
└──────────────┬──────────────────┘
|
||||
│
|
||||
┌─────▼─────┐
|
||||
│ TDLib C │
|
||||
│ library │
|
||||
└───────────┘
|
||||
```
|
||||
|
||||
### Data Flow
|
||||
```
|
||||
TDLib Updates → mpsc channel → App state → UI rendering
|
||||
User Input → handlers → App methods (traits) → TdClient → TDLib API
|
||||
```
|
||||
|
||||
## Обзор директорий
|
||||
|
||||
```
|
||||
tele-tui/
|
||||
├── .github/ # GitHub конфигурация
|
||||
│ ├── ISSUE_TEMPLATE/ # Шаблоны для issue
|
||||
│ │ ├── bug_report.md
|
||||
│ │ └── feature_request.md
|
||||
│ ├── workflows/ # GitHub Actions CI/CD
|
||||
│ │ └── ci.yml
|
||||
├── src/
|
||||
│ ├── main.rs # Точка входа, event loop
|
||||
│ ├── lib.rs # Экспорт модулей для тестов
|
||||
│ ├── types.rs # ChatId, MessageId (newtype wrappers)
|
||||
│ ├── constants.rs # MAX_MESSAGES_IN_CHAT, etc.
|
||||
│ ├── formatting.rs # Markdown entity форматирование
|
||||
│ ├── message_grouping.rs # Группировка сообщений по дате/отправителю
|
||||
│ ├── notifications.rs # Desktop уведомления (NotificationManager)
|
||||
│ │
|
||||
│ ├── app/ # Состояние приложения
|
||||
│ │ ├── mod.rs # App<T> struct, конструкторы, getters (372 loc)
|
||||
│ │ ├── state.rs # AppScreen enum
|
||||
│ │ ├── chat_state.rs # ChatState enum (state machine)
|
||||
│ │ ├── chat_filter.rs # ChatFilter, ChatFilterCriteria
|
||||
│ │ ├── chat_list_state.rs # Состояние списка чатов
|
||||
│ │ ├── auth_state.rs # Состояние авторизации
|
||||
│ │ ├── compose_state.rs # Состояние compose bar
|
||||
│ │ ├── ui_state.rs # UI-related state
|
||||
│ │ ├── message_service.rs # Сервис сообщений
|
||||
│ │ ├── message_view_state.rs # Состояние просмотра сообщений
|
||||
│ │ └── methods/ # Trait-based методы App (Этап 2)
|
||||
│ │ ├── mod.rs # Re-exports 5 trait модулей
|
||||
│ │ ├── navigation.rs # NavigationMethods (7 методов)
|
||||
│ │ ├── messages.rs # MessageMethods (8 методов)
|
||||
│ │ ├── compose.rs # ComposeMethods (10 методов)
|
||||
│ │ ├── search.rs # SearchMethods (15 методов)
|
||||
│ │ └── modal.rs # ModalMethods (27 методов)
|
||||
│ │
|
||||
│ ├── config/ # Конфигурация (Этап 5)
|
||||
│ │ ├── mod.rs # Config struct, defaults (350 loc)
|
||||
│ │ ├── keybindings.rs # Command enum, Keybindings
|
||||
│ │ ├── validation.rs # validate(), parse_color()
|
||||
│ │ └── loader.rs # load(), save(), credentials
|
||||
│ │
|
||||
│ ├── input/ # Обработка пользовательского ввода
|
||||
│ │ ├── mod.rs # Роутинг по экранам
|
||||
│ │ ├── auth.rs # Ввод на экране авторизации
|
||||
│ │ ├── main_input.rs # Роутер главного экрана (159 loc, Этап 1)
|
||||
│ │ ├── key_handler.rs # Trait-based обработка клавиш
|
||||
│ │ └── handlers/ # Специализированные обработчики (Этап 1)
|
||||
│ │ ├── mod.rs # Exports + scroll_to_message()
|
||||
│ │ ├── global.rs # Ctrl+R/S/P/F глобальные команды
|
||||
│ │ ├── chat.rs # Открытый чат: ввод, скролл, selection
|
||||
│ │ ├── chat_list.rs # Навигация по списку чатов, папки
|
||||
│ │ ├── compose.rs # Forward mode
|
||||
│ │ ├── modal.rs # Profile, reactions, pinned, delete
|
||||
│ │ ├── search.rs # Поиск чатов и сообщений
|
||||
│ │ ├── clipboard.rs # Копирование в буфер обмена
|
||||
│ │ └── profile.rs # Хелперы профиля
|
||||
│ │
|
||||
│ ├── tdlib/ # TDLib интеграция
|
||||
│ │ ├── mod.rs # Экспорт публичных типов
|
||||
│ │ ├── types.rs # MessageInfo, ChatInfo, ProfileInfo, etc.
|
||||
│ │ ├── trait.rs # TdClientTrait (DI для тестов)
|
||||
│ │ ├── client.rs # TdClient struct, конструктор
|
||||
│ │ ├── client_impl.rs # impl TdClientTrait for TdClient
|
||||
│ │ ├── auth.rs # Авторизация (phone, code, 2FA)
|
||||
│ │ ├── chats.rs # Загрузка чатов, папок
|
||||
│ │ ├── users.rs # Кеш пользователей, статусы
|
||||
│ │ ├── reactions.rs # ReactionInfo, toggle_reaction
|
||||
│ │ ├── chat_helpers.rs # Вспомогательные функции чатов
|
||||
│ │ ├── update_handlers.rs # Обработка TDLib update events
|
||||
│ │ ├── message_converter.rs # Конвертация TDLib → MessageInfo
|
||||
│ │ ├── message_conversion.rs # Доп. функции конвертации
|
||||
│ │ └── messages/ # Менеджер сообщений (Этап 4)
|
||||
│ │ ├── mod.rs # MessageManager struct (99 loc)
|
||||
│ │ ├── convert.rs # convert_message, fetch_reply_info
|
||||
│ │ └── operations.rs # 11 TDLib API операций (616 loc)
|
||||
│ │
|
||||
│ ├── ui/ # Рендеринг интерфейса
|
||||
│ │ ├── mod.rs # render() — роутинг по экранам
|
||||
│ │ ├── loading.rs # Экран загрузки
|
||||
│ │ ├── auth.rs # Экран авторизации
|
||||
│ │ ├── main_screen.rs # Главный экран + папки
|
||||
│ │ ├── footer.rs # Футер с командами и статусом сети
|
||||
│ │ ├── chat_list.rs # Список чатов + онлайн-статус
|
||||
│ │ ├── messages.rs # Область сообщений (364 loc, Этап 3)
|
||||
│ │ ├── compose_bar.rs # Multi-mode input box (Этап 3)
|
||||
│ │ ├── profile.rs # Профиль пользователя/чата
|
||||
│ │ ├── modals/ # Модальные окна (Этап 3)
|
||||
│ │ │ ├── mod.rs # Re-exports
|
||||
│ │ │ ├── delete_confirm.rs # Подтверждение удаления
|
||||
│ │ │ ├── reaction_picker.rs # Выбор реакции
|
||||
│ │ │ ├── search.rs # Поиск по сообщениям
|
||||
│ │ │ └── pinned.rs # Закреплённые сообщения
|
||||
│ │ └── components/ # Переиспользуемые UI компоненты (Этап 6)
|
||||
│ │ ├── mod.rs # Re-exports
|
||||
│ │ ├── modal.rs # render_modal(), render_delete_confirm
|
||||
│ │ ├── input_field.rs # render_input_field()
|
||||
│ │ ├── message_bubble.rs # render_message_bubble(), sender, date
|
||||
│ │ ├── message_list.rs # render_message_item(), help_bar, scroll
|
||||
│ │ ├── chat_list_item.rs # render_chat_list_item()
|
||||
│ │ └── emoji_picker.rs # render_emoji_picker()
|
||||
│ │
|
||||
│ └── utils/ # Утилиты
|
||||
│ ├── mod.rs # Exports, with_timeout helpers
|
||||
│ ├── formatting.rs # format_timestamp, format_date, etc.
|
||||
│ ├── tdlib.rs # disable_tdlib_logs (FFI)
|
||||
│ ├── validation.rs # is_non_empty и др.
|
||||
│ ├── modal_handler.rs # handle_yes_no для Y/N модалок
|
||||
│ └── retry.rs # Retry утилиты
|
||||
│
|
||||
├── tests/ # Интеграционные тесты
|
||||
│ ├── helpers/ # Тестовая инфраструктура
|
||||
│ │ ├── mod.rs
|
||||
│ │ ├── app_builder.rs # TestAppBuilder (fluent API)
|
||||
│ │ ├── fake_tdclient.rs # FakeTdClient (мок TDLib)
|
||||
│ │ ├── fake_tdclient_impl.rs # impl TdClientTrait for FakeTdClient
|
||||
│ │ ├── test_data.rs # create_test_chat, TestMessageBuilder
|
||||
│ │ └── snapshot_utils.rs # Snapshot testing хелперы
|
||||
│ ├── input_navigation.rs # Тесты навигации клавиатурой
|
||||
│ ├── chat_list.rs # Тесты списка чатов
|
||||
│ ├── messages.rs # Тесты сообщений
|
||||
│ ├── send_message.rs # Тесты отправки
|
||||
│ ├── edit_message.rs # Тесты редактирования
|
||||
│ ├── delete_message.rs # Тесты удаления
|
||||
│ ├── reply_forward.rs # Тесты reply/forward
|
||||
│ ├── reactions.rs # Тесты реакций
|
||||
│ ├── search.rs # Тесты поиска
|
||||
│ ├── modals.rs # Тесты модальных окон
|
||||
│ ├── profile.rs # Тесты профиля
|
||||
│ ├── navigation.rs # Тесты навигации
|
||||
│ ├── drafts.rs # Тесты черновиков
|
||||
│ ├── copy.rs # Тесты копирования
|
||||
│ ├── screens.rs # Тесты экранов
|
||||
│ ├── footer.rs # Тесты футера
|
||||
│ ├── input_field.rs # Тесты поля ввода
|
||||
│ ├── config.rs # Тесты конфигурации
|
||||
│ ├── network_typing.rs # Тесты typing status
|
||||
│ ├── e2e_smoke.rs # Smoke тесты
|
||||
│ └── e2e_user_journey.rs # E2E user journey тесты
|
||||
│
|
||||
├── .github/ # GitHub конфигурация
|
||||
│ ├── ISSUE_TEMPLATE/
|
||||
│ ├── workflows/ci.yml
|
||||
│ └── pull_request_template.md
|
||||
│
|
||||
├── docs/ # Дополнительная документация
|
||||
│ └── TDLIB_INTEGRATION.md
|
||||
├── Cargo.toml # Манифест проекта
|
||||
├── Cargo.lock # Точные версии зависимостей
|
||||
├── build.rs # Build script (TDLib)
|
||||
├── rustfmt.toml # cargo fmt конфигурация
|
||||
├── .editorconfig # Настройки IDE
|
||||
├── .gitignore # Git ignore
|
||||
│
|
||||
├── 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 # Утилиты
|
||||
├── config.toml.example # Пример конфигурации
|
||||
├── credentials.example # Пример credentials
|
||||
│
|
||||
├── 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 # Политика безопасности
|
||||
├── CLAUDE.md # Инструкции для AI
|
||||
├── CONTEXT.md # Текущий статус
|
||||
├── ROADMAP.md # План развития
|
||||
├── DEVELOPMENT.md # Правила разработки
|
||||
├── REQUIREMENTS.md # Требования
|
||||
├── ARCHITECTURE.md # C4, sequence diagrams
|
||||
├── PROJECT_STRUCTURE.md # Этот файл
|
||||
├── E2E_TESTING.md # Гайд по тестированию
|
||||
├── HOTKEYS.md # Горячие клавиши
|
||||
├── CHANGELOG.md # История изменений
|
||||
├── README.md # Главная документация
|
||||
├── INSTALL.md # Установка
|
||||
├── FAQ.md # FAQ
|
||||
├── CONTRIBUTING.md # Гайд по контрибуции
|
||||
├── SECURITY.md # Безопасность
|
||||
└── LICENSE # MIT лицензия
|
||||
```
|
||||
|
||||
## Исходный код (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
|
||||
`App<T: TdClientTrait>` — главная структура, параметризована trait'ом для DI.
|
||||
|
||||
#### state.rs
|
||||
- `AppScreen` enum — текущий экран (Loading, Auth, Main)
|
||||
**State machine** (`ChatState` enum):
|
||||
```
|
||||
Normal → MessageSelection → Editing
|
||||
→ Reply
|
||||
→ Forward
|
||||
→ DeleteConfirmation
|
||||
→ ReactionPicker
|
||||
→ Profile
|
||||
→ SearchInChat
|
||||
→ PinnedMessages
|
||||
```
|
||||
|
||||
### 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
|
||||
- Футер с командами
|
||||
- Индикатор состояния сети
|
||||
**Trait-based methods** (5 traits на `App<T>`):
|
||||
| Trait | Методы | Описание |
|
||||
|-------|--------|----------|
|
||||
| NavigationMethods | 7 | next/previous_chat, close_chat, select_current_chat |
|
||||
| MessageMethods | 8 | is_editing, is_replying, get_selected_message, etc. |
|
||||
| ComposeMethods | 10 | start_reply, cancel_editing, load_draft, etc. |
|
||||
| SearchMethods | 15 | start_search, enter_message_search_mode, etc. |
|
||||
| ModalMethods | 27 | enter_profile_mode, exit_pinned_mode, etc. |
|
||||
|
||||
### input/ — Обработка ввода
|
||||
|
||||
#### mod.rs
|
||||
- Роутинг ввода по экранам
|
||||
**Маршрутизация** (порядок приоритетов в `main_input.rs`):
|
||||
1. Global commands (Ctrl+R/S/P/F)
|
||||
2. Profile mode
|
||||
3. Message search mode
|
||||
4. Pinned messages mode
|
||||
5. Reaction picker mode
|
||||
6. Delete confirmation
|
||||
7. Forward mode
|
||||
8. Chat search mode
|
||||
9. Enter/Esc commands
|
||||
10. Open chat input / Chat list navigation
|
||||
|
||||
#### auth.rs
|
||||
- Обработка ввода на экране авторизации
|
||||
### tdlib/ — Telegram интеграция
|
||||
|
||||
#### 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
|
||||
- Поддержка русской раскладки
|
||||
**Dependency Injection**: `TdClientTrait` позволяет подменять TdClient на `FakeTdClient` в тестах.
|
||||
|
||||
## Конфигурационные файлы
|
||||
**MessageManager** — управление сообщениями:
|
||||
- `convert.rs` — конвертация TDLib JSON → MessageInfo
|
||||
- `operations.rs` — 11 API операций (get_history, send, edit, delete, forward, search, etc.)
|
||||
|
||||
### Cargo.toml
|
||||
Манифест проекта:
|
||||
- Metadata (name, version, authors, license)
|
||||
- Dependencies
|
||||
- Build dependencies (tdlib-rs)
|
||||
### ui/ — Рендеринг
|
||||
|
||||
### rustfmt.toml
|
||||
Конфигурация `cargo fmt`:
|
||||
- max_width = 100
|
||||
- imports_granularity = "Crate"
|
||||
- Стиль комментариев
|
||||
**Компоненты** (`ui/components/`):
|
||||
| Компонент | Описание |
|
||||
|-----------|----------|
|
||||
| message_bubble | Рендеринг пузыря сообщения с реакциями |
|
||||
| message_list | Элемент списка сообщений (search/pinned) |
|
||||
| chat_list_item | Элемент списка чатов |
|
||||
| input_field | Поле ввода с курсором |
|
||||
| emoji_picker | Сетка выбора реакций |
|
||||
| modal | Центрированная модалка |
|
||||
|
||||
### .editorconfig
|
||||
Универсальные настройки для IDE:
|
||||
- Unix line endings (LF)
|
||||
- UTF-8 encoding
|
||||
- Отступы (4 spaces для Rust)
|
||||
### config/ — Конфигурация
|
||||
|
||||
## Рантайм файлы
|
||||
- **mod.rs** — struct Config, GeneralConfig, ColorsConfig, NotificationsConfig
|
||||
- **keybindings.rs** — Command enum (30+ команд), кастомные горячие клавиши
|
||||
- **validation.rs** — валидация timezone, цветов
|
||||
- **loader.rs** — загрузка из `~/.config/tele-tui/config.toml`, credentials
|
||||
|
||||
### tdlib_data/
|
||||
Создаётся автоматически TDLib:
|
||||
- Токены авторизации
|
||||
- Кеш сообщений и файлов
|
||||
- **НЕ коммитится** (в .gitignore)
|
||||
- **НЕ делиться** (содержит чувствительные данные)
|
||||
## Тестирование
|
||||
|
||||
### ~/.config/tele-tui/
|
||||
XDG config directory:
|
||||
- `config.toml` — пользовательская конфигурация
|
||||
- `credentials` — API_ID и API_HASH
|
||||
**500+ тестов** через `cargo test` (без TDLib).
|
||||
|
||||
## Документация
|
||||
**Инфраструктура**:
|
||||
- `TestAppBuilder` — fluent API для создания App с нужным состоянием
|
||||
- `FakeTdClient` — мок TDLib, реализует TdClientTrait
|
||||
- `TestMessageBuilder` — создание тестовых сообщений
|
||||
|
||||
### Пользовательская
|
||||
- **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
|
||||
}
|
||||
```
|
||||
**Типы тестов**:
|
||||
- Unit-тесты — в `#[cfg(test)]` секциях модулей
|
||||
- Integration-тесты — в `tests/` (навигация, отправка, UI рендеринг)
|
||||
- Doc-тесты — примеры в документации
|
||||
- E2E — smoke и user journey тесты
|
||||
|
||||
## Потоки выполнения
|
||||
|
||||
### Main thread
|
||||
- Event loop (16ms tick для 60 FPS)
|
||||
- UI rendering
|
||||
- Input handling
|
||||
- App state updates
|
||||
```
|
||||
Main thread TDLib thread
|
||||
│ │
|
||||
│ ◄── mpsc ─────── │ td_client.receive() в Tokio task
|
||||
│ │
|
||||
├── poll events │
|
||||
├── handle input │
|
||||
├── update state │
|
||||
├── render UI │
|
||||
└── sleep 16ms ──► │
|
||||
```
|
||||
|
||||
### TDLib thread
|
||||
- `td_client.receive()` в отдельном Tokio task
|
||||
- Updates отправляются через `mpsc::channel`
|
||||
- Неблокирующий для main thread
|
||||
## Рантайм файлы
|
||||
|
||||
### Blocking operations
|
||||
- Загрузка конфига (при запуске)
|
||||
- Авторизация (блокирует до ввода кода)
|
||||
- Graceful shutdown (2 sec timeout)
|
||||
| Путь | Описание |
|
||||
|------|----------|
|
||||
| `~/.config/tele-tui/config.toml` | Пользовательская конфигурация |
|
||||
| `~/.config/tele-tui/credentials` | API_ID и API_HASH |
|
||||
| `tdlib_data/` | TDLib сессия (НЕ коммитится) |
|
||||
|
||||
## Зависимости
|
||||
|
||||
### 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/`
|
||||
| Категория | Крейт | Назначение |
|
||||
|-----------|-------|------------|
|
||||
| UI | ratatui 0.29 | TUI framework |
|
||||
| UI | crossterm 0.28 | Terminal control |
|
||||
| Telegram | tdlib-rs 1.1 | TDLib bindings |
|
||||
| Async | tokio 1.x | Async runtime |
|
||||
| Config | serde + toml | Serialization |
|
||||
| Time | chrono 0.4 | Date/time |
|
||||
| System | dirs 5.0 | XDG directories |
|
||||
| System | arboard 3.4 | Clipboard |
|
||||
| Notify | notify-rust 4.11 | Desktop уведомления (feature) |
|
||||
| URL | open 5.0 | Открытие URL (feature) |
|
||||
|
||||
Reference in New Issue
Block a user