* Add Chinese localizations
* Fix Chinese locale selection
* Revert "Fix Chinese locale selection"
This reverts commit fa59dc2df05e90551334622d72b600ccc8f6816e.
* Use zh fallback for Simplified Chinese
* Fix script-specific locale equality
* fix: persist Chinese locale settings
Bump whitenoise-rs to the current ref with Chinese language variants and map zh/zh_Hant through the Rust language bridge.
Co-authored-by: stupidloud <klever1988@protonmail.com>
* fix: preserve system locale scripts
Preserve supported system locale script codes when resolving language settings and rendering the system language label.
---------
Co-authored-by: Jeff Gardner <202880+erskingardner@users.noreply.github.com>
* Filter blocked users and fix widgetbook analysis
* Filter blocked users across messaging surfaces
* Guard blocked-user loading windows
* Remove chat list subscription from chat screen and use chat summary (#633)
* chore: update rust crate
* refactor: move chat summary type to its own rust bridge file
* feat: add get chat summary to rust bridge
* refactor: add use chat summary hook
* feat: add util for shared logig on chat summary dispplay across screens
* refactor: remove chat list suscription from chat screen and replace use chat profile with chat summary
* refactor: use chat summary instead of chat profile in chat info screen
* refactor: use chat summary instead of chat profile in chat invite screen
* refactor: remove use chat profile hook
* Address blocked chat review feedback
* Preserve unread count for blocked chat updates
---------
Co-authored-by: Pepi <mariajosefinaalliende@gmail.com>
* feat: add feature flags provider for leave group
* feat: update leave group locales
* feat: add self remove to chat list chat summary
* feat: adjust use leave group hook to show it only when allowed
* chore: update podfile.lock
* feat: add UserBlockChanged to ChatListUpdateTrigger bridge
* feat: add block/unblock user bridge functions
* chore: regenerate flutter_rust_bridge bindings for mute_list API
* test: enforce exact order in userBlockChanged chat list assertions
* chore: bump whitenoise-rs rev and regenerate bridge bindings
* chore: format generated dart bridge files
* chore: rustfmt generated bridge file
* chore: rebase with master and regenerate bridge bindings
* fix: remove duplicate test function in chat_list
* 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>
* feat: expose mute/unmute chat through Flutter bridge
Bridge whitenoise-rs mute_chat, unmute_chat, and mute_forever_timestamp
to Dart via flutter_rust_bridge. Add muted_until to ChatSummary and
ChatMuteChanged trigger for real-time UI updates.
Also fixes pre-existing subscribe_to_group_messages API mismatch
(new limit parameter added upstream).
* test: cover chatMuteChanged trigger in use_chat_list
* make ccoderabbit happy
* feat: expose ChatMuteDuration enum through Flutter bridge
* chore: regenerate freezed code for ChatMuteDuration
* remove MUTE_FOREVER reference from doc comment
* feat: add archive translations
* feat: add archive rust bridge methods
* feat: extend use chat list hook to work with archived stream
* feat: add archive/unarchive actions to chat list tile menu
* feat: show archived chats view in chat list screen
* feat: add hook to archive/unarchive by receiving account and group id
* feat: add archive/unarchive option in chat info screens
* docs: udpate changelog
* test: improve coverage
Bumps whitenoise-rs to b5c9e8b and regenerates flutter_rust_bridge bindings.
- Add removed_at: Option<DateTime<Utc>> to ChatSummary so the Flutter
layer can tell when a group membership was revoked by an admin
- Add RemovedFromGroup variant to ChatListUpdateTrigger so real-time
removal events can be handled distinctly from archive/unarchive
- Regenerate frb_generated.rs, frb_generated.dart, and
api/chat_list.dart from the updated bridge definition
* chore: bump whitenoise-rs to 0.2.1 for 2026.3.5 release
* chore: sync widgetbook lockfile with app version
* fix: export iOS deployment target for Rust iOS build
* chore: align changelog release key with app version
* chore: drop build suffix from changelog release key
* fix: blurhash size in message bubble media
* fix: show sender data in chat invite screen bubbles
* feat: add retry method to message service
* refactor: make chat status names match rust
* fix: padding and status positioning in message bubbles and add retry on tap
* feat: retry sending messages from chat screen
* docs: update changelog
* chore: updgrade whitenoise-rs and mdk-core
* feat: wire delivery status from Rust bridge to Flutter UI
* chore: regenerate flutter_rust_bridge codegen
* Fix cargo fmt lint and handle messageRetried edge case
Fix import ordering in frb_generated.rs and line break in messages.rs
to pass cargo fmt check. Handle messageRetried when message ID is not
yet in the display list by appending it instead of silently ignoring.
* Run dart format on generated bridge files
* Update whitenoise-rs rev to aa56ba6 to fix mdk version conflict
* Add tests for deliveryStatusChanged and messageRetried handlers
* Add tests for DeliveryStatus mapping in ChatMessageBubble
* Sync with Rust retry redesign: add Retried status, remove messageRetried
Update whitenoise-rs rev to 74a3071 and re-run codegen to sync with
the retry-as-new-message design. DeliveryStatus now includes Retried,
UpdateTrigger no longer has MessageRetried.
- Update whitenoise-rs rev to 74a3071
- Add DeliveryStatus.retried variant and From impl in bridge
- Remove MessageRetried from UpdateTrigger enum and From impl
- Remove messageRetried handler from useChatMessages hook
- Add Retried case to DeliveryStatus mapping in ChatMessageBubble
- Remove messageRetried tests, add retried conversion test
* cargo fmt on generated code, add Retried delivery status test
* Run dart format on generated bridge files
The app wrapper's initialize_tracing() set a global tracing subscriber
before whitenoise-rs's init_tracing() (called inside initialize_whitenoise),
which then panicked via .init() -> .expect() because the global slot was
already taken. Remove the wrapper's subscriber setup entirely since
whitenoise-rs already handles file + stdout tracing with daily rotation
and OnceLock-based idempotency.
Closes#426