# Структура проекта ## Архитектура (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 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` — главная структура, параметризована trait'ом для DI. **State machine** (`ChatState` enum): ``` Normal → MessageSelection → Editing → Reply → Forward → DeleteConfirmation → ReactionPicker → Profile → SearchInChat → PinnedMessages ``` **Trait-based methods** (5 traits на `App`): | 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) |