Files
telegram-tui/PROJECT_STRUCTURE.md
Mikhail Kilin ffd52d2384 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>
2026-02-06 15:28:11 +03:00

329 lines
18 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Структура проекта
## Архитектура (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/
├── 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
├── Cargo.toml # Манифест проекта
├── Cargo.lock # Точные версии зависимостей
├── build.rs # Build script (TDLib)
├── rustfmt.toml # cargo fmt конфигурация
├── .editorconfig # Настройки IDE
├── .gitignore # Git ignore
├── config.toml.example # Пример конфигурации
├── credentials.example # Пример credentials
├── 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 лицензия
```
## Ключевые модули
### app/ — Состояние приложения
`App<T: TdClientTrait>` — главная структура, параметризована trait'ом для DI.
**State machine** (`ChatState` enum):
```
Normal → MessageSelection → Editing
→ Reply
→ Forward
→ DeleteConfirmation
→ ReactionPicker
→ Profile
→ SearchInChat
→ PinnedMessages
```
**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/ — Обработка ввода
**Маршрутизация** (порядок приоритетов в `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
### tdlib/ — Telegram интеграция
**Dependency Injection**: `TdClientTrait` позволяет подменять TdClient на `FakeTdClient` в тестах.
**MessageManager** — управление сообщениями:
- `convert.rs` — конвертация TDLib JSON → MessageInfo
- `operations.rs` — 11 API операций (get_history, send, edit, delete, forward, search, etc.)
### ui/ — Рендеринг
**Компоненты** (`ui/components/`):
| Компонент | Описание |
|-----------|----------|
| message_bubble | Рендеринг пузыря сообщения с реакциями |
| message_list | Элемент списка сообщений (search/pinned) |
| chat_list_item | Элемент списка чатов |
| input_field | Поле ввода с курсором |
| emoji_picker | Сетка выбора реакций |
| modal | Центрированная модалка |
### config/ — Конфигурация
- **mod.rs** — struct Config, GeneralConfig, ColorsConfig, NotificationsConfig
- **keybindings.rs** — Command enum (30+ команд), кастомные горячие клавиши
- **validation.rs** — валидация timezone, цветов
- **loader.rs** — загрузка из `~/.config/tele-tui/config.toml`, credentials
## Тестирование
**500+ тестов** через `cargo test` (без TDLib).
**Инфраструктура**:
- `TestAppBuilder` — fluent API для создания App с нужным состоянием
- `FakeTdClient` — мок TDLib, реализует TdClientTrait
- `TestMessageBuilder` — создание тестовых сообщений
**Типы тестов**:
- Unit-тесты — в `#[cfg(test)]` секциях модулей
- Integration-тесты — в `tests/` (навигация, отправка, UI рендеринг)
- Doc-тесты — примеры в документации
- E2E — smoke и user journey тесты
## Потоки выполнения
```
Main thread TDLib thread
│ │
│ ◄── mpsc ─────── │ td_client.receive() в Tokio task
│ │
├── poll events │
├── handle input │
├── update state │
├── render UI │
└── sleep 16ms ──► │
```
## Рантайм файлы
| Путь | Описание |
|------|----------|
| `~/.config/tele-tui/config.toml` | Пользовательская конфигурация |
| `~/.config/tele-tui/credentials` | API_ID и API_HASH |
| `tdlib_data/` | TDLib сессия (НЕ коммитится) |
## Зависимости
| Категория | Крейт | Назначение |
|-----------|-------|------------|
| 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) |