Commit Graph
3761 Commits
Author SHA1 Message Date
Evgeny @ SimpleX Chat cd0d46c5e3 android, desktop: exact alignment and spacing (#7946)
* android, desktop: exact alignment and spacing

* android, desktop: previews of the views changed for alignment and spacing

* ci: desktop references of exact alignment and spacing

* android, desktop: preview of chat rows with unread messages, mentions and muted chats

* android, desktop: deleted text, What's new and app version keep master's layout; link strip follows iOS

* ci: desktop references of the review round and of chat rows with unread messages

* android, desktop: previews of the private routing and downgrade pickers and of the migration network step

* ci: desktop references of the private routing and downgrade pickers and the migration network step

* android, desktop: channel text aligned; master row date, strips, icons

* ci: desktop references of reverted views and the aligned channel icon

* android, desktop: the pull request holds only the agreed changes; new chat sheet and previews of reverted changes as on master
2026-11-01 07:47:07 +00:00
Evgeny @ SimpleX Chat 56b4ca73cc ios: exact alignment and spacing (#7945)
* ios: exact alignment and spacing

* ios: previews of the views changed for alignment and spacing

* ci: iOS references of exact alignment and spacing

* ios: single check and the time under a received emoji keep their places

* ios: deleted text, link strip text, What's new, app version, QR cards and onion hosts keep master's layout; info headers get more space above the avatar; chat row preview with contact requests

* ci: iOS references of the review round and of chat rows with contact requests

* ios: keep master's tags, requests, group icon, footers, compose strips

* ci: iOS references of the views back on master's layout

* ios: the pull request holds only the agreed changes, without previews of reverted ones

* ios: contact request view as on master
2026-11-01 07:46:07 +00:00
Narasimha-sc d1b3da8410 android, desktop: chat info shows another chat's mute, receipts and search; contact edits revert (#7927)
* desktop: show the open chat's mute, receipts and search in chat info

* android, desktop: show the open chat's mute state in the chat menu

* android, desktop: keep both contact info changes to mute and receipts

* android, desktop: list all members when the member search is hidden

* android, desktop: remove the unused chat menu mute state
2026-10-31 20:19:58 +00:00
Narasimha-sc 0735bd2c6e desktop: after a chat switch, chat info shows the previous chat's security code, link or members (#7926)
* desktop: reload chat info when it is shown for another chat

The info pane keeps the values it last loaded. When the pane is composed
again for another chat - after clicking another chat with a page such as
"Verify security code" open over it, or when switching between a contact
and a group - KeyChangeEffect takes the new chat id as its starting key, so
nothing is reloaded: "Verify security code" opened from the new contact's
info showed the previous contact's code, and a group's info missed its
members.

Remember which chat the loaded values belong to and reload whenever the
shown chat differs from it.

Fixes #5135

* plans: desktop chat info stale after chat switch (#5135)

* desktop: don't show another chat's info while the shown chat loads

When the info pane showed a chat other than the one its values were
loaded for, it reloaded them, but until the reload returned it showed the
previous chat's values: "Verify security code" opened the previous
contact's code, and a group showed the previous group's link, so "Group
link" opened and shared another group's link.

Start the contact info, security code and group link empty when they
belong to another chat. Hide the "Create group link" / "Group link" row
and disable the channel "Link" button until the link is loaded: with no
link yet, both open the link page, which creates a link when it gets
none, and for a group that already has one the core creates a server
queue before failing with a duplicate link error.

* desktop: keep a late group link update from replacing another chat's link

A link created, changed or deleted on the "Group link" page finishes in
the background. If the user switched chats meanwhile and the pane already
loaded the next group, the update replaced that group's stored link, and
the next time the pane was composed for it, it showed the previous group's
link, or no link after a delete.

Store the update only while the stored values belong to the group the
update came from.

* desktop: reload group info when its members were cleared

Switching chats clears the group members, and the preload skips storing
them when another chat is open when they arrive. Clicking info on group A,
then another chat and back to A before the preload finished, opened A's
info with the preloaded values marked as A's, so nothing was reloaded and
the members list showed only the user.

Reload the group info also when its members are not loaded.

* plans: chat info while it reloads, late link update, cleared members (#5135)

* desktop: hide channel owner link rows until the link is loaded

* plans: test of the channel owner rows, which builds the tables are for

* plans: restructure chat info plan into problem, cause, fix and scope

* plans: correct the Android and iOS scope of the chat info plan

* plans: chat info plan wording
2026-10-31 20:18:45 +00:00
SimpleX Chat 6016a7067b 7.1-beta.8: android 388, desktop 169, ios 364 2026-10-31 09:38:31 +00:00
Evgeny @ SimpleX Chat 5230eadbab ios, android, desktop: load JPEG, PNG, GIF and WebP image files (#7956) 2026-10-31 07:14:01 +00:00
Evgeny @ SimpleX ChatandEvgeny Poberezkin 51d9eb2785 core: faster image resizing (#7957)
* core: optimise image processing in builds without optimisation

* core: faster image sharpening

* core: faster transparency check for images

* docs: plan PNG previews from a predicted size

* core: start PNG previews at a predicted size

* ios: update core

---------

Co-authored-by: Evgeny Poberezkin <evgeny@poberezkin.com>
2026-10-31 07:09:40 +00:00
Evgeny @ SimpleX Chatandspacedandy-agents-simplex cedd13f57b ui: what's new in v7.1-beta.8 (#7953)
* ui: what's new in v7.1

* ui: v7.1 what's new wording, moderator icon and badge item style

* ui: better calls in v7.1 what's new

* ui: phone icon for better calls in v7.1 what's new

* ui: v7.1 what's new preview screenshots

* ui: even gap below the supporter badge in v7.1 what's new

* ui: supporter badge picture rises above its text in v7.1 what's new

* ui: v7.1 what's new preview screenshots with the badge layout

* ui: v7.1 what's new desktop screenshot after the master merge

* ui: v7.1-beta.8 what's new wording

* ui: v7.1-beta.8 what's new: promote contributors to moderators

* ci: desktop references of v7.1-beta.8 what's new

* ui: v7.1-beta.8 what's new: larger supporter phone aligned by its head

* ci: desktop references of the supporter phone placement

* ci: iOS references of v7.1-beta.8 what's new

---------

Co-authored-by: spacedandy-agents-simplex <342056592+spacedandy-agents-simplex@users.noreply.github.com>
2026-10-30 20:58:35 +00:00
Narasimha-sc 05ac3612b7 android, desktop: a migration link pasted with extra whitespace downloads without its proxy settings (#7885)
* multiplatform: trim pasted migration link before reading its network config

MigrateToDevice.checkUserLink checked link.trim() and stored link.trim() in
every MigrationToState payload, but passed the raw link to
MigrationFileLinkData.readFromLink. A migration link pasted (or scanned)
with leading whitespace, or with trailing non-ASCII whitespace such as a no-
break space, passed the check but its "/_download info" request failed to
parse or returned no network settings, so readFromLink returned null and the
link's network settings were silently dropped: "Confirm network settings"
was skipped, the archive downloaded without the link's SOCKS proxy, and the
proxy stayed off after migration.

Compute the trimmed link once and use it throughout, so classification and
consumption see the same string.

* plans: migration link trim

* plans: migration link trim: text after the link, proxy-less download

* plans: migration link trim: exact trim coverage, settings-read reporting

* plans: migration link trim: shadowing reason, trim coverage, wording

* plans: migration link trim: title scope, NBSP bytes, tab, review reason

* plans: migration link trim: title precision, line-break case, rejections

* plans: migration link trim: line break inside desc gives a visible error

* plans: migration link trim: exact alert title
2026-10-30 20:06:20 +00:00
spaced4ndyandspacedandy-agents-simplex 4b1841c9a0 android: fix blank badges screen after a badge change (#7952)
* core: credit and lapse a test badge on a timer, for app tests

* ci: watch the desktop badges screen through badge credits and lapses

* ci: watch the Android badges screen through badge credits and lapses

* ci: tell the badges support page from the settings section

* android, desktop: log badges screen state changes, for app tests

* ci: check that the badges screen draws its page, not only lists it

* ci: start the app again when it crashes at start before badge cycles

* ci: reinstall the app before badge cycles, as the smoke test installs it

* ci: reach the Android chat console through the app version in Settings

* ci: tell Settings from the version screen on the way to the badges screen

* ci: keep one record of the last badges page the cycles read

* ci: let the Android harness set the app bars' blur

* ci: judge badge cycles by the page the Android screen draws

* ci: run badge cycles with the app bars' blur on and off

* ci: read each Android badge reading's pixels to the end

* ci: shorten the badge cycles with the app bars' blur on and off

* android, desktop: remove the badges screen's test logging

* android, desktop: fix the badges screen going blank when a badge is issued or ends

* ci: verify the badges screen over 31 credit and lapse cycles

* android, desktop: say why the badges pages are not cross-faded

* ci: type the badge cycles command again when characters are lost

* core: remove the test badge cycles

* ci: move the badge cycle steps to their own branch

---------

Co-authored-by: spacedandy-agents-simplex <342056592+spacedandy-agents-simplex@users.noreply.github.com>
2026-10-30 19:02:40 +00:00
shandHosted Weblate a3a285049b Update translation files (#7948)
Updated by "Remove blank strings" hook in Weblate.

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

Co-authored-by: Hosted Weblate <hosted@weblate.org>
2026-10-30 14:33:06 +00:00
+104 0d608e3e47 ui: translations (#7944)
* Translated using Weblate (Russian)

Currently translated at 99.5% (2501 of 2513 strings)

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

* Translated using Weblate (Russian)

Currently translated at 99.5% (2501 of 2513 strings)

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

* Translated using Weblate (Russian)

Currently translated at 99.5% (2501 of 2513 strings)

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

* Translated using Weblate (Russian)

Currently translated at 99.5% (2501 of 2513 strings)

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

* Translated using Weblate (Russian)

Currently translated at 99.5% (2501 of 2513 strings)

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

* Translated using Weblate (Russian)

Currently translated at 99.5% (2501 of 2513 strings)

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

* Translated using Weblate (Russian)

Currently translated at 99.5% (2501 of 2513 strings)

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

* Translated using Weblate (Russian)

Currently translated at 99.5% (2501 of 2513 strings)

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

* Translated using Weblate (Russian)

Currently translated at 99.5% (2501 of 2513 strings)

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

* Translated using Weblate (Russian)

Currently translated at 99.5% (2501 of 2513 strings)

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

* Translated using Weblate (French)

Currently translated at 100.0% (2513 of 2513 strings)

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

* Translated using Weblate (French)

Currently translated at 100.0% (2513 of 2513 strings)

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

* Translated using Weblate (French)

Currently translated at 100.0% (2513 of 2513 strings)

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

* Translated using Weblate (French)

Currently translated at 100.0% (2513 of 2513 strings)

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

* Translated using Weblate (French)

Currently translated at 100.0% (2513 of 2513 strings)

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

* Translated using Weblate (French)

Currently translated at 100.0% (2513 of 2513 strings)

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

* Translated using Weblate (French)

Currently translated at 100.0% (2513 of 2513 strings)

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

* Translated using Weblate (French)

Currently translated at 100.0% (2513 of 2513 strings)

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

* Translated using Weblate (French)

Currently translated at 100.0% (2513 of 2513 strings)

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

* Translated using Weblate (French)

Currently translated at 100.0% (2513 of 2513 strings)

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

* Translated using Weblate (French)

Currently translated at 100.0% (2513 of 2513 strings)

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

* Translated using Weblate (Italian)

Currently translated at 100.0% (2513 of 2513 strings)

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

* Translated using Weblate (Italian)

Currently translated at 100.0% (2513 of 2513 strings)

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

* Translated using Weblate (Italian)

Currently translated at 100.0% (2513 of 2513 strings)

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

* Translated using Weblate (Italian)

Currently translated at 100.0% (2513 of 2513 strings)

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

* Translated using Weblate (Italian)

Currently translated at 100.0% (2513 of 2513 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 97.6% (2453 of 2513 strings)

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

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

Currently translated at 97.6% (2453 of 2513 strings)

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

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

Currently translated at 97.6% (2453 of 2513 strings)

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

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

Currently translated at 97.6% (2453 of 2513 strings)

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

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

Currently translated at 97.6% (2453 of 2513 strings)

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

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

Currently translated at 97.6% (2453 of 2513 strings)

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

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

Currently translated at 97.6% (2453 of 2513 strings)

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

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

Currently translated at 97.6% (2453 of 2513 strings)

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

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

Currently translated at 97.6% (2453 of 2513 strings)

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

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

Currently translated at 97.6% (2453 of 2513 strings)

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

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

Currently translated at 97.6% (2453 of 2513 strings)

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

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

Currently translated at 97.6% (2453 of 2513 strings)

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

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

Currently translated at 97.6% (2453 of 2513 strings)

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

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

Currently translated at 97.6% (2453 of 2513 strings)

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

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

Currently translated at 97.6% (2453 of 2513 strings)

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

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

Currently translated at 97.6% (2453 of 2513 strings)

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

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

Currently translated at 97.6% (2453 of 2513 strings)

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

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

Currently translated at 97.6% (2453 of 2513 strings)

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

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

Currently translated at 96.4% (2424 of 2513 strings)

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

* Translated using Weblate (Spanish)

Currently translated at 100.0% (2513 of 2513 strings)

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

* Translated using Weblate (Spanish)

Currently translated at 100.0% (2513 of 2513 strings)

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

* Translated using Weblate (Spanish)

Currently translated at 100.0% (2513 of 2513 strings)

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

* Translated using Weblate (Spanish)

Currently translated at 100.0% (2513 of 2513 strings)

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

* Translated using Weblate (Spanish)

Currently translated at 100.0% (2513 of 2513 strings)

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

* Translated using Weblate (Spanish)

Currently translated at 100.0% (2513 of 2513 strings)

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

* Translated using Weblate (Spanish)

Currently translated at 100.0% (2513 of 2513 strings)

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

* Translated using Weblate (Spanish)

Currently translated at 100.0% (2513 of 2513 strings)

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

* Translated using Weblate (Spanish)

Currently translated at 100.0% (2513 of 2513 strings)

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

* Translated using Weblate (Spanish)

Currently translated at 100.0% (2513 of 2513 strings)

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

* Translated using Weblate (Spanish)

Currently translated at 100.0% (2513 of 2513 strings)

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

* Translated using Weblate (Dutch)

Currently translated at 81.3% (2044 of 2513 strings)

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

* Translated using Weblate (Dutch)

Currently translated at 81.3% (2044 of 2513 strings)

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

* Translated using Weblate (Dutch)

Currently translated at 81.3% (2044 of 2513 strings)

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

* Translated using Weblate (Dutch)

Currently translated at 81.3% (2044 of 2513 strings)

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

* Translated using Weblate (Dutch)

Currently translated at 81.3% (2044 of 2513 strings)

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

* Translated using Weblate (Japanese)

Currently translated at 48.7% (1224 of 2513 strings)

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

* Translated using Weblate (Japanese)

Currently translated at 48.7% (1224 of 2513 strings)

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

* Translated using Weblate (Japanese)

Currently translated at 48.7% (1224 of 2513 strings)

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

* Translated using Weblate (Japanese)

Currently translated at 48.7% (1224 of 2513 strings)

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

* Translated using Weblate (Japanese)

Currently translated at 48.7% (1224 of 2513 strings)

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

* Translated using Weblate (Japanese)

Currently translated at 48.7% (1224 of 2513 strings)

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

* Translated using Weblate (Japanese)

Currently translated at 48.7% (1224 of 2513 strings)

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

* Translated using Weblate (Japanese)

Currently translated at 48.7% (1224 of 2513 strings)

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

* Translated using Weblate (Japanese)

Currently translated at 48.7% (1224 of 2513 strings)

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

* Translated using Weblate (Japanese)

Currently translated at 48.7% (1224 of 2513 strings)

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

* Translated using Weblate (Japanese)

Currently translated at 48.7% (1224 of 2513 strings)

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

* Translated using Weblate (Japanese)

Currently translated at 48.7% (1224 of 2513 strings)

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

* Translated using Weblate (Japanese)

Currently translated at 48.7% (1224 of 2513 strings)

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

* Translated using Weblate (Japanese)

Currently translated at 48.7% (1224 of 2513 strings)

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

* Translated using Weblate (Japanese)

Currently translated at 48.7% (1224 of 2513 strings)

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

* Translated using Weblate (Czech)

Currently translated at 50.2% (1264 of 2513 strings)

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

* Translated using Weblate (Czech)

Currently translated at 50.2% (1264 of 2513 strings)

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

* Translated using Weblate (Czech)

Currently translated at 50.2% (1264 of 2513 strings)

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

* Translated using Weblate (Czech)

Currently translated at 50.2% (1264 of 2513 strings)

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

* Translated using Weblate (Czech)

Currently translated at 50.2% (1264 of 2513 strings)

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

* Translated using Weblate (Czech)

Currently translated at 50.2% (1264 of 2513 strings)

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

* Translated using Weblate (Czech)

Currently translated at 50.2% (1264 of 2513 strings)

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

* Translated using Weblate (Czech)

Currently translated at 50.2% (1264 of 2513 strings)

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

* Translated using Weblate (Czech)

Currently translated at 50.2% (1264 of 2513 strings)

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

* Translated using Weblate (Czech)

Currently translated at 50.2% (1264 of 2513 strings)

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

* Translated using Weblate (Czech)

Currently translated at 50.2% (1264 of 2513 strings)

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

* Translated using Weblate (Portuguese (Brazil))

Currently translated at 35.6% (896 of 2513 strings)

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

* Translated using Weblate (Croatian)

Currently translated at 1.8% (47 of 2513 strings)

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

* Translated using Weblate (Croatian)

Currently translated at 1.8% (47 of 2513 strings)

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

* Translated using Weblate (Arabic)

Currently translated at 29.2% (735 of 2513 strings)

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

* Translated using Weblate (Ukrainian)

Currently translated at 85.6% (2152 of 2513 strings)

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

* Translated using Weblate (Ukrainian)

Currently translated at 85.6% (2152 of 2513 strings)

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

* Translated using Weblate (Ukrainian)

Currently translated at 85.6% (2152 of 2513 strings)

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

* Translated using Weblate (Ukrainian)

Currently translated at 85.6% (2152 of 2513 strings)

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

* Translated using Weblate (Ukrainian)

Currently translated at 85.6% (2152 of 2513 strings)

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

* Translated using Weblate (Ukrainian)

Currently translated at 85.6% (2152 of 2513 strings)

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

* Translated using Weblate (Ukrainian)

Currently translated at 85.6% (2152 of 2513 strings)

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

* Translated using Weblate (Ukrainian)

Currently translated at 85.6% (2152 of 2513 strings)

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

* Translated using Weblate (Ukrainian)

Currently translated at 85.6% (2152 of 2513 strings)

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

* Translated using Weblate (Ukrainian)

Currently translated at 85.6% (2152 of 2513 strings)

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

* Translated using Weblate (Ukrainian)

Currently translated at 85.6% (2152 of 2513 strings)

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

* Translated using Weblate (Ukrainian)

Currently translated at 85.6% (2152 of 2513 strings)

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

* Translated using Weblate (Lithuanian)

Currently translated at 1.5% (38 of 2513 strings)

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

* Translated using Weblate (Finnish)

Currently translated at 44.2% (1113 of 2513 strings)

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

* Translated using Weblate (Finnish)

Currently translated at 44.2% (1113 of 2513 strings)

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

* Translated using Weblate (Finnish)

Currently translated at 44.2% (1113 of 2513 strings)

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

* Translated using Weblate (Korean)

Currently translated at 17.5% (441 of 2513 strings)

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

* Translated using Weblate (Korean)

Currently translated at 17.5% (441 of 2513 strings)

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

* Translated using Weblate (Polish)

Currently translated at 86.2% (2168 of 2513 strings)

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

* Translated using Weblate (Polish)

Currently translated at 86.2% (2168 of 2513 strings)

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

* Translated using Weblate (Polish)

Currently translated at 86.2% (2168 of 2513 strings)

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

* Translated using Weblate (Polish)

Currently translated at 86.2% (2168 of 2513 strings)

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

* Translated using Weblate (Polish)

Currently translated at 86.2% (2168 of 2513 strings)

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

* Translated using Weblate (Polish)

Currently translated at 86.2% (2168 of 2513 strings)

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

* Translated using Weblate (Polish)

Currently translated at 86.2% (2168 of 2513 strings)

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

* Translated using Weblate (Polish)

Currently translated at 86.2% (2168 of 2513 strings)

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

* Translated using Weblate (Portuguese)

Currently translated at 6.0% (153 of 2513 strings)

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

* Translated using Weblate (Greek)

Currently translated at 1.0% (27 of 2513 strings)

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

* Translated using Weblate (Hebrew)

Currently translated at 26.3% (661 of 2513 strings)

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

* Translated using Weblate (Thai)

Currently translated at 42.9% (1079 of 2513 strings)

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

* Translated using Weblate (Thai)

Currently translated at 42.9% (1079 of 2513 strings)

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

* Translated using Weblate (Bengali)

Currently translated at 0.1% (3 of 2513 strings)

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

* Translated using Weblate (Bulgarian)

Currently translated at 61.4% (1544 of 2513 strings)

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

* Translated using Weblate (Bulgarian)

Currently translated at 61.4% (1544 of 2513 strings)

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

* Translated using Weblate (Bulgarian)

Currently translated at 61.4% (1544 of 2513 strings)

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

* Translated using Weblate (Turkish)

Currently translated at 85.4% (2147 of 2513 strings)

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

* Translated using Weblate (Turkish)

Currently translated at 85.4% (2147 of 2513 strings)

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

* Translated using Weblate (Turkish)

Currently translated at 85.4% (2147 of 2513 strings)

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

* Translated using Weblate (Turkish)

Currently translated at 85.4% (2147 of 2513 strings)

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

* Translated using Weblate (Turkish)

Currently translated at 85.4% (2147 of 2513 strings)

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

* Translated using Weblate (Turkish)

Currently translated at 85.4% (2147 of 2513 strings)

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

* Translated using Weblate (Turkish)

Currently translated at 85.4% (2147 of 2513 strings)

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

* Translated using Weblate (Turkish)

Currently translated at 85.4% (2147 of 2513 strings)

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

* Translated using Weblate (Turkish)

Currently translated at 85.4% (2147 of 2513 strings)

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

* Translated using Weblate (Turkish)

Currently translated at 85.4% (2147 of 2513 strings)

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

* Translated using Weblate (Turkish)

Currently translated at 85.4% (2147 of 2513 strings)

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

* Translated using Weblate (Turkish)

Currently translated at 85.4% (2147 of 2513 strings)

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

* Translated using Weblate (Turkish)

Currently translated at 85.4% (2147 of 2513 strings)

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

* Translated using Weblate (Hungarian)

Currently translated at 100.0% (2513 of 2513 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% (2513 of 2513 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% (2513 of 2513 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% (2513 of 2513 strings)

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

* Translated using Weblate (Azerbaijani)

Currently translated at 47.0% (1183 of 2513 strings)

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

* Translated using Weblate (Azerbaijani)

Currently translated at 47.0% (1183 of 2513 strings)

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

* Translated using Weblate (Bulgarian)

Currently translated at 80.9% (2430 of 3001 strings)

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

* Translated using Weblate (Russian)

Currently translated at 93.9% (2820 of 3001 strings)

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

* Translated using Weblate (German)

Currently translated at 96.5% (2898 of 3001 strings)

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

* Translated using Weblate (Lithuanian)

Currently translated at 56.6% (1701 of 3001 strings)

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

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

Currently translated at 92.0% (2763 of 3001 strings)

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

* Translated using Weblate (Thai)

Currently translated at 42.2% (1269 of 3001 strings)

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

* Translated using Weblate (Polish)

Currently translated at 82.0% (2463 of 3001 strings)

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

* Translated using Weblate (Greek)

Currently translated at 81.7% (2454 of 3001 strings)

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

* Translated using Weblate (Croatian)

Currently translated at 48.5% (1457 of 3001 strings)

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

* Translated using Weblate (Czech)

Currently translated at 89.4% (2685 of 3001 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 96.5% (2898 of 3001 strings)

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

* Translated using Weblate (Hebrew)

Currently translated at 69.1% (2074 of 3001 strings)

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

* Translated using Weblate (Persian)

Currently translated at 81.1% (2434 of 3001 strings)

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

* Translated using Weblate (Dutch)

Currently translated at 78.0% (2342 of 3001 strings)

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

* Translated using Weblate (Indonesian)

Currently translated at 88.3% (2650 of 3001 strings)

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

* Translated using Weblate (Bengali)

Currently translated at 1.7% (53 of 3001 strings)

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

* Translated using Weblate (Arabic)

Currently translated at 94.2% (2827 of 3001 strings)

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

* Translated using Weblate (Korean)

Currently translated at 49.5% (1488 of 3001 strings)

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

* Translated using Weblate (Italian)

Currently translated at 96.5% (2898 of 3001 strings)

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

* Translated using Weblate (Hungarian)

Currently translated at 96.5% (2898 of 3001 strings)

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

* Translated using Weblate (Finnish)

Currently translated at 47.9% (1438 of 3001 strings)

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

* Translated using Weblate (French)

Currently translated at 96.5% (2898 of 3001 strings)

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

* Translated using Weblate (Romanian)

Currently translated at 82.0% (2463 of 3001 strings)

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

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

Currently translated at 96.5% (2897 of 3001 strings)

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

* Translated using Weblate (Azerbaijani)

Currently translated at 0.3% (10 of 3001 strings)

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

* Translated using Weblate (Ukrainian)

Currently translated at 86.3% (2590 of 3001 strings)

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

* Translated using Weblate (Japanese)

Currently translated at 91.1% (2735 of 3001 strings)

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

* Translated using Weblate (Turkish)

Currently translated at 92.8% (2787 of 3001 strings)

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

* Translated using Weblate (Spanish)

Currently translated at 96.5% (2898 of 3001 strings)

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

* Translated using Weblate (Portuguese)

Currently translated at 39.3% (1180 of 3001 strings)

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

* Translated using Weblate (Catalan)

Currently translated at 81.3% (2440 of 3001 strings)

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

* Translated using Weblate (Danish)

Currently translated at 30.8% (927 of 3001 strings)

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

* Translated using Weblate (Hindi)

Currently translated at 10.2% (307 of 3001 strings)

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

* Translated using Weblate (Kurdish)

Currently translated at 36.6% (1101 of 3001 strings)

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

* Translated using Weblate (Latvian)

Currently translated at 80.9% (2428 of 3001 strings)

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

* Translated using Weblate (Malayalam)

Currently translated at 13.7% (412 of 3001 strings)

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

* Translated using Weblate (Norwegian Bokmål)

Currently translated at 7.4% (225 of 3001 strings)

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

* Translated using Weblate (Slovak)

Currently translated at 47.9% (1438 of 3001 strings)

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

* Translated using Weblate (Swedish)

Currently translated at 0.3% (10 of 3001 strings)

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

* Translated using Weblate (Vietnamese)

Currently translated at 81.6% (2450 of 3001 strings)

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

* Update translation files

Updated by "Remove blank strings" hook in Weblate.

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

* Translated using Weblate (German)

Currently translated at 97.9% (2938 of 3001 strings)

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

* Translated using Weblate (Italian)

Currently translated at 99.0% (2971 of 3001 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 99.1% (2975 of 3001 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 99.2% (2651 of 2671 strings)

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

* Translated using Weblate (Italian)

Currently translated at 99.8% (2996 of 3001 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 99.8% (2668 of 2671 strings)

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

* Translated using Weblate (Hungarian)

Currently translated at 100.0% (2671 of 2671 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% (3001 of 3001 strings)

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

* Translated using Weblate (Italian)

Currently translated at 99.9% (2998 of 3001 strings)

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

* Translated using Weblate (Arabic)

Currently translated at 94.4% (2833 of 3001 strings)

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

* Translated using Weblate (Hungarian)

Currently translated at 100.0% (2671 of 2671 strings)

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

* Translated using Weblate (Portuguese (Brazil))

Currently translated at 97.8% (2936 of 3001 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 94.6% (2839 of 3001 strings)

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

* Translated using Weblate (Hungarian)

Currently translated at 100.0% (3001 of 3001 strings)

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

* Translated using Weblate (Portuguese)

Currently translated at 39.4% (1185 of 3001 strings)

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

* Translated using Weblate (French)

Currently translated at 96.4% (2577 of 2671 strings)

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

* Translated using Weblate (Portuguese)

Currently translated at 6.2% (167 of 2671 strings)

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

* Translated using Weblate (French)

Currently translated at 98.5% (2631 of 2671 strings)

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

* Translated using Weblate (French)

Currently translated at 98.6% (2634 of 2671 strings)

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

* Translated using Weblate (Italian)

Currently translated at 99.9% (2670 of 2671 strings)

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

* Translated using Weblate (Hungarian)

Currently translated at 100.0% (2671 of 2671 strings)

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

* Translated using Weblate (Italian)

Currently translated at 99.9% (3003 of 3006 strings)

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

* Translated using Weblate (Hungarian)

Currently translated at 100.0% (3006 of 3006 strings)

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

* Translated using Weblate (French)

Currently translated at 99.2% (2652 of 2671 strings)

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

* Translated using Weblate (German)

Currently translated at 98.0% (2948 of 3006 strings)

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

* Translated using Weblate (Italian)

Currently translated at 99.9% (3005 of 3006 strings)

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

* Translated using Weblate (French)

Currently translated at 99.9% (2670 of 2671 strings)

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

* Translated using Weblate (French)

Currently translated at 96.4% (2899 of 3006 strings)

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

* Translated using Weblate (Portuguese)

Currently translated at 100.0% (3006 of 3006 strings)

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

* Translated using Weblate (Portuguese)

Currently translated at 100.0% (3006 of 3006 strings)

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

* Translated using Weblate (German)

Currently translated at 98.5% (2962 of 3006 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 97.8% (2614 of 2671 strings)

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

* Translated using Weblate (German)

Currently translated at 100.0% (3006 of 3006 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% (2671 of 2671 strings)

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

* Translated using Weblate (German)

Currently translated at 100.0% (3007 of 3007 strings)

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

* Translated using Weblate (Italian)

Currently translated at 99.9% (3006 of 3007 strings)

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

* Translated using Weblate (Hungarian)

Currently translated at 100.0% (3007 of 3007 strings)

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

* Translated using Weblate (Portuguese)

Currently translated at 100.0% (3007 of 3007 strings)

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

* Translated using Weblate (Portuguese (Brazil))

Currently translated at 98.7% (2969 of 3007 strings)

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

* Translated using Weblate (French)

Currently translated at 97.8% (2941 of 3007 strings)

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

* Translated using Weblate (Hungarian)

Currently translated at 100.0% (2671 of 2671 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% (3007 of 3007 strings)

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

* Translated using Weblate (Italian)

Currently translated at 99.9% (3011 of 3012 strings)

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

* Translated using Weblate (French)

Currently translated at 97.7% (2943 of 3012 strings)

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

* Update translation files

Updated by "Cleanup translation files" hook in Weblate.

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

* Translated using Weblate (Italian)

Currently translated at 100.0% (2671 of 2671 strings)

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

* Translated using Weblate (Italian)

Currently translated at 100.0% (3051 of 3051 strings)

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

* Translated using Weblate (Hungarian)

Currently translated at 98.7% (3013 of 3051 strings)

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

* Translated using Weblate (Hungarian)

Currently translated at 100.0% (3051 of 3051 strings)

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

* Translated using Weblate (Portuguese)

Currently translated at 99.1% (3024 of 3051 strings)

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

* Translated using Weblate (French)

Currently translated at 96.7% (2953 of 3051 strings)

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

* Translated using Weblate (German)

Currently translated at 100.0% (3051 of 3051 strings)

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

* Translated using Weblate (French)

Currently translated at 97.6% (2980 of 3051 strings)

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

* Translated using Weblate (Portuguese)

Currently translated at 99.6% (3041 of 3051 strings)

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

* Translated using Weblate (Portuguese)

Currently translated at 100.0% (3051 of 3051 strings)

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

* ios: add localization round-trip script

* ios: list each localization problem once

* translations: import/export ios

* android, ios: check kotlin and removed strings

* translations: fix issues

* translations: fix broken links

* android: apply adjustFormatting to translations

* android: port adjustFormatting rewrite to script

* translations: fix review findings in PR #7944 (#7950)

pt: render "link" as "link" instead of "endereço" (address), so SimpleX
links, 1-time links and the SimpleX address stay distinct; "badge" is
"distintivo" everywhere; fix payment footers (keep, buy), typos, actions
shown as states, contributor, migrate label, ratchet sync, address change.
pt iOS: "passphrase" is "frase-chave".
de: To purchase key, signing alert, % off, TEE, Credential, Balance start.
fr: Balance start, proofs. hu: SimpleX typo, (chat), Balance start,
badge ended, Credential. it: renews on date, Paga, article.
az iOS: restore the "Mark ..." actions, Forward, Keep conversation,
Lock after, bold markup. cs: 1 day, Test relay. tr iOS: delivery
receipts. pt-rBR: marked for deletion. ar: badge shown, host names.

---------

Co-authored-by: thedmdim <thedmdim@users.noreply.hosted.weblate.org>
Co-authored-by: Hosted Weblate user 107176 <zhuk2@users.noreply.hosted.weblate.org>
Co-authored-by: Artem Vorotnikov <vorot93@users.noreply.hosted.weblate.org>
Co-authored-by: Paul <acornacre@users.noreply.hosted.weblate.org>
Co-authored-by: А О <twofish85@users.noreply.hosted.weblate.org>
Co-authored-by: whoami11 <whoami021992@users.noreply.hosted.weblate.org>
Co-authored-by: Skyward Copied <skywardcopied@users.noreply.hosted.weblate.org>
Co-authored-by: Evgeny <esp@users.noreply.hosted.weblate.org>
Co-authored-by: Игорь Линчевский <insrtnqme@users.noreply.hosted.weblate.org>
Co-authored-by: Name Lastname <simplex-edit0r@users.noreply.hosted.weblate.org>
Co-authored-by: Ophiushi <41908476+ishi-sama@users.noreply.github.com>
Co-authored-by: khalidbelk <khalidbelk@users.noreply.hosted.weblate.org>
Co-authored-by: Mqlx <mqlx@users.noreply.hosted.weblate.org>
Co-authored-by: Evgeny Poberezkin <epoberezkin@users.noreply.hosted.weblate.org>
Co-authored-by: J. Lavoie <edanas@users.noreply.hosted.weblate.org>
Co-authored-by: Anonymous <anonymous@users.noreply.hosted.weblate.org>
Co-authored-by: Ranakan <ranak4n@users.noreply.hosted.weblate.org>
Co-authored-by: Karl Rinneberg <hundertwasser@users.noreply.hosted.weblate.org>
Co-authored-by: indiandoc <indiandoc@users.noreply.hosted.weblate.org>
Co-authored-by: J R <jrs@users.noreply.hosted.weblate.org>
Co-authored-by: cedev-1 <121963179+cedev-1@users.noreply.github.com>
Co-authored-by: Deleted User <deleted-6980@users.noreply.hosted.weblate.org>
Co-authored-by: Random <random-r@users.noreply.hosted.weblate.org>
Co-authored-by: sith-on-mars <sith-on-mars@users.noreply.hosted.weblate.org>
Co-authored-by: Float <float@users.noreply.hosted.weblate.org>
Co-authored-by: Deleted User <dnstxqet@users.noreply.hosted.weblate.org>
Co-authored-by: BlacAmDK <blacamdk@users.noreply.hosted.weblate.org>
Co-authored-by: re me <jisizhang001@users.noreply.hosted.weblate.org>
Co-authored-by: Aaron H <chieferino@users.noreply.hosted.weblate.org>
Co-authored-by: Loping151 <loping151@users.noreply.hosted.weblate.org>
Co-authored-by: cllih <cllih@users.noreply.hosted.weblate.org>
Co-authored-by: Zhiyounihao <zhiyouni@users.noreply.hosted.weblate.org>
Co-authored-by: M Sarmad Qadeer <msarmadqadeer@users.noreply.hosted.weblate.org>
Co-authored-by: Albert Bob <vicdorke@users.noreply.hosted.weblate.org>
Co-authored-by: 小连招 <onecombo666@users.noreply.hosted.weblate.org>
Co-authored-by: Yay <yay9hbx5otn5@users.noreply.hosted.weblate.org>
Co-authored-by: Frank Yang <frankyang96@users.noreply.hosted.weblate.org>
Co-authored-by: Citrus <citrus@users.noreply.hosted.weblate.org>
Co-authored-by: Ross Li <ross89223@users.noreply.hosted.weblate.org>
Co-authored-by: No name <certainbot@users.noreply.hosted.weblate.org>
Co-authored-by: Luis Morillo Najarro <lsmor@users.noreply.hosted.weblate.org>
Co-authored-by: Darío Hereñú <kant@users.noreply.hosted.weblate.org>
Co-authored-by: Víctor <vzamanillo@users.noreply.hosted.weblate.org>
Co-authored-by: kudebug <kudebug@users.noreply.hosted.weblate.org>
Co-authored-by: Carlos Perez <charlieper@users.noreply.hosted.weblate.org>
Co-authored-by: Isaac ALejandro Lopez <justanormalguy@users.noreply.hosted.weblate.org>
Co-authored-by: gacarel <gacarel@users.noreply.hosted.weblate.org>
Co-authored-by: John m <jvanmanen@users.noreply.hosted.weblate.org>
Co-authored-by: M1K4 <mika-nl@users.noreply.hosted.weblate.org>
Co-authored-by: a4318 <a4318@users.noreply.hosted.weblate.org>
Co-authored-by: Miyu Sakatsuki <miyu-dev@users.noreply.hosted.weblate.org>
Co-authored-by: ikyhtr <ikyhtr@users.noreply.hosted.weblate.org>
Co-authored-by: 小林照幸 <koba-ninkigumi@users.noreply.hosted.weblate.org>
Co-authored-by: proudmuslim-dev <proudmuslim-dev@users.noreply.hosted.weblate.org>
Co-authored-by: Ikko Eltociear Ashimine <eltociear@gmail.com>
Co-authored-by: Rei <rei_@users.noreply.hosted.weblate.org>
Co-authored-by: yokoba0413 <yokoba0413@users.noreply.hosted.weblate.org>
Co-authored-by: ryokky3 <ryokky3@users.noreply.hosted.weblate.org>
Co-authored-by: koreirozzu <koreirozzu@users.noreply.hosted.weblate.org>
Co-authored-by: daydreamer-json <daydreamer-json@users.noreply.hosted.weblate.org>
Co-authored-by: acevif <acevif@users.noreply.hosted.weblate.org>
Co-authored-by: ActiveTK. <webmaster@activetk.jp>
Co-authored-by: Dima Sivan <dimasivan@users.noreply.hosted.weblate.org>
Co-authored-by: zenobit <zenobit@disroot.org>
Co-authored-by: Mehmed <don43@users.noreply.hosted.weblate.org>
Co-authored-by: mslr8 <hosted.weblate.org.poncho089@passmail.net>
Co-authored-by: Pluto <offplutonium@users.noreply.hosted.weblate.org>
Co-authored-by: idk <ciganzelezo@users.noreply.hosted.weblate.org>
Co-authored-by: Nenad <nenadmirkovic00@gmail.com>
Co-authored-by: Magorak Magorov <magorakmagorov@users.noreply.hosted.weblate.org>
Co-authored-by: Maksym Lukashenko <prototypem995@users.noreply.hosted.weblate.org>
Co-authored-by: Max <prototypem95@users.noreply.hosted.weblate.org>
Co-authored-by: ghost <ghosthamster@users.noreply.hosted.weblate.org>
Co-authored-by: rider of the storm <passat-b6-tdi@users.noreply.hosted.weblate.org>
Co-authored-by: Deleted User <mgorpinic2005@gmail.com>
Co-authored-by: Hotripak <hotr1pak@users.noreply.hosted.weblate.org>
Co-authored-by: Groovy394 <groovy394@users.noreply.hosted.weblate.org>
Co-authored-by: aquaticexpectancy <aquaticexpectancy@users.noreply.hosted.weblate.org>
Co-authored-by: Andrii Sudak <andrii-sudak@users.noreply.hosted.weblate.org>
Co-authored-by: sr sr <sr1919os@users.noreply.hosted.weblate.org>
Co-authored-by: petri <petrik@users.noreply.hosted.weblate.org>
Co-authored-by: Jiri Grönroos <artnay@users.noreply.hosted.weblate.org>
Co-authored-by: jaeone <jaeone22@users.noreply.hosted.weblate.org>
Co-authored-by: B.O.S.S <BxOxSxS@protonmail.com>
Co-authored-by: Jester Hodl <jesterhodl@users.noreply.hosted.weblate.org>
Co-authored-by: Kszyche <hostedweblate001user@users.noreply.hosted.weblate.org>
Co-authored-by: Wiesław Fijołek <percival@users.noreply.hosted.weblate.org>
Co-authored-by: Arturro43 <arturro43@users.noreply.hosted.weblate.org>
Co-authored-by: Omikorin <git@omikor.in>
Co-authored-by: Titapa (PunPun) Chaiyakiturajai <titapapunne@users.noreply.hosted.weblate.org>
Co-authored-by: elgratea <flantito@users.noreply.hosted.weblate.org>
Co-authored-by: 109247019824 <109247019824@users.noreply.hosted.weblate.org>
Co-authored-by: Kaanito <kaanito@users.noreply.hosted.weblate.org>
Co-authored-by: Abdullah Koyuncu <wiseweb-works@users.noreply.hosted.weblate.org>
Co-authored-by: goknarbahceli <goknarbahceli@users.noreply.hosted.weblate.org>
Co-authored-by: Dennis <dennnis@users.noreply.hosted.weblate.org>
Co-authored-by: cervezagua <cervezagua@users.noreply.hosted.weblate.org>
Co-authored-by: Deleted User <deleted-65564@users.noreply.hosted.weblate.org>
Co-authored-by: Egehan KAHRAMAN <vastsea0@users.noreply.hosted.weblate.org>
Co-authored-by: Omer <abulomer@users.noreply.hosted.weblate.org>
Co-authored-by: xe1st <xe1st@users.noreply.hosted.weblate.org>
Co-authored-by: echoloji <echoloji@users.noreply.hosted.weblate.org>
Co-authored-by: U.S. <usnetiz@users.noreply.hosted.weblate.org>
Co-authored-by: summoner001 <summoner@disroot.org>
Co-authored-by: Ghost of Sparta <makesocialfoss32@keemail.me>
Co-authored-by: d4f5409d <d4f5409d@users.noreply.hosted.weblate.org>
Co-authored-by: Mireli5656 <mireli5656@users.noreply.hosted.weblate.org>
Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: mlanp <mlanp@users.noreply.hosted.weblate.org>
Co-authored-by: jonnysemon <jonnysemon@users.noreply.hosted.weblate.org>
Co-authored-by: SanctumSaturn <sanctumsaturn@users.noreply.hosted.weblate.org>
Co-authored-by: Fábio Pereira (Serzedo) <fpereira-84@users.noreply.hosted.weblate.org>
Co-authored-by: Narasimha-sc <166327228+Narasimha-sc@users.noreply.github.com>
2026-10-30 14:18:08 +00:00
fbca2cae81 core, ui: resize images in the core for sharper previews and images (#7941)
* WIP: Haskell impl of resizeImageToStrSize

* WIP: add FFI export wrapper

* WIP: switch ios resizeImageToStrSizeSync to backend

* WIP: fix resizeImageToStrSizeSync

* WIP: add JNI wrappers

* Add non-base64 resize and cWriteImage

* WIP: add chat_write_image

* fix resizeToStr

* fixes

* fix syntax, raise jpeg quality back

* add chatWriteImage

* Fix cfArgs in tests

* Use jpeg-turbo encoder

* add nix pins

* bump jpeg-turbo

* add CI deps

* add encoding funs to android lib

* bump jpeg-turbo for 20.04 fix

* jpeg-turbo fix for 8.10

* android fixes

* Bump jpeg-turbo

* set static flag for jpeg-turbo

* Fix nix for aarch64/android

* Fix android C api

* Fix resize in android

* Bump hs-libjpeg-turbo

* target correct override

* override android lib from android pkgs

* add macos build tweaks

* bump hs-jpeg-turbo for 8.10 fixes

* more build fixes

* make ios compile

* Always use pkgconfig for libjpeg-turbo

* WIP: debug libjpeg in ubuntu pkg-config CI

* Add pkg-config to dockerfiles

* Add libturbojpeg to dockerfiles

* Use -dev version of libturbojpeg in dockerfiles

* Install pkg-config in windows CI

* Disable flag for custom libturbojpeg linking options

Workarounds relocation error on x86_64-linux with gcc:
  /usr/bin/ld: /usr/lib/gcc/x86_64-linux-gnu/13/../../../x86_64-linux-gnu/libturbojpeg.a(turbojpeg.c.o): relocation R_X86_64_TPOFF32 against `errStr' can not be used when making a shared object; recompile with -fPIC
  /usr/bin/ld: failed to set dynamic section sizes: bad value

* WIP: debug libjpeg in windows pkg-config CI

* WIP: debug libjpeg package in windows CI

* core: image resize module and buffer FFI

* ci: link libjpeg-turbo statically on all platforms

* ui: resize images in the core

* core: rename image resize functions to chat_resize_image and chat_resize_image_uri

* ci: restore whitespace in build.yml

* ci: build libjpeg-turbo 3.1.4.1 from a submodule

* core: hs-jpeg-turbo from github.com/simplex-chat

* nodejs: resize images

* python: resize images

* core: hs-jpeg-turbo from gitlab.com, the GitHub import lacks LFS objects

* core: generate /img previews

* ci: link libjpeg-turbo on Windows without pkg-config

* ci: build libjpeg-turbo on Windows with the GHC toolchain

* docs: plan for image resizing in the core

* docs: update image resizing plan

* ios: prevent crash when wallpaper image cannot be resized

* android, desktop: raise an error when an image cannot be resized

* docs: update spec references for image resizing

* docker: build the CLI image from a clone without submodules

* docs: apply review fixes to image resizing plan

* docker: build the CLI from a git worktree with the submodule present

* docs: apply second review to image resizing plan

* docs: point image resizing plan at the rewritten commit

* core: choose image format by transparency in chat_resize_image

* nodejs: resize images to the app sizes

* python: resize images to the app sizes

* nodejs, python: describe the core modules as used for image resizing

* docs: add license notices of the image libraries

* ci: describe the avatar method without attributing it to the apps

* ci, ios, nix: remove the libjpeg-turbo build outside cabal

* python: name resize_image in the core module text

* nodejs, python: describe resizing to the app image sizes

* core: refuse images larger than the supported size

* core: resize to JPEG images with a side above 65500 pixels

* docs: record image resizing decisions for the bundled libjpeg-turbo

* core, docs: build libjpeg-turbo and stb from the fork submodules

* docs: record the fork pins in the image resizing plan

* core: resize images to at most 4320 pixels per side, refuse above 16384

* docs: record the image side limits in the image resizing plan

* core: pin the rebased hs-jpeg-turbo fork

* core: pin the hs-jpeg-turbo fork without package.yaml

* docs: plan scaled JPEG decoding and EXIF orientation of images

* docs: copy the JuicyPixels-stbir licence of the pinned fork

* core: pin the hs-jpeg-turbo fork with scaled JPEG decoding

* core: decode JPEG at the display size, up to 65500 pixels per side

* core: rotate JPEG images by their EXIF orientation

* docs: refer the image plan to the JPEG decoding code

* docs: record the approved image processing decisions

* core: limit JPEG decoding memory to 1024 MB outside iOS and Android

* docs: name JPEG decoding in the libjpeg-turbo notice

* docs: plan image resizing from files and the decisions of 26 Oct

* core: scale images in one Catmull-Rom pass with sharpening

* docs: plan image sizes at a fixed quality

* core: resize images at a fixed quality to fill the size limit

* core: resize images from a file path or a file descriptor

* ios, android, desktop: resize picked images from their files

* core: encode resized images with mozjpeg

* tests: check descriptor closing by the file it refers to

* core: raise JPEG quality only for a full-size image below 97% of the limit

* ci: name the mozjpeg submodule in the Windows cleanup comments

* docs: refer the image plan to the current code

* docs: refer the image plan to the code merged with master

* core: export every image resizing function from each library

* core: close the file descriptor when its handle cannot be created

* docs: count the C sources of mozjpeg with the arithmetic decoder

* core: use the reviewed hs-jpeg-turbo and JuicyPixels-stbir forks

* ci: build the armv7a Android core library on request

* core: round image heights half up in the size search

* ios: describe the file image resizing functions in SimpleX.h

* ci: pick, preview and send images in the Claude app tests

* core: decode PNG images with libspng and refuse other formats

* core: encode PNG with libspng, keeping the smaller filter choice

* ci: pick, preview and send images in the scripted app smoke tests

* flake: build the PNG decoder package in nix builds

* ios: remove the copy of a picked image after sending it

* core: refuse image files larger than the decode memory limit

* core: scale a JPEG image to its largest size once per resize

* core: bisect JPEG quality without a step function

* core: reduce the memory used to sharpen and to decode PNG images

* android, desktop: pass the image format to the core as an integer

* android, desktop: fuse the preview conditions of picked media

* android, desktop, ci: check that the core resized the smoke test images

* python: remove the docstrings of the explicit image resizing functions

* docs: add the second review fixes to the image plan

* ci: tap the iOS attachment button by its accessibility label

* core: keep the colour profiles of resized images

* docs: add the colour profiles to the image plan

* ci: wait up to 30 s for the new group screens in the iOS smoke test

* ci: pick the Android smoke test images from their own photo folders

* ci: tap the iOS photo picker by position, as its tree is not shown

* ci: pick the test card and the logo by their iOS picker positions

* core: update JuicyPixels-stbir with the stb_image_resize licence terms

* core: write a fixed Display P3 profile for Display P3 images only

* core: do not keep the input image in memory for its colour profile

* core: read the JPEG segments once for the orientation and the profile

* core: read an image file into one buffer of its size

* docs: add the third review fixes to the image plan

* core: resize images with Display P3 or no profile, not profile bytes

* ci: check the pixel sizes of the images sent in the iOS smoke test

* core: update hs-jpeg-turbo with PNG chunk limits and encoder fixes

* docs: list Compact ICC Profiles, libspng and miniz in the dependencies

* android, desktop: reword the picked media preview comment

* docs: refer the image plan to the code merged with master

* ci: render the iOS snapshots before the images case

* ci: dismiss the snapshot tests' camera alert before the iOS images case

* core: update hs-jpeg-turbo with tests and the JuicyPixels-spng synopsis

* core: pin hs-jpeg-turbo and JuicyPixels-stbir in simplex-chat repositories

* update ios core library

* core, ui: accept only JPEG and PNG image data

* core: update JuicyPixels-stbir

* docs: plan for the iOS copy of picked images

---------

Co-authored-by: IC Rainbow <aenor.realm@gmail.com>
Co-authored-by: Evgeny Poberezkin <evgeny@poberezkin.com>
Co-authored-by: Alexandre Esteves <alexfmpe@proton.me>
2026-10-30 12:14:51 +00:00
Narasimha-sc 1491d0cff8 android, desktop: fix chat console crash on concurrent writes (#7921)
* android, desktop: fix chat console crash on concurrent writes

Fixes #7755.

* plans: chat console race: decisions and mechanics only
2026-10-30 09:38:18 +00:00
Evgeny @ SimpleX Chat 17c9ad1c61 ios, android, desktop: previews render the same in every snapshot run (#7938)
* ios, android, desktop: previews draw fixed sample data instead of calling the core

* desktop: database error preview passes the keychain setting

* ios: snapshot fixtures use fixed parsed markdown instead of the core

* ios: snapshot fixtures: raw string delimiters past the # in markdown JSON

* desktop: snapshot test sets the app bar height as the app does

* docs: plan to replace preview-only parameters with test measures

* ios, desktop: previews run master's code; badges and version views split

Preview-only parameters are removed. BadgesCheckOrderView, BadgesHowLongView and VersionView are split into a loader and a layout, which their previews draw. Snapshot tests set a fixed QR picture: the environment value fixedQRCode on iOS, LocalFixedQRCode on desktop.

* ios: snapshot fixtures build parsed markdown with initializers

The table held the JSON of the Linux core, which the iOS app does not decode. The values are those the core returns for each text.

* ci: references of fixed QR codes and version; ios: call overlay preview as on master

iOS references from https://github.com/evgeny-simplex/simplex-chat/actions/runs/40944118370, desktop references from https://github.com/evgeny-simplex/simplex-chat/actions/runs/40932566864. ActiveCallOverlay_Previews, its scene and its references are restored as on master.

* ios, desktop: snapshot tests render every preview, no exclusion lists

BadgesChooseBadgeView, ServersSummaryView and TerminalView are split into a loader and a layout. AddChannelView, AddGroupView, GroupProfileView and UserProfileView layouts take the name and description validators, so desktop previews render without the core library. NewChatView's preview opens the Connect tab, UserProfilesView's preview has its own users. AppearanceSettings, MigrateFromDevice and the duplicate UserProfileLayoutEditOn previews are deleted.

* ios, desktop: previews show short links; tests draw the fixed QR code with each app's generator

The snapshot tests draw the fixed QR picture for a short address link with generateImage on iOS and qrCodeBitmap on desktop, in place of committed images. Previews of group links, addresses, a pending connection and QR codes pass short links, as the apps show them. The fixture markdown table equals the output of master's parser.

* ios, desktop: excluded previews and their views as on master

* ci: references of short-link QR codes
2026-10-30 06:41:40 +00:00
Evgeny @ SimpleX Chat 094b1837d8 core, ios: markdown phones, domains, underscores, quotes, rules and delimiters (#7943) 2026-10-29 22:03:06 +00:00
Evgeny @ SimpleX Chat b7bae8c47e core, ui: markdown links in parentheses, keep single line breaks (#7940)
* core: tests of markdown links in parentheses and single line breaks

* core, ui: markdown links in parentheses, keep single line breaks

* core: test of a hyperlink text across lines with the address as a link

* ci: desktop references with **bold** in the markdown help

* ci: iOS references with **bold** in the markdown help
2026-10-29 20:36:16 +00:00
Evgeny @ SimpleX Chat 3bdecd63f8 android, desktop: chat view previews draw member names (#7915)
* android, desktop: chat view previews draw member names and the input bar

* android, desktop: compose view parses no empty draft

* ci: update references of the chat view preview snapshots

* android, desktop: chat view previews without the input bar, which calls the core

* ci: references of the chat view previews without the input bar

* ci: desktop references with member names in the group chat preview
2026-10-29 16:31:34 +00:00
Evgeny @ SimpleX ChatandEvgeny Poberezkin 1217fbea42 ui: even insets, line heights and time placement in classic bubbles (#7896)
* plan: UI improvements to improve LLM usage via SimpleX

* core, ui: types for chat layout

* core, ui: settings for alternative terminal-like chat layout for managing LLMs or other service bots

* plan: message priority

* fixes

* query plan

* update plans

* remove silent messages plan

* rename migrations

* implement layout

* amend

* fix

* fix

* fix

* improve

* time on the right, sender name in blue

* no avatar in direct chats

* better previews

* update, fixes

* update

* time gap

* changes

* ui: terminal layout line heights, gaps and time placement

* ui: simplify terminal meta layout, correct its docs and tests

* ui: right-to-left emoji edge in terminal rows, time placement tests

* android, desktop: raise Kotlin compiler memory to 4 GB

* ui: terminal captions as follow-up text, classic event separators

* ui: terminal media edge and overlay time, plan decisions

* ui: simplify terminal row separation, correct doc line references

* ui: keep the media time inside terminal rows, restore caption conditions

* ui: terminal heading capitals at large font scales, idle live message time

* ui: rename the classic voice-with-text flag, correct the meta copy docs

* ui: smaller terminal layout diff, sender gap and meta names

* ui: terminal row as tall as the media time

* docs: remove the chat layout section from the bots readme

* docs: shorten the terminal layout section of the chat view

* core: address settings API as on master, /auto_accept reads the stored layout

* ui: smaller terminal headings

* ui: classic sender rows and avatar rule as on master

* ui: classic reply quote text colour as on master

* ios: keep the chat layout setting with other UI settings

* ui: go-to button at the end of terminal rows, no gutter in direct chats

* ui: forwarded arrow on the header line of terminal rows, above the time

* ui: forwarded arrow centred above the time line of terminal rows

* ui: even insets, line heights and exact time space in classic bubbles

* ui: draw the time once in classic decryption errors

* tests: two-line text in the bubble inset test

* ui: exact time space in classic group invitations

* docs: classic bubbles plan: results and open questions

* ui: the time alone moves to the next line in classic bubbles

* ui: file icon on the size-line baseline in classic bubbles

* ui: calls in classic chats as on master

* ui: headings at 1.5625, 1.25 and 1 of the body size in both chat layouts

* ui: 11sp text inset and 14dp sides in classic bubbles

* ui: tail space in classic deleted and error items

* ui: events in classic chats grouped in runs

* ui: group sender name at the bubble edge in classic chats

* docs: classic bubbles plan: results of the 2026-10-26 decisions

* ui: events classified by the sender rule, one file icon size

* tests: no invisible character in the bubble copy test

* docs: classic bubbles plan: the shared sender rule

* docs: product concepts: the renamed meta copy

* ui: inline the copy of the time in decryption errors

* docs: chat view spec: line links after the classic bubbles changes

* ui: group invitation time on the last baseline, joined to the last word

* docs: classic bubbles: tail and time of a message above an event run

* ui: time on the last line of wrapped deleted and error texts

* ui: one layout switch in deleted and error items

* ui: one layout switch in message text padding

* ui: one name for the chat typography flag

* ui: one check whether a chat item tail is drawn

* ui: event run gaps in the chat list, row separation as on master

* ui: chat item previews draw bubbles as the chat does

* docs: classic bubbles: item cards, tail check, previews

* ui: deleted and error items without tails, insets fixed at large fonts

* ui, ci: references of classic bubbles, chat view previews in bubbles

* ci: desktop references of classic bubbles with message text at 95%

* ui: time on the drawn text baseline in desktop bubbles

* ci: desktop references with the time on the drawn text baseline

---------

Co-authored-by: Evgeny Poberezkin <evgeny@poberezkin.com>
2026-10-29 14:35:23 +00:00
Evgeny @ SimpleX ChatandEvgeny Poberezkin c3c733e0d4 ios, ui, ci: terminal chat layout in the iOS app (#7898)
* plan: UI improvements to improve LLM usage via SimpleX

* core, ui: types for chat layout

* core, ui: settings for alternative terminal-like chat layout for managing LLMs or other service bots

* plan: message priority

* fixes

* query plan

* update plans

* remove silent messages plan

* rename migrations

* implement layout

* amend

* fix

* fix

* fix

* improve

* time on the right, sender name in blue

* no avatar in direct chats

* better previews

* update, fixes

* update

* time gap

* changes

* ui: terminal layout line heights, gaps and time placement

* ui: simplify terminal meta layout, correct its docs and tests

* ui: right-to-left emoji edge in terminal rows, time placement tests

* android, desktop: raise Kotlin compiler memory to 4 GB

* ui: terminal captions as follow-up text, classic event separators

* ui: terminal media edge and overlay time, plan decisions

* ui: simplify terminal row separation, correct doc line references

* ui: keep the media time inside terminal rows, restore caption conditions

* ui: terminal heading capitals at large font scales, idle live message time

* ui: rename the classic voice-with-text flag, correct the meta copy docs

* ui: smaller terminal layout diff, sender gap and meta names

* ui: terminal row as tall as the media time

* docs: remove the chat layout section from the bots readme

* docs: shorten the terminal layout section of the chat view

* core: address settings API as on master, /auto_accept reads the stored layout

* ui: smaller terminal headings

* ui: classic sender rows and avatar rule as on master

* ui: classic reply quote text colour as on master

* ios: keep the chat layout setting with other UI settings

* ui: go-to button at the end of terminal rows, no gutter in direct chats

* ui: forwarded arrow on the header line of terminal rows, above the time

* ui: forwarded arrow centred above the time line of terminal rows

* ios: terminal chat layout, chosen per app, profile and chat

* ios: event time reserve of three spaces, app layout picker as Kotlin

* ios: spec and plan of the terminal chat layout

* ios: classic message text at 87% in dark themes, as terminal rows

* ios: terminal gaps scaled by the body size, 17/16 of Kotlin values

* ios: terminal quote sender at 13.5pt, thumbnail at the item end

* ios: product docs of the terminal layout, plans updated for iOS

* ios: chat scenes rendered to PNG by a unit test in the simulator CI

* ios: snapshots rendered by the smoke test script, workflow unchanged

* ios: terminal names at 13.5 x 17/16 pt, as the gaps

* ios: Markdown views at the 87% message colour in dark themes

* ios: terminal quote thumbnail 12pt after the quote text or the bar

* ios: terminal rule-only message widened by a wider quote or header

* ios: member avatars scaled with the text size, as in the chat list

* ios: snapshot rows at their own height, as list cells, so text wraps

* ios: member avatars back at 34pt, for the snapshot before scaling

* ios: member avatars scaled with the text size, as in the chat list

* ui: terminal quote thumbnail 12dp after the quote text or the bar

* ios: classic group bubble width follows the scaled member avatar

* ci: ios-sim README describes the snapshots rendered after the smoke test

* ios: scratch, padding variants for the I7 and I8 renders, to revert

* ios: revert the scratch padding variants after their renders

* ui: contrast of the voice message button in terminal rows

* ios: scratch, spacing variants and list margins to render, to revert

* ios: revert the scratch spacing variants after their renders

* ios: snapshots at a fixed date, in UTC and the en_US locale

* ios: snapshots drawn as 8-bit sRGB without alpha

* ci: compare iOS snapshots with the references in the repository

* ci: record and check iOS snapshot references on GitHub's runner

* ios: scratch, list margins on the remaining screens, to revert

* ios: revert the scratch list margins after their measurement

* ci: snapshot scripts executable, as the other CI scripts

* ios: scratch, voice circle variants in light themes, to revert

* ios: revert the scratch voice circle variants

* ios: one 12pt padding at the edges and after avatars in terminal rows

* ios: classic group sender name on the bubble edge

* ui: one 12dp padding at the edges and after avatars in terminal rows

* ios: one heading scale in both chat layouts

* ios: snapshot references of the chat scenes

* docs: leave the headings and classic lines of the plan to ep/classic-bubbles

* ios: declare terminal layout functions inside types

* ios: keep layout constants at file scope

* ios: keep file-scope functions, move only extension members into types

* ios: snapshot tests record row heights at first layout and the appearance layout switch

* ios: appearance preview follows the chat layout setting at once

* ios: snapshot test measures first-layout rows by SwiftUI and by cells

* ios: chat rows measured at the chat width when they first appear

* ios: snapshot test checks that chat rows keep their first height after a reload

* ios, ci: references of terminal and classic chat scenes, dark message text

* ios: message text at 95% in dark themes

* ios, ci: references with message text at 95% in dark themes

* ios: media in terminal rows end at the time's right inset

* ios, ci: references with terminal media at the time's right inset

---------

Co-authored-by: Evgeny Poberezkin <evgeny@poberezkin.com>
2026-10-29 12:45:34 +00:00
Evgeny @ SimpleX Chat bcb1afba40 ci: desktop snapshots render animations at their end (#7916)
* ci: desktop snapshots render animations at their end

* ci: re-record the desktop snapshots of the loading link preview
2026-10-29 09:55:40 +00:00
Evgeny @ SimpleX Chat 501eec671d ios: chat rows measured at the chat width when they first appear (#7931)
* ios: chat rows measured at the chat width when they first appear

* ios, ci: chat view references with rows at their measured height
2026-10-29 09:43:24 +00:00
Evgeny @ SimpleX Chat 563fe17f93 ios, ci: badge references with the fixed prices of the previews (#7930) 2026-10-29 09:42:58 +00:00
Evgeny @ SimpleX Chat 3be145105a android, desktop: message text at 95% in dark themes (#7929)
* android, desktop: message text at 95% in dark themes

* ci: desktop references with message text at 95% in dark themes
2026-10-29 09:42:50 +00:00
Evgeny @ SimpleX Chat c7a6c65960 ios: badge previews show fixed prices (#7917)
* ios: badge previews show fixed prices

* ci: references of badge previews with prices and of channel members

* ios: badge price list computes annual savings from the amounts

* ios: badge previews pass what is for sale and earlier subscriptions with the prices
2026-10-28 17:46:46 +00:00
Narasimha-sc 26c6b3172b desktop: start when JNA cannot load, turn off the macOS theme detector log (#7919)
* desktop: do not fail startup when the system theme detector cannot load JNA

The detector was created in top-level vals of Resources.desktop.kt and
Theme.desktop.kt. When JNA's native library cannot be mapped (for example a
noexec JNA temp directory), the LinkageError ended the app before any window
opened. The detector is now one shared value that is null in that case, and the
theme falls back to light.

* desktop: turn off the macOS theme detector's log

When macOS leaves the AppleInterfaceStyle default unset (light mode), the
library's isDark() throws a NullPointerException inside the library, logs it as
an error with a stack trace and returns false. slf4j-simple can only set a level
per logger, so the whole com.jthemedetecor.MacOSThemeDetector logger is turned
off.
2026-10-28 17:36:32 +00:00
spaced4ndyandspacedandy-agents-simplex 9696a71b91 core, badge-service: renew supporter badges from App Store and Google Play subscriptions (#7716)
* core, badge-service: name Apple claims by reference

Rename appleTransactionId to appleTransactionRef, matching googlePurchaseRef
and StoreTransactionRef. No behaviour change: the next change makes it
return a subscription's original transaction id, which the old name would
misstate.

Run: 001-badge-subscriptions, slice 1

* core, badge-service: store subscription charges and carry the subscription state

Add the service migration 20261012_badge_subscriptions: the subscription
charges table, the ledger's charge_id, and the payment's subscription state,
check time and Play token, replacing three subscription columns nothing
wrote. The ledger now stores and reads back charge credits, and the badge
credential response gains an optional subscription state that older clients
ignore and that reads an unknown state without failing. Nothing writes a
charge or a state yet, so no behaviour changes.

Run: 001-badge-subscriptions, slice 2

* core, badge-service: plan subscription charges and claim Apple subscriptions by original id

Add chargeEntries, the one planner for a store charge's ledger rows: a
lapse to the billing period start, the grant dated to that start, and a
lapse to now, so coverage follows the store's periods and every row
verifies by re-running it at its createdAt. A test runs its rows through
the client's own balanceChecked for first charges, monthly and annual
renewals, billing-retry recovery and grace.

An Apple auto-renewable transaction is now claimed by its original
transaction id, which every renewal keeps, so renewals resolve to one
purchase. One function names the ref for both the claim and the real
verifier, so they cannot disagree.

Run: 001-badge-subscriptions, slice 3a

* badge-service: credit a store subscription purchase

The catalog now tells subscription products from one-time ones and maps a
store plan to its tier and months. A subscription receipt is checked with
the store once: with a grantable charge, the service plans the charge's
rows from the store's period start, signs the first month, and writes the
payment, purchase, charge, ledger rows, issuance, state and Play token in
one transaction, answering with the subscription state. Without one, it
answers payment_pending (300 s while the period has not started or the
store is pending, a day otherwise), receipt_invalid for an ended Play
subscription, or test_purchase, and writes nothing. Replays carry the
state. The store verifier interface gains the subscription check, which no
real store implements yet; the fake store does.

Run: 001-badge-subscriptions, slice 3b

* badge-service: renew a subscription once its paid coverage ends

While a subscription purchase's coverage runs, issueBadge is unchanged
and makes no store call. Once it has ended, the service asks the store at
most once an hour per subscription, stamping every attempt, and answers
from the stored state in between; a failed check is retried after the
whole interval. A grantable charge is planned from the tip at the store's
period start, signed, and written with its issuance and state in one
transaction that re-reads the tip, answering internal if it moved. Any
other charge and the state are recorded without a ledger row. Every answer
for a subscription purchase carries its state.

Run: 001-badge-subscriptions, slice 4

* core: keep a subscription badge until the service says it ended

A purchase is a subscription exactly when its ledger replica holds a
charge credit, so the kind is derived with no column or migration. A
subscription is still asked about at zero months, at the shared weekly
moment, and keeps its badge past paidThrough until an answer says the
subscription ended, so a renewed month is presented at the old
credential's expiry with no gap, and a charge the store recovers later
still re-activates it. While it waits, the client records no failure and
raises no support-ended alert; "issued no credential" now fires only while
the ledger still owes a month. Prepaid purchases are unchanged.

Run: 001-badge-subscriptions, slice 5

* badge-service: check Apple subscriptions with the App Store Server API

With an in-app purchase key configured in [apple], the service reads a
subscription's status by its original transaction id from Get All
Subscription Statuses, authenticated by an ES256 token reused until near
expiry. Each signed transaction and renewal info is verified against the
pinned Apple root through the same chain check as one-time purchases, now a
separate function, and a body that fails it is a verifier failure, never a
refusal. Statuses map to renewing, cancelled, billing retry and ended;
family-shared transactions are refused; 401 and 403 are this service's
failure, other errors and timeouts unreachable. A verifier failure thrown
by a store check is answered internal, and a test subscription is refused
in one place for first purchases and renewals. Without the key, Apple
one-time purchases verify as before and subscriptions are not configured.

Run: 001-badge-subscriptions, slice 6

* badge-service: check and acknowledge Google Play subscriptions

The Play subscription check reads purchases.subscriptionsv2 by token
through the existing service-account client, with the same HTTP classes as
product reads, and maps Play's state, base plan, period, order id and
offer phase; the period start is its end minus the plan's length, and a
pending subscription stays pending. A subscription is acknowledged with
purchases.subscriptions.acknowledge before it is credited, skipped when
Play reports it acknowledged, so it never reaches the one-time endpoint.
Each store's subscriptions answer provider_not_configured when that store
is not configured. A charge on a plan the catalog does not sell is pending
rather than a malformed period.

Run: 001-badge-subscriptions, slice 7

* review: round 1 fixes

R1-1: test an App Store subscription renewal through issueBadge, including
a charge recorded before its period starts and granted later under the
same charge id.
R1-2: make the ledger's charge_id index unique, so the schema itself grants
each store charge at most once.
R1-3: pin that a charge on a plan the catalog does not sell, with an empty
period, is pending at purchase and recorded at renewal, never internal.

Run: 001-badge-subscriptions, review round 1

* core: update query plans

getBadgePurchase derives the purchase kind from the ledger replica, and a
subscription test makes a held store receipt due.

Run: 001-badge-subscriptions, final verification

* fixes

* core: move SubscriptionState to Badges.Types (structural)

BadgeState, which lives in Badges.Types, is about to carry a subscription's
state, and Badges.Service imports Badges.Types. Service re-exports it, as it
does BadgeServiceErrorCode. No behaviour change.

Run: 003-badge-subscriptions-ui, slice 1

* core: keep a store subscription's state on the client

The screens and alerts need to know whether a subscription renews, was
cancelled, waits for a charge, or ended, and the client dropped every state
the service sent but ended. It is now stored on the purchase: from the
answer to the first credit, and from a renewal answer only when the
asserted tip's coverage had ended, since while coverage runs the service
repeats what it read at the last renewal (a year old for an annual plan).

BadgeState gains `subscription` (the plan's months, from the latest charge
credit, and the state), and fills renewsAt/willRenew from it. A changed
state is announced with CEvtBadgeChanged. The column goes into the
unreleased M20260925 migration.

Run: 003-badge-subscriptions-ui, slice 2

* core: record the device store's view of a subscription

The service reads the store only once a subscription's paid coverage has
ended, so it never sees a cancellation while the period runs. The apps read
the device's store (StoreKit's renewal state, Play's isAutoRenewing) and
report it with /_badge subscription <state> <payment>, which records it on
the credited subscription purchase the payment resolves to and announces the
change to its owner.

A renewing report does not replace billingRetry or ended: Play lists a
subscription in its grace period with auto-renew on, and the service's next
answer clears billing retry once the charge lands.

Run: 003-badge-subscriptions-ui, slice 3

* core: claim a store-listed transaction only on the device that bought it

A store account's purchases are listed on every device signed into it:
Play's purchase query lists active subscriptions for their whole life, and
Apple's Transaction.updates delivers auto-renewables made on other devices.
A hand-over with no record and an unknown echoed invoice made a new record
under the presenting profile, so another device could claim a buyer's
subscription for its own active profile, or repeat a refused request every
30 days after cleanup.

/_badge purchase now takes a `listed` mark, which the apps' sweeps and
purchase listeners send: it joins only a record this core already has for
the transaction or its echoed invoice, and otherwise records and sends
nothing (CRStoreReceiptNotRecorded). The purchase call and Restore hand over
unmarked, as before.

Run: 003-badge-subscriptions-ui, slice 4

* core: let a held App Store subscription adopt its later transactions

A held Apple subscription record is keyed by its original transaction id,
so every renewal resolves to it. It kept the payment's back-off when a new
transaction arrived, and adopted any payment handed over, including a
revoked renewal, which the service refuses as receipt_invalid and so would
refuse the whole subscription.

A held Apple record now adopts a JWS only for another transaction with a
later purchaseDate and no revocationDate, read from the unverified payload,
and is then due at once with its retry delay and credit error cleared. A
re-delivered or re-signed copy changes nothing. A failed attempt writes its
back-off only if the record still holds the payment it sent.

Run: 003-badge-subscriptions-ui, slice 5

* core: refuse a badge code or invoice while a store receipt is pending

A code redeemed while a store receipt is held put the code's badge on the
profile, and the held receipt then waited behind it; for a subscription the
store kept charging every period meanwhile. Code redemption and invoice
creation now answer "store purchase open" while the profile holds an App
Store subscription receipt, or another receipt whose last failure can clear
on its own. A receipt that failed for good does not block, except an Apple
subscription, which Apple keeps charging; an uncredited Play subscription is
refunded by Play.

Run: 003-badge-subscriptions-ui, slice 6

* core: alert a subscriber that a payment failed, a renewal nears, or it was cancelled or ended

A subscription's alerts were the prepaid ones: a retired subscription said
"support ended", and nothing told the user a payment failed, an annual
renewal was near, or a cancelled subscription still runs. The derived alert
for a subscription is now, in order: subscription_ended once retired,
payment_issue while the store retries, issue_failed as before,
subscription_cancelled before paidThrough, and renewal_approaching from
three days before an annual plan renews, with a wake at that moment. Monthly
plans get no reminder, as there is no opt-out yet.

The unreleased migration's down step clears an acked subscription_cancelled,
which an older core cannot read.

Run: 003-badge-subscriptions-ui, slice 7

* badge-service: let the dev mock vouch for store subscriptions

With [dev] accept_unverified_store_receipts on, every subscription was
answered provider_not_configured, so the apps' subscription screens could
not be tried against a dev service. The mock now credits an App Store
subscription for the plan its product names, and a Play subscription for
the base plan a test token test.<basePlanId>.<uuid> names, or else its
product's monthly plan, from a minute ago; it remembers the plan in memory
and grants each renewal a new charge, answering a subscription it does not
know (after a restart) as ended.

The subscription check is given the product the presented receipt names,
which only the mock reads; it reads the service's badge clock at check time.

Run: 003-badge-subscriptions-ui, slice 8

* ios: hand App Store subscriptions to the core and report their renewal state

A subscription transaction was finished uncredited, so a buyer would pay and
get nothing. Every badge product now goes through a core invoice and is
handed over, and finished only once the core answers it credited or refused.
Transactions the store lists (the launch sweep, Transaction.updates) are
handed over as listed, so another device's purchase is not claimed here;
Restore purchases syncs with the App Store and claims them for this profile.
A revoked renewal is finished without hand-over, as the service would refuse
it and so the whole subscription.

The app reports StoreKit's renewal state to the core at each sweep, after the
manage-subscriptions sheet and after a restore. Monthly and annual are offered
only to an Apple ID with no earlier subscription in the group, which Apple
would fold a new one into.

Run: 003-badge-subscriptions-ui, slice 9

* ios: sell badge subscriptions and show their state on Your badge

Monthly and annual subscriptions are offered on How long and Check your
order, with the App Store's subscription disclosure, Terms of use and
Privacy policy links, and Restore purchases. Your badge shows a
subscription's state - Renews {date} · {price}, Ends {date}, Payment
problem, Renewing or Ended - with why another badge cannot be bought or
redeemed while it waits for its charge, Manage subscription and Restore
purchases. The chat list shows one banner for the current badge alert of
any kind: renewal soon, payment problem, cancelled, ended, as well as the
expired and renewal-failed ones it had.

Run: 003-badge-subscriptions-ui, slice 10

* android: hand Play subscriptions to the core and report their renewal state

The Kotlin port of the iOS store change. A Play subscription was
acknowledged uncredited; every badge product now goes through a core
invoice and is handed over. The sweep queries subscriptions as well as
one-time products, and the sweep and purchases listener hand over as listed,
so another device on the Google account does not claim them; Restore claims
them for this profile. A subscription is bought on its base plan's own
offer, and the app never acknowledges one itself: the service does when it
credits it, so Play still refunds one the service never credits.

The app reports Play's isAutoRenewing to the core as renewing or cancelled.

Run: 003-badge-subscriptions-ui, slice 11

* android, desktop: sell badge subscriptions and show their state on Your badge

The Kotlin port of the iOS screens. How long and Check your order offer
monthly and annual with Google Play's subscription disclosure, the privacy
policy link and Restore purchases. Your badge shows the subscription's state
with the same texts as iOS, the store named Google Play with a store lane and
"the store" without one, and Manage subscription and Restore purchases only
with a store lane on the local host. The chat list shows one banner for the
current badge alert of any kind. Desktop shows the state, footers and banners
without store rows or a price.

Run: 003-badge-subscriptions-ui, slice 12

* docs: describe the one badge alert banner in the apps' chat-list specs

Both chat-list specs described two hand-written badge banners (expired,
renewal failed); the chat list now has one banner for the current badge
alert of any kind. Also moves the line links this run shifted.

Run: 003-badge-subscriptions-ui, slice 13

* review: round 1 fixes

ios: stop selling a subscription once this device has seen one, so a
second profile is not charged for a subscription Apple folds into the
first (R1-12). Continue pins the chosen period on both apps (R1-13).
Only a device with a subscription asks its store for products and status
when reporting, and the purchases are marked checked before the report
(R1-14, R1-5: Kotlin now loads the products, so the price shows after a
restart). Restore says "Nothing to restore" after a cancelled purchase
(R1-7). Android keeps sweeping one-time purchases when the subscriptions
query fails (R1-6). The freshness comment in requestBadgeIssue states the
service's one-hour repeat of its last check (R1-1).

Run: 003-badge-subscriptions-ui, review round 1

* badge-service: answer a long-expired Play subscription as ended, and hash Play order ids

Play answers HTTP 410 for a subscription that expired too long ago to be
queried; it was read as unreachable, so the service never answered ended,
the badge was never retired and the profile stayed blocked from buying or
redeeming (R1-2). Play order ids appear on the buyer's receipt email, so
charges now store a hash of the order id, as purchase tokens already are
(R1-10).

Run: 004-badge-subscriptions-review, review round 1

* review: run 003 round 2 and run 004 round 1 app fixes

ios: buy a subscription only while it is still for sale, after re-reading
the Apple ID's transactions, and disable Pay once it is not, so a Check
your order screen opened before another profile or device subscribed
cannot buy one Apple folds into the earlier subscription (run 003 R2-1,
run 004 R1-4). android: skip the subscriptions query only on a device
whose Play does not support subscriptions, so Restore no longer says
"Nothing to restore" when the query failed (run 003 R2-2).

Run: 003-badge-subscriptions-ui round 2; 004-badge-subscriptions-review round 1

* review: round 3 fixes

ios: a subscription refused because this Apple ID subscribed before has
its own error, and Check your order says why Pay is disabled (R3-2).
android: skip the subscriptions query only when Play does not support
subscriptions, so a disconnected client fails the sweep or Restore
rather than reading as no subscriptions (R3-1).

Run: 003-badge-subscriptions-ui, review round 3

* core: update query plans

Regenerated by the full suite for the purchase, subscription status and adoption queries. Run: 003-badge-subscriptions-ui, final step

* badge-service: say what hashing the Play order id protects

The hash is unkeyed, so a holder of the buyer's receipt can still find the row (R2-1). Run: 004-badge-subscriptions-review, review round 2

* badge-service: name the rule for when a subscription is due a store check

The issue path's purchase read becomes getIssuePurchase and its "ask the
store now" test becomes subscriptionCheckDue, so the request router can
read the same rows by the same rule. No behaviour change.

Run: 005-subscriptions-load-timing, slice 1

* badge-service: answer every request that may ask a store on the store lane

App Store subscription purchases and subscription renewal checks called
their store from the main lane, so one slow or repeated store call held up
code redemptions and every other renewal. The router now reads the
purchase the way the issue path does and sends to the store lane every
request that may ask a store: Play purchases, App Store auto-renewable
purchases, and issue requests for a subscription due its store check,
judged a minute ahead so the handler never finds one due on the main lane.

Run: 005-subscriptions-load-timing, slice 2

* core: send no badge request before the wake a request that issued nothing set

While a subscription waited for its store charge, or a prepaid renewal
kept failing, every launch, foreground, profile switch and badge-state
read sent the issue request again, so the badge service saw the user's
app-open times for weeks. A due request now waits for the wake the last
pass stored, as long as that wake is no more than a stall interval away,
so it is asked again a day later as the renewal design says.

Run: 005-subscriptions-load-timing, slice 3

* fixup! core: send no badge request before the wake a request that issued nothing set

* fixup! badge-service: answer every request that may ask a store on the store lane

* badge-service: ask the App Store about a subscription purchase at most once an hour per claim

Anyone holding a real but uncreditable App Store subscription JWS, such as
their own lapsed subscription, could present it again and again, each time
spending an App Store Server API call from the quota every subscriber's
renewal check needs. The purchase path now remembers, in memory, which
subscription claims it asked about within the hour and answers a repeat
payment_pending with the time left. Keys are original transaction ids from
JWS that verified offline, entries expire after the hour, and a full table
asks rather than refuses, so memory stays bounded and no buyer waits on
another's claim.

Run: 005-subscriptions-load-timing, slice 4

* fixup! badge-service: ask the App Store about a subscription purchase at most once an hour per claim

* review: round 1 fixes

badge-service: a Play charge whose clipped period start leaves its month
already spent is answered as period over, not internal (R1-A1).
docs: the per-store answer classes list Play's 410 and the App Store
subscription check (R1-A2).
tests: a held receipt with no attempt yet blocks an invoice (R1-B2); a
renewing report keeps an ended status (R1-B3); a test comment names
[google] (run 005 C2-R2-1).
ios: a subscription refused because this Apple ID subscribed before
shows its sentence, not the error's name (R1-C2); ios, android, desktop:
the Check your order footnotes share one helper (R1-C3).

Run: 006-subscriptions-branch-review, review round 1

* fixup! review: round 1 fixes

* core: wait a day after a badge request that issued nothing, whatever the service or a snooze says

The hold on the stored wake let two moments the client does not schedule end it early. A renewal whose store check failed was answered with an hour's retryAfter, so the next activation after each hour sent it again, sampling when the app is opened. A snooze set before a request ended its wait at the snooze's end, timing the next request by the user's tap. Now a request that issued nothing waits the stall or a ledger moment: retryAfter only marks the failure transient, and a snooze is not a wake while a request waits; the request's own wake raises the alert again.

Run: 005-subscriptions-load-timing, slice 5

* fixup! review: round 1 fixes

* fixup! core: wait a day after a badge request that issued nothing, whatever the service or a snooze says

* badge-service: ask Play about a subscription purchase at most once an hour per token

The purchase path's hourly bound covered only App Store claims, so a re-presented Play subscription token, uncredited or credited to another key, spent a subscriptionsv2.get call each time, from the quota bucket Play renewal checks use. The bound now lives in purchaseSubscription, which both stores' purchase paths call, with one map per store: Play's keyed by the token's hash, so made-up Play tokens cannot fill the App Store's. Distinct made-up tokens are still one call each.

Run: 005-subscriptions-load-timing, slice 6

* badge-service: read Play's paused subscription as waiting to renew

An unmapped SUBSCRIPTION_STATE_PAUSED was answered internal, so a paused subscriber's renewal failed for the whole pause. Play reports a pause with auto-renewal on and charges again when it ends, so it now maps as an active subscription does: renewing, or cancelled with auto-renewal off. Pause is being turned off on the base plan; this is defence in depth. A pause grants nothing: Play names no new order, and the last one is already granted.

Run: 005-subscriptions-load-timing, slice 9

* core: retire a subscription badge once no store could still charge it, whatever the service answers

A subscription badge retired only on an ended answer, so a service that never sent one (a final error such as unknown_purchase_key, a rollback, a service that never answers) left the badge shown, one request a day forever, and the profile unable to redeem, buy or have a held receipt credited. Now it also retires once paidThrough is older than the longest store recovery window: Apple retries a failed renewal for up to 60 days, the longest with Play's pause off, plus a week. paidThrough counts every month the ledger holds, so banked months are never retired by it.

Run: 005-subscriptions-load-timing, slice 8

* ios, android: no Restore purchases on Your badge, where a restored purchase could not be credited

Your badge shows only while a badge is shown, so a purchase Restore found there with no record on this device was held under a profile whose held receipts are not processed while it shows a badge: not credited, nothing said, and on Android acknowledged, ending Play's three-day refund. Restore stays on Check your order, the one screen where a restored purchase can be processed.

Run: 005-subscriptions-load-timing, slice 7

* review: round 4 fixes

R4-1: a subscription badge is asked about first and retired only after the service answers, judged on the ledger after that answer. Retiring before asking used the client's paidThrough, which moves only when the client asks, so a subscriber who had not opened the app for longer than the recovery window while the store kept charging lost the badge at the next launch and was never asked again. A request that is not answered retires nothing. Tests: testSubscriptionRetiredAfterRecoveryWindow changed, testIdleSubscriptionKeptPastWindow and testSubscriptionNotRetiredWithoutAnswer added.
R4-2: one snooze comment where two contradicted each other.
R4-3: the recovery window's comment names Play's clipped period start.
R4-4: the retirement tests use subscriptionRecoveryWindow.

* badge-service: name the lane each request waits on

The router answered "may this request ask a store" as a Bool; renewal checks are to get a lane of their own, which a Bool cannot say. requestLane now names the lane: main, purchase or renewal. Both store lanes still share one queue, so no request changes lane.

Run: 007-subscriptions-retirement-lane, slice 1

* badge-service: check renewals on a lane no purchase waits on

Renewal checks shared the store lane with every purchase, so made-up Play tokens, which anyone can send, and the weekly burst of genuine purchases delayed them. Renewal checks now wait on a lane of their own, which only a request signed by the purchase key it names, and due its hourly store check, can reach.

Run: 007-subscriptions-retirement-lane, slice 2

* badge-service: name the web limiter's fixed-window step

takeToken counted a request against a minute's limit inline. The step becomes takeFrom, a pure function, so the purchase path's Play read allowance can use the same rule. No behaviour change.

Run: 007-subscriptions-retirement-lane, slice 3a

* badge-service: read Play's subscriptions at most 300 times a minute for purchases

A Play subscription purchase is asked about without any offline check, so any token in the accepted grammar spends a read from the Subscriptions quota renewal checks share. The purchase path now takes one of a minute's 300 reads for each Play subscription it asks about, a tenth of Play's default quota; with none left, the claim is answered rate_limited with the seconds left in the minute and is not held, as Play was not asked. A claim already held takes no read, and App Store claims, verified offline first, take none.

Run: 007-subscriptions-retirement-lane, slice 3

* core: count the subscription retirement window from the first answer that renewed nothing

The window was counted from the client's paidThrough, which moves only when the client asks, so after months away the first answer that granted nothing for any reason, a transient error, Play's clipped last days or a billing retry, retired a subscriber whose store may still have been charging. The purchase now stores its unrenewed run: the first answered request after which the ledger covered nothing, and the latest one. The badge retires once the window has passed since the run started, still only after an answer; a renewal ends the run, and an answer that comes a window or more after the latest one starts a new run, since an absence or an outage that long may hide a renewal. The window stays 67 days, written as Apple's 60-day billing retry plus the week contacts give an expired credential.

Run: 007-subscriptions-retirement-lane, slice 4

* review: round 1 fixes

R1-A1: the docs and the PlayReads comment said the purchase path reads Play's subscriptions at most 300 times a minute; it asks about at most 300 subscriptions, and a credited one is read once more to acknowledge it, so made-up tokens can spend at most a tenth of the quota renewal checks share.
R1-A2: a comment on RequestLane repeated the one above the queues.
R1-B1: a test that a held pass, which sends no request, leaves the unrenewed run unchanged.
R1-B2: the outage test's last wait for the run is 30 s instead of 5 s.

Run: 007-subscriptions-retirement-lane, review round 1

* core: add the badge subscription columns in their own migration

M20261016_badge_store_receipts shipped to master in #7587, so it must
stay as released. Restore it in both dialects and move the
subscription_status, unrenewed_since and last_unrenewed_at columns,
with the down step that clears subscription_cancelled acknowledgements
master cannot read, into M20261016_badge_subscriptions.

Run: 008-subs-migration-split, slice 1

* tests: drop the FilePath import a merge duplicated

The branch and master each added import System.FilePath ((</>)) to
Direct.hs on 2026-10-14 at different positions, and an earlier merge
kept both, so GHC warned that one was redundant. Keep master's.

Run: 008-subs-migration-split, slice 2

* fixup! core: add the badge subscription columns in their own migration

* ios, android, desktop: choose a badge in the app

* ios, android, desktop: use the dev badge page for testing (don't merge)

* update postgres schema

* update ios lib

* ios, android: hide Restore purchases on the order screen

* docs: summarize the badge subscriptions PR for reviewers, with diagrams

A summary of PR #7716 as built: buying, renewing and retiring on each
store, the retirement window, lanes and store limits, RPC, API and
database changes, alerts, tests, open items, and a review map. Seven
SVG diagrams, an HTML page with them inline, and a link from the plan.

* ios, android, desktop: restore purchases on the Support SimpleX screen

* ios, android, desktop: show the badge privacy policy in the app

* docs: keep only the badge subscription diagrams, with a README

The reviewer summary leaves the repo; the folder keeps the seven
diagrams with a README that captions each, and the plan links the
README.

* ios, android, desktop: smaller Restore purchases label

* ios: no alert when a badge purchase is cancelled

* docs: replace the badge subscriptions diagrams README with a short summary

A plain-English summary for anyone on the team, with the seven
diagrams and a self-contained HTML page; the plan links it again.
Diagrams follow the branch: Restore purchases is on Support SimpleX,
"Renewing" shows past paidThrough, and only a present retryAfter is
raised to an hour.

* ui

* ui wip

* core: retire a subscription badge as soon as its store says it ended

A subscription badge retired only on an ended answer to a request that was due, and only once the ledger's paidThrough had passed, so an ended answer while the ledger still covered, or the iOS app's report of StoreKit's expired or revoked state, left the badge shown, Support SimpleX unreachable and every purchase refused until a later request. Now an answered ended state is stored even while coverage runs (the service writes it only from a store check, after which it grants nothing), and every pass retires a subscription whose state, from this pass's answer or else as stored, is ended, whatever the ledger covers. The paidThrough guard stays at the prepaid call site, its only remaining user.

Run: 010-subscription-lifecycle, slice S1

* docs: record that a badge subscription cannot be restored or bought again

Restoring a subscription on a new device or under another profile fails for two independent reasons, the client's restore reading only unfinished transactions on iOS and the service answering any key but the one it credited receipt_used, and a lapsed iOS subscriber cannot subscribe again on the same install either. Both gaps files record it in their own format, and both restorePurchases() say why reading the store's entitlements alone would not help.

Run: 010-subscription-lifecycle, slice S2c

* fixup! core: retire a subscription badge as soon as its store says it ended

* transfer plan

* shorter plan

* update plan

* badge-service: let a dev deployment ask its mock store while coverage runs

[dev] check_store_during_coverage = on makes every issueBadge for a
subscription ask the dev mock, during paid coverage too, and bank the
month of a charge it can grant, issued once coverage reaches it. So a
renewal can be watched by hand without waiting a month, and a mock that
forgot the plan after a restart answers ended at once.

Off by default, and refused unless accept_unverified_store_receipts is
on, which is itself refused beside a real store: a real store has not
started its next charge while coverage runs, and asking spends the
quota every subscriber shares.

Run: 011-subscription-tools, slice S3a

* core: send a badge request at once from a build for the dev badge service

/_badge request <userId> sends the profile's badge request now, while
its badge is shown, and runs the badge pass on the answer, so a renewal
or an ended subscription can be watched by hand against the dev
service.

It is allowed only when ChatConfig's badgeDevRequests is set, which no
shipped build does and nothing sets at runtime: the dev-service branch
sets it beside its own badge service overrides. A request off the shared
expiry would tell requests apart, so every other build refuses it, and
it is refused from a paired remote controller.

Run: 011-subscription-tools, slice S3b

* fixup! badge-service: let a dev deployment ask its mock store while coverage runs

* fixup! badge-service: let a dev deployment ask its mock store while coverage runs

* fixup! core: send a badge request at once from a build for the dev badge service

* core: split the badge request's lock from its body

The receipt worker's attempt already holds the owner's badge lock, which is not reentrant, so it cannot call requestBadgeIssue. The body becomes sendBadgeIssue, and both answer a service error as Left (code, retryAfter) instead of Nothing, so that caller can classify it as it does today. No behaviour change.

Run: 011-subscription-resume, slice S2-0

* core: retire on a device's ended report only once the paid period is over

StoreKit can report a subscription expired during Apple's billing retry, and Apple may then recover the charge, so retiring at once on that report left a paying user without the badge. The service's answered ended still retires at once, also while the ledger covers. A stored ended, which is how the device's report arrives, retires once paidThrough has passed.

Run: 011-subscription-resume, slice S1c

* core: resume a retired Apple subscription when its store charges it again

A same-install resubscription keeps Apple's original transaction id, so its hand-over found the old credited record and was answered from it with the old credential: the subscriber paid and got nothing. A credited record is now held again when a later charge of its subscription is handed over, the charge is not revoked, its paid period runs and it is dated less than a day ahead of this device's clock, and the record's purchase is its owner's newest, a subscription and not shown, with no other receipt held. The receipt worker then sends the purchase's issueBadge, and the service grants the charge as a renewal. A covered answer shows the purchase again with the newest credential and clears an ended state. A charge the service answers without crediting is deferred an hour and refused a day after its purchase date, so it holds the profile for about a day. A refused resume is remembered on the record (every credit, re-hold and resume clears credit_error), so the app's sweep does not hold the same charge again after its day.

Run: 011-subscription-resume, slice S2a

* fixup! core: resume a retired Apple subscription when its store charges it again

Review round 1 fixes:
- R1-1: a resumable charge waiting behind another held receipt of the owner is answered held and left unfinished, rather than answered from the record and finished uncredited.
- R1-3: a resume shows the purchase again only with a credential that has not expired.
- R1-2, R1-8: tests of the resumable-charge rule and the hold's edge, of a held charge whose paid period ends before it is sent, and that a resumed profile shows the newest credential. The resume test is split in two, one environment each.
- R2-V1: a test comment that the reordered steps made false.

Run: 011-subscription-resume, review rounds 1 and 2

* core, ios, android, desktop: let a lapsed iOS subscriber subscribe again to the badge the profile retired

The iOS app refused any subscription to an Apple ID that ever subscribed, so a lapsed subscriber could never subscribe again in the app. Core now tells the apps each subscription's store reference (BadgeSubscription.transactionRef, optional in JSON), and the iOS gate opens a subscription card only when every earlier subscription of the Apple ID is the active profile's newest purchase, retired, of the card's badge: the one charge core resumes. Kotlin gets the model field only, as Play gives a resubscription a new token and needs no gate.

Run: 011-subscription-resume, slice S2b

* docs: bound a badge move by the previous credential's expiry

* badge-service: credit test purchases and check the store during coverage in a dev deployment

* core: let a dev build ask the badge service on an interval

* badge-service: log each request's command and each store check's outcome

* fix compilation

* badge-service: name the purchase each request came from in the log

* badge-service: name the purchase each request came from in the log

* core, ios, android: explain a failed badge renewal and stop retrying a subscription the store forgot; tests (#7788)

* core, badge-service, ios, android: change badge tier in the store, and restore a subscription on another device (#7795)

* core: tell the apps when a badge request banks a month without issuing it

A pass announced the badge state only when the balance start moved, so a charge granted onto running coverage, or a debit the service wrote, changed months left and paid-through without an event, and the apps kept showing the old renewal date until the screen was reopened. The pass now announces whenever the ledger's last entry is not the one it started from, which a moved balance start implies.

Run: 015-badge-fixes, slice 1

* core: test that every Play charge of a month-end subscription funds its month

Play reports only a period's end, and the service dates the charge a plan length before it, so month-end clipping could leave a charge funding less than its month. Walk a monthly and an annual Play plan anchored on 31 January through their renewals at the device's request moments, through the deployed Play verifier: each charge funds exactly its months, paid-through stays at most the grace behind Play's period end (three days at most in this walk), and no charge is left without a grant.

Run: 015-badge-fixes, slice 2

* core: test that the newest issued badge credential is taken by its ledger row

After a tier change the newer issuance can end before the older one, so ordering issuances by period end would answer the superseded credential to the worker and to the resume and tier-change paths. Pin the row order: the test fails if the query goes back to period_end order.

Run: 015-badge-fixes, slice 3

* review: round 1 fixes

The App Store tier-change hold, reviewed for the first time:

- R1-B2: a tier change's credit now shows its purchase again (shown_badge_id) in the same transaction, as a resume's does, so a retire that ran while the change was with the service cannot leave a paid purchase unshown and never renewed.
- R1-B5: a tier change of a shown purchase is held whatever other receipt is held, as the worker serves it while the badge is shown; only a resume waits for other held receipts.
- R1-B3: test a tier change the store does not vouch for: refused in silence, the badge kept, and answered from the record after.
- R1-B8: the changeTier comment names when the record settles.

Run: 015-badge-fixes, review round 1

* review: round 2 fixes

- R2-1: a granted tier change clears an ended state the device reported before it. A renewing report never replaces ended, and a charge of the new tier granted proves the subscription has not ended, so without this the worker retired the new tier's badge at its paid-through while the subscription renewed.
- R1-B3: test a tier change whose credential does not verify: the failure stays on the receipt record, not the purchase, and Supporter stays shown.
- R2-3: the refused tier change's test buys Supporter through an invoice, so it shows the refusal announces nothing.
- R2-2: the changeTier comment says what follows each way the record settles.

Run: 015-badge-fixes, review round 2

* review: round 3 fixes

- R3-1: a tier change whose answer says the subscription ended is not credited, as a resume is not, so the credit's clearing of a stored ended never drops the one this answer carries.
- R3-2: the changeTier comment in two lines.

Run: 015-badge-fixes, review round 3

* core: apply an App Store tier change at once only when it raises the tier

Apple keeps charging the old plan to the end of the period, so applying a downgrade at once took away a badge the subscriber had already paid for. A charge of another tier is now held and sent at once only from supporter to legend; a lower tier, or one that is not ranked (investor, unknown), is answered from the record and the renewal check grants it, as badges-rpc.md says. A record already held for such a change settles silently.

Run: 016-tier-change-direction

* core: test that an App Store change to a lower tier waits for the renewal

A Supporter charge handed over while Legend is shown is answered from the record and sends nothing, and the renewal check grants Supporter, shown once the Legend credential expires; a record an older build held for a lower tier settles with no request. Both fail if every change of tier is sent at once again.

Run: 016-tier-change-direction

* badge-service: let a restore ask the store without waiting for the purchase's own check

* docs: describe badge tier changes and restore as the service handles them

The RPC document splits a store tier change by store and direction: the
app never starts one, an App Store raise seen within a day of its charge
is sent as upgradeBadgeSubscription, every other change waits for the
renewal check, and a Play plan change is a new token, a new purchase.
transferBadge and its limits are checked against the handlers, and the
upgrades that are not built are marked so.

The overview admits what Restore discloses: the service links the two
purchase keys, a store receipt moves its subscription to whoever presents
it within the move limit, and a new badge or tier is shown as soon as it
is issued. The Android gap names what remains of Restore.

* docs: tell the badge subscriptions story with tier changes and restore

The summary now covers the whole lifecycle: buying, renewing, changing
tier, moving to another device or profile, and ending. The badge retires
as soon as the store says the subscription ended, a lapsed iOS subscriber
can resume the retired badge, an App Store raise is granted at once and
a lower tier at the renewal, and a Play plan change is a new purchase.
The known limits and the before-sale list follow the code.

The seven diagrams are updated, with stale file and line references
dropped, and two are added: a tier change and a restore. The page now
points at the diagram files instead of carrying copies of them.

* fixup! docs: describe badge tier changes and restore as the service handles them

* fixup! docs: tell the badge subscriptions story with tier changes and restore

* fixup! docs: describe badge tier changes and restore as the service handles them

* fixup! docs: tell the badge subscriptions story with tier changes and restore

* core: make the badge subscription tests fail on the defects they name (#7798)

* fix compilation

* fix api

* ios, android, desktop: open the badge page on the site again

* ios: choose a badge on the site, not in the app

* tests: hold the move with no charge to grant, not with the purchase's store check

* unfocus test

* update postgres schema

* badge-service: break a tie between issuances by their period, so both databases agree

* badge subscription review fixes (#7799)

* update badge subscriptions docs (#7802)

* core: show a changed badge tier to contacts as soon as it is granted

* update plans

* core: show a raised badge tier to contacts at once, hold back a lower one

* update sqlite schema

* badge subscriptions review fixes (#7903)

* update ios lib

* update query plans

* ios: one property wrapper on the chat view's chat (#7910)

* android: a shorter note under Restore purchases

* Revert "ios: one property wrapper on the chat view's chat (#7910)"

This reverts commit d5a24bb342.

* ci: larger RAM disk so tests do not run out of space

* update sqlite schema

* ios: preview references for the badge screens

---------

Co-authored-by: spacedandy-agents-simplex <342056592+spacedandy-agents-simplex@users.noreply.github.com>
2026-10-28 13:54:10 +00:00
Evgeny @ SimpleX Chat 03ba484f11 android, desktop: chat view previews show their sample messages (#7914)
* android, desktop: chat view previews show their sample messages

* ci: references of the chat view preview snapshots
2026-10-28 07:45:07 +00:00
Evgeny @ SimpleX Chat 70b9cf66f4 ios: previews of chat preview and badge billing render fixed dates (#7913)
* ios: snapshot tests render all previews at fixed dates

* ios: previews of your servers and terminal render without errors

* ios: snapshots fill the screen height for lists, skip device migration

* ios: snapshots show the sample user, secondary chat preview has items

* ios: snapshots skip previews of live prices, profiles and console

* ci: references of all iOS previews

* ci: snapshot docs state window height, exclusions and timing

* ios: snapshots skip previews with a blinking caret or a spinner

* ios: snapshots end editing and stop animations, restoring 8 previews

* ci: references of the restored cursor and spinner previews

* ios: sample contact and badge billing footer take fixed preview dates

* ci: references of chat preview and badge billing previews

* ios: chat item previews clip items to bubbles as the chat view does

* ci: references of chat item previews with bubbles

* ci: references of badge previews as rendered after the merge
2026-10-28 05:25:49 +00:00
Evgeny @ SimpleX Chat cfb9b7c656 ios: snapshot tests render all app previews (#7912)
* ios: snapshot tests render all previews at fixed dates

* ios: previews of your servers and terminal render without errors

* ios: snapshots fill the screen height for lists, skip device migration

* ios: snapshots show the sample user, secondary chat preview has items

* ios: snapshots skip previews of live prices, profiles and console

* ci: references of all iOS previews

* ci: snapshot docs state window height, exclusions and timing

* ios: snapshots skip previews with a blinking caret or a spinner

* ios: snapshots end editing and stop animations, restoring 8 previews

* ci: references of the restored cursor and spinner previews

* ios: chat item previews clip items to bubbles as the chat view does

* ci: references of chat item previews with bubbles
2026-10-28 05:18:10 +00:00
Evgeny @ SimpleX Chat b1c90784ad ci: render all desktop previews in tests, compare with references (#7911)
* ci: render all desktop previews in tests, compare with references

* ci: desktop snapshot test provides the app bar handler and window state

* ci: leave out desktop previews that call the core library

* ci: references of the desktop preview snapshots

* ci: desktop snapshot test clears the terminal before each render

* ci: reference of the dark terminal preview with an empty terminal
2026-10-27 23:05:15 +00:00
spaced4ndyandspacedandy-agents-simplex e4d05097e2 ios, android, desktop: channel owners can require signed messages and make subscribers moderators (#7805)
* core: test that history posted before channel signing reaches later joiners as signature missing, and channel moderator delete for all

Confirms the case the owner's new alert describes: a subscriber who joins after the owner turned on "Sign messages" sees the earlier posts as "signature missing" and later ones as signed, while earlier subscribers keep them unmarked. Also covers a non-owner channel moderator deleting a contributor's signed post for everyone.

Run: 001-channel-signing-moderators, slice 1

* ios: keep "Chat with admins" off when saving group preferences

toGroupPreferences left out the support preference, so the saved profile had none and core filled in its default, on: every channel preference save from iOS silently turned on chats with admins, which have no end-to-end encryption in channels. Android and desktop already pass it.

Run: 001-channel-signing-moderators, slice 2

* ui: let channel owners turn on "Sign messages", warning that earlier messages will show signature missing

The channel preference was hidden while signing was recipient-only. Owners now see the switch; turning it on asks for confirmation, because subscribers who join later receive the earlier posts unsigned through history and see them as "signature missing". The "Signature missing" explanation now says the message may predate signing or have been forwarded by a relay without its signature, instead of only implying tampering.

Run: 001-channel-signing-moderators, slice 3

* ui: channel owners can make subscribers moderators, and moderators see the subscriber list

Core already lets a channel owner make a subscriber a moderator; the role picker offered only subscriber and contributor. It now offers moderator too (not admin, by decision). Moderators see the full member list the owner sees, so they can reach the subscribers they may block (subscribers can't post, so there was no other way to reach them), and member info is headed Moderator or Contributor instead of Subscriber for those roles.

Run: 001-channel-signing-moderators, slice 4

* ci: long-press and right-click for app tests, safer ui arguments, desktop Kotlin 4 GB, desktop session limits from claude-scope

Message menus open only on long-press (iOS) or right-click (desktop), so Claude sessions couldn't reach Moderate, Info or Delete. Ported from f/directory-search unchanged, with its hardening: the guards refuse unquoted glob, brace and tilde expansion, and desktop ui checks numbers and sends one key per call so a key argument can't run an xdotool command. The desktop app job's Kotlin compiler gets 4 GB, as f/directory-search needed after merging master. Desktop sessions take max-turns and max-budget-usd from claude-scope like iOS (60 and 3 when unset, as before), and the Claude job may run 120 minutes.

Run: 001-channel-signing-moderators, slice 5

* ci: Claude test plans for channel message signing and channel moderators

This branch's iOS device test plan and desktop prompt replace master's smoke tests: the owner creates a channel on the preset relays, turns on Sign messages through its alert, and two more profiles in the same app join by the copied link; the owner makes one a moderator, who then sees the subscriber list, moderates a contributor's message and blocks the contributor. Signatures are checked as text in message Info. One layout, no test backend.

Run: 001-channel-signing-moderators, slice 6

* fixup! ui: let channel owners turn on "Sign messages", warning that earlier messages will show signature missing

* update plans

* fixup! ui: let channel owners turn on "Sign messages", warning that earlier messages will show signature missing

* fixup! ci: Claude test plans for channel message signing and channel moderators

* fixup! ui: let channel owners turn on "Sign messages", warning that earlier messages will show signature missing

* fixup! ci: Claude test plans for channel message signing and channel moderators

* fixup! ui: let channel owners turn on "Sign messages", warning that earlier messages will show signature missing

* fixup! ci: Claude test plans for channel message signing and channel moderators

---------

Co-authored-by: spacedandy-agents-simplex <342056592+spacedandy-agents-simplex@users.noreply.github.com>
2026-10-27 20:27:31 +00:00
Evgeny @ SimpleX Chat 0b4c798e50 ci: render iOS previews in the simulator, compare with references (#7905)
* ci: render iOS previews in the simulator, compare with references

* docs: assets license covers app screenshots and test snapshot images

* ci: references of the iOS preview snapshots
2026-10-27 11:49:16 +00:00
Evgeny @ SimpleX Chat 6bc1c692b5 docs: the Swift rule covers extension members, not file-scope functions (#7904) 2026-10-27 10:09:16 +00:00
Evgeny @ SimpleX Chat 91675ec5ab docs: Swift functions inside types, extensions only where required (#7901) 2026-10-27 07:46:01 +00:00
Evgeny @ SimpleX Chat b72379c640 desktop: ask before replacing a file, do not suggest hidden file names (#7877)
* desktop: ask before replacing a file, do not suggest hidden file names

* desktop: test the file name suggested by the Save dialog
2026-10-26 20:19:21 +00:00
Evgeny @ SimpleX Chat c3b709a807 docs: CLAUDE.md importing the contributing and CI guides (#7871) 2026-10-26 10:34:31 +00:00
Evgeny @ SimpleX ChatandEvgeny Poberezkin 7810fc4752 core, ui: terminal chat layout for LLM and service bot chats (#7811)
* plan: UI improvements to improve LLM usage via SimpleX

* core, ui: types for chat layout

* core, ui: settings for alternative terminal-like chat layout for managing LLMs or other service bots

* plan: message priority

* fixes

* query plan

* update plans

* remove silent messages plan

* rename migrations

* implement layout

* amend

* fix

* fix

* fix

* improve

* time on the right, sender name in blue

* no avatar in direct chats

* better previews

* update, fixes

* update

* time gap

* changes

* ui: terminal layout line heights, gaps and time placement

* ui: simplify terminal meta layout, correct its docs and tests

* ui: right-to-left emoji edge in terminal rows, time placement tests

* android, desktop: raise Kotlin compiler memory to 4 GB

* ui: terminal captions as follow-up text, classic event separators

* ui: terminal media edge and overlay time, plan decisions

* ui: simplify terminal row separation, correct doc line references

* ui: keep the media time inside terminal rows, restore caption conditions

* ui: terminal heading capitals at large font scales, idle live message time

* ui: rename the classic voice-with-text flag, correct the meta copy docs

* ui: smaller terminal layout diff, sender gap and meta names

* ui: terminal row as tall as the media time

* docs: remove the chat layout section from the bots readme

* docs: shorten the terminal layout section of the chat view

* core: address settings API as on master, /auto_accept reads the stored layout

* ui: smaller terminal headings

* ui: classic sender rows and avatar rule as on master

* ui: classic reply quote text colour as on master

* ios: keep the chat layout setting with other UI settings

* ui: go-to button at the end of terminal rows, no gutter in direct chats

* ui: forwarded arrow on the header line of terminal rows, above the time

* ui: forwarded arrow centred above the time line of terminal rows

---------

Co-authored-by: Evgeny Poberezkin <evgeny@poberezkin.com>
2026-10-25 18:03:11 +00:00
Evgeny @ SimpleX Chat a5cf718b3c core, tests: fix flaky tests; use simplexmq with one thread per agent worker (#7812)
* tests: fix group tests

* fix test

* fix

* fix delivery worker fix

* watch ci

* debug

* fix delivery worker not forwarding to moderators during host acceptance

* add script, update simplexmq

* debug lines

* more debug

* rerun

* debug

* fix, debug

* simplexmq

* simplexmq

* fix

* debug: log member-not-found call sites, restore hang diagnostics, use simplexmq fork

* tests: do not prompt for migration confirmation in strict tables test

* ci: run tests with one capability; simplexmq: end inactive sessions without closing under readers

* ci: run tests on all capabilities

* remote: close the HTTP2 client before its TLS connection

* cabal: use warp that kills timed out connection threads without closing their sockets

* remove diagnostics: member-not-found log, thread dump, CI watchdog; update simplexmq

* badge-service: prevent interleaving of concurrent log lines

* tests: wait for badge group broadcasts before closing members

* tests: log contact connected events received twice

* tests: log member connected events received twice

* core: use simplexmq that logs connections emitting CON twice

* core: keep the team contact above notes in a new user's chat list

* ci: skip macOS and Windows builds while hunting a Linux-only flake

* core: use simplexmq that logs the history of connections emitting CON twice

* tests: remove the logging of connected events received twice

* ci: run macOS and Windows builds again

* core: use simplexmq that runs one thread per agent worker

* core: use the merged simplex-chat/wai warp and the updated simplexmq

* core: use the merged simplexmq

* core: update simplexmq

* core, badge service: comment single writes of terminal segments and log lines
2026-10-25 15:37:06 +00:00
Narasimha-sc d5bab6d9d7 desktop: stop the gsettings theme monitor when the app exits (#7747)
* desktop: stop the gsettings theme monitor when the app exits

On Linux the theme detector library starts `gsettings monitor` to
follow the system theme and never stops it. The process outlived the
app, one per run, each holding a D-Bus connection until the next
theme change. A shutdown hook now stops it.

* plans: gsettings theme monitor left running after the app exits

* desktop: install the gsettings shutdown hook on Linux only

* plans: correct the Ctrl-C note for the gsettings monitor

* plans: gsettings ignores SIGPIPE; the monitor lives until killed or logout
2026-10-24 22:56:23 +01:00
sh 31c4b68189 ui: don't reconnect calls with peers before v22 (#7785) 2026-10-23 10:06:33 +01:00
Narasimha-sc cfcce1b43c ui: create one group on a double click of Create group (#7759)
* desktop: open a pending connection's "Learn more" and "Incognito" pages once

On desktop the connection view stays clickable in the center pane, so each
click on these rows pushed another modal onto the right pane. Close the
right-pane modals first, as ChatView does when the connection opens. The page
is closed and shown again in one event, so its content is keyed by its
ModalData to start fresh.

Desktop only: on Android the view can itself be the open modal of the shared
manager ("Set contact name"), and the new page already covers the row.

Fixes #6270

* ui: open a modal once when its button is double-clicked

A modal slides in over 250 ms, and until it covers the button that opened it the button still takes clicks, so a double click opened two copies (left-pane pages and most stacked center and right-pane pages on desktop, animated modals on Android). When a modal opens, the page it covers draws an empty pointerInput box over itself while it slides out; when a pane's first modal slides in, the empty page sliding out covers the view under the pane. The page sliding in already takes clicks, and nothing is blocked when a page closes.

* ui: add isTopModalOpen, which ignores modals that are sliding out

A modal closed with animation stays in modalViews until it has slid out, and isLastModalOpen counts it. A check-then-closeModal() on it would close the modal under it. Uses the same index as isLastModal; isLastModalOpen and its callers are unchanged.

* desktop: don't open a second badges page or profile form

These buttons stay clickable on desktop while their page is shown in another pane, so each click opened another copy:
- "Support SimpleX" in the chat's large-file and badge alerts (Badges on the right): the alerts skip while Badges is open, on desktop only, as on Android the page covers the button;
- "+ Add profile" in Your chat profiles and "Create chat profile" in the picker (form in the center): skip while the form is on top, keeping what was typed, before asking for authentication; the picker row still hides the picker.

* desktop: replace a page of the same kind on top instead of stacking another

These buttons stay clickable on desktop while their page is shown in another pane, so each click pushed another copy:
- the chat banner's bio "Read more" (right pane);
- a markdown file clicked in a support chat (viewer in the center);
- message "Info" in the main chat while a support or reports chat is open on the right.
Their content depends on what was clicked and the pane can hold other pages (a support chat), so a page of the same kind on top is replaced. The new page is drawn where the old one was, so its content is keyed by its ModalData to start fresh. The markdown file and Info load on a background thread; their close and show now run on the main thread. The markdown check is desktop only, as on Android the viewer covers its file once it has loaded.

* plans: a page opens again on every click of its button (#6270)

* ui: create one group on a double click of Create group

"Create group" creates the group, opens it and only then closes its
page, and the core does not deduplicate, so a double click created two
groups. The page now ignores a click while its create is in progress,
on desktop and Android.

* plans: a double click on "create group" creates two groups

* plans: D2 is valid at 80 ms only

* ui: ignore a click on Create group until its page has closed after a create
2026-10-22 18:48:32 +01:00
Narasimha-sc cc3f49f794 android, desktop: fix chat preview and unread counter updating wrong chat (#7072)
* android, desktop: fix chat preview and unread counter updating wrong chat

While "Chat with admins", a member support chat or the reports view was
open, ChatsContext.addChatItem in the secondary context looked up the
chat's index in its own list but read and wrote the main chat list at
that index (chatsContext.chats[i]), so an unrelated chat in the main
list got the message as its preview and its unread count went up.

Use the context's own list at all four sites again. The main-list
qualifier had also made a pending invitee's sent support messages reach
the group's preview in the main list (at a secondary-list index), so
send that update to the main list explicitly: addSentChatItem passes a
sent item to the main chat list context as well when it is sent from a
secondary view and belongs in the main list (inMainChatList, the same
rule addChatItem uses for previews). Count unread stats only in the
main chat list context, so the revert does not make the open secondary
view count main-list messages in its own list.

* plans: wrong-chat preview and unread fix
2026-10-21 22:36:34 +01:00
Narasimha-sc 87e3f8c3f6 ui: open a page once when its button is clicked again or double-clicked (#7725)
* desktop: open a pending connection's "Learn more" and "Incognito" pages once

On desktop the connection view stays clickable in the center pane, so each
click on these rows pushed another modal onto the right pane. Close the
right-pane modals first, as ChatView does when the connection opens. The page
is closed and shown again in one event, so its content is keyed by its
ModalData to start fresh.

Desktop only: on Android the view can itself be the open modal of the shared
manager ("Set contact name"), and the new page already covers the row.

Fixes #6270

* ui: open a modal once when its button is double-clicked

A modal slides in over 250 ms, and until it covers the button that opened it the button still takes clicks, so a double click opened two copies (left-pane pages and most stacked center and right-pane pages on desktop, animated modals on Android). When a modal opens, the page it covers draws an empty pointerInput box over itself while it slides out; when a pane's first modal slides in, the empty page sliding out covers the view under the pane. The page sliding in already takes clicks, and nothing is blocked when a page closes.

* ui: add isTopModalOpen, which ignores modals that are sliding out

A modal closed with animation stays in modalViews until it has slid out, and isLastModalOpen counts it. A check-then-closeModal() on it would close the modal under it. Uses the same index as isLastModal; isLastModalOpen and its callers are unchanged.

* desktop: don't open a second badges page or profile form

These buttons stay clickable on desktop while their page is shown in another pane, so each click opened another copy:
- "Support SimpleX" in the chat's large-file and badge alerts (Badges on the right): the alerts skip while Badges is open, on desktop only, as on Android the page covers the button;
- "+ Add profile" in Your chat profiles and "Create chat profile" in the picker (form in the center): skip while the form is on top, keeping what was typed, before asking for authentication; the picker row still hides the picker.

* desktop: replace a page of the same kind on top instead of stacking another

These buttons stay clickable on desktop while their page is shown in another pane, so each click pushed another copy:
- the chat banner's bio "Read more" (right pane);
- a markdown file clicked in a support chat (viewer in the center);
- message "Info" in the main chat while a support or reports chat is open on the right.
Their content depends on what was clicked and the pane can hold other pages (a support chat), so a page of the same kind on top is replaced. The new page is drawn where the old one was, so its content is keyed by its ModalData to start fresh. The markdown file and Info load on a background thread; their close and show now run on the main thread. The markdown check is desktop only, as on Android the viewer covers its file once it has loaded.

* plans: a page opens again on every click of its button (#6270)

* plans: D2 is valid at 80 ms only
2026-10-21 22:35:29 +01:00
EvgenyandEvgeny @ SimpleX Chat 3126d9b544 ios: set default proxy mode (#7790)
Co-authored-by: Evgeny @ SimpleX Chat <259188159+evgeny-simplex@users.noreply.github.com>
2026-10-21 14:35:41 +01:00
SimpleX Chat fcef2ad008 7.1-beta.7: android 387, desktop 168, ios 363 2026-10-20 12:34:51 +00:00
+104 8af38dc33e ui: translations (#7782)
* Translated using Weblate (German)

Currently translated at 100.0% (2513 of 2513 strings)

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

* Translated using Weblate (German)

Currently translated at 100.0% (2513 of 2513 strings)

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

* Translated using Weblate (German)

Currently translated at 100.0% (2513 of 2513 strings)

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

* Translated using Weblate (German)

Currently translated at 100.0% (2513 of 2513 strings)

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

* Translated using Weblate (German)

Currently translated at 100.0% (2513 of 2513 strings)

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

* Translated using Weblate (German)

Currently translated at 100.0% (2513 of 2513 strings)

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

* Translated using Weblate (German)

Currently translated at 100.0% (2513 of 2513 strings)

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

* Translated using Weblate (German)

Currently translated at 100.0% (2513 of 2513 strings)

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

* Translated using Weblate (German)

Currently translated at 100.0% (2513 of 2513 strings)

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

* Translated using Weblate (German)

Currently translated at 100.0% (2513 of 2513 strings)

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

* Translated using Weblate (German)

Currently translated at 100.0% (2513 of 2513 strings)

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

* Translated using Weblate (Russian)

Currently translated at 99.5% (2501 of 2513 strings)

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

* Translated using Weblate (Russian)

Currently translated at 99.5% (2501 of 2513 strings)

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

* Translated using Weblate (Russian)

Currently translated at 99.5% (2501 of 2513 strings)

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

* Translated using Weblate (Russian)

Currently translated at 99.5% (2501 of 2513 strings)

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

* Translated using Weblate (Russian)

Currently translated at 99.5% (2501 of 2513 strings)

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

* Translated using Weblate (Russian)

Currently translated at 99.5% (2501 of 2513 strings)

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

* Translated using Weblate (Russian)

Currently translated at 99.5% (2501 of 2513 strings)

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

* Translated using Weblate (Russian)

Currently translated at 99.5% (2501 of 2513 strings)

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

* Translated using Weblate (Russian)

Currently translated at 99.5% (2501 of 2513 strings)

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

* Translated using Weblate (Russian)

Currently translated at 99.5% (2501 of 2513 strings)

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

* Translated using Weblate (Russian)

Currently translated at 99.5% (2501 of 2513 strings)

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

* Translated using Weblate (Russian)

Currently translated at 99.5% (2501 of 2513 strings)

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

* Translated using Weblate (Russian)

Currently translated at 99.5% (2501 of 2513 strings)

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

* Translated using Weblate (Russian)

Currently translated at 99.5% (2501 of 2513 strings)

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

* Translated using Weblate (French)

Currently translated at 100.0% (2513 of 2513 strings)

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

* Translated using Weblate (French)

Currently translated at 100.0% (2513 of 2513 strings)

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

* Translated using Weblate (French)

Currently translated at 100.0% (2513 of 2513 strings)

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

* Translated using Weblate (French)

Currently translated at 100.0% (2513 of 2513 strings)

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

* Translated using Weblate (French)

Currently translated at 100.0% (2513 of 2513 strings)

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

* Translated using Weblate (French)

Currently translated at 100.0% (2513 of 2513 strings)

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

* Translated using Weblate (French)

Currently translated at 100.0% (2513 of 2513 strings)

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

* Translated using Weblate (French)

Currently translated at 100.0% (2513 of 2513 strings)

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

* Translated using Weblate (French)

Currently translated at 100.0% (2513 of 2513 strings)

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

* Translated using Weblate (French)

Currently translated at 100.0% (2513 of 2513 strings)

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

* Translated using Weblate (French)

Currently translated at 100.0% (2513 of 2513 strings)

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

* Translated using Weblate (Italian)

Currently translated at 100.0% (2513 of 2513 strings)

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

* Translated using Weblate (Italian)

Currently translated at 100.0% (2513 of 2513 strings)

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

* Translated using Weblate (Italian)

Currently translated at 100.0% (2513 of 2513 strings)

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

* Translated using Weblate (Italian)

Currently translated at 100.0% (2513 of 2513 strings)

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

* Translated using Weblate (Italian)

Currently translated at 100.0% (2513 of 2513 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 97.6% (2453 of 2513 strings)

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

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

Currently translated at 97.6% (2453 of 2513 strings)

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

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

Currently translated at 97.6% (2453 of 2513 strings)

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

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

Currently translated at 97.6% (2453 of 2513 strings)

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

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

Currently translated at 97.6% (2453 of 2513 strings)

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

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

Currently translated at 97.6% (2453 of 2513 strings)

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

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

Currently translated at 97.6% (2453 of 2513 strings)

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

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

Currently translated at 97.6% (2453 of 2513 strings)

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

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

Currently translated at 97.6% (2453 of 2513 strings)

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

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

Currently translated at 97.6% (2453 of 2513 strings)

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

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

Currently translated at 97.6% (2453 of 2513 strings)

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

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

Currently translated at 97.6% (2453 of 2513 strings)

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

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

Currently translated at 97.6% (2453 of 2513 strings)

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

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

Currently translated at 97.6% (2453 of 2513 strings)

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

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

Currently translated at 97.6% (2453 of 2513 strings)

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

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

Currently translated at 97.6% (2453 of 2513 strings)

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

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

Currently translated at 97.6% (2453 of 2513 strings)

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

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

Currently translated at 97.6% (2453 of 2513 strings)

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

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

Currently translated at 96.4% (2424 of 2513 strings)

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

* Translated using Weblate (Spanish)

Currently translated at 100.0% (2513 of 2513 strings)

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

* Translated using Weblate (Spanish)

Currently translated at 100.0% (2513 of 2513 strings)

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

* Translated using Weblate (Spanish)

Currently translated at 100.0% (2513 of 2513 strings)

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

* Translated using Weblate (Spanish)

Currently translated at 100.0% (2513 of 2513 strings)

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

* Translated using Weblate (Spanish)

Currently translated at 100.0% (2513 of 2513 strings)

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

* Translated using Weblate (Spanish)

Currently translated at 100.0% (2513 of 2513 strings)

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

* Translated using Weblate (Spanish)

Currently translated at 100.0% (2513 of 2513 strings)

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

* Translated using Weblate (Spanish)

Currently translated at 100.0% (2513 of 2513 strings)

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

* Translated using Weblate (Spanish)

Currently translated at 100.0% (2513 of 2513 strings)

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

* Translated using Weblate (Spanish)

Currently translated at 100.0% (2513 of 2513 strings)

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

* Translated using Weblate (Spanish)

Currently translated at 100.0% (2513 of 2513 strings)

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

* Translated using Weblate (Dutch)

Currently translated at 81.3% (2044 of 2513 strings)

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

* Translated using Weblate (Dutch)

Currently translated at 81.3% (2044 of 2513 strings)

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

* Translated using Weblate (Dutch)

Currently translated at 81.3% (2044 of 2513 strings)

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

* Translated using Weblate (Dutch)

Currently translated at 81.3% (2044 of 2513 strings)

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

* Translated using Weblate (Dutch)

Currently translated at 81.3% (2044 of 2513 strings)

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

* Translated using Weblate (Japanese)

Currently translated at 48.7% (1224 of 2513 strings)

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

* Translated using Weblate (Japanese)

Currently translated at 48.7% (1224 of 2513 strings)

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

* Translated using Weblate (Japanese)

Currently translated at 48.7% (1224 of 2513 strings)

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

* Translated using Weblate (Japanese)

Currently translated at 48.7% (1224 of 2513 strings)

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

* Translated using Weblate (Japanese)

Currently translated at 48.7% (1224 of 2513 strings)

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

* Translated using Weblate (Japanese)

Currently translated at 48.7% (1224 of 2513 strings)

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

* Translated using Weblate (Japanese)

Currently translated at 48.7% (1224 of 2513 strings)

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

* Translated using Weblate (Japanese)

Currently translated at 48.7% (1224 of 2513 strings)

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

* Translated using Weblate (Japanese)

Currently translated at 48.7% (1224 of 2513 strings)

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

* Translated using Weblate (Japanese)

Currently translated at 48.7% (1224 of 2513 strings)

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

* Translated using Weblate (Japanese)

Currently translated at 48.7% (1224 of 2513 strings)

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

* Translated using Weblate (Japanese)

Currently translated at 48.7% (1224 of 2513 strings)

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

* Translated using Weblate (Japanese)

Currently translated at 48.7% (1224 of 2513 strings)

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

* Translated using Weblate (Japanese)

Currently translated at 48.7% (1224 of 2513 strings)

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

* Translated using Weblate (Japanese)

Currently translated at 48.7% (1224 of 2513 strings)

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

* Translated using Weblate (Czech)

Currently translated at 50.2% (1264 of 2513 strings)

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

* Translated using Weblate (Czech)

Currently translated at 50.2% (1264 of 2513 strings)

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

* Translated using Weblate (Czech)

Currently translated at 50.2% (1264 of 2513 strings)

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

* Translated using Weblate (Czech)

Currently translated at 50.2% (1264 of 2513 strings)

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

* Translated using Weblate (Czech)

Currently translated at 50.2% (1264 of 2513 strings)

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

* Translated using Weblate (Czech)

Currently translated at 50.2% (1264 of 2513 strings)

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

* Translated using Weblate (Czech)

Currently translated at 50.2% (1264 of 2513 strings)

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

* Translated using Weblate (Czech)

Currently translated at 50.2% (1264 of 2513 strings)

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

* Translated using Weblate (Czech)

Currently translated at 50.2% (1264 of 2513 strings)

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

* Translated using Weblate (Czech)

Currently translated at 50.2% (1264 of 2513 strings)

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

* Translated using Weblate (Czech)

Currently translated at 50.2% (1264 of 2513 strings)

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

* Translated using Weblate (Portuguese (Brazil))

Currently translated at 35.6% (896 of 2513 strings)

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

* Translated using Weblate (Croatian)

Currently translated at 1.8% (47 of 2513 strings)

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

* Translated using Weblate (Arabic)

Currently translated at 29.2% (735 of 2513 strings)

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

* Translated using Weblate (Ukrainian)

Currently translated at 85.6% (2152 of 2513 strings)

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

* Translated using Weblate (Ukrainian)

Currently translated at 85.6% (2152 of 2513 strings)

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

* Translated using Weblate (Ukrainian)

Currently translated at 85.6% (2152 of 2513 strings)

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

* Translated using Weblate (Ukrainian)

Currently translated at 85.6% (2152 of 2513 strings)

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

* Translated using Weblate (Ukrainian)

Currently translated at 85.6% (2152 of 2513 strings)

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

* Translated using Weblate (Ukrainian)

Currently translated at 85.6% (2152 of 2513 strings)

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

* Translated using Weblate (Ukrainian)

Currently translated at 85.6% (2152 of 2513 strings)

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

* Translated using Weblate (Ukrainian)

Currently translated at 85.6% (2152 of 2513 strings)

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

* Translated using Weblate (Ukrainian)

Currently translated at 85.6% (2152 of 2513 strings)

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

* Translated using Weblate (Ukrainian)

Currently translated at 85.6% (2152 of 2513 strings)

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

* Translated using Weblate (Ukrainian)

Currently translated at 85.6% (2152 of 2513 strings)

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

* Translated using Weblate (Ukrainian)

Currently translated at 85.6% (2152 of 2513 strings)

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

* Translated using Weblate (Lithuanian)

Currently translated at 1.5% (38 of 2513 strings)

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

* Translated using Weblate (Finnish)

Currently translated at 44.2% (1113 of 2513 strings)

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

* Translated using Weblate (Finnish)

Currently translated at 44.2% (1113 of 2513 strings)

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

* Translated using Weblate (Finnish)

Currently translated at 44.2% (1113 of 2513 strings)

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

* Translated using Weblate (Korean)

Currently translated at 17.5% (441 of 2513 strings)

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

* Translated using Weblate (Polish)

Currently translated at 86.2% (2168 of 2513 strings)

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

* Translated using Weblate (Polish)

Currently translated at 86.2% (2168 of 2513 strings)

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

* Translated using Weblate (Polish)

Currently translated at 86.2% (2168 of 2513 strings)

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

* Translated using Weblate (Polish)

Currently translated at 86.2% (2168 of 2513 strings)

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

* Translated using Weblate (Polish)

Currently translated at 86.2% (2168 of 2513 strings)

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

* Translated using Weblate (Polish)

Currently translated at 86.2% (2168 of 2513 strings)

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

* Translated using Weblate (Polish)

Currently translated at 86.2% (2168 of 2513 strings)

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

* Translated using Weblate (Polish)

Currently translated at 86.2% (2168 of 2513 strings)

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

* Translated using Weblate (Portuguese)

Currently translated at 6.0% (153 of 2513 strings)

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

* Translated using Weblate (Greek)

Currently translated at 1.0% (27 of 2513 strings)

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

* Translated using Weblate (Hebrew)

Currently translated at 26.3% (661 of 2513 strings)

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

* Translated using Weblate (Thai)

Currently translated at 42.9% (1079 of 2513 strings)

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

* Translated using Weblate (Thai)

Currently translated at 42.9% (1079 of 2513 strings)

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

* Translated using Weblate (Bengali)

Currently translated at 0.1% (3 of 2513 strings)

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

* Translated using Weblate (Bulgarian)

Currently translated at 61.4% (1544 of 2513 strings)

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

* Translated using Weblate (Bulgarian)

Currently translated at 61.4% (1544 of 2513 strings)

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

* Translated using Weblate (Bulgarian)

Currently translated at 61.4% (1544 of 2513 strings)

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

* Translated using Weblate (Turkish)

Currently translated at 85.4% (2147 of 2513 strings)

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

* Translated using Weblate (Turkish)

Currently translated at 85.4% (2147 of 2513 strings)

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

* Translated using Weblate (Turkish)

Currently translated at 85.4% (2147 of 2513 strings)

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

* Translated using Weblate (Turkish)

Currently translated at 85.4% (2147 of 2513 strings)

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

* Translated using Weblate (Turkish)

Currently translated at 85.4% (2147 of 2513 strings)

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

* Translated using Weblate (Turkish)

Currently translated at 85.4% (2147 of 2513 strings)

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

* Translated using Weblate (Turkish)

Currently translated at 85.4% (2147 of 2513 strings)

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

* Translated using Weblate (Turkish)

Currently translated at 85.4% (2147 of 2513 strings)

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

* Translated using Weblate (Turkish)

Currently translated at 85.4% (2147 of 2513 strings)

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

* Translated using Weblate (Turkish)

Currently translated at 85.4% (2147 of 2513 strings)

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

* Translated using Weblate (Turkish)

Currently translated at 85.4% (2147 of 2513 strings)

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

* Translated using Weblate (Turkish)

Currently translated at 85.4% (2147 of 2513 strings)

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

* Translated using Weblate (Turkish)

Currently translated at 85.4% (2147 of 2513 strings)

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

* Translated using Weblate (Hungarian)

Currently translated at 100.0% (2513 of 2513 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% (2513 of 2513 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% (2513 of 2513 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% (2513 of 2513 strings)

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

* Translated using Weblate (Azerbaijani)

Currently translated at 47.0% (1183 of 2513 strings)

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

* Translated using Weblate (Azerbaijani)

Currently translated at 47.0% (1183 of 2513 strings)

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

* Translated using Weblate (Bulgarian)

Currently translated at 80.9% (2430 of 3001 strings)

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

* Translated using Weblate (Russian)

Currently translated at 93.9% (2820 of 3001 strings)

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

* Translated using Weblate (German)

Currently translated at 96.5% (2898 of 3001 strings)

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

* Translated using Weblate (Lithuanian)

Currently translated at 56.6% (1701 of 3001 strings)

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

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

Currently translated at 92.0% (2763 of 3001 strings)

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

* Translated using Weblate (Thai)

Currently translated at 42.2% (1269 of 3001 strings)

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

* Translated using Weblate (Polish)

Currently translated at 82.0% (2463 of 3001 strings)

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

* Translated using Weblate (Greek)

Currently translated at 81.7% (2454 of 3001 strings)

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

* Translated using Weblate (Croatian)

Currently translated at 48.5% (1457 of 3001 strings)

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

* Translated using Weblate (Czech)

Currently translated at 89.4% (2685 of 3001 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 96.5% (2898 of 3001 strings)

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

* Translated using Weblate (Hebrew)

Currently translated at 69.1% (2074 of 3001 strings)

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

* Translated using Weblate (Persian)

Currently translated at 81.1% (2434 of 3001 strings)

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

* Translated using Weblate (Dutch)

Currently translated at 78.0% (2342 of 3001 strings)

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

* Translated using Weblate (Indonesian)

Currently translated at 88.3% (2650 of 3001 strings)

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

* Translated using Weblate (Bengali)

Currently translated at 1.7% (53 of 3001 strings)

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

* Translated using Weblate (Arabic)

Currently translated at 94.2% (2827 of 3001 strings)

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

* Translated using Weblate (Korean)

Currently translated at 49.5% (1488 of 3001 strings)

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

* Translated using Weblate (Italian)

Currently translated at 96.5% (2898 of 3001 strings)

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

* Translated using Weblate (Hungarian)

Currently translated at 96.5% (2898 of 3001 strings)

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

* Translated using Weblate (Finnish)

Currently translated at 47.9% (1438 of 3001 strings)

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

* Translated using Weblate (French)

Currently translated at 96.5% (2898 of 3001 strings)

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

* Translated using Weblate (Romanian)

Currently translated at 82.0% (2463 of 3001 strings)

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

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

Currently translated at 96.5% (2897 of 3001 strings)

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

* Translated using Weblate (Azerbaijani)

Currently translated at 0.3% (10 of 3001 strings)

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

* Translated using Weblate (Ukrainian)

Currently translated at 86.3% (2590 of 3001 strings)

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

* Translated using Weblate (Japanese)

Currently translated at 91.1% (2735 of 3001 strings)

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

* Translated using Weblate (Turkish)

Currently translated at 92.8% (2787 of 3001 strings)

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

* Translated using Weblate (Spanish)

Currently translated at 96.5% (2898 of 3001 strings)

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

* Translated using Weblate (Portuguese)

Currently translated at 39.3% (1180 of 3001 strings)

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

* Update translation files

Updated by "Remove blank strings" hook in Weblate.

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

* ios: remove empty targets, restore az/cs strings

* ios: import and export localizations

* ios: fix broken placeholders in translations

* ios: restore cs draft translations

* ios: fix more broken placeholders and link

---------

Co-authored-by: mlanp <mlanp@users.noreply.hosted.weblate.org>
Co-authored-by: Anonymous <anonymous@users.noreply.hosted.weblate.org>
Co-authored-by: Pixelcode <{pixelcode|git}@pgp.forgoodeyesonly.eu>
Co-authored-by: Evgeny Poberezkin <epoberezkin@users.noreply.hosted.weblate.org>
Co-authored-by: tn <tr4jan@users.noreply.hosted.weblate.org>
Co-authored-by: J. Lavoie <edanas@users.noreply.hosted.weblate.org>
Co-authored-by: J R <jrs@users.noreply.hosted.weblate.org>
Co-authored-by: Sarfaraz Ahmed <sahmed@users.noreply.hosted.weblate.org>
Co-authored-by: sith-on-mars <sith-on-mars@users.noreply.hosted.weblate.org>
Co-authored-by: TheFirstMonster <thefirstmonster@users.noreply.hosted.weblate.org>
Co-authored-by: khalidbelk <khalidbelk@users.noreply.hosted.weblate.org>
Co-authored-by: Near <near8954@users.noreply.hosted.weblate.org>
Co-authored-by: thedmdim <thedmdim@users.noreply.hosted.weblate.org>
Co-authored-by: Hosted Weblate user 107176 <zhuk2@users.noreply.hosted.weblate.org>
Co-authored-by: Artem Vorotnikov <vorot93@users.noreply.hosted.weblate.org>
Co-authored-by: Paul <acornacre@users.noreply.hosted.weblate.org>
Co-authored-by: А О <twofish85@users.noreply.hosted.weblate.org>
Co-authored-by: whoami11 <whoami021992@users.noreply.hosted.weblate.org>
Co-authored-by: Skyward Copied <skywardcopied@users.noreply.hosted.weblate.org>
Co-authored-by: Evgeny <esp@users.noreply.hosted.weblate.org>
Co-authored-by: Игорь Линчевский <insrtnqme@users.noreply.hosted.weblate.org>
Co-authored-by: Name Lastname <simplex-edit0r@users.noreply.hosted.weblate.org>
Co-authored-by: Ophiushi <41908476+ishi-sama@users.noreply.github.com>
Co-authored-by: Mqlx <mqlx@users.noreply.hosted.weblate.org>
Co-authored-by: Ranakan <ranak4n@users.noreply.hosted.weblate.org>
Co-authored-by: Karl Rinneberg <hundertwasser@users.noreply.hosted.weblate.org>
Co-authored-by: indiandoc <indiandoc@users.noreply.hosted.weblate.org>
Co-authored-by: cedev-1 <121963179+cedev-1@users.noreply.github.com>
Co-authored-by: Deleted User <deleted-6980@users.noreply.hosted.weblate.org>
Co-authored-by: Random <random-r@users.noreply.hosted.weblate.org>
Co-authored-by: Float <float@users.noreply.hosted.weblate.org>
Co-authored-by: Deleted User <dnstxqet@users.noreply.hosted.weblate.org>
Co-authored-by: BlacAmDK <blacamdk@users.noreply.hosted.weblate.org>
Co-authored-by: re me <jisizhang001@users.noreply.hosted.weblate.org>
Co-authored-by: Aaron H <chieferino@users.noreply.hosted.weblate.org>
Co-authored-by: Loping151 <loping151@users.noreply.hosted.weblate.org>
Co-authored-by: cllih <cllih@users.noreply.hosted.weblate.org>
Co-authored-by: Zhiyounihao <zhiyouni@users.noreply.hosted.weblate.org>
Co-authored-by: M Sarmad Qadeer <msarmadqadeer@users.noreply.hosted.weblate.org>
Co-authored-by: Albert Bob <vicdorke@users.noreply.hosted.weblate.org>
Co-authored-by: 小连招 <onecombo666@users.noreply.hosted.weblate.org>
Co-authored-by: Yay <yay9hbx5otn5@users.noreply.hosted.weblate.org>
Co-authored-by: Frank Yang <frankyang96@users.noreply.hosted.weblate.org>
Co-authored-by: Citrus <citrus@users.noreply.hosted.weblate.org>
Co-authored-by: Ross Li <ross89223@users.noreply.hosted.weblate.org>
Co-authored-by: No name <certainbot@users.noreply.hosted.weblate.org>
Co-authored-by: Luis Morillo Najarro <lsmor@users.noreply.hosted.weblate.org>
Co-authored-by: Darío Hereñú <kant@users.noreply.hosted.weblate.org>
Co-authored-by: Víctor <vzamanillo@users.noreply.hosted.weblate.org>
Co-authored-by: kudebug <kudebug@users.noreply.hosted.weblate.org>
Co-authored-by: Carlos Perez <charlieper@users.noreply.hosted.weblate.org>
Co-authored-by: Isaac ALejandro Lopez <justanormalguy@users.noreply.hosted.weblate.org>
Co-authored-by: gacarel <gacarel@users.noreply.hosted.weblate.org>
Co-authored-by: John m <jvanmanen@users.noreply.hosted.weblate.org>
Co-authored-by: M1K4 <mika-nl@users.noreply.hosted.weblate.org>
Co-authored-by: a4318 <a4318@users.noreply.hosted.weblate.org>
Co-authored-by: Miyu Sakatsuki <miyu-dev@users.noreply.hosted.weblate.org>
Co-authored-by: ikyhtr <ikyhtr@users.noreply.hosted.weblate.org>
Co-authored-by: 小林照幸 <koba-ninkigumi@users.noreply.hosted.weblate.org>
Co-authored-by: proudmuslim-dev <proudmuslim-dev@users.noreply.hosted.weblate.org>
Co-authored-by: Ikko Eltociear Ashimine <eltociear@gmail.com>
Co-authored-by: Rei <rei_@users.noreply.hosted.weblate.org>
Co-authored-by: yokoba0413 <yokoba0413@users.noreply.hosted.weblate.org>
Co-authored-by: ryokky3 <ryokky3@users.noreply.hosted.weblate.org>
Co-authored-by: koreirozzu <koreirozzu@users.noreply.hosted.weblate.org>
Co-authored-by: daydreamer-json <daydreamer-json@users.noreply.hosted.weblate.org>
Co-authored-by: acevif <acevif@users.noreply.hosted.weblate.org>
Co-authored-by: ActiveTK. <webmaster@activetk.jp>
Co-authored-by: Dima Sivan <dimasivan@users.noreply.hosted.weblate.org>
Co-authored-by: zenobit <zenobit@disroot.org>
Co-authored-by: Mehmed <don43@users.noreply.hosted.weblate.org>
Co-authored-by: mslr8 <hosted.weblate.org.poncho089@passmail.net>
Co-authored-by: Pluto <offplutonium@users.noreply.hosted.weblate.org>
Co-authored-by: idk <ciganzelezo@users.noreply.hosted.weblate.org>
Co-authored-by: Nenad <nenadmirkovic00@gmail.com>
Co-authored-by: Magorak Magorov <magorakmagorov@users.noreply.hosted.weblate.org>
Co-authored-by: Maksym Lukashenko <prototypem995@users.noreply.hosted.weblate.org>
Co-authored-by: Max <prototypem95@users.noreply.hosted.weblate.org>
Co-authored-by: ghost <ghosthamster@users.noreply.hosted.weblate.org>
Co-authored-by: rider of the storm <passat-b6-tdi@users.noreply.hosted.weblate.org>
Co-authored-by: Deleted User <mgorpinic2005@gmail.com>
Co-authored-by: Hotripak <hotr1pak@users.noreply.hosted.weblate.org>
Co-authored-by: Groovy394 <groovy394@users.noreply.hosted.weblate.org>
Co-authored-by: aquaticexpectancy <aquaticexpectancy@users.noreply.hosted.weblate.org>
Co-authored-by: Andrii Sudak <andrii-sudak@users.noreply.hosted.weblate.org>
Co-authored-by: sr sr <sr1919os@users.noreply.hosted.weblate.org>
Co-authored-by: petri <petrik@users.noreply.hosted.weblate.org>
Co-authored-by: Jiri Grönroos <artnay@users.noreply.hosted.weblate.org>
Co-authored-by: B.O.S.S <BxOxSxS@protonmail.com>
Co-authored-by: Jester Hodl <jesterhodl@users.noreply.hosted.weblate.org>
Co-authored-by: Kszyche <hostedweblate001user@users.noreply.hosted.weblate.org>
Co-authored-by: Wiesław Fijołek <percival@users.noreply.hosted.weblate.org>
Co-authored-by: Arturro43 <arturro43@users.noreply.hosted.weblate.org>
Co-authored-by: Omikorin <git@omikor.in>
Co-authored-by: Titapa (PunPun) Chaiyakiturajai <titapapunne@users.noreply.hosted.weblate.org>
Co-authored-by: elgratea <flantito@users.noreply.hosted.weblate.org>
Co-authored-by: 109247019824 <109247019824@users.noreply.hosted.weblate.org>
Co-authored-by: Kaanito <kaanito@users.noreply.hosted.weblate.org>
Co-authored-by: Abdullah Koyuncu <wiseweb-works@users.noreply.hosted.weblate.org>
Co-authored-by: goknarbahceli <goknarbahceli@users.noreply.hosted.weblate.org>
Co-authored-by: Dennis <dennnis@users.noreply.hosted.weblate.org>
Co-authored-by: cervezagua <cervezagua@users.noreply.hosted.weblate.org>
Co-authored-by: Deleted User <deleted-65564@users.noreply.hosted.weblate.org>
Co-authored-by: Egehan KAHRAMAN <vastsea0@users.noreply.hosted.weblate.org>
Co-authored-by: Omer <abulomer@users.noreply.hosted.weblate.org>
Co-authored-by: xe1st <xe1st@users.noreply.hosted.weblate.org>
Co-authored-by: echoloji <echoloji@users.noreply.hosted.weblate.org>
Co-authored-by: U.S. <usnetiz@users.noreply.hosted.weblate.org>
Co-authored-by: summoner001 <summoner@disroot.org>
Co-authored-by: Ghost of Sparta <makesocialfoss32@keemail.me>
Co-authored-by: d4f5409d <d4f5409d@users.noreply.hosted.weblate.org>
Co-authored-by: Mireli5656 <mireli5656@users.noreply.hosted.weblate.org>
Co-authored-by: Hosted Weblate <hosted@weblate.org>
2026-10-20 09:27:01 +01:00
EvgenyandEvgeny @ SimpleX Chat ba9269a3ad desktop: fix race condition when searching for address (#7776)
Co-authored-by: Evgeny @ SimpleX Chat <259188159+evgeny-simplex@users.noreply.github.com>
2026-10-19 17:54:57 +01:00
+9 5b61fd5c99 ui: translations (#7770)
* website: disable badge page temporarily (#7516)

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

* Translated using Weblate (German)

Currently translated at 100.0% (2921 of 2921 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% (2513 of 2513 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 100.0% (2921 of 2921 strings)

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

* Translated using Weblate (French)

Currently translated at 100.0% (2513 of 2513 strings)

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

* Translated using Weblate (Italian)

Currently translated at 100.0% (2921 of 2921 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% (2513 of 2513 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% (2920 of 2921 strings)

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

* Translated using Weblate (Portuguese (Brazil))

Currently translated at 99.6% (2911 of 2921 strings)

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

* Translated using Weblate (Hungarian)

Currently translated at 100.0% (2921 of 2921 strings)

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

* Translated using Weblate (Hungarian)

Currently translated at 100.0% (2513 of 2513 strings)

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

* Translated using Weblate (Azerbaijani)

Currently translated at 32.9% (827 of 2513 strings)

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

* Translated using Weblate (Kurdish)

Currently translated at 29.3% (858 of 2921 strings)

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

* Translated using Weblate (Kurdish)

Currently translated at 32.8% (961 of 2921 strings)

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

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

Currently translated at 99.9% (2929 of 2930 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% (2930 of 2930 strings)

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

* Translated using Weblate (Hungarian)

Currently translated at 100.0% (2930 of 2930 strings)

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

* Translated using Weblate (Kurdish)

Currently translated at 38.3% (1123 of 2930 strings)

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

* Translated using Weblate (German)

Currently translated at 100.0% (2930 of 2930 strings)

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

* Translated using Weblate (Azerbaijani)

Currently translated at 33.2% (835 of 2513 strings)

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

* Update translation files

Updated by "Cleanup translation files" hook in Weblate.

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

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

Currently translated at 97.6% (2903 of 2972 strings)

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

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

Currently translated at 97.8% (2909 of 2972 strings)

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

* Translated using Weblate (Hungarian)

Currently translated at 100.0% (2972 of 2972 strings)

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

* Translated using Weblate (Hungarian)

Currently translated at 100.0% (2513 of 2513 strings)

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

* Translated using Weblate (Italian)

Currently translated at 98.0% (2913 of 2972 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% (2972 of 2972 strings)

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

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

Currently translated at 97.9% (2911 of 2972 strings)

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

* Translated using Weblate (German)

Currently translated at 100.0% (2972 of 2972 strings)

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

* Translated using Weblate (French)

Currently translated at 99.3% (2952 of 2972 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% (2972 of 2972 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% (2513 of 2513 strings)

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

* Translated using Weblate (Arabic)

Currently translated at 97.1% (2888 of 2972 strings)

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

* Translated using Weblate (French)

Currently translated at 99.8% (2967 of 2972 strings)

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

* Translated using Weblate (Spanish)

Currently translated at 99.0% (2943 of 2972 strings)

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

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

Currently translated at 99.9% (2971 of 2972 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% (2972 of 2972 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% (2513 of 2513 strings)

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

* Translated using Weblate (Spanish)

Currently translated at 100.0% (2972 of 2972 strings)

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

* Translated using Weblate (Portuguese (Brazil))

Currently translated at 97.1% (2886 of 2972 strings)

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

* Translated using Weblate (Azerbaijani)

Currently translated at 37.4% (942 of 2513 strings)

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

* Translated using Weblate (French)

Currently translated at 100.0% (2972 of 2972 strings)

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

* Translated using Weblate (Czech)

Currently translated at 90.8% (2701 of 2972 strings)

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

* Translated using Weblate (Azerbaijani)

Currently translated at 42.6% (1071 of 2513 strings)

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

* Translated using Weblate (Czech)

Currently translated at 91.0% (2705 of 2972 strings)

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

* Translated using Weblate (Czech)

Currently translated at 50.2% (1264 of 2513 strings)

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

* Translated using Weblate (Azerbaijani)

Currently translated at 45.2% (1136 of 2513 strings)

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

* Translated using Weblate (Azerbaijani)

Currently translated at 45.3% (1140 of 2513 strings)

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

* Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (2972 of 2972 strings)

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

* Translated using Weblate (Azerbaijani)

Currently translated at 46.2% (1162 of 2513 strings)

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

* Translated using Weblate (Portuguese)

Currently translated at 37.2% (1108 of 2972 strings)

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

* Translated using Weblate (Portuguese)

Currently translated at 40.1% (1193 of 2972 strings)

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

* Translated using Weblate (Portuguese)

Currently translated at 40.2% (1195 of 2972 strings)

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

* Translated using Weblate (Slovak)

Currently translated at 36.6% (1089 of 2972 strings)

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

* Translated using Weblate (Azerbaijani)

Currently translated at 47.0% (1183 of 2513 strings)

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

* android, desktop: remove unused translations

* ui: fix translations (stale badge texts, missing placeholder, inverted and verbless strings)

- de, es, fr, hu, it, pt-BR, zh-Hans: re-translate badge strings from the current English (#7544 rewrote them after they were translated), restore the %1$s detail in badges_error_bad_service_response
- es, pt-BR: badges_savings is a discount, not "store"
- zh-Hans: Legend badge tier is 传奇, not a chart legend
- ku: "removed you" read as "you removed"; removed status is derxistî
- pt: verb buttons (Open, Archive, Save address settings, Paste link / Scan), link vs address in onboarding, accepted/removed %1$s events
- az (iOS): Mark deleted/verified/read, Keep conversation, Forward, Lock after, broken bold
- pt-BR: Monthly badge period, "shown on your profile" caption
- de: Support SimpleX as an action (it is also an alert button)
- cs (iOS): %d day singular, Test relay caption grammar

---------

Co-authored-by: Evgeny <evgeny@poberezkin.com>
Co-authored-by: Evgeny @ SimpleX Chat <259188159+evgeny-simplex@users.noreply.github.com>
Co-authored-by: mlanp <github@lang.xyz>
Co-authored-by: Ranakan <ranakan.dev@protonmail.ch>
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: SanctumSaturn <oraculogithub@gmail.com>
Co-authored-by: summoner001 <summoner@disroot.org>
Co-authored-by: Mireli5656 <miraliseyidli5656@gmail.com>
Co-authored-by: Terciman <ter.distant121@passinbox.com>
Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: jonnysemon <jonnysemon@users.noreply.hosted.weblate.org>
Co-authored-by: No name <usir.alerts@onionmail.org>
Co-authored-by: zenobit <zenobit@disroot.org>
Co-authored-by: Fábio Pereira (Serzedo) <fpereira-84@users.noreply.hosted.weblate.org>
Co-authored-by: Martin Kozempel <martin1928@users.noreply.hosted.weblate.org>
Co-authored-by: Mireli5656 <mireli5656@users.noreply.hosted.weblate.org>
Co-authored-by: Narasimha-sc <166327228+Narasimha-sc@users.noreply.github.com>
2026-10-19 12:24:24 +00:00
2ea1ec0d50 ui: reconnect call (#7711)
* Update Call.hs

* Update Internal.hs

* add reconnecting string

* Update WebRTC.kt

* desktop: show reconnecting state, keep call duration

* android keep connection time correct wiith adding reconnecting

* Update CallTypes.swift add reconnecting status on IOS

* Update WebRTC.swift add reconnecting

* add reconnecting and make sure call duration is correct

* Update call.ts

* core: regenerate call.js from call.ts

* Update Call.hs revert call status change

minimization

* Update Internal.hs rever to minimize changes

* Update CallTypes.swift minimize changes

* Update WebRTC.kt minimize changes

* Update CallView.desktop.kt desktop shows reconnecting without sending to core

* Update CallView.android.kt show reconnecting without sending it to the core

* Update ActiveCallView.swift show reconnecting to ui without sending to core

* Update CallView.desktop.kt add reconnecting sound on reconnect

* Update CallView.android.kt add reconnecting sound

* Update ActiveCallView.swift play reconnecting sound when reconnecting

* Update RecAndPlay.desktop.kt

* rebuild

* refactor

* build

* android, desktop: restart ICE to reconnect calls

* ios: restart ICE to reconnect calls

* webrtc: add call reconnection e2e tests

* android, desktop: fix lost call commands

---------

Co-authored-by: GuavaGoat <320862384+GuavaGoat@users.noreply.github.com>
Co-authored-by: Evgeny Poberezkin <evgeny@poberezkin.com>
Co-authored-by: Evgeny @ SimpleX Chat <259188159+evgeny-simplex@users.noreply.github.com>
2026-10-19 12:17:16 +01:00