The count is seeded by getUsersInfo, which counts RcvNew items where ntfsEnabled
holds - every item for an unmuted chat, only mentions for a mentions-only one,
none for a muted one. The deltas that maintain it afterwards did not follow that
rule for the active profile: addChatItem incremented for every item regardless
of the chat's notification setting; on Android and desktop the mark-read helpers
subtracted the full unread count, while on iOS Mark read and Clear followed the
mentions-only setting but subtracted the full count for muted chats, and
per-item reads forwarded the raw delta; removeChat left a deleted chat's unread
behind; and changing the setting moved a chat between rules without moving the
count.
Chat.userUnreadCount names what a chat contributes, and it is not a new rule:
totalUnreadCountForAllUsers already computed exactly this inline for the app
badge, and now calls it. The sites that change a chat's stats, its settings or
its presence report the contribution before and after, and the count moves by
the difference - apart from the exceptions noted at the end.
For that to hold the stats it reads have to be maintained, so on Android and
desktop decreaseCounterInPrimaryContext now decrements unreadMentions alongside
unreadCount when the item was a mention. Without it a mentions-only chat's
contribution never moved on any of that function's three paths - a deleted item,
a moderated member item, or an item going from New to Read. iOS already passed
the mention delta on its deletion paths.
This is visible beyond the profile picker, which badges only other profiles: the
desktop tray dot sums the count across profiles including the active one, and on
iOS these same deltas drive the app icon badge. So on iOS, muting a chat with
unread now drops the badge by its contribution, deleting a chat drops it, and a
message in a muted chat no longer raises it - each of which now agrees with
totalUnreadCountForAllUsers, which the badge is also set from.
addChat is deliberately not the mirror of removeChat: adding a chat means it is
being loaded into view, and its items were already counted by the seed, so
counting them again on ChatItemsLoader's addChat would double them. The one
place that removes and re-adds a chat while keeping its items - deleting a
contact in "keep conversation" mode on iOS - now carries its stats across and
restores the contribution explicitly, since the core keeps both the contact row
and its items there and the seed still counts them.
Wherever the chat list is re-read wholesale the counts are re-read with it: both
resume paths, and setting a chat item TTL, which deletes the active profile's
items without per-item events and so leaves its count stale. They are assigned
before the chats, which matters on iOS because updateChats recomputes the app
badge from users there. Reading users is best effort on both
platforms - losing them must not cost us the chats already fetched.
This does not make the count exact. getUsersInfo has no group_scope_tag filter
where the query behind chatStats.unreadCount does, so the seed counts
support-scope items that no client-side rule can, and the count steps up by the
outstanding support unread on each reseed. replaceChat also installs a whole
chatStats without moving the count: on Android and desktop from a snapshot taken
before the API call, in ChatListNavLinkView's markChatRead and markChatUnread
and ChatView's markUnreadChatAsRead, and on iOS from the server in the
receivedContactRequest handler in SimpleXAPI. Settings changes that arrive in
events through updateChatInfo do not move it either.
* android: add google and foss build flavors
* android: get the Google Play account country in the google flavor
* android, desktop: update whats new
* temp: comment out wefunder link
The desktop app polled full clipboard contents every second on the AWT
event thread to update ChatModel.clipboardHasText. On X11, each read
blocks up to sun.awt.datatransfer.timeout (10s) when the selection owner
does not respond (e.g. after KeePassXC's clipboard auto-clear), making
every click/scroll wait ~9s. clipboardHasText has had no readers since
its only consumer was removed in #4398, so the whole mechanism (desktop
poll, Android clip listener, onResume refresh, expect/actual, state
field) is deleted. See plans/2026-07-11-fix-desktop-clipboard-freeze.md.
* android, desktop: core API event timeout setting
* chat_recv_msg_wait with STM timeout
* Revert "chat_recv_msg_wait with STM timeout"
This reverts commit fdfa2964c5.
* do not use permanent wake lock
* wakelock option, get wakelock on network information change
* remove option
* core: pass event and response error without dedicated constructor
* ios: WIP
* android, desktop: update UI for new API
* ios: fix parser
* fix showing invalid chats
* fix mobile api tests
* ios: split ChatResponse to 3 enums, decode API results on the same thread
* tweak types
* remove throws
* rename
* core, ui: optionally use short links (#5799)
* core: optionally use short links
* update test
* update simplexmq, short group links
* fix query
* fix parser for _connect
* ios: use short links
* shorten links to remove fingerprint and onion hosts from known servers
* fix parser
* tests
* nix
* update query plans
* update simplexmq, simplex: schema for short links
* simplexmq
* update ios
* fix short links in ios
* android: use short links
* fix short group links, test short link connection plans
* core: fix connection plan to recognize own short links
* update simplexmq
* space
* all tests
* relative symlinks in simplexmq to fix windows build
* core: improve connection plan for short links (#5825)
* core: improve connection plan for short links
* improve connection plans
* update UI
* update simplexmq
* ios: add preset server domains to entitlements, add short link paths to .well-known/apple-app-site-association
* update simplexmq
* fix group short link in iOS, fix simplex:/ scheme saved to database or used for connection plans
* update simplexmq
* ios: delay opening URI from outside until the app is started
* update simplexmq
* android, desktop: landscape calls on Android and better local camera ratio management
The main thing is that now when exiting from CallActivity while in call
audio devices are not reset to default. It allows to have landscape mode
enabled
* styles
* fix changing calls
* android: show info for Xiaomi users about autostart restrictions
* text and placement
* update strings
---------
Co-authored-by: Evgeny Poberezkin <evgeny@poberezkin.com>
* multiplatform: insets
* more features and better performance
* calls and removed unused code
* changes
* removed logs
* status and nav bar colors
* chatList and newChatSheet search fields
* overhaul
* search fields, devtools, chatlist, newchatsheet, onehand on desktop, scrollbars
* android, desktop: update to Compose 1.7.0
- support image drag-and-drop from other applications right to a chat
(with and without transparent pixels - will be png or jpg)
* stable
* workaround
* changes
* ideal adapting height layout
* dropdownmenu, userpicker, onehandui, call layout, columns
* rename bars properties and strings
* faster update and better layout
* gallery in landscape with cutout
* better cutout
* 1% step on slider
* app bar moves to bottom in one hand ui
* default alpha
* changes
* userpicker colors
* changes
* blur
* fix wrong drawing area in chatview
* fix
* fixed differently
* changes
* changes
* android fix
* Revert "android fix"
This reverts commit 7d417afd9b.
* changes
* changes
* blur
* swap
* no logs
* fix build
* old Android support
* fix position of menu
* disable blur on Android 12
* call button padding
* useless code
* fix padding in group info view
* rename
* rename
* newline
* one more fix
* changes
---------
Co-authored-by: Evgeny Poberezkin <evgeny@poberezkin.com>
* android: re-apply custom language when webview appears
There is a bug on Android related to including WebView. App language
changes to system language regardless of what was set before in
context's configuration. Re-set needed to be done twice: after creating
of WebView and after removing it from a view
* add link to bug
---------
Co-authored-by: Evgeny <evgeny@poberezkin.com>
* android, desktop: calls switching from audio to video and back
* refactor
* working all 4 streams with mute handling differently
* changes
* changes
* wrong file
* changes
* padding
* android camera service type
* icons, sizes, clickable
* refactor
* Revert "android camera service type"
This reverts commit 9878ff38e9.
* late init camera permissions
* enabling camera sooner than call establishes (not fully done)
* changes
* alpha
* fixes for Safari
* enhancements
* fix Safari sound
* padding between buttons on desktop
* android default values for padding
* changes
* calls without encryption are supported and flipping camera on some devices works
* unused param
* logs
* background color
* play local video in Safari
* no line height
* removed one listener from per frame processing
* enhancements
---------
Co-authored-by: Evgeny Poberezkin <evgeny@poberezkin.com>
* user picker as modal
* android dirty layout
* color mode switcher
* close picker on desktop opening modals
* cleanup
* remote hosts working
* icon buttons
* profile picker modal for external shares
* remove stroke
* color changes
* add unread badge to users row
* chat database settings section
* safe remove of you settings section
* picker should now open for single user
* remove create profile from settings
* paddings
* handle big names
* fonts and align
* simple animations and shadow
* address messaging
* active is grey
* padding
* hide non active devices from pills
* picker positioning
* pills order
* change view all profiles icon
* bigger space between profiles
* hosts ordering and fixes
* device pill in app bar
* simplex address -> public
* better switch of opacity bg
* create public address
* font match
* add icon for dark mode
* padding
* profile name as header
* h2 is too big
* icon colors
* icons
* settings as modal
* center settings
* fix use from desktop
* remove logs
* bar colors
* remove drawer unused code
* animate shading
* fade in fade out
* add system mode toast
* shading colors
* stop pushing shade up
* same button as ios for opening all profiles
* simplify nav bar color set
* broken transition change
* color mix
* gradient and horizontal scroll
* separate title
* align avatars to top
* picker should always remain open
* use chevron icon to see all profiles
* improvements on status and nav color set
* best case bars switching working
* change bar and shading on theme change
* remove unused var
* reset navbar colors on navigate
* updated icon color
* protect android calls
* desktop menu matching size of right side modals
* remove shading from desktop
* close user picker on settings click in desktop
* bigger profile image smaller gap to name
* fix spacer for row scroll on android
* smaller profile name
* remove unused code
* small refactor
* unused
* move desktop/mobile connection
* close drawer on swipe down 30%
* progress dump on new android design
* paddings in scroller
* gradient
* android paddings
* split inactive user picker between platforms
* move your chat profiles inside android specific
* always show your chat profiles in desktop
* fix profile creation in desktop
* remove unused var
* update android space between badges
* initial desktop design
* center android icons with avatar
* centered avatars
* unread badge
* extra space in the end of user list for android
* aligned paddings on desktop
* desktop paddings
* paddings
* remove you
* unread badge same style as chatlist
* use bedtime moon for dark mode
* chevron same size as sun/moon
* chevron and gradient
* paddings
* split android and desktop scaffold for picker
* move bars logic to android
* remove android check
* more android checks
* initial version of swipable modal
* muted as grey
* unused
* close drawer on 3/4
* better close control
* make all animations match
* move shadow with offset
* always close pciker on selection
* animated float doing nothing
* sync animation
* animation using single float
* fixed warnings
* better state update
* fix scrim color
* better handling of picker closure on desktop
* landscape mode
* intentation
* rename UserPickerScaffold
* hide shadow when picker not open
* reset inactive user scroll position on pick
* unused class
* left panel after new menu can be without padding
* small changes
* make ActiveProfilePicker reusable to reduce code duplication
* make picker scrollable
* refactor
* refactor and fix instant reload of profiles
* refactor
* icon sizes
* returned back ability to scroll to the picker on Android
* setting system theme on desktop's right click
* box
* refactor
* picker pill
* fix desktop shadow
* small change
* hiding keyboard when opening picker
* state specifying
---------
Co-authored-by: Evgeny Poberezkin <evgeny@poberezkin.com>
Co-authored-by: Avently <7953703+avently@users.noreply.github.com>