Thread buffers rebuilt themselves from scratch on every refresh with no
deduplication and no guard against overlapping runs, and the list control was
mutated from the update timer's background thread. Threads opened from the same
account also shared a single session.db entry, because the buffer name was
derived from the author instead of the post.
- Name conversation buffers after the post URI, and navigate to an already open
thread instead of opening a second buffer for it.
- Deduplicate thread items by URI, and refuse a refresh while one is in flight.
- Move the clear-and-fill step onto the GUI thread via wx.CallAfter.
- Stop start_buffers() from starting a buffer that create_buffer() already
started, since needs_init was never cleared.
The direct messages list never focused an item after being rebuilt, so its
position was announced as "0 of 1", which cannot exist. The conversation list
now focuses an item whenever it cannot restore the previous selection, and the
buffer navigation announcements no longer report a position while nothing is
focused.
Verified against the live Bluesky API that app.bsky.feed.getPostThread itself
returns no repeated posts, so the duplication was entirely on our side.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
wx only decodes the image formats its own handlers support. Mastodon
instances commonly serve avatars and headers as WebP, so wx.Image failed
and raised a modal "Unknown image format" dialog, which blocked the user
from updating their profile or from reading someone's profile.
Images are now decoded with Pillow and their raw pixel data handed over
to wx, through a new mysc.image_utils module shared by the Mastodon and
Bluesky profile dialogs. Undecodable or unreachable images log the
problem and leave an empty placeholder instead of raising.
Also accept WebP and JPEG files in the header/avatar file pickers, warn
the user with a common message dialog when the picked file cannot be
read, and fix the parentless wx.StaticBitmap placeholders that were
created when a profile image could not be downloaded.
Resolve sender DIDs to display names by building member maps from conversation
data. Fix compose functions to prefer snake_case attributes (ATProto SDK convention).
Ensure stable key comparison in dedup logic by converting ATProto objects to strings.
Move Chats buffer to appear after Mentions and before Notifications.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
application.app was never set anywhere - application.py is just a
constants module. Every call to view_chat(), on_new_chat(),
view_conversation(), on_reposts(), and on_likes() crashed with
AttributeError, silently swallowed by get_event's except clause.
Fix: store controller reference on each buffer during create_buffer()
in mainController, then use self.controller instead of the broken
application.app.controller pattern throughout all Bluesky buffer and
dialog code.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
ChatBuffer now has get_message(), get_formatted_message(), and view_item()
so repeat_item, copy_to_clipboard, and view work correctly with chat
messages. open_conversation (Ctrl+Win+Alt+C) detects chat buffers and
delegates to view_chat(). Opening a chat buffer now announces its name
and item count for screen reader feedback.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replicate the Mastodon pattern where conversation buffers are inserted
as children of the direct_messages node, making Chats expandable in the
tree. Also adds duplicate detection and auto-navigation to existing
chat buffers.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Fix Bluesky quoted post rendering across list output, screen-reader speech, and View Post by centralizing quote extraction.
- Add robust quote URL extraction (facets/embed/text), include quoted URLs in URL shortcuts, and append full quoted URLs when hidden/truncated.
- Improve reply context handling:
- add and use `$reply_to` template variable,
- hydrate missing reply target handles in home/feed items,
- keep backward compatibility for templates that do not include `$reply_to`.
- Align Bluesky default/fallback post templates to include reply context (`$reply_to`).
- Add/extend focused Bluesky tests for quote text, quote URLs, reply context, and template fallback behavior.
- Refactor scripts:
- add bootstrap-dev.ps1 for environment setup (submodules, venv, deps),
- keep run-tests.ps1 focused on running tests only,
- add PowerShell comment-based help in English.
- Update README with the new bootstrap/test workflow and examples.