Previously, handle_view_image called td_client.download_file() synchronously
while process_pending_chat_init already had a background synchronous=true
download in flight for the same file. TDLib returned is_downloading_completed=false
causing the view to fail on first press.
Fix: replace the blocking download in NotDownloaded/Downloading branches with
a pending_image_open intent flag. The main loop opens the modal automatically
when the background download result arrives via photo_download_rx. If no
background channel exists, a new one is started via direct tdlib_rs call.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- config.example.toml: duplicate of config.toml.example
- REFACTORING_ROADMAP.md, REFACTORING_OPPORTUNITIES.md: refactoring done in Phase 13
- TESTING_PROGRESS.md, TESTING_ROADMAP.md: stale since February, superseded by ROADMAP.md
- CHANGELOG.md: never maintained
- FAQ.md, CONTRIBUTING.md, SECURITY.md, INSTALL.md: boilerplate for a personal project
- .github/: GitHub templates unused (project hosted on Gitea)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Remove account deletion from modal and parallel polling — these won't
be implemented in the current scope.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
DarkGray renders differently across terminals; a specific RGB value gives
consistent appearance. Also always show the account indicator in the footer.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Snapshots now reflect the new behaviour where the account indicator
is always visible (including "default"), matching the footer.rs change.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Move all three phases of chat message loading from scattered locations
into a single dedicated module for better cohesion and navigability:
- Phase 1: open_chat_and_load_data (from handlers/chat_list.rs)
- Phase 2: process_pending_chat_init (extracted from 70-line inline block in main.rs)
- Phase 3: load_older_messages_if_needed (from handlers/chat.rs)
No behaviour changes — pure refactoring.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Render " " (2 spaces) for unselected messages instead of nothing,
so text stays aligned when navigating with the ▶ selection indicator.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When pressing down on the last message or up on the first message in
chat navigation, stay on the current message instead of exiting
message selection mode.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Prevent running multiple tele-tui instances with the same account by
using advisory file locks (flock). Lock is acquired before raw mode so
errors print to normal terminal. Account switching acquires new lock
before releasing old. Also log set_tdlib_parameters errors via tracing
instead of silently discarding them.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add #[allow(unused_imports)] on pub re-exports used only by lib/tests
- Add #[allow(dead_code)] on public API items unused in binary target
- Fix collapsible_if, redundant_closure, unnecessary_map_or in main.rs
- Prefix unused test variables with underscore
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add UnboundedReceiver for background photo downloads to App state,
reset it on close_chat. Fix account_switcher tests to navigate past
all accounts dynamically instead of assuming single account.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
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>
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>
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>
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>