Commit Graph
6404 Commits
Author SHA1 Message Date
Narasimha-sc eab9e36300 desktop: fix profile image lost when creating the first chat profile
createProfileInNoProfileSetup passed the image positionally as Profile's 4th
argument, which is description, not image - so the chosen avatar was stored as
the profile description and no picture was set.

Both are String?, so it type-checked silently. The sibling createProfileInProfiles
avoids this by passing image by name.

Only reachable on desktop with no local chat profile: the user picker then offers
"Create chat profile" (desktopNoUserNoRemote), which opens the profile form with
its avatar picker, and localUserCreated is false so submission takes this branch.
Onboarding is unaffected - both first-profile screens take a name only, with no
avatar picker, and call createProfileOnboarding instead.

Unrelated to the rest of this branch - safe to drop or move to its own PR.
2026-08-03 16:12:10 +00:00
Narasimha-sc 49344c32fb android, desktop: offer creating a profile for a one-time invitation link
Adds "Add profile" to the profile picker reached from "Share profile" on a
one-time link, so a link can be handed out under a new identity without setting
one up in settings first. Reuses the existing users_add string.

Extracts the existing selection handler into selectProfile so the new profile
takes exactly the same path as picking an existing one - the connection change
and the switch cannot drift apart.

The row sits outside the active-profile branch: inside it, it would disappear
whenever the active profile is filtered out by the search text. It is only
offered when there is a connection to move, so it does not appear in the share
list, where a new profile would have nothing to share into.
2026-08-03 16:12:10 +00:00
Narasimha-sc c270a1531d android, desktop: extract profile selection from the picker row handler
ActiveProfilePicker performed the whole profile change - connection reassignment,
switch, alerts, close - inside the row's onSelected lambda, where nothing else can
reach it.

Lift it to selectProfile(user), called by the row. Pure move: the body is unchanged
apart from indentation, so picking a profile behaves exactly as before. It gives the
next commit a way to take the same path for a newly created profile rather than
duplicating it.
2026-08-03 16:12:10 +00:00
Narasimha-sc b0b852a10f android, desktop: offer creating a profile when accepting an invitation
Opening someone's link prepares a chat and shows the profile picker above the
compose box. It listed existing profiles and Incognito, so connecting as
someone new meant leaving the invitation, creating a profile in settings, and
coming back to the link.

Adds "Add profile" to that picker, reusing the existing users_add string. The
profile is created without becoming active, so the profile that owns the
prepared chat stays active for the reassignment, which then switches once -
rather than switching away and back.

The row is emitted last, so with the reversed layout it renders at the top of
the expanded list with the current selection nearest the compose box.

After switching, the chat is reopened explicitly: keepingChatId only preserves
its place in the reloaded list, so without that the switch lands on the chat
list of the new profile rather than the invitation it was chosen for. This
applies to picking an existing profile too.

The form is only dismissed once creation succeeds, so a rejected duplicate name
does not discard what was typed. A dismissal guard keeps a back-tap during
creation from switching the profile anyway, and the created profile is put into
the picker list immediately so it stays visible if the reassignment fails.

If the core activated the profile despite keepActiveUser - an older remote host
ignoring the field - the reassignment would fail, so that case resyncs to what
the host actually did instead.

Updates the onboarding flow doc, which names the arguments of the command that
gains the field.
2026-08-03 13:12:00 +00:00
Narasimha-sc 4375a839f6 core: test creating a user without making it active
Two tests, both driving /_create user with JSON - the path the apps actually
use, which no test covered before:

- keepActiveUser creates the profile while leaving the active user alone, and
  the prepared contact can then be reassigned to it and connected.
- omitting keepActiveUser still parses and still activates. This is a
  regression guard: iOS does not send the field, so if the record ever stopped
  accepting its absence, profile creation there would break silently.
2026-08-03 07:59:49 +00:00
Narasimha-sc bc1e8b6de7 core: allow creating a user without making it active
Adds keepActiveUser to NewUser. When set, the new user is created but the
current active user is preserved.

This is needed to create a profile for an invitation: the prepared chat is
resolved under the active user by APIChangePreparedContactUser, so the profile
that owns the invitation has to stay active until the chat has been moved to
the new one. Creating and activating in one step makes that reassignment
impossible without switching back and forth.

BoolDef gives the field omittedField = False, so clients that do not send it -
iOS, the CLI, and any older caller - keep the current behaviour of activating
the new user.

keepActiveUser is ignored when there is no active user to keep, which would
otherwise leave the app with none at all.

Note the response is still CRActiveUser: it carries the created user, which is
not the active one on this path. Documented at the field.

Regenerates the API docs and the generated TypeScript and Python client types,
which are checked by the Bot API docs tests.

The generator emits BoolDef fields as required in the client types, so the two
hand-maintained clients that build a NewUser literal - simplex-chat-python and
simplex-chat-nodejs - stop type-checking until the field is added there too. No
test covers those; a4e3a1ea1 did the same when clientService was added.
2026-08-03 07:59:49 +00:00
Narasimha-sc c38c87e26a android, desktop: don't switch profile when prepared chat reassignment fails
changeActiveUser_ was called outside the guards that check whether
apiChangePreparedContactUser / apiChangePreparedGroupUser actually succeeded.
When the reassignment failed the app still switched to the other profile,
leaving the invitation behind in the original one - and keepingChatId then held
a chat belonging to a different user.

Reachable today: open a link, expand the profile picker, and have the connection
start in the window before tapping. profileChangeProhibited flips to true, the
API returns null, and the switch happened anyway.

The sibling picker in NewChatView already guards this correctly. iOS is
unaffected: there apiChangePreparedContactUser throws, so a failure skips the
switch by control flow.
2026-08-03 07:59:49 +00:00
Narasimha-sc 7c6f046b58 android, desktop: parameterise create-profile form's submit action
CreateProfile hardcoded what happens after submission, choosing between
createProfileInProfiles and createProfileInNoProfileSetup inside the button
handler. That conditional is a hidden premise: two call sites invoke the
composable and neither can see from the call that submission behaves
differently for them.

Lift the choice to the callers. The callback passes raw fields rather than a
Profile because the two paths do not build the same one - the no-profile-setup
path drops shortDescr and passes a null remote host id - so a Profile-shaped
callback would silently change its behaviour.

The chatModel parameter was redundant besides: UserPicker passed the
platform-level chatModel global, which the parameter merely shadowed.

No behaviour change - the conditional moves verbatim into createProfileFromForm,
which both call sites invoke, rather than being copied into each.
2026-08-03 07:59:49 +00:00
EvgenyandGitHub 34b74d1c49 directory: remove support for directory log file (#7331)
* directory: remove support for directory log file

* remove unused exports
2026-08-02 16:01:22 +01:00
EvgenyandGitHub 31faceef73 docs: add bot library APIs (#7334) 2026-08-02 14:12:57 +01:00
Evgeny Poberezkin cbae9c5e87 core: 7.1.0.0 (simplexmq 7.1.0.0) 2026-08-01 13:13:40 +01:00
EvgenyGitHubEvgeny @ SimpleX Chat <259188159+evgeny-simplex@users.noreply.github.com>Evgeny @ SimpleX Chat <259188159+evgeny-simplex@users.noreply.github.com>Evgeny @ SimpleX Chat <259188159+evgeny-simplex@users.noreply.github.com>
e1a349b90f core: support contact addresses with DR keys, service requests (#7310)
* core: use double ratchet keys in contact address (#7278)

* core: use double ratchet keys in contact address

* use PQ from the first message

* query plans

* update simplexmq

* api to rotate keys, option to show full links in CLI

* shorter description

* ui: add error parameters

* disable DR in addresses

* core: parameter for create address command to configure ratchet keys

* add pqRatchet param to address-related commands

* query plan

* fix parser

* fix kotlin

---------

Co-authored-by: Evgeny @ SimpleX Chat <259188159+evgeny-simplex@users.noreply.github.com>

* core: contact request rejection and service requests (#7292)

* update simplexmq

* implement service requests and rejections

* tests

* migration

* fix migration

* add api event and response

* bot api, postgres migration

* nix shas

* bot types, rename property

* update bot type

* sign service requests

* update bots api

* query plan

* update plan

* update simplexmq

* fix test, update bot api

* fix bot api

* resolve name for service request

* refactor

---------

Co-authored-by: Evgeny @ SimpleX Chat <259188159+evgeny-simplex@users.noreply.github.com>

* update simplexmq

* update simplexmq

* test delays

---------

Co-authored-by: Evgeny @ SimpleX Chat <259188159+evgeny-simplex@users.noreply.github.com>
2026-08-01 12:51:03 +01:00
EvgenyGitHubEvgeny @ SimpleX Chat <259188159+evgeny-simplex@users.noreply.github.com>
61012d208e core, ui: extend profile peer type (#7277)
* core, ui: extend profile peer type

* remove comments

Co-authored-by: Evgeny <evgeny@poberezkin.com>

---------

Co-authored-by: Evgeny @ SimpleX Chat <259188159+evgeny-simplex@users.noreply.github.com>
2026-07-31 23:53:12 +01:00
EvgenyGitHubEvgeny @ SimpleX Chat <259188159+evgeny-simplex@users.noreply.github.com>
f1418f9e55 core: drop support of chat versions older than 08/2024 (#7319)
* core: drop support of chat versions older than 08/2024

* fix encoding tests

* skip failing tests

* rename

* fix

* query plans

* remove unused legacy code

* remove more unused

* remove unused

* remove unused names

---------

Co-authored-by: Evgeny @ SimpleX Chat <259188159+evgeny-simplex@users.noreply.github.com>
2026-07-29 19:06:20 +01:00
EvgenyGitHubEvgeny @ SimpleX Chat <259188159+evgeny-simplex@users.noreply.github.com>
64bf358040 core: fix version update on binary chunks (#7320)
* core: fix version update on binary chunks

* pass chat event

* pass encoding

* revert

---------

Co-authored-by: Evgeny @ SimpleX Chat <259188159+evgeny-simplex@users.noreply.github.com>
2026-07-28 17:51:01 +01:00
Evgeny Poberezkin 8dc387cb56 Merge branch 'stable' 2026-07-28 16:58:15 +01:00
SimpleX ChatandEvgeny Poberezkin e11128ce5b 7.0: android 366, desktop 155, ios 345 v7.0.0 2026-07-28 16:41:46 +01:00
Narasimha-scandGitHub bd298a1d4a ios, android, desktop: fix draft in support chat appearing in group chat (#7309)
Group chat and its support chats have the same chat id, so a draft saved
in "chat with admins" was restored in the group chat and shown as its draft
in the chat list. Include chat scope in the draft chat id.

Also save the draft when support chat is closed without changing chat id -
in that case KeyChangeEffect that saves drafts doesn't run.
2026-07-28 13:55:49 +01:00
spaced4ndyandGitHub 7c931d08ea ui: show "connect to name" button starting with 5 characters; ios: show button in New chat view search (#7318)
* ui: show "connect to name" button starting with 5 characters

* show button in new chat view search
2026-07-28 12:03:42 +01:00
shGitHubmlanpEvgeny PoberezkinHosted Weblate user 54392No nameEvgeny @ SimpleX Chat <259188159+evgeny-simplex@users.noreply.github.com>Narasimha-sc
a58cd51c49 ui: translations (#7317)
* Translated using Weblate (German)

Currently translated at 100.0% (2899 of 2899 strings)

Translation: SimpleX Chat/SimpleX Chat Android
Translate-URL: https://hosted.weblate.org/projects/simplex-chat/android/de/

* Translated using Weblate (Russian)

Currently translated at 97.5% (2829 of 2899 strings)

Translation: SimpleX Chat/SimpleX Chat Android
Translate-URL: https://hosted.weblate.org/projects/simplex-chat/android/ru/

* Translated using Weblate (Chinese (Simplified Han script))

Currently translated at 99.9% (2898 of 2899 strings)

Translation: SimpleX Chat/SimpleX Chat Android
Translate-URL: https://hosted.weblate.org/projects/simplex-chat/android/zh_Hans/

* Translated using Weblate (Spanish)

Currently translated at 100.0% (2899 of 2899 strings)

Translation: SimpleX Chat/SimpleX Chat Android
Translate-URL: https://hosted.weblate.org/projects/simplex-chat/android/es/

* Translated using Weblate (Spanish)

Currently translated at 100.0% (2497 of 2497 strings)

Translation: SimpleX Chat/SimpleX Chat iOS
Translate-URL: https://hosted.weblate.org/projects/simplex-chat/ios/es/

* ru translations

* Translated using Weblate (German)

Currently translated at 100.0% (2899 of 2899 strings)

Translation: SimpleX Chat/SimpleX Chat Android
Translate-URL: https://hosted.weblate.org/projects/simplex-chat/android/de/

* Translated using Weblate (Russian)

Currently translated at 97.5% (2829 of 2899 strings)

Translation: SimpleX Chat/SimpleX Chat Android
Translate-URL: https://hosted.weblate.org/projects/simplex-chat/android/ru/

* Translated using Weblate (Chinese (Simplified Han script))

Currently translated at 99.9% (2898 of 2899 strings)

Translation: SimpleX Chat/SimpleX Chat Android
Translate-URL: https://hosted.weblate.org/projects/simplex-chat/android/zh_Hans/

* Translated using Weblate (Spanish)

Currently translated at 100.0% (2899 of 2899 strings)

Translation: SimpleX Chat/SimpleX Chat Android
Translate-URL: https://hosted.weblate.org/projects/simplex-chat/android/es/

* Translated using Weblate (Spanish)

Currently translated at 100.0% (2497 of 2497 strings)

Translation: SimpleX Chat/SimpleX Chat iOS
Translate-URL: https://hosted.weblate.org/projects/simplex-chat/ios/es/

* process translations

* ui: fix translation errors in es, ru, de, it, hu

Review of the translations in this PR against the English originals.
Values only - no keys added, removed or renamed.

Spanish:
- "The sender deleted the connection request." said "El servidor..."
  (the server), attributing the deletion to a server rather than the
  sender. Restored "El remitente".
- "Require/Do not require signing messages." were rendered as statements
  ("Se requieren mensajes firmados."), making the toggle options read
  identically to the separate status strings "Message signing is
  (not) required.". Restored the imperative.
- "...compare (or scan) the code on your devices." said "en tu
  dispositivo" (singular); the code has to be compared on both.
- "How to register a test name" was pluralised to "nombres en pruebas".

Russian:
- "Помошь и поддержка" -> "Помощь и поддержка" (spelling).
- "File servers" was the calque "Файл серверы" -> "Серверы файлов",
  matching the iOS translation of the same string.
- "Если Вы выберите" -> "выберете" (imperative used for future).
- "Create web preview." said "Создать веб страницу." (web page, also
  missing the hyphen) -> "Создать веб-предпросмотр.".
- webpage_info dropped "to show your channel preview to visitors before
  they subscribe"; webpage_url_footer said "страницы канала" instead of
  the preview. Both restored from the iOS wording.
- "Enter description (optional)" lost "(optional)"; "Error adding
  relays" was truncated to "Ошибка добавления".
- "Add contributors." used "авторов"; the member role is "соавтор".
- "удален(а)" -> "удалён", "подтвержденный" -> "подтверждённый".

German, Italian, Hungarian:
- The source strings "Names for your channel or business." and
  "SimpleX names (BETA)" were renamed to "Public names..." and
  "SimpleX public names (BETA)", but the old values were carried over,
  so "public" was missing. Android German and Chinese had already been
  updated in this PR; this brings iOS German, and both platforms for
  Italian and Hungarian, in line.
- iOS German "How to register a test name" still read "Einen Test-Namen
  registrieren", while Android German was updated in this PR.

---------

Co-authored-by: mlanp <github@lang.xyz>
Co-authored-by: Evgeny Poberezkin <e.poberezkin@me.com>
Co-authored-by: Hosted Weblate user 54392 <hamburger2048@users.noreply.hosted.weblate.org>
Co-authored-by: No name <usir.alerts@onionmail.org>
Co-authored-by: Evgeny @ SimpleX Chat <259188159+evgeny-simplex@users.noreply.github.com>
Co-authored-by: Narasimha-sc <166327228+Narasimha-sc@users.noreply.github.com>
2026-07-28 11:26:04 +01:00
Narasimha-scandGitHub 02178fb611 android, desktop: fix accepting contact request from notification for non-active profile (#7316)
* android, desktop: switch to the request's profile when accepting contact request from notification

* plans: justify accepting contact request from notification fix
2026-07-27 20:25:56 +01:00
spaced4ndyandGitHub b414d7579a ios: fix connection dialogue not shown if app is opened via link before onboarding (#7301)
* ios: fix connection dialogue not shown if app is opened via link before onboarding

* wip

* debug

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* comment
2026-07-27 18:00:32 +01:00
spaced4ndyandGitHub 6152f2a7ee ios: fix chat not opening when contact connects via 1-time link (#7315) 2026-07-27 15:04:45 +00:00
spaced4ndyandGitHub 45ee868e0b android, desktop: fix reply header not filling message width for emoji (#7314) 2026-07-27 14:47:05 +00:00
Narasimha-scandGitHub 1108e87ee2 desktop: fix forwarding moving message draft to another chat (#7307)
* desktop: fix forwarding moving message draft to another chat

The same ComposeView is reused when switching chats, so the `chat`
captured by the desktop-only `onDispose` is the chat that was open when
the view was first composed, not the one the message is forwarded from.
The draft was saved under that stale chat id, and when it happened to be
the chat forwarded to, sending the forward restored the draft there.

* plan: justify desktop forward/draft fix and cross-platform findings
2026-07-25 18:23:04 +01:00
Evgeny Poberezkin 4b97110fd9 7.0.0-beta.6: android 365, desktop 154 v7.0.0-beta.6 2026-07-25 18:16:23 +01:00
Evgeny Poberezkin 15ef21de0c ios: build 344 2026-07-25 17:17:39 +01:00
Evgeny Poberezkin 09254c5a53 ui: update whats new 2026-07-25 16:14:22 +01:00
+16 8c80e4fd57 ui: translations (#7305)
* Translated using Weblate (German)

Currently translated at 100.0% (2897 of 2897 strings)

Translation: SimpleX Chat/SimpleX Chat Android
Translate-URL: https://hosted.weblate.org/projects/simplex-chat/android/de/

* Translated using Weblate (German)

Currently translated at 100.0% (2495 of 2495 strings)

Translation: SimpleX Chat/SimpleX Chat iOS
Translate-URL: https://hosted.weblate.org/projects/simplex-chat/ios/de/

* Translated using Weblate (French)

Currently translated at 82.3% (2387 of 2897 strings)

Translation: SimpleX Chat/SimpleX Chat Android
Translate-URL: https://hosted.weblate.org/projects/simplex-chat/android/fr/

* Translated using Weblate (Italian)

Currently translated at 100.0% (2897 of 2897 strings)

Translation: SimpleX Chat/SimpleX Chat Android
Translate-URL: https://hosted.weblate.org/projects/simplex-chat/android/it/

* Translated using Weblate (Italian)

Currently translated at 100.0% (2897 of 2897 strings)

Translation: SimpleX Chat/SimpleX Chat Android
Translate-URL: https://hosted.weblate.org/projects/simplex-chat/android/it/

* Translated using Weblate (Italian)

Currently translated at 100.0% (2495 of 2495 strings)

Translation: SimpleX Chat/SimpleX Chat iOS
Translate-URL: https://hosted.weblate.org/projects/simplex-chat/ios/it/

* Translated using Weblate (Chinese (Simplified Han script))

Currently translated at 99.9% (2896 of 2897 strings)

Translation: SimpleX Chat/SimpleX Chat Android
Translate-URL: https://hosted.weblate.org/projects/simplex-chat/android/zh_Hans/

* Translated using Weblate (Chinese (Traditional Han script))

Currently translated at 96.7% (2803 of 2897 strings)

Translation: SimpleX Chat/SimpleX Chat Android
Translate-URL: https://hosted.weblate.org/projects/simplex-chat/android/zh_Hant/

* Translated using Weblate (Dutch)

Currently translated at 82.2% (2382 of 2897 strings)

Translation: SimpleX Chat/SimpleX Chat Android
Translate-URL: https://hosted.weblate.org/projects/simplex-chat/android/nl/

* Translated using Weblate (Japanese)

Currently translated at 96.9% (2810 of 2897 strings)

Translation: SimpleX Chat/SimpleX Chat Android
Translate-URL: https://hosted.weblate.org/projects/simplex-chat/android/ja/

* Translated using Weblate (Czech)

Currently translated at 93.6% (2712 of 2897 strings)

Translation: SimpleX Chat/SimpleX Chat Android
Translate-URL: https://hosted.weblate.org/projects/simplex-chat/android/cs/

* Translated using Weblate (Portuguese (Brazil))

Currently translated at 80.2% (2325 of 2897 strings)

Translation: SimpleX Chat/SimpleX Chat Android
Translate-URL: https://hosted.weblate.org/projects/simplex-chat/android/pt_BR/

* Translated using Weblate (Arabic)

Currently translated at 100.0% (2897 of 2897 strings)

Translation: SimpleX Chat/SimpleX Chat Android
Translate-URL: https://hosted.weblate.org/projects/simplex-chat/android/ar/

* Translated using Weblate (Ukrainian)

Currently translated at 91.8% (2660 of 2897 strings)

Translation: SimpleX Chat/SimpleX Chat Android
Translate-URL: https://hosted.weblate.org/projects/simplex-chat/android/uk/

* Translated using Weblate (Lithuanian)

Currently translated at 58.5% (1696 of 2897 strings)

Translation: SimpleX Chat/SimpleX Chat Android
Translate-URL: https://hosted.weblate.org/projects/simplex-chat/android/lt/

* Translated using Weblate (Finnish)

Currently translated at 49.2% (1427 of 2897 strings)

Translation: SimpleX Chat/SimpleX Chat Android
Translate-URL: https://hosted.weblate.org/projects/simplex-chat/android/fi/

* Translated using Weblate (Korean)

Currently translated at 50.5% (1463 of 2897 strings)

Translation: SimpleX Chat/SimpleX Chat Android
Translate-URL: https://hosted.weblate.org/projects/simplex-chat/android/ko/

* Translated using Weblate (Polish)

Currently translated at 86.8% (2516 of 2897 strings)

Translation: SimpleX Chat/SimpleX Chat Android
Translate-URL: https://hosted.weblate.org/projects/simplex-chat/android/pl/

* Translated using Weblate (Hebrew)

Currently translated at 71.0% (2058 of 2897 strings)

Translation: SimpleX Chat/SimpleX Chat Android
Translate-URL: https://hosted.weblate.org/projects/simplex-chat/android/he/

* Translated using Weblate (Thai)

Currently translated at 42.5% (1233 of 2897 strings)

Translation: SimpleX Chat/SimpleX Chat Android
Translate-URL: https://hosted.weblate.org/projects/simplex-chat/android/th/

* Translated using Weblate (Bulgarian)

Currently translated at 85.4% (2476 of 2897 strings)

Translation: SimpleX Chat/SimpleX Chat Android
Translate-URL: https://hosted.weblate.org/projects/simplex-chat/android/bg/

* Translated using Weblate (Turkish)

Currently translated at 98.7% (2862 of 2897 strings)

Translation: SimpleX Chat/SimpleX Chat Android
Translate-URL: https://hosted.weblate.org/projects/simplex-chat/android/tr/

* Translated using Weblate (Hungarian)

Currently translated at 100.0% (2897 of 2897 strings)

Translation: SimpleX Chat/SimpleX Chat Android
Translate-URL: https://hosted.weblate.org/projects/simplex-chat/android/hu/

* Translated using Weblate (Persian)

Currently translated at 84.9% (2461 of 2897 strings)

Translation: SimpleX Chat/SimpleX Chat Android
Translate-URL: https://hosted.weblate.org/projects/simplex-chat/android/fa/

* Translated using Weblate (Hungarian)

Currently translated at 100.0% (2495 of 2495 strings)

Translation: SimpleX Chat/SimpleX Chat iOS
Translate-URL: https://hosted.weblate.org/projects/simplex-chat/ios/hu/

* Translated using Weblate (Hungarian)

Currently translated at 100.0% (2899 of 2899 strings)

Translation: SimpleX Chat/SimpleX Chat Android
Translate-URL: https://hosted.weblate.org/projects/simplex-chat/android/hu/

* Translated using Weblate (Chinese (Simplified Han script))

Currently translated at 99.9% (2898 of 2899 strings)

Translation: SimpleX Chat/SimpleX Chat Android
Translate-URL: https://hosted.weblate.org/projects/simplex-chat/android/zh_Hans/

* Translated using Weblate (Italian)

Currently translated at 100.0% (2899 of 2899 strings)

Translation: SimpleX Chat/SimpleX Chat Android
Translate-URL: https://hosted.weblate.org/projects/simplex-chat/android/it/

* Translated using Weblate (Italian)

Currently translated at 100.0% (2495 of 2495 strings)

Translation: SimpleX Chat/SimpleX Chat iOS
Translate-URL: https://hosted.weblate.org/projects/simplex-chat/ios/it/

* Translated using Weblate (German)

Currently translated at 100.0% (2899 of 2899 strings)

Translation: SimpleX Chat/SimpleX Chat Android
Translate-URL: https://hosted.weblate.org/projects/simplex-chat/android/de/

* Translated using Weblate (German)

Currently translated at 100.0% (2495 of 2495 strings)

Translation: SimpleX Chat/SimpleX Chat iOS
Translate-URL: https://hosted.weblate.org/projects/simplex-chat/ios/de/

* Translated using Weblate (Arabic)

Currently translated at 100.0% (2899 of 2899 strings)

Translation: SimpleX Chat/SimpleX Chat Android
Translate-URL: https://hosted.weblate.org/projects/simplex-chat/android/ar/

* process translations

* ui: fix translation errors found in review

Android (strings.xml):
- de: "Fehler beim SimpleX-Name" -> "-Namen" (dative of Name)
- de: connection_error_auth title updated to match new EN
  "Connection link removed"; fix reflexive "Um Sie" -> "Um sich"
- hu: typo "egyszer használató" -> "használható"
- hu, it: connection_error_auth title updated to match new EN
- ar: "استيثاق الجهاز غير مفعّلة" -> "مفعّل" (masculine agreement,
  stale after the المصادقة -> الاستيثاق terminology change)
- ar: "الذين شاركَ الرابط معهم" -> "شاركتَ" (subjectless verb)
- ar: "سيظل جميع جهات اتصالك متصلين" -> "ستظل ... متصلة" (x2,
  جهات is feminine plural)
- ar: add missing trailing period to v7_0_channels_relays
- ar: passive voice for skipped-message counters, matching EN
- zh-rCN: connection_error_auth reworded as a title, not a
  subjectless clause; restore the \n dropped from _desc

iOS:
- de: same dative fix in Localizable.strings and de.xliff
- de, hu, it: add missing File servers / "File servers: %@"
  targets, ported from the Android translations in this PR

---------

Co-authored-by: mlanp <github@lang.xyz>
Co-authored-by: Ophiushi <41908476+ishi-sama@users.noreply.github.com>
Co-authored-by: Deleted User <noreply+6980@weblate.org>
Co-authored-by: Random <random-r@users.noreply.hosted.weblate.org>
Co-authored-by: Hosted Weblate user 54392 <hamburger2048@users.noreply.hosted.weblate.org>
Co-authored-by: Olivia Ng <uloo592@gmail.com>
Co-authored-by: John m <jvanmanen@gmail.com>
Co-authored-by: tomato potato <tomato.games@protonmail.com>
Co-authored-by: M Sarmad Qadeer <msarmadqadeer@gmail.com>
Co-authored-by: HypocrisyCollector <work.j6nnu@slmail.me>
Co-authored-by: jonnysemon <jonnysemon@users.noreply.hosted.weblate.org>
Co-authored-by: Maksym Lukashenko <livelmaxim@gmail.com>
Co-authored-by: Anonimas <anonimas3@users.noreply.hosted.weblate.org>
Co-authored-by: petri <pkajander@gmail.com>
Co-authored-by: 5olivetree <5olivetree+github.com@mailbox.org>
Co-authored-by: B.O.S.S <BxOxSxS@protonmail.com>
Co-authored-by: Roee Hershberg <roihershberg@protonmail.com>
Co-authored-by: Titapa (PunPun) Chaiyakiturajai <titapapunne@gmail.com>
Co-authored-by: elgratea <weblate@fastmail.com>
Co-authored-by: Kaanito <kaanpeker196@gmail.com>
Co-authored-by: summoner001 <summoner@disroot.org>
Co-authored-by: Siavash <ciavash@proton.me>
Co-authored-by: Narasimha-sc <166327228+Narasimha-sc@users.noreply.github.com>
Co-authored-by: Evgeny Poberezkin <evgeny@poberezkin.com>
2026-07-25 16:07:00 +01:00
9d47d88311 website: translations (#7306)
* Translated using Weblate (German)

Currently translated at 100.0% (374 of 374 strings)

Translation: SimpleX Chat/SimpleX Chat website
Translate-URL: https://hosted.weblate.org/projects/simplex-chat/website/de/

* Translated using Weblate (Italian)

Currently translated at 100.0% (374 of 374 strings)

Translation: SimpleX Chat/SimpleX Chat website
Translate-URL: https://hosted.weblate.org/projects/simplex-chat/website/it/

* Translated using Weblate (Hungarian)

Currently translated at 100.0% (374 of 374 strings)

Translation: SimpleX Chat/SimpleX Chat website
Translate-URL: https://hosted.weblate.org/projects/simplex-chat/website/hu/

* Translated using Weblate (German)

Currently translated at 100.0% (374 of 374 strings)

Translation: SimpleX Chat/SimpleX Chat website
Translate-URL: https://hosted.weblate.org/projects/simplex-chat/website/de/

* Translated using Weblate (Italian)

Currently translated at 100.0% (374 of 374 strings)

Translation: SimpleX Chat/SimpleX Chat website
Translate-URL: https://hosted.weblate.org/projects/simplex-chat/website/it/

* Translated using Weblate (Hungarian)

Currently translated at 100.0% (374 of 374 strings)

Translation: SimpleX Chat/SimpleX Chat website
Translate-URL: https://hosted.weblate.org/projects/simplex-chat/website/hu/

* website: fix Italian translation of 'Host Chat Relay'

'Gestisci' means manage/run, not host. The sibling entries in the same
docs dropdown ('Host SMP Server', 'Host XFTP Server') use 'Ospita', and
all three render adjacently in the menu.

---------

Co-authored-by: mlanp <github@lang.xyz>
Co-authored-by: Random <random-r@users.noreply.hosted.weblate.org>
Co-authored-by: summoner001 <summoner@disroot.org>
Co-authored-by: Narasimha-sc <166327228+Narasimha-sc@users.noreply.github.com>
2026-07-25 16:03:11 +01:00
Evgeny Poberezkin 83bf107804 ios: update core library 2026-07-25 15:51:21 +01:00
spaced4ndyandGitHub c7e83d88ae desktop: fix opening contact request leaving previous open chat in connecting state (#7302) 2026-07-25 14:47:31 +01:00
Evgeny Poberezkin cdef9f51e6 core: 7.0.0.11 (simplexmq 7.0.0.6) 2026-07-25 12:22:49 +01:00
Narasimha-scandGitHub 6a34b5e052 support bot: fix double invite when joining a customer chat (#7129)
addOrFindTeamMember added the team member as Member and then immediately
called apiSetMembersRole(Owner). For a not-yet-accepted (GSMemInvited)
member the core re-sends the group invitation on a role change, so every
/join and /team produced two invitations. Add the member directly as
Owner in a single apiAddMember call; onMemberConnected still re-asserts
Owner idempotently as a fallback.
2026-07-25 11:27:06 +01:00
8bcb9d048b directory: expand service README (#6701)
* directory: expand README with build, run, and command reference

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* directory: remove system packages from README prerequisites

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* directory: README fixes

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* directory: standalone web page

* directory: Improve README.md

* directory: fix README inaccuracies, complete flags, expand self-hosting docs

- correct /filter name-filter semantics (long/blocked names, not "no name");
  note it needs --profile-name-limit / --blocked-*-file to do anything
- list the remaining directory flags and note core chat options + --help
- add the required cabal.project.local OpenSSL step; use `cabal list-bin`
- hosting page: copy files out of the repo (directory.js is a symlink, data
  URL is a top-level const), provide /img/group.svg, promoted.json unused
- bootstrap: bot prints/creates its contact address on startup
- document --owners-group / --directory-file (+ --migrate-directory-file)
- redraw lifecycle diagram; Active->PendingUpdate on link removal vs
  Active->PendingApproval on other profile changes; SuspendedBadRoles auto-restore

* directory: clarify group lifecycle diagram

Linear forward-path diagram (invitation -> Active), with transitions out
of Active as a list instead of cramped back-arrows.

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-25 11:26:22 +01:00
Narasimha-scandGitHub 3726040d84 core: ignore mentions and replies of blocked members (#7303)
Messages of blocked members are hidden, but they still marked chat item
as user mention, showing mention badge and counting group as unread in
"mentions only" notification mode:
- createNonLive passed mentions unfiltered, allowing members blocked by
  admin to mention user - it is the default path, as it is only used
  when full delete is not allowed;
- userReply was set for replies to user messages from blocked members.
2026-07-25 10:42:34 +01:00
Narasimha-scandGitHub e7c94472c4 desktop: fix chat switch deleting the in-app updater's download (#7295)
* desktop: fix chat switch deleting the in-app updater's download

createTmpFileAndDelete registered every temp file it created in
ChatModel.filesToDelete, which ComposeView.deleteUnusedFiles() empties on every
chat open/switch/close. The updater's ~350 MB download lives in such a file for
minutes, so switching chats during it deleted the file. copyTo kept writing
through the still-open fd, so the transfer completed and progress reached 100%;
only the following Files.move failed, with NoSuchFileException on the source,
and that went into a catch that logs to stdout only - no dialog, no error, no
file.

The registration was redundant for every caller: the helper's own
finally { tmpFile.delete() } already removes the file, deleteOnExit() covers a
clean JVM exit, and Main.kt wipes tmpDir at startup for crashes. It only ever
duplicated the finally while arming a trap for long-running lambdas - the same
window also existed for the settings and themes writers.

* desktop: download the app update into a file the updater owns

Per review of #7295: instead of removing the ChatModel.filesToDelete
registration from createTmpFileAndDelete, stop using that helper for the
downloaded file.

downloadAsset now writes into "<asset name>.part" in tmpDir and moves it onto
the asset name when the transfer completes, so the download is never registered
in ChatModel.filesToDelete and ComposeView.deleteUnusedFiles() can no longer
delete it mid-transfer. Cleanup is unchanged in substance: the finally block
removes the partial file when the download fails or is cancelled (and is a
no-op after a successful move, as the helper's own finally was), deleteOnExit
covers a clean exit, and Main.kt wipes tmpDir at startup after a crash.

createTmpFileAndDelete is restored to its previous behaviour, with a comment
warning that its file does not survive a chat switch.

* desktop: reduce comments in updater download fix
2026-07-24 21:07:56 +01:00
spaced4ndyandGitHub 5c196d0e2d ui: rename "how to register name" button (#7300) 2026-07-24 15:25:52 +00:00
spaced4ndyandGitHub 08711dbc33 ios: fix app crashing after onboarding (#7299) 2026-07-24 14:47:16 +00:00
spaced4ndyandGitHub 3755dc43be ios: fix receipts toggles in user settings (#7298) 2026-07-24 14:33:54 +00:00
spaced4ndyandGitHub 53daafa675 ios: put "connect to name" button below search in top bar layout (#7297) 2026-07-24 14:19:52 +00:00
EvgenyandGitHub 8320730440 core: prohibit image previews when images are prohibited (#7296) 2026-07-24 10:50:46 +01:00
Narasimha-scandGitHub dc3c106bda core: remove SimpleX Status preset contact (#7231)
* core: remove SimpleX Status preset contact

Preset contact cards are only created at user record creation
(createPresetContactCards), so this affects new profiles only;
existing profiles keep their stored SimpleX Status contact.

Removing the card shifts contact ids allocated after /create user
down by one, hence the test id updates.

* plans: justify SimpleX Status preset contact removal
2026-07-24 09:05:12 +01:00
fc28914455 desktop: fix saving files with '[', '*', or '?' in name on Linux (#7290)
* desktop: fix saving files with '[', '*', or '?' in name on Linux

JFileChooser's BasicFileChooserUI treats filenames containing
'[', '*', or '?' as glob patterns on Unix when the file does not
exist on disk. The Save button's ApproveSelectionAction then
applies a GlobFilter and returns without saving — the dialog
stays open and nothing is written.

Regression introduced in #2789 (commit 02d00944f, 2023-07-28),
which started pre-populating the filename via selectedFile =
File(filename). Before that the save dialog ran in
DIRECTORIES_ONLY mode and the JDK glob check never saw the
filename.

Fix: on Linux save dialogs, find the Save button by identity
(BasicFileChooserUI.getApproveSelectionAction() is public and
returns the exact ActionListener wired on the button) and
replace it with a wrapper that delegates to the original
action for non-glob names and calls approveSelection()
directly for glob names.

Windows (per the JDK only '*' and '?' are glob chars there)
and macOS (uses AWT FileDialog) are unaffected. Open dialogs
keep glob filtering for power-user search.

* desktop: always bypass JFileChooser glob-on-save on Linux

Earlier in this branch we added a heuristic to delegate to the
original ApproveSelectionAction for non-'[' names so that typing
'*.pdf' in the save dialog would still glob-filter the listing.
That preserved a Swing-only quirk that no native OS save dialog
implements:
  - macOS uses NSSavePanel (already used in this app via AWT
    FileDialog) — no glob-on-save.
  - Native Windows / Linux GTK / KDE save dialogs — no glob-on-save.
  - JFileChooser on Windows — has it, but '*' and '?' aren't even
    legal NTFS filename chars, so users won't be typing them.

It also blocks legitimate filenames containing '*' or '?' on Linux
(legal on POSIX filesystems) from being saved, since they too get
intercepted as glob.

Replace the Save button's action with a handler that always treats
the typed text as a literal filename. The result: any filename can
be saved on Linux, behaviour aligns with macOS and with every
native OS save dialog. The open dialog is untouched, so '*.pdf'
glob-filtering there still works.

* desktop: restore directory-only save dialog on Linux

The previous commit installed the literal-filename glob bypass for
every Linux save dialog (!isLoad && isLinux), including the
DIRECTORIES_ONLY mode used when filename == null — e.g. the
"Save QR code as image" flow (saveTempImageUncompressed →
saveDialog.awaitResult() with no params).

In that mode the bypass broke directory selection entirely:
selecting a subfolder + Save traversed into it instead of approving
it, and Save with an empty filename field no-oped. Net result:
QR-code image saving was unusable on Linux.

The glob-on-save bug only arises because a filename is pre-populated
(selectedFile = File(filename)), which never happens in
DIRECTORIES_ONLY mode. Gate the bypass on filename != null so the
directory-save path keeps JFileChooser's original approve action.

* desktop: simplify Linux save glob bypass via getDefaultButton

---------

Co-authored-by: shum <github.shum@liber.li>
2026-07-23 10:18:11 +01:00
Narasimha-scandGitHub 177a591466 core: fix member support chats staying marked unread after they're read (#7281)
* core: don't mark member support chat items read when reading group without scope

Reading a group without a scope marked support-scope items read without
decrementing the per-member support_chat_items_* counters, so members stayed
unread in the support list even after their chat was fully read. Restrict the
no-scope group read and its timed-items query to main-scope items.

* plans: support chat unread on no-scope group read

* core: update query plans for group scope read

The main-scope read and timed-items queries now filter on group_scope_tag
and group_scope_group_member_id, so they seek via idx_chat_items_group_scope_stats_all
(5-column) instead of idx_chat_items_groups_user_mention (3-column).

* plans: document query-plan and benchmark performance results

* tests: fix unreliable support item id capture in no-scope group read test

lastItemId returns the latest item by item_ts, which right after createGroup2
can be the group "connected" event rather than the just-sent support message.
The per-item read then targeted the wrong (already-read, main-scope) item and
never decremented the support counters, so the test failed regardless of the
fix (consistently in CI, flakily locally depending on item ordering).

Capture the support item id directly from the member-support scope instead,
keeping the change contained to this test. Verified: the test passes with the
fix and fails when the fix is reverted.

* tests: fix name-shadowing build error in no-scope group read test

The local pattern binding `itemId` shadowed the `itemId` helper imported
from ChatTests.Utils, which -Wname-shadowing (Werror) rejects. Rename the
local binding to `iId`.
2026-07-23 10:17:27 +01:00
spaced4ndyandGitHub 8ec4b424cb core: prohibit to change or assign relay role (#7284) 2026-07-22 19:39:05 +00:00
spaced4ndyandGitHub 49a8664331 core: reject group message forwards from unexpected admins (#7289) 2026-07-22 19:26:28 +00:00
Evgeny Poberezkin 03d6803ee7 blog: correction 2026-07-22 19:06:44 +01:00
Evgeny Poberezkin 9ee79aae8d blog: corrections 2026-07-22 18:40:23 +01:00
EvgenyandGitHub 5cf03de92d blog: SimpleX public names (#7291)
* post

* update readme

* update

* typos

* the
2026-07-22 18:37:53 +01:00