* feat: add thumbhash support with blurhash fallback
Bump whitenoise-rs to 0d8024be and mdk-core to fbd3a1be to pick up
thumbhash generation alongside blurhash. Surface the new thumbhash
field through the Flutter Rust bridge, add the thumbhash Dart package,
and replace WnBlurhashPlaceholder with WnMediaPlaceholder that prefers
thumbhash, falls back to blurhash, then a neutral color.
Also wire the new LeftGroup ChatListUpdateTrigger variant from upstream.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* style: fix dart formatting in wn_media_error_placeholder
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* chore: add CLAUDE.md symlink pointing to AGENTS.md
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* test: add thumbhash and leftGroup test coverage
- WnMediaPlaceholder: thumbhash rendering, preference over blurhash,
invalid thumbhash fallback (already covered)
- WnMediaErrorPlaceholder: thumbhash display, preference over blurhash
- ChatMediaThumbnail: thumbhash placeholder while loading, preference
- ChatMessageMedia: thumbhash placeholder, preference, error state
- MediaImage: thumbhash placeholder, preference, error state,
removal after fade
- useChatList: leftGroup trigger removes chat, no-op for unknown chat
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: leftGroup trigger keeps chat in list; guard empty hash tags
- leftGroup now updates the chat item in the map (like removedFromGroup)
instead of removing it, so ChatScreen's isRemovedFromGroup check can
detect the removal and show the notice/disable input
- Guard thumbhash and blurhash imeta tag emission against empty/whitespace
strings
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: use trimmed hash values in imeta tag emission
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>