Fixes https://github.com/simplex-chat/simplex-chat/issues/5448
The original report documents four user-visible regressions under an RTL
locale (Arabic, Persian, Hebrew): chat bubble tails on the wrong side,
chat header call/menu buttons not mirrored, settings back arrow pointing
the wrong way, and the chat list profile avatar / signal icon laid out
in their LTR positions. This commit addresses all of them and a handful
of related directional-icon mirroring sites discovered during the audit.
- Chat bubble tail direction: chatItemShape now reads layoutDirection
from the GenericShape lambda and conditions the matrix mirror on
sent != isRtl, so sent-bubble tails point toward the user's profile
and received-bubble tails toward the contact's profile under both
LTR and RTL. The bubble-tail paddings in FramedItemView and ChatView
already use direction-aware start/end and now align with the
mirrored shape automatically.
- App-bar slot mirroring: CenteredRowLayout in FramedItemView switches
from place(...) to placeRelative(...) so the navigation icon and the
action buttons swap visual sides under RTL. Both the chat header
(call/menu buttons) and the chat list header (profile avatar, signal
icon) flow through this layout, so one fix covers both.
- Asymmetric directional drawables: add Modifier.mirrorIfRtl()
(Modifier.scale(-1f, 1f) when LocalLayoutDirection.current is Rtl)
and apply it to the back arrow in NavigationButtonBack, every variant
of the SubscriptionStatusIcon waves, the WhatsNewView pagination
arrows, the back arrow and submenu chevron in CommandsMenuView, the
back arrow in OnboardingCards and ImageFullScreenView.desktop, the
share-profile chevron in NewChatView, and the sent-via-proxy arrow
in CIMetaView and ChatItemInfoView.
DropdownMenu offsets in ChatView (DpOffset(-width, ...)) are left
unchanged: DropdownMenuPositionProvider already negates the content
offset under RTL, so menus anchor and open correctly once
CenteredRowLayout is fixed.
* plans: 20260207-support-bot.md
* Update 20260207-support-bot.md
* plans: 20260207-support-bot-implementation.md
* plans: Update 20260207-support-bot-implementation.md
* Relocate plans
* apps: support bot code & tests
* apps: support bot relocate
* support-bot: Fix basic functionality
* apps: support-bot /add command & fixes
* apps: simplex-support-bot: Change Grok logo
* Further usability improvements
* simplex-support-bot: Update support plan to reflect current flow
* simplex-support-bot: update product design plan
* support-bot: update plan
* support-bot: review and refine product spec
* support-bot: update product spec — complete state, /join team-only, card debouncing
- Group preferences applied once at creation, not on every startup
- /join restricted to team group only
- Team/Grok reply or reaction auto-completes conversation (✅)
- Customer message reverts to incomplete
- Card updates debounced globally with 15-minute batch flush
* support-bot: update implementation plan
* support-bot: implement stateless bot with cards, Grok, team flow, hardening
Complete rewrite of the support bot to stateless architecture:
- State derived from group composition + chat history (survives restarts)
- Card dashboard in team group with live status, preview, /join commands
- Two-profile architecture (main + Grok) with profileMutex serialization
- Grok join race condition fix via bufferedGrokInvitations
- Card preview: newest-first truncation, newline sanitization, sender prefixes
- Best-effort startup (invite link, group profile update)
- Team group preferences: directMessages, fullDelete, commands
- 122 tests across 27 suites
* support-bot: use apiCreateMemberContact and apiSendMemberContactInvitation instead of raw commands
Replace sendChatCmd("/_create member contact ...") and sendChatCmd("/_invite member contact ...")
with the typed API methods added in simplex-chat-nodejs. Update plans and build script accordingly.
* plans: 20260207-support-bot.md
* Update 20260207-support-bot.md
* plans: 20260207-support-bot-implementation.md
* plans: Update 20260207-support-bot-implementation.md
* Relocate plans
* apps: support bot code & tests
* apps: support bot relocate
* support-bot: Fix basic functionality
* apps: support-bot /add command & fixes
* apps: simplex-support-bot: Change Grok logo
* Further usability improvements
* simplex-support-bot: Update support plan to reflect current flow
* simplex-support-bot: update product design plan
* support-bot: update plan
* support-bot: review and refine product spec
* support-bot: update product spec — complete state, /join team-only, card debouncing
- Group preferences applied once at creation, not on every startup
- /join restricted to team group only
- Team/Grok reply or reaction auto-completes conversation (✅)
- Customer message reverts to incomplete
- Card updates debounced globally with 15-minute batch flush
* support-bot: update implementation plan
* support-bot: implement stateless bot with cards, Grok, team flow, hardening
Complete rewrite of the support bot to stateless architecture:
- State derived from group composition + chat history (survives restarts)
- Card dashboard in team group with live status, preview, /join commands
- Two-profile architecture (main + Grok) with profileMutex serialization
- Grok join race condition fix via bufferedGrokInvitations
- Card preview: newest-first truncation, newline sanitization, sender prefixes
- Best-effort startup (invite link, group profile update)
- Team group preferences: directMessages, fullDelete, commands
- 122 tests across 27 suites
* support-bot: use apiCreateMemberContact and apiSendMemberContactInvitation instead of raw commands
Replace sendChatCmd("/_create member contact ...") and sendChatCmd("/_invite member contact ...")
with the typed API methods added in simplex-chat-nodejs. Update plans and build script accordingly.
* support-bot: more improvemets
* support-bot: add tests for Grok batch dedup and initial response gating
7 new tests covering the duplicate Grok reply fix:
- batch dedup: only last customer message per group triggers API call
- batch dedup: multi-group batches handled independently
- batch dedup: non-customer messages filtered from batch
- initial response gating: per-message responses suppressed during activateGrok
- gating clears: per-message responses resume after activation completes
Update implementation plan test catalog (122 → 129 tests).
* support-bot: load context from context file
* Rename Grok AI -> Grok
* Remove unused strings.ts
* support-bot: change messages
* cardFlushMinutes 15 -> cardFlushSeconds 300
* support-bot: /team message when grok present
* support-bot: correct messages
* support-bot: update plans to reflect latest changes
* Update plan for state derivation
* support-bot: Update state machine plans
* support-bot: implement customData state
* Fix Grok revertStateOnFail race condition
* support-bot: plans adversarial review
* support-bot: /join ID part of card in plan
* support-bot: implement /join ID inside card
* support-bot: plans use params instead of regex in /join
* support-bot: Implement adversarial review changes
* support-bot: no re-invite if already invited
* support-bot: /team should give owner to invited member
* Don't change username for existing database
* support-bot: update bot commands before sending commands
* support-bot: adversarial review fixes
* support-bot: implement postgresql (#6876)
* support-bot: sqlite/postgres backend via typed DbConfig and parseArgs flags
* support-bot: add README with setup and flags reference
* support-bot: use published simplex-chat, drop build.sh/start.sh
* support-bot: switch CLI to commander, add --help
* support-bot: update README
---------
Co-authored-by: shum <github.shum@liber.li>
Co-authored-by: sh <37271604+shumvgolove@users.noreply.github.com>
* core: test support chats in channels, CLI defaults to sending as member in support chat
* ui: enable support chats in channels
* use correct scope when sending from UI
* more readable
* remove test output
* show member support chat in channels
* preference for support chats
* ios: types for support preference
* mp: support preference types
* show support preference in UI
* fix ios
* make support preference optional in JSON parser
* update string
* change strings, pass parameters to prefs
* refactor kotlin
* take support preference into account
* refactor core
* do not show broadcast placeholder in support scope
* move role check, add pref check on update
* support preference test (failing)
* fix version
* fix tests
* warning alert when enabling chats with admins
* revert on dismiss
* update text and icons
* query plans
---------
Co-authored-by: Evgeny @ SimpleX Chat <259188159+evgeny-simplex@users.noreply.github.com>
* core, ui: item about no e2ee in public channels
* fix, refactor
* all tests
* update bot api types
---------
Co-authored-by: Evgeny @ SimpleX Chat <259188159+evgeny-simplex@users.noreply.github.com>
* directory: support public channels and relay-based groups (plan)
* types
* amend types
* directory types, resolve known link
* implementation, test fails
* fix test
* fix test
* more test
* minimal test
* more test
* debug test
* clean up
* remove debug logs
* refactor
* use group/channel terms correctly
* remove unsupported commands
* manage profile update
* owner left the channel
* more tests, correct response to sent link
* re-registration
* /help and /link commands
* correct listing for channels
* fix test
* fix bot api
* refactor
* do not include link data in GLPKnown
* refactor
* diff
* undo refactor
* simplify
* remove harness test
* remove flip
* add v6.5 app requirement for channels
* add website support
* update bot api types
* correct member count, fix test
* members -> subscribers
* add link to channel description
* fix css
* move version note
---------
Co-authored-by: Evgeny @ SimpleX Chat <259188159+evgeny-simplex@users.noreply.github.com>
VideoPlayer's mediaPlayerReady listener called mediaPlayer.audio().setVolume(100)
on every freshly created VLC player. On Windows, VLCJ routes setVolume through
WASAPI's ISimpleAudioVolume, which is the per-app entry in the Windows Volume
Mixer — so every video playback snapped SimpleX Chat's mixer volume back to 100%,
overriding the user's own setting.
The call was also redundant: VLCJ's default volume for a new MediaPlayer is
already 100, and the only path that previously used setVolume (enableSound) has
been disabled since VLCJ issue #985 ("Impossible to change volume for only one
player. It changes for every player.").
Dropping the setVolume(100) line fixes the Windows regression without changing
playback loudness on any platform. AudioPlayer / SoundPlayer / CallSoundsPlayer
use a singleton VLC player and never called setVolume, so voice messages and
ringtones are unaffected.
Co-authored-by: Evgeny Poberezkin <evgeny@poberezkin.com>
* desktop: fix sending files with + in file name
Use RFC 3986 URI encoding (File.toURI()) instead of application/x-www-form-urlencoded
(URLEncoder/URLDecoder) for file path URIs. URLDecoder treated literal + as space,
corrupting filenames containing + on desktop.
* less breaking approach
* ios: sharing channel links/cards
* update nix shas
* improve
* fix preview
* change condition
* move button for owner
* refactor
* refactor 2
* fix sheets
* MsgChatLink JSON encoding
* correct default icon when editing group profile
* drop link from card
* card layout
* strip link from text
* remove file ref
* share via chat when created
* rename file, do not show text when there is no text
* better card layout
* padding, info string
* add log
* padding
* text layout
* warning emoji if signature verification failed
* chat link preview in chat list
* description
* alert information
* tappable preview
* better
* conditional border color
* sending and forwarding views
* small link icons for forwarding
* strip link in one place
* forwarded context
* quote view for chat links
* reduce diff, remove unnecessary changes
* simplify
* trim description
* diff
---------
Co-authored-by: Evgeny @ SimpleX Chat <259188159+evgeny-simplex@users.noreply.github.com>