Commit Graph

62 Commits

Author SHA1 Message Date
Mikhail Kilin
78fe09bf11 feat: implement photo albums (media groups) and persist account selection
Group photos with shared media_album_id into single album bubbles with
grid layout (up to 3x cols). Album navigation treats grouped photos as
one unit (j/k skip entire album). Persist selected account to
accounts.toml so it survives app restart.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-22 16:18:04 +03:00
Mikhail Kilin
8bd08318bb fixes
Some checks failed
CI / Check (pull_request) Has been cancelled
CI / Format (pull_request) Has been cancelled
CI / Clippy (pull_request) Has been cancelled
CI / Build (macos-latest) (pull_request) Has been cancelled
CI / Build (ubuntu-latest) (pull_request) Has been cancelled
CI / Build (windows-latest) (pull_request) Has been cancelled
2026-02-14 17:57:37 +03:00
Mikhail Kilin
6639dc876c fixes 2026-02-13 19:52:53 +03:00
Mikhail Kilin
6d08300daa feat: implement audio seeking with arrow keys via ffplay restart
Seek now works by restarting ffplay with -ss offset instead of the
broken player.seek() stub. MoveLeft/MoveRight added as aliases for
SeekBackward/SeekForward to fix HashMap non-deterministic iteration
order causing Left arrow to resolve to MoveLeft instead of SeekBackward.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-09 18:51:45 +03:00
Mikhail Kilin
8a467b6418 feat: complete Phase 12 — voice playback ticker, cache, config, and UI
Add playback position ticker in event loop with 1s UI refresh rate,
integrate VoiceCache for downloaded voice files, add [audio] config
section (cache_size_mb, auto_download_voice), and render progress bar
with waveform visualization in message bubbles.

Fix race conditions in AudioPlayer: add `starting` flag to prevent
false `is_stopped()` during ffplay startup, guard pid cleanup so old
threads don't overwrite newer process pids. Implement `resume_from()`
with ffplay `-ss` for real audio seek on unpause (-1s rewind).

Kill ffplay on app exit via `stop_playback()` in shutdown + Drop impl.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-09 16:37:02 +03:00
Mikhail Kilin
7bc264198f feat: implement Phase 12 — voice message playback with ffplay
Add voice message playback infrastructure:
- AudioPlayer using ffplay subprocess with SIGSTOP/SIGCONT for pause/resume
- VoiceCache with LRU eviction (100 MB limit)
- TDLib integration: VoiceInfo, VoiceDownloadState, PlaybackState types
- download_voice_note() in TdClientTrait
- Keybindings: Space (play/pause), ←/→ (seek ±5s)
- Auto-stop playback on message navigation
- Remove debug_log module
2026-02-09 02:35:49 +03:00
Mikhail Kilin
2a5fd6aa35 perf: optimize Phase 11 image rendering with dual-protocol architecture
Redesigned UX and performance for inline photo viewing:

UX changes:
- Always-show inline preview (fixed 50 chars width)
- Fullscreen modal on 'v' key with ←/→ navigation between photos
- Loading indicator " Загрузка..." in modal for first view
- ImageModalState type for modal state management

Performance optimizations:
- Dual renderer architecture:
  * inline_image_renderer: Halfblocks protocol (fast, Unicode blocks)
  * modal_image_renderer: iTerm2/Sixel protocol (high quality)
- Frame throttling: inline images 15 FPS (66ms), text remains 60 FPS
- Lazy loading: only visible images loaded (was: all images)
- LRU cache: max 100 protocols with eviction
- Skip partial rendering to prevent image shrinking/flickering

Technical changes:
- App: added inline_image_renderer, modal_image_renderer, last_image_render_time
- ImageRenderer: new() for modal (auto-detect), new_fast() for inline (Halfblocks)
- messages.rs: throttled second-pass rendering, visible-only loading
- modals/image_viewer.rs: NEW fullscreen modal with loading state
- ImagesConfig: added inline_image_max_width, auto_download_images

Result: 10x faster navigation, smooth 60 FPS text, quality modal viewing

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-08 01:36:36 +03:00
Mikhail Kilin
b0f1f9fdc2 feat: implement Phase 11 — inline photo viewing with ratatui-image
Add feature-gated (`images`) inline photo support:
- New types: MediaInfo, PhotoInfo, PhotoDownloadState, ImagesConfig
- Media module: ImageCache (LRU filesystem cache), ImageRenderer (terminal protocol detection)
- Photo metadata extraction from TDLib MessagePhoto with download_file() API
- ViewImage command (v/м) to toggle photo expand/collapse in message selection
- Two-pass UI rendering: placeholder lines in message bubbles + StatefulImage overlay
- Collapse all expanded photos on Esc (exit selection mode)

Dependencies: ratatui-image 8.1, image 0.25 (optional, behind `images` feature flag)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-06 21:25:17 +03:00
Mikhail Kilin
6845ee69bf docs: trim CONTEXT.md and ROADMAP.md (3006→246 lines, -92%)
Completed phases condensed to summary tables, detailed history
removed (available in git log). Detailed plans kept only for
upcoming phases 11 (images) and 12 (voice messages).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-06 16:57:27 +03:00
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
Mikhail Kilin
931954d829 refactor: split app/mod.rs into trait-based architecture (1015→371 lines)
Split monolithic App impl into 5 specialized trait modules:
- methods/navigation.rs (NavigationMethods) - 7 methods for chat navigation
- methods/messages.rs (MessageMethods) - 8 methods for message operations
- methods/compose.rs (ComposeMethods) - 10 methods for reply/forward/draft
- methods/search.rs (SearchMethods) - 15 methods for search functionality
- methods/modal.rs (ModalMethods) - 27 methods for modal dialogs

Changes:
- app/mod.rs: 1015→371 lines (removed 644 lines, -63%)
- Created app/methods/ with 5 trait impl blocks
- Left in app/mod.rs: constructors, get_command, get_selected_chat_id/chat, getters/setters
- 116 functions → 5 trait impl blocks (67 in traits + 48 in core)
- Single Responsibility Principle achieved
- Updated CONTEXT.md with refactoring metrics
- Updated ROADMAP.md: Phase 13 Etap 2 marked as DONE

Phase 13 Etap 2: COMPLETED (100%)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-06 00:59:14 +03:00
Mikhail Kilin
1d0bfb53e0 refactor: split main_input.rs into modular handlers (1199→164 lines)
Split monolithic input handler into 5 specialized modules:
- handlers/chat.rs (452 lines) - chat keyboard input
- handlers/modal.rs (316 lines) - modal dialogs
- handlers/chat_list.rs (142 lines) - chat list navigation
- handlers/search.rs (140 lines) - search functionality
- handlers/compose.rs (80 lines) - forward/reply/edit modes

Changes:
- main_input.rs: 1199→164 lines (removed 1035 lines, -86%)
- Preserved existing handlers: clipboard, global, profile
- Created clean router pattern in main_input.rs
- Fixed keybinding conflict: Ctrl+I→Ctrl+U for profile
- Fixed modifier handling in chat input (ignore Ctrl/Alt chars)
- Updated CONTEXT.md with refactoring metrics
- Updated ROADMAP.md: Phase 13 Etap 1 marked as DONE

Phase 13 Etap 1: COMPLETED (100%)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-06 00:43:52 +03:00
Mikhail Kilin
776271ff36 docs: add Phase 12 - voice message playback
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>
2026-02-05 02:51:04 +03:00
Mikhail Kilin
8844c2953d docs: add Phase 11 - image display in chat
Documented new feature for displaying images directly in terminal
instead of text placeholders like "[Фото]".

Documentation Changes:
- ROADMAP.md: Added Phase 11 with 6 stages
  - Stage 1: Infrastructure (media module, ImageCache, dependencies)
  - Stage 2: TDLib integration (PhotoInfo, download_photo)
  - Stage 3: UI rendering (inline previews, scaling)
  - Stage 4: Fullscreen viewer (new ViewImage mode)
  - Stage 5: Configuration and UX (MediaConfig in config.toml)
  - Stage 6: Error handling and fallback

- CONTEXT.md: Added PLANNED section for Phase 11
  - Technical stack: ratatui-image 1.0, TDLib downloadFile
  - Protocols: Sixel, Kitty Graphics, iTerm2, Unicode Halfblocks
  - Architecture: src/media/ module with 3 submodules
  - LRU cache (100 MB limit)
  - Async loading, lazy loading for visible images
  - Configuration options in config.toml

- HOTKEYS.md: Added new hotkeys
  - `v` / `м` - open image in fullscreen (in selection mode)
  - `←` / `→` - navigate between images (in viewer mode)
  - `Esc` - close image viewer
  - Added new "View Image Mode" section

- PROJECT_STRUCTURE.md: Added media/ module documentation
  - image_cache.rs - LRU cache for downloaded images
  - image_loader.rs - Async loading via TDLib
  - image_renderer.rs - Rendering with protocol detection
  - Updated dependencies section
  - Updated App state with new fields

Technical Details:
- Terminal protocol auto-detection (Sixel/Kitty/iTerm2/Halfblocks)
- Cross-platform support (Linux, macOS, Windows)
- Graceful fallback to Unicode halfblocks for all terminals
- Async non-blocking image loading
- Smart caching with size limits
- Configurable quality and protocol settings

New Configuration (config.toml):
- show_images: bool - enable/disable image display
- image_cache_mb: usize - cache size limit in MB
- preview_quality: "low" | "medium" | "high"
- render_protocol: "auto" | "sixel" | "kitty" | "iterm2" | "halfblocks"

Status: PLANNED (documentation complete, implementation pending)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-05 02:43:04 +03:00
Mikhail Kilin
bea0bcbed0 feat: implement desktop notifications with comprehensive filtering
Implemented Phase 10 (Desktop Notifications) with three stages:
notify-rust integration, smart filtering, and production polish.

Stage 1 - Base Implementation:
- Add NotificationManager module (src/notifications.rs, 350+ lines)
- Integrate notify-rust 4.11 with feature flag "notifications"
- Implement NotificationsConfig in config.toml (enabled, only_mentions, show_preview)
- Add notification_manager field to TdClient
- Create configure_notifications() method for config integration
- Hook into handle_new_message_update() to send notifications
- Send notifications for messages outside current chat
- Format notification body with sender name and message preview

Stage 2 - Smart Filtering:
- Sync muted chats from Telegram (sync_muted_chats method)
- Filter muted chats from notifications automatically
- Add MessageInfo::has_mention() to detect @username mentions
- Implement only_mentions filter (notify only when mentioned)
- Beautify media labels with emojis (📷 📹 🎤 🎨 📎 etc.)
- Support 10+ media types in notification preview

Stage 3 - Production Polish:
- Add graceful error handling (no panics on notification failure)
- Implement comprehensive logging (tracing::debug!/warn!)
- Add timeout_ms configuration (0 = system default)
- Add urgency configuration (low/normal/critical, Linux only)
- Platform-specific #[cfg] for urgency support
- Log all notification skip reasons at debug level

Hotkey Change:
- Move profile view from 'i' to Ctrl+i to avoid conflicts

Technical Details:
- Cross-platform support (macOS, Linux, Windows)
- Feature flag for optional notifications support
- Graceful fallback when notifications unavailable
- LRU-friendly muted chats sync
- Test coverage for all core notification logic
- All 75 tests passing

Files Changed:
- NEW: src/notifications.rs - Complete NotificationManager
- NEW: config.example.toml - Example configuration with notifications
- Modified: Cargo.toml - Add notify-rust 4.11 dependency
- Modified: src/config/mod.rs - Add NotificationsConfig struct
- Modified: src/tdlib/types.rs - Add has_mention() method
- Modified: src/tdlib/client.rs - Add notification integration
- Modified: src/tdlib/update_handlers.rs - Hook notifications
- Modified: src/config/keybindings.rs - Change profile to Ctrl+i
- Modified: tests/* - Add notification config to tests

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-05 01:27:44 +03:00
Mikhail Kilin
1cc61ea026 refactor: clean up dead code and optimize performance
Major changes:
- Remove unused field `selecting_chat` from ChatState::Forward
- Remove unused field `start_offset` from WrappedLine in messages.rs
- Delete unused functions from modal_handler.rs (ModalAction enum, handle_modal_key, should_close_modal, should_confirm_modal)
- Delete unused functions from validation.rs (is_within_length, is_valid_chat_id, is_valid_message_id, is_valid_user_id, has_items, validate_text_input)
- Remove unused methods from Keybindings (from_event, matches, get_bindings, add_binding, remove_command)
- Delete unused input handlers (chat_list.rs, messages.rs, modal.rs, search.rs)
- Remove unused imports across multiple files

Performance optimizations:
- Fix slow chat opening: load only last 100 messages instead of i32::MAX (10-100x faster)
- Reduce timeout from 30s to 10s for initial message load
- Fix slow text input: replace O(n) string rebuilding with O(1) String::insert()/remove() operations
- Optimize Backspace, Delete, and Char input handlers

Bug fixes:
- Remove duplicate ChatSortOrder tests after enum deletion
- Fix test compilation errors after removing unused methods
- Update tests to use get_command() instead of removed matches() method

Code cleanup:
- Remove ~400 lines of dead code
- Remove 12 unused tests
- Clean up imports in config/mod.rs, main_input.rs, tdlib/messages.rs

Test status: 565 tests passing
Warnings reduced from 40+ to 9

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-04 22:27:02 +03:00
Mikhail Kilin
bd5e5be618 refactor: extract state modules and services from monolithic files
Some checks failed
CI / Check (pull_request) Has been cancelled
CI / Format (pull_request) Has been cancelled
CI / Clippy (pull_request) Has been cancelled
CI / Build (macos-latest) (pull_request) Has been cancelled
CI / Build (ubuntu-latest) (pull_request) Has been cancelled
CI / Build (windows-latest) (pull_request) Has been cancelled
Извлечены state модули и сервисы из монолитных файлов для улучшения структуры:

State модули:
- auth_state.rs: состояние авторизации
- chat_list_state.rs: состояние списка чатов
- compose_state.rs: состояние ввода сообщений
- message_view_state.rs: состояние просмотра сообщений
- ui_state.rs: UI состояние

Сервисы и утилиты:
- chat_filter.rs: централизованная фильтрация чатов (470+ строк)
- message_service.rs: сервис работы с сообщениями (17KB)
- key_handler.rs: trait для обработки клавиш (380+ строк)

Config модуль:
- config.rs -> config/mod.rs: основной конфиг
- config/keybindings.rs: настраиваемые горячие клавиши (420+ строк)

Тесты: 626 passed 

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-04 19:29:25 +03:00
Mikhail Kilin
72c4a886fa fix: implement dynamic message history loading with retry logic
Проблема:
- При открытии чата видно только последнее сообщение
- TDLib возвращал 1 сообщение при первом запросе
- Не было retry логики для ожидания синхронизации с сервером

Решение:
1. Динамическая загрузка с retry (до 20 попыток на чанк)
2. Загрузка всей доступной истории (без лимита)
3. Retry при получении малого количества сообщений
4. Корректная чанковая загрузка по 50 сообщений

Алгоритм:
- При открытии чата: get_chat_history(i32::MAX) - загружает всё
- Чанками по 50: TDLIB_MESSAGE_LIMIT
- Retry если получено < 50 при первой загрузке
- Остановка если 3 раза подряд пусто
- Порядок: старые чанки вставляются в начало (splice)
- При скролле: load_older_messages_if_needed() подгружает автоматически

Изменения:
src/tdlib/messages.rs:
- Убрана фиксированная задержка 100ms после open_chat
- Добавлен счетчик consecutive_empty_results
- Retry логика без искусственных sleep()
- Проверка: если получено мало - продолжить попытки

src/input/main_input.rs:
- limit: 100 → i32::MAX (без ограничений)
- timeout: 10s → 30s

tests/chat_list.rs:
- test_chat_history_chunked_loading: проверка 100, 120, 200 сообщений
- test_chat_history_loads_all_without_limit: загрузка 200 без лимита
- test_load_older_messages_pagination: подгрузка при скролле

Все тесты: 104/104 

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-04 03:56:58 +03:00
Mikhail Kilin
9a04455113 docs: mark refactoring as complete (100%) and ready to merge 2026-02-04 02:16:27 +03:00
Mikhail Kilin
5ac10ea24c refactor: complete large files/functions refactoring (Phase 6-7)
Phase 6: Refactor tdlib/client.rs 
- Extract update handlers to update_handlers.rs (302 lines, 8 functions)
- Extract message converter to message_converter.rs (250 lines, 6 functions)
- Extract chat helpers to chat_helpers.rs (149 lines, 3 functions)
- Result: client.rs 1259 → 599 lines (-52%)

Phase 7: Refactor tdlib/messages.rs 
- Create message_conversion.rs module (158 lines)
- Extract 6 helper functions:
  - extract_content_text() - content extraction (~80 lines)
  - extract_entities() - formatting extraction (~10 lines)
  - extract_sender_name() - sender name with API call (~15 lines)
  - extract_forward_info() - forward info (~12 lines)
  - extract_reply_info() - reply info (~15 lines)
  - extract_reactions() - reactions extraction (~26 lines)
- Result: convert_message() 150 → 57 lines (-62%)
- Result: messages.rs 850 → 757 lines (-11%)

Summary:
-  All 4 large files refactored (100%)
-  All 629 tests passing
-  Category #2 "Large files/functions" COMPLETE
-  Documentation updated (REFACTORING_OPPORTUNITIES.md, CONTEXT.md)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-04 01:29:26 +03:00
Mikhail Kilin
b081886e34 docs: update CONTEXT.md with Phase 6 start 2026-02-03 22:26:51 +03:00
Mikhail Kilin
88ff4dd3b7 docs: update CONTEXT.md with Phase 5 completion 2026-02-03 21:30:48 +03:00
Mikhail Kilin
6150fe3cdb docs: update CONTEXT.md with Phase 4 results
Документация Phase 4: Упрощение вложенности
- Глубина вложенности: 6+ → 2-3 уровня
- Применены паттерны: early returns, let-else guards
- Извлечено 3 вспомогательных функции
- 6 функций упрощены

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-03 20:35:45 +03:00
Mikhail Kilin
7e372bffef docs: update CONTEXT.md with complete refactoring results
Обновлена документация с результатами Phase 3:
- Функция handle() сократилась с 891 до 82 строк (91% сокращение!)
- Всего извлечено 13 специализированных функций
- Phase 2: 2 функции (~163 строки)
- Phase 3: 11 функций (~783 строки)

Код стал линейным и простым для понимания.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-03 17:16:33 +03:00
Mikhail Kilin
a518875421 docs: update CONTEXT.md with Phase 2 completion
Обновлена документация рефакторинга main_input.rs:
- Phase 1: 10 функций (~704 строки)
- Phase 2: 2 функции (~163 строки)
- Итого: 12 функций, сокращение handle() с 891 до 734 строк

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-03 17:01:27 +03:00
Mikhail Kilin
ee416dff45 docs: update CONTEXT.md with refactoring progress 2026-02-03 16:33:34 +03:00
Mikhail Kilin
3c8fec7ca6 refactor: integrate validation utils and complete refactoring #1
Завершена интеграция validation utils во всех местах проверки user input:

Changes:
- src/utils/mod.rs: раскомментирован экспорт validation::*
- src/input/auth.rs: 3 замены .is_empty() -> is_non_empty()
  * phone_input validation (line 18)
  * code_input validation (line 50)
  * password_input validation (line 82)
- src/input/main_input.rs: 1 замена для message_input (line 484)
- src/main.rs: заменён последний прямой timeout на with_timeout_ignore

Documentation:
- REFACTORING_OPPORTUNITIES.md: обновлён статус категории #1
  * Отмечено как "ПОЛНОСТЬЮ ЗАВЕРШЕНО" (2026-02-02)
  * Добавлены метрики: 100% покрытие retry utils, 0 прямых timeouts
  * Обновлён план выполнения: фаза 1 завершена
- CONTEXT.md: добавлен раздел об интеграции validation utils

Result:
 Категория #1 (Дублирование кода) - ПОЛНОСТЬЮ ЗАВЕРШЕНА!
  - retry utils: 100% покрытие (8+ мест)
  - modal_handler: 2 диалога
  - validation: 4 места

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-02 17:38:49 +03:00
Mikhail Kilin
8e48d076de refactor: implement trait-based DI for TdClient and fix stack overflow
Implement complete trait-based dependency injection pattern for TdClient
to enable testing with FakeTdClient mock. Fix critical stack overflow bugs
caused by infinite recursion in trait implementations.

Breaking Changes:
- App is now generic: App<T: TdClientTrait = TdClient>
- All UI and input handlers are generic over TdClientTrait
- TdClient methods now accessed through trait interface

New Files:
- src/tdlib/trait.rs: TdClientTrait definition with 40+ methods
- src/tdlib/client_impl.rs: TdClientTrait impl for TdClient
- tests/helpers/fake_tdclient_impl.rs: TdClientTrait impl for FakeTdClient

Critical Fixes:
- Fix stack overflow in send_message, edit_message, delete_messages
- Fix stack overflow in forward_messages, current_chat_messages
- Fix stack overflow in current_pinned_message
- All methods now call message_manager directly to avoid recursion

Testing:
- FakeTdClient supports configurable auth_state for auth screen tests
- Added pinned message support in FakeTdClient
- All 196+ tests passing (188 tests + 8 benchmarks)

Dependencies:
- Added async-trait = "0.1"

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-02 05:42:19 +03:00
Mikhail Kilin
ed5a4f9c72 refactor: complete UI components - implement message_bubble.rs
Some checks failed
CI / Check (pull_request) Has been cancelled
CI / Format (pull_request) Has been cancelled
CI / Clippy (pull_request) Has been cancelled
CI / Build (macos-latest) (pull_request) Has been cancelled
CI / Build (ubuntu-latest) (pull_request) Has been cancelled
CI / Build (windows-latest) (pull_request) Has been cancelled
Finalize Priority 3 UI components refactoring (5/5 complete):

- Create message_bubble.rs (437 lines) with 3 rendering functions:
  * render_date_separator() - centered date separators
  * render_sender_header() - sender headers (incoming/outgoing)
  * render_message_bubble() - messages with forward/reply/reactions

- Simplify messages.rs by removing ~300 lines:
  * Use message_grouping::group_messages() for logic
  * Use UI components for rendering
  * Cleaner separation of concerns

- Update module exports and main.rs

All 196 tests passing (188 tests + 8 benchmarks). No regressions.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-02 03:41:03 +03:00
Mikhail Kilin
2980e52113 commit
Some checks failed
CI / Check (pull_request) Has been cancelled
CI / Format (pull_request) Has been cancelled
CI / Clippy (pull_request) Has been cancelled
CI / Build (macos-latest) (pull_request) Has been cancelled
CI / Build (ubuntu-latest) (pull_request) Has been cancelled
CI / Build (windows-latest) (pull_request) Has been cancelled
2026-02-02 03:18:55 +03:00
Mikhail Kilin
4d9d76ed23 refactor: prepare handlers structure for future input refactoring
Preparation for splitting large input file (#2):
- Created src/input/handlers/ structure (7 modules)
  - clipboard.rs (~100 lines) - clipboard operations extracted
  - global.rs (~90 lines) - global commands (Ctrl+R/S/P/F) extracted
  - Stubs: profile.rs, search.rs, modal.rs, messages.rs, chat_list.rs
- main_input.rs remains monolithic (1139 lines)
  - Attempted full migration broke navigation - rolled back
  - Handlers remain as preparation for gradual migration

Updated documentation:
- REFACTORING_OPPORTUNITIES.md: #2.1 status updated
- CONTEXT.md: Added lesson about careful refactoring

Lesson learned: Critical input logic requires careful step-by-step
refactoring with functionality verification after each step.

Tests: 563 passed, 0 failed

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-02 00:08:56 +03:00
Mikhail Kilin
dff0897da4 refactor: add modal/validation utils and partial App encapsulation
Quick wins refactoring (Variant 1):
- Created src/utils/modal_handler.rs (120+ lines)
  - 4 functions for modal handling (close, confirm, yes/no)
  - ModalAction enum for type-safe processing
  - English and Russian keyboard layout support
  - 4 unit tests
- Created src/utils/validation.rs (180+ lines)
  - 7 validation functions (empty, length, IDs, etc)
  - Covers all common validation patterns
  - 7 unit tests
- Partial App encapsulation:
  - Made config field private (readonly via app.config())
  - Added 30+ getter/setter methods
  - Updated ui/messages.rs to use config()
- Updated documentation:
  - REFACTORING_OPPORTUNITIES.md: #1 Complete, #5 Partial
  - CONTEXT.md: Added quick wins section

Tests: 563 passed, 0 failed

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-01 23:55:49 +03:00
Mikhail Kilin
e690acfb09 test: complete Phase 4 testing - utils tests and performance benchmarks
Added 9 new unit tests for utils/formatting.rs functions:
- format_date: 4 tests (today, yesterday, old, epoch)
- format_was_online: 5 tests (just now, minutes/hours/days ago, very old)

Created 3 performance benchmark files using criterion:
- benches/group_messages.rs - message grouping benchmarks
- benches/formatting.rs - timestamp/date formatting benchmarks
- benches/format_markdown.rs - markdown parsing benchmarks

Updated documentation:
- CONTEXT.md: added Phase 4.1 (Utils) and 4.2 (Benchmarks) completion
- Total coverage: 188 tests + 8 benchmarks = 196 tests (100%)

All 565 tests passing with 100% success rate.
2026-02-01 23:04:43 +03:00
Mikhail Kilin
09c5c5674e feat: add structured logging with tracing (P5.17)
Some checks failed
CI / Check (pull_request) Has been cancelled
CI / Format (pull_request) Has been cancelled
CI / Clippy (pull_request) Has been cancelled
CI / Build (macos-latest) (pull_request) Has been cancelled
CI / Build (ubuntu-latest) (pull_request) Has been cancelled
CI / Build (windows-latest) (pull_request) Has been cancelled
Replaced eprintln! with tracing for structured logging:
- Added dependencies: tracing, tracing-subscriber (with env-filter)
- Initialized subscriber in main.rs with default warn level
- Replaced all eprintln! calls in src/config.rs with tracing macros:
  * warn!() for warnings (4 occurrences)
  * error!() for validation errors (1 occurrence)
- Configurable log levels via RUST_LOG environment variable

Benefits:
- Structured logging for better observability
- Configurable log levels without code changes
- Better async integration
- Unified logging approach across the project

🎉🎉🎉 REFACTORING COMPLETE: All 20/20 tasks done (100%)! 🎉🎉🎉

Priority 5: 3/3 tasks  COMPLETE
Total progress: 20/20 tasks (100%)  COMPLETE

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-01 02:29:08 +03:00
Mikhail Kilin
67739583f3 refactor: generalize LruCache to support any key type (P5.16)
Made LruCache generic over key type K, not just UserId:
- LruCache<V> → LruCache<K, V>
- Added trait bounds: K: Eq + Hash + Clone + Copy
- Updated UserCache field types:
  * user_usernames: LruCache<UserId, String>
  * user_names: LruCache<UserId, String>
  * user_statuses: LruCache<UserId, UserOnlineStatus>

Benefits:
- Reusable cache implementation for any key types
- Type-safe caching
- No additional dependencies

Progress: Priority 5: 2/3 tasks, Total: 18/20 (90%)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-01 02:26:03 +03:00
Mikhail Kilin
56bddabbe1 feat: add optional feature flags for clipboard and url-open (P5.15)
Implemented feature flags to make dependencies optional:
- clipboard feature: controls arboard dependency
- url-open feature: controls open dependency
- Both enabled by default for backward compatibility

Changes:
- Cargo.toml: Added [features] section with optional deps
- src/input/main_input.rs: Conditional compilation for open::that() and copy_to_clipboard()
- tests/copy.rs: Clipboard tests only compile with feature enabled
- Graceful degradation: user-friendly error messages when features disabled

Benefits:
- Smaller binary size when features disabled
- Modular functionality
- Better platform compatibility

Progress: Priority 5: 1/3 tasks, Total: 17/20 (85%)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-01 02:23:17 +03:00
Mikhail Kilin
426af96941 docs: update CONTEXT.md with Priority 3 completion
- Document P3.10 Hotkey mapping completion (9 tests)
- Document P3.9 Message grouping completion (7 tests)
- Document P4.12 Rustdoc partial progress (30%)
- Update Priority 3 status: 100% (4/4 tasks) complete
- All 464 tests passing

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-01 00:25:57 +03:00
Mikhail Kilin
1b70b12799 docs: update CONTEXT.md with refactoring progress
- Document P3.9 (Message Grouping) completion
- Document P3.10 (Hotkey Mapping) completion
- Document P4.12 (Rustdoc) partial completion
- Priority 3: 100% complete! 🎉
- Overall refactoring: 12/17 tasks (71%)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-31 23:53:58 +03:00
Mikhail Kilin
1629c0fc6a refactor: add hotkey mapping configuration (P3.10)
- Add HotkeysConfig structure in src/config.rs
- Implement matches(key: KeyCode, action: &str) method
- Support for 10 configurable hotkeys:
  * Navigation: up, down, left, right (vim + russian + arrows)
  * Actions: reply, forward, delete, copy, react, profile
- Add support for char keys and special keys (Up, Down, Delete, etc)
- Add default values for all hotkeys (english + russian layouts)
- Write 9 unit tests (all passing)
- Add rustdoc documentation with examples
- Update REFACTORING_ROADMAP.md (Priority 3: 4/4 tasks, 100%)
- Update CONTEXT.md with implementation details
- Overall refactoring progress: 12/17 tasks (71%)

Priority 3 is now 100% complete! 🎉

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-31 23:51:10 +03:00
Mikhail Kilin
0ca3da54e7 refactor: extract message grouping logic (P3.9)
- Create src/message_grouping.rs module (255 lines)
- Add MessageGroup enum (DateSeparator, SenderHeader, Message)
- Add group_messages() function for date/sender grouping
- Write 5 unit tests (all passing)
- Add full rustdoc documentation with examples
- Update REFACTORING_ROADMAP.md (Priority 3: 3/4 tasks, 75%)
- Update CONTEXT.md with refactoring progress
- Overall refactoring progress: 11/17 tasks (65%)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-31 23:30:41 +03:00
Mikhail Kilin
c5896b7f14 tests 2026-01-31 23:02:53 +03:00
Mikhail Kilin
af3c36b9a1 docs: обновлён CONTEXT.md с описанием исправлений
Добавлено описание исправлений от 31 января (вечер):
- Исправление отображения новых сообщений
- Исправление редактирования
- Исправление reply
- Удаление отладочных логов
2026-01-31 18:38:47 +03:00
Mikhail Kilin
644e36597d fixes 2026-01-31 03:48:50 +03:00
Mikhail Kilin
1bf9b3d703 docs: celebrate Priority 2 completion! 🎉
Обновлена документация для отражения ПОЛНОГО ЗАВЕРШЕНИЯ Priority 2
(все 5 задач выполнены на 100%).

Изменения:
- CONTEXT.md: отмечен Priority 2 как завершённый (100%, 5/5)
- CONTEXT.md: добавлена секция P2.7 MessageBuilder
- CONTEXT.md: обновлён раздел "Последние обновления" с празднованием
- CONTEXT.md: добавлены итоги Priority 2
- CONTEXT.md: обновлён технический долг
- REFACTORING_ROADMAP.md: отмечен P2.7 как завершённый
- REFACTORING_ROADMAP.md: добавлена детальная секция MessageBuilder
- REFACTORING_ROADMAP.md: обновлён общий прогресс (47%, 8/17 задач)

🏆 ИТОГИ PRIORITY 2 (100%):
 P2.5 — Error enum
 P2.3 — Config validation
 P2.4 — Newtype для ID
 P2.6 — MessageInfo реструктуризация
 P2.7 — MessageBuilder pattern

Статус: Priority 2 ПОЛНОСТЬЮ ЗАВЕРШЁН! 🎊
Следующий этап: Priority 3 (UI компоненты, форматирование)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-31 02:03:59 +03:00
Mikhail Kilin
5709fab9c3 docs: update documentation for P2.6 completion
Обновлена документация для отражения завершения задачи P2.6
(реструктуризация MessageInfo).

Изменения:
- CONTEXT.md: добавлен P2.6 в завершённые задачи Priority 2
- CONTEXT.md: обновлён статус Priority 2 (80%, 4/5 задач)
- CONTEXT.md: добавлена детальная секция "Последние обновления"
- CONTEXT.md: обновлён технический долг
- REFACTORING_ROADMAP.md: отмечен P2.6 как завершённый
- REFACTORING_ROADMAP.md: обновлён общий прогресс (41%, 7/17 задач)
- REFACTORING_ROADMAP.md: добавлено "Что сделано" для P2.6

Статус: Priority 2 - 80% (4/5 задач)
Осталась последняя задача: P2.7 MessageBuilder pattern

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-31 01:47:51 +03:00
Mikhail Kilin
7081a886ad refactor: implement newtype pattern for IDs (P2.4)
Добавлены типобезопасные обёртки ChatId, MessageId, UserId для предотвращения
смешивания разных типов идентификаторов на этапе компиляции.

Изменения:
- Создан src/types.rs с тремя newtype структурами
- Реализованы методы: new(), as_i64(), From<i64>, Display
- Добавлены traits: Hash, Eq, Serialize, Deserialize
- Обновлены 15+ модулей для использования новых типов:
  * tdlib: types.rs, chats.rs, messages.rs, users.rs, reactions.rs, client.rs
  * app: mod.rs, chat_state.rs
  * input: main_input.rs
  * tests: app_builder.rs, test_data.rs
- Исправлены 53 ошибки компиляции связанные с type conversions

Преимущества:
- Компилятор предотвращает смешивание разных типов ID
- Улучшенная читаемость кода (явные типы вместо i64)
- Самодокументирующиеся типы

Статус: Priority 2 теперь 60% (3/5 задач)
-  Error enum
-  Config validation
-  Newtype для ID
-  MessageInfo реструктуризация
-  MessageBuilder pattern

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-31 01:33:18 +03:00
Mikhail Kilin
38e73befc1 fixes 2026-01-31 01:00:43 +03:00
Mikhail Kilin
bba5cbd22d fixes 2026-01-30 23:55:01 +03:00
Mikhail Kilin
a4cf6bac72 fixes 2026-01-30 16:18:16 +03:00
Mikhail Kilin
126c7482af fixes
Some checks failed
CI / Check (pull_request) Has been cancelled
CI / Format (pull_request) Has been cancelled
CI / Clippy (pull_request) Has been cancelled
CI / Build (macos-latest) (pull_request) Has been cancelled
CI / Build (ubuntu-latest) (pull_request) Has been cancelled
CI / Build (windows-latest) (pull_request) Has been cancelled
2026-01-29 01:22:57 +03:00