Compare commits

...

613 Commits

Author SHA1 Message Date
Evgeny Poberezkin
bf25b116d7 Merge branch 'stable' into stable-ios 2024-01-18 20:59:49 +00:00
Evgeny Poberezkin
5236e0f201 core: 5.4.4.0 2024-01-18 20:56:45 +00:00
Evgeny Poberezkin
1eb1ed92f7 ci: disable *-armv7a tags 2024-01-17 19:27:07 +00:00
Evgeny Poberezkin
c25e9e3b72 scripts: curl/wget security (#3693) 2024-01-17 15:23:43 +00:00
Evgeny Poberezkin
300223b32e core: update simplexmq 5.5.0.6 (fix race conditions) (#3691)
* core: update simplexmq (fix race conditions)

* simplexmq 5.5.0.6
2024-01-16 23:42:29 +00:00
Evgeny Poberezkin
8d7dcb550a core: update simplexmq, optimize batching, remove builder (#3685)
* core: update simplexmq (optimize batching, remove builder)

* do not use builder to batch

* refactor
2024-01-15 10:46:13 +00:00
Evgeny Poberezkin
c070d69114 Merge branch 'stable' into stable-ios 2024-01-10 12:17:26 +00:00
Evgeny Poberezkin
045b195483 5.4.3: ios 188, android 169, desktop 22 2024-01-10 11:56:57 +00:00
Evgeny Poberezkin
a3b91ad182 Merge branch 'stable' into stable-ios 2024-01-09 20:20:52 +00:00
Evgeny Poberezkin
53414608db core: 5.4.3.0 (simplexmq 5.5.0.5) 2024-01-09 20:20:14 +00:00
Stanislav Dmitrenko
c7cf206585 android: fix call sound when the app in the background (#3660)
* android: fix call sound when the app in the background

* using previous notification channel

* Revert "using previous notification channel"

This reverts commit 19da9a9ce193c39b353f478e884a97bbbf002e77.

* prevent playing sound on call twice
2024-01-09 19:45:46 +00:00
Evgeny Poberezkin
6067ac3c93 ios: more aggressive GC in NSE 2024-01-09 19:34:54 +00:00
Evgeny Poberezkin
591df1e0f4 Merge branch 'stable' into stable-ios 2024-01-09 10:40:52 +00:00
Evgeny Poberezkin
a2f190a6c6 core: update simplexmq (better batching) 2024-01-09 09:15:35 +00:00
Stanislav Dmitrenko
267178dddb android, desktop: show alerts on critical and internal errors (#3653)
* android, desktop: show alerts on critical and internal errors

* test

* don't stop chat if it's stopped already

* show notification

* restart chat or app

* Revert "test"

This reverts commit 5b78bbae5b.

* update strings

* strings2

* refactoring

* refactoring2

* refactoring3

---------

Co-authored-by: Evgeny Poberezkin <2769109+epoberezkin@users.noreply.github.com>
2024-01-08 18:20:52 +00:00
spaced4ndy
fadce0c140 core: create new chat controller with chatActivated set to true 2024-01-08 17:34:10 +04:00
spaced4ndy
58ad97fe6d core: pause cleanup when chat is suspended (#3658) 2024-01-08 17:28:01 +04:00
Evgeny Poberezkin
3ccd9903a7 core: do not start clean up manager in background NSE (#3657)
* core: do not start clean up manager in background NSE

* update UIs

* fix test
2024-01-08 12:53:16 +00:00
Evgeny Poberezkin
e294999044 ios: fix callkit calls via NSE (#3655)
* ios: fix callkit calls via NSE

* comments

* more reliable NSE start

* remove public logs, different RTS parameters for NSE

* only suspend NSE if we have chat controller, to avoid crashes if suspension attempted without controller created

* comments

* fix

* simplify
2024-01-08 10:56:01 +00:00
Evgeny Poberezkin
b1156d401c Merge branch 'stable' into stable-ios 2024-01-06 11:49:37 +00:00
Evgeny Poberezkin
2bbc687f4a core: simplexmq 5.5.0.4 2024-01-06 11:48:28 +00:00
Evgeny Poberezkin
bb61b9c658 core: update simplexmq (critical errors, worker restarts, subscription timeouts) 2024-01-05 20:07:19 +00:00
sh
575d899f5a build-android: fix new arrangement of nix command (#3634) 2024-01-02 14:39:23 +00:00
Evgeny Poberezkin
3411658a8d Merge branch 'stable' into stable-ios 2023-12-30 10:21:46 +00:00
sh
825257e898 build-android: update nix and add armv7a branch switch (#3612)
* build-android: build armv7a in seperate tag

And update nix install.

* build-android: change tag detection logic

* build-android: minor change of logic
2023-12-30 10:19:56 +00:00
Evgeny Poberezkin
fdbfeb6652 Merge branch 'master-ios' into stable-ios 2023-12-28 09:18:42 +00:00
Evgeny Poberezkin
51bf2f413c 5.4.2: ios 186, android 166, desktop 20 2023-12-27 22:24:21 +00:00
Evgeny Poberezkin
2c6b0ef917 Merge branch 'master-ghc8107' into master-ios 2023-12-27 21:03:06 +00:00
Evgeny Poberezkin
ff239d81e5 Merge branch 'master' into master-ghc8107 2023-12-27 21:02:11 +00:00
Evgeny Poberezkin
e3a69b12ba core: 5.4.2.1 (simplexmq 5.5.0.2) 2023-12-27 21:00:19 +00:00
Evgeny Poberezkin
0a6e47dd61 Merge branch 'master' into master-ghc8107 2023-12-27 20:57:25 +00:00
Evgeny Poberezkin
ee75219ed3 core: 5.4.2.1 (simplexmq 5.5.0.2) 2023-12-27 20:57:05 +00:00
Evgeny Poberezkin
b220b5f6ec core: fix contact subscriptions (#3611) 2023-12-27 18:55:50 +00:00
Stanislav Dmitrenko
0b8346701c android, desktop: fix terminal items crash (#3607)
* android, desktop: fix terminal items crash

* test

* Revert "test"

This reverts commit 3f1e5c93ca.

---------

Co-authored-by: Evgeny Poberezkin <2769109+epoberezkin@users.noreply.github.com>
2023-12-27 14:59:38 +00:00
Evgeny Poberezkin
efc873b09b core: min version for remote connection 5.4.2.0 (#3594) 2023-12-27 14:48:28 +00:00
Stanislav Dmitrenko
9f71502b51 desktop (windows): fix script that generates localization (#3606)
* desktop (windows): fix script that generates localization

* firstOrNull
2023-12-27 14:47:04 +00:00
Evgeny Poberezkin
5d8dd8ffd3 Merge branch 'master-ghc8107' into master-ios 2023-12-27 14:10:02 +00:00
Evgeny Poberezkin
9918d91def Merge branch 'master' into master-ghc8107 2023-12-27 14:09:23 +00:00
Evgeny Poberezkin
bbde6d81ee core: update simplexmq 2023-12-27 13:57:02 +00:00
Stanislav Dmitrenko
58906e1a60 desktop (windows): fixed handling non-utf8 Windows profile names (#3605) 2023-12-27 13:56:48 +00:00
Stanislav Dmitrenko
ed3d234826 android, desktop: limit text length in terminal view (#3604) 2023-12-27 11:27:34 +00:00
Stanislav Dmitrenko
dded56d8b8 ios: converting video to mp4 and making quality lower (#3597)
* ios: converting video to mp4 and making quality lower

Lower quality allows to play that videos on Android as well

* update export settings

---------

Co-authored-by: Avently <avently@local>
Co-authored-by: Evgeny Poberezkin <2769109+epoberezkin@users.noreply.github.com>
2023-12-27 11:23:46 +00:00
spaced4ndy
4d5aefa82c ui: don't share address at onboarding by default (#3603)
* ios: don't share address at onboarding by default

* android
2023-12-27 10:54:44 +00:00
Evgeny Poberezkin
235b220378 Merge branch 'master-ghc8107' into master-ios 2023-12-26 21:27:34 +00:00
Evgeny Poberezkin
de637fab50 Merge branch 'master' into master-ghc8107 2023-12-26 21:12:36 +00:00
Evgeny Poberezkin
9ac99ec2d9 core: update simplexmq (mark failed work items to continue processing) (#3600)
* core: update simplexmq (mark failed work items to continue processing) WIP

* simplexmq
2023-12-26 19:53:58 +00:00
spaced4ndy
37d033c7a5 core: test group members connect in group when they were previously connected as contacts (#3595) 2023-12-25 11:03:02 +04:00
spaced4ndy
5798efcf71 code: modify test 2023-12-24 20:55:03 +04:00
spaced4ndy
e086719f27 core: add to tests 2023-12-24 20:44:30 +04:00
spaced4ndy
bb4293eb5e fix tests 2023-12-24 20:23:09 +04:00
Evgeny Poberezkin
c3c66182f2 Merge branch 'stable' 2023-12-24 14:20:58 +00:00
Evgeny Poberezkin
5b90d92ca2 core: add group tests 2023-12-24 14:20:07 +00:00
Evgeny Poberezkin
af22348bf8 core: use version from config, add tests (#3588)
* core: use version from config, add tests

* comment

* refactor
2023-12-24 13:27:51 +00:00
Stanislav Dmitrenko
5a6670998c android, desktop: loading prev messages better (#3585)
* android, desktop: loading prev messages better

* better

* better

---------

Co-authored-by: Evgeny Poberezkin <2769109+epoberezkin@users.noreply.github.com>
2023-12-24 12:22:00 +00:00
spaced4ndy
700f6fa663 core, docs: drop message views if they exist, remove mentions in docs (#3589)
* core, docs: drop message views if they exist, remove mentions in docs

* fix migration
2023-12-24 11:13:34 +00:00
Stanislav Dmitrenko
d474cae705 ios: saving and sharing items menu item (#3581)
* ios: saving and sharing items menu item

* refactor

---------

Co-authored-by: Avently <avently@local>
Co-authored-by: Evgeny Poberezkin <2769109+epoberezkin@users.noreply.github.com>
2023-12-23 23:15:31 +00:00
Evgeny Poberezkin
6a8dba25f0 Merge branch 'master-ghc8107' into master-ios 2023-12-23 19:57:49 +00:00
Evgeny Poberezkin
6d0a83aa58 Merge branch 'master' into master-ghc8107 2023-12-23 19:57:08 +00:00
Evgeny Poberezkin
2834b192ce core: do not create group history item (#3586)
* core: do not create group history item

* fix tests
2023-12-23 19:56:01 +00:00
Evgeny Poberezkin
decfbdb07b Merge branch 'master-ghc8107' into master-ios 2023-12-23 17:25:40 +00:00
Evgeny Poberezkin
6a66525927 Merge branch 'master' into master-ghc8107 2023-12-23 17:24:47 +00:00
Evgeny Poberezkin
b8cb954882 ios: update library 2023-12-23 17:24:30 +00:00
Evgeny Poberezkin
6aeef6f132 5.4.2.0: fix migration in simplexmq 2023-12-23 16:09:08 +00:00
Evgeny Poberezkin
9becf48db6 Merge branch 'master-ghc8107' into master-ios 2023-12-23 15:13:16 +00:00
Evgeny Poberezkin
f5ed8debcc Merge branch 'master' into master-ghc8107 2023-12-23 15:11:38 +00:00
Evgeny Poberezkin
355d2449c5 fix for GHC 8.10.7 2023-12-23 15:05:36 +00:00
Evgeny Poberezkin
fa1702a566 5.4.2.0: update .cabal 2023-12-23 14:13:38 +00:00
Evgeny Poberezkin
f7382cdd6f Merge branch 'master' into master-ghc8107 2023-12-23 13:52:44 +00:00
Evgeny Poberezkin
95d6df926c 5.4.2.0 2023-12-23 13:46:11 +00:00
Evgeny Poberezkin
cccd517277 core: fix simplexmq commit 2023-12-23 13:08:40 +00:00
spaced4ndy
12d1ada25e core: support batch sending in groups, batch introductions; send recent message history to new members (#3519)
* core: batch send stubs, comments

* multiple events in ChatMessage and supporting types

* Revert "multiple events in ChatMessage and supporting types"

This reverts commit 9b239b26ba.

* schema, refactor group processing for batched messages

* encoding, refactor processing

* refactor code to work with updated schema

* encoding, remove instances

* wip

* implement batching

* batch introductions

* wip

* collect and send message history

* missing new line

* rename

* test

* rework to build history via chat items

* refactor, tests

* correctly set member version range, dont include deleted items

* tests

* fix disappearing messages

* check number of errors

* comment

* check size in encodeChatMessage

* fix - don't check msg size for binary

* use builder

* rename

* rename

* rework batching

* lazy msg body

* use withStoreBatch

* refactor

* reverse batches

* comment

* possibly fix builder for single msg

* refactor batcher

* refactor

* dont repopulate msg_deliveries on down migration

* EncodedChatMessage type

* remove type

* batcher tests

* add tests

* group history preference

* test group link

* fix tests

* fix for random update

* add test testImageFitsSingleBatch

* refactor

* rename function

* refactor

* mconcat

* rename feature

* catch error on each batch

* refactor file inv retrieval

* refactor gathering item forward events

* refactor message batching

* unite migrations

* move files

* refactor

* Revert "unite migrations"

This reverts commit 0be7a3117a.

* refactor splitFileDescr

* improve tests

* Revert "dont repopulate msg_deliveries on down migration"

This reverts commit 2944c1cc28.

* fix down migration

---------

Co-authored-by: Evgeny Poberezkin <2769109+epoberezkin@users.noreply.github.com>
2023-12-23 13:07:23 +00:00
Evgeny Poberezkin
f93f68e425 core: agent background mode for iOS NSE (#3574)
* core: agent background mode for iOS NSE

* change parameter for APIActivateChat

* fix

* update lib

* update lib

* simplexmq

* simplify
2023-12-23 13:06:59 +00:00
Andor Kesselman
23989aca57 Update README.md (#3553) 2023-12-22 08:48:26 +00:00
Andor Kesselman
57a6e85668 docs: fix typo (#3552) 2023-12-22 08:47:48 +00:00
Stanislav Dmitrenko
67590f3258 Revert "ios: making thumbnails faster" (#3571)
This reverts commit cd9cb8e064.
2023-12-22 08:46:55 +00:00
Stanislav Dmitrenko
c83238c35a desktop: enable sending images and files with enter (#3582) 2023-12-21 22:48:32 +00:00
Stanislav Dmitrenko
8b0d2dede7 android, desktop: saving and sharing files menu item (#3580) 2023-12-21 15:19:36 +00:00
Stanislav Dmitrenko
c4855313b6 android: splash screen with background color on Android 12+ (#3579) 2023-12-21 13:49:49 +00:00
Evgeny Poberezkin
2bff3b9c97 desktop, android: update api to pass controller when encrypting files (use ChaChaDRG as source of randomness) (#3578) 2023-12-21 12:49:18 +00:00
Evgeny Poberezkin
aa037c0662 ios: update core library (uses GHC 9.6.3) 2023-12-21 10:05:43 +00:00
Evgeny Poberezkin
2590fc0c80 Merge branch 'master-ghc8107' into master-ios 2023-12-21 10:00:44 +00:00
Evgeny Poberezkin
521b901cc9 Merge branch 'master' into master-ghc8107 (without changes for iPhone7) 2023-12-21 09:59:25 +00:00
Evgeny Poberezkin
d198d6a8db core: build iOS library with ghc 9.6.3 with iPhone7 etc. support (#3577)
* bump haskell.nix

* bump flake.lock

* Try openssl fix

* CFLAGS. not CCFLAGS

* Fix iOS build issues and improve static library handling

---------

Co-authored-by: Moritz Angermann <moritz.angermann@gmail.com>
2023-12-21 09:57:43 +00:00
Evgeny Poberezkin
cdd735930d Merge branch 'master-ghc8107' into master-ios 2023-12-21 00:45:46 +00:00
Evgeny Poberezkin
754c76d6fd Merge branch 'master' into master-ghc8107 2023-12-21 00:45:10 +00:00
Evgeny Poberezkin
7bcda7e54b core: use ChaChaDRG as the source of randomness (#3551)
* core: use ChaChaDRG as the source of randomness

* do not use entropy directly

* dont use RNG from agent

* simplexmq

* update iOS
2023-12-21 00:42:40 +00:00
Stanislav Dmitrenko
4a4d470859 android, desktop: try-catch composables (#3575)
* android, desktop: try-catch composables

* test

* better catching on Android

* more try-catch'es

* Revert "test"

This reverts commit adaf92b116.

* more try-catch'es

* unneeded imports
2023-12-20 18:00:44 +00:00
Evgeny Poberezkin
6ba3100d34 core: batch sending messages (#3566)
* core: batch sending messages

* batch without iorefs (#3573)

* one-pass

* simplexmq

* simplexmq

* simplexmq

* simplexmq

* revert change to ios project file

* refactor

* simplify

---------

Co-authored-by: Alexander Bondarenko <486682+dpwiz@users.noreply.github.com>
2023-12-20 10:38:39 +04:00
Evgeny Poberezkin
7b073ba9f8 core: allow deleting last user (#3567)
* core: allow deleting last user (tests fail)

* tests, allow activating the hidden user when there is no active user

* hide logs

Co-authored-by: spaced4ndy <8711996+spaced4ndy@users.noreply.github.com>

* comment

Co-authored-by: spaced4ndy <8711996+spaced4ndy@users.noreply.github.com>

* comment

Co-authored-by: spaced4ndy <8711996+spaced4ndy@users.noreply.github.com>

---------

Co-authored-by: spaced4ndy <8711996+spaced4ndy@users.noreply.github.com>
2023-12-19 10:26:01 +00:00
Stanislav Dmitrenko
5e042d222e desktop: saving qr code as an image (#3572) 2023-12-19 10:24:13 +00:00
Stanislav Dmitrenko
26a189917b sctipt: check string formatting (#3570)
* sctipt: check string formatting

* all
2023-12-18 21:37:10 +00:00
spaced4ndy
ce9218b186 ios: rework authentication (#3556) 2023-12-18 22:04:49 +04:00
Evgeny Poberezkin
f0338a03d1 directory: better search, allow both simplex:/ and simplex.chat links in description (#3546)
* directory: new commands

* better search

* search test

* return group links in simplex.chat domain, allow both simplex:/ and simplex.chat links in group description
2023-12-18 10:41:08 +00:00
Evgeny Poberezkin
6fa0001ea7 ios: delay suspendChat in NSE, background schedule depends on notifications mode (#3561)
* ios: delay suspendChat in NSE

* different background refresh interval depending on the settings

* simplify

* comment

* reduce NSE suspend interval

* space
2023-12-18 10:36:25 +00:00
Stanislav Dmitrenko
974fa448b4 android, desktop: some alerts became privacy sensitive (#3554)
* android, desktop: some alerts became privacy sensitive

* changes
2023-12-14 13:11:19 +00:00
spaced4ndy
8cec5428ee core: save CIContent tag in chat_items table (#3555) 2023-12-14 17:08:40 +04:00
Evgeny Poberezkin
73130bf321 ios: update core library 2023-12-13 21:48:25 +00:00
Evgeny Poberezkin
9bfc2ed16e nix: fix script 2023-12-13 20:30:25 +00:00
Evgeny Poberezkin
aea7ff1c89 nix: fix script 2023-12-13 20:27:58 +00:00
Evgeny Poberezkin
52c22c2f77 nix: fix direct-sqlcipher sha 2023-12-13 20:23:18 +00:00
Evgeny Poberezkin
f16da09213 Merge branch 'master-ghc8107' into master-ios 2023-12-13 12:36:22 +00:00
Evgeny Poberezkin
256f85024f Merge branch 'master' into master-ghc8107 2023-12-13 12:35:37 +00:00
spaced4ndy
67241ff65c ios: fix code scanners only attempting to scan once (#3548) 2023-12-13 16:13:05 +04:00
spaced4ndy
b6b041490f core: improve chat list pagination performance, simplify logic by always reading chat stats and last item id for previews (#3541)
* core: improve chat list pagination performance

* fix query

* core: improve chat list pagination performance, simplify logic by always reading chat stats (#3543)

* microseconds

* fix

* update simplexmq

* simplify queries

---------

Co-authored-by: Evgeny Poberezkin <2769109+epoberezkin@users.noreply.github.com>
2023-12-13 15:32:23 +04:00
Evgeny Poberezkin
7f9f9a674c ios: fix member view freezing on iOS 15, closes #3487 (#3547) 2023-12-13 11:27:28 +00:00
Evgeny Poberezkin
ae94bb6f87 core: use crypton instead of cryptonite (#3542)
* update hackage

* use crypton instead of cryptonite

* remove http2 from cabal.project

* simplexmq
2023-12-13 11:20:03 +00:00
Evgeny Poberezkin
870f9e42dd Merge branch 'master' into master-ghc8107 2023-12-12 20:09:39 +00:00
Evgeny Poberezkin
7ec39d1ffa all: increase default TCP timeouts, update simplexmq (#3540) 2023-12-12 13:13:36 +00:00
Evgeny Poberezkin
ca6dfb5ea1 docs: update latest version 2023-12-12 10:25:02 +00:00
Evgeny Poberezkin
a5048db6fa ios: improve media picker for multiple images/videos (#3538)
* ios: improve media picker to work with multiple images reliably

* MainActor
2023-12-12 09:04:48 +00:00
Evgeny Poberezkin
aca3a71b38 ios: update library 2023-12-11 18:57:42 +00:00
Evgeny Poberezkin
a993a26920 Merge branch 'master-ghc8107' into master-ios 2023-12-11 17:37:17 +00:00
Evgeny Poberezkin
8a66390a78 fix for GHC 8.10.7 2023-12-11 16:14:56 +00:00
Evgeny Poberezkin
aff589becd Merge branch 'master-ghc8107' into master-ios 2023-12-11 14:57:49 +00:00
Evgeny Poberezkin
6546426ec0 Merge branch 'master' into master-ghc8107 2023-12-11 14:56:25 +00:00
Evgeny Poberezkin
d358390e3d Merge pull request #3532 from simplex-chat/ios-notifications
improve iOS notifications
2023-12-11 14:55:03 +00:00
Evgeny Poberezkin
f9a125bc32 Merge branch 'master' into ios-notifications 2023-12-11 14:11:00 +00:00
spaced4ndy
5125b27938 Merge branch 'master-ghc8107' into master-ios 2023-12-11 17:53:26 +04:00
spaced4ndy
53560378bb Merge branch 'master' into master-ghc8107 2023-12-11 17:52:48 +04:00
Alexander Bondarenko
35c1975d66 core: chat list pagination (#3505)
* add pagination args to APIGetChats

* add search to chat list API

* rename arg to paginationTs_ to match type

* lift another condition to ids query

* collect all chat refs before sorting, then get details

* split remaining preview functions

* roll back to collecting ids first with query cleanup

* add connection join back to filter out groups

* extract and expand tests

* add fav/unread args

* WIP

* lay out the queries with favs

* tweak tests

* add fav tests

* fix order by in the before case

* build query footer wholly from pagination

* add migration for direct contacts

* fix setting contact_used

* fix setting contact_used for group link contacts

* align search x filters space with UI, support filter by either favorite or unread, optimize queries, indexes

* always set chat_ts, fix tests

* refactor tests

* fix pagination logic, more tests

* refactor, rename

* increase default pagination count

* comments

* refactor

* comment

* report errors

* refactor

* remove unused type

---------

Co-authored-by: spaced4ndy <8711996+spaced4ndy@users.noreply.github.com>
2023-12-11 17:50:32 +04:00
Evgeny Poberezkin
0bfe37137c core: update simplexmq (message notification markers) 2023-12-11 13:11:35 +00:00
Evgeny Poberezkin
666903ae76 Merge branch 'master' into ios-notifications 2023-12-11 13:06:32 +00:00
Evgeny Poberezkin
8a41a4c214 ios: do not start chat if it was stopped, deliver "app stopped" notifications (#3535)
* add stopped notifications, remove full off mode

* core: allow initializing chat data without starting chat

* ios: ask before starting chat if it was stopped

* correct text

Co-authored-by: spaced4ndy <8711996+spaced4ndy@users.noreply.github.com>

* fix comment

---------

Co-authored-by: spaced4ndy <8711996+spaced4ndy@users.noreply.github.com>
2023-12-11 12:59:49 +00:00
Evgeny Poberezkin
79a954336c ios: communication between NSE and app via files (#3533)
* ios: communication between NSE and app via files

* clean up

* better concurrency
2023-12-11 12:34:56 +00:00
Evgeny Poberezkin
f65b8a9e78 core: mark all user messages read (#3530) 2023-12-11 12:26:45 +00:00
Evgeny Poberezkin
e8016adfdc simplexmq 2023-12-10 17:47:44 +00:00
Evgeny Poberezkin
d3059afc99 ios, core: better notifications processing to avoid contention for database (#3485)
* core: forward notifications about message processing (for iOS notifications)

* simplexmq

* the option to keep database key, to allow re-opening the database

* export new init with keepKey and reopen DB api

* stop remote ctrl when suspending chat

* ios: close/re-open db on suspend/activate

* allow activating chat without restoring (for NSE)

* update NSE to suspend/activate (does not work)

* simplexmq

* suspend chat and close database when last notification in the process is processed

* stop reading notifications on message markers

* replace async stream with cancellable concurrent queue

* better synchronization of app and NSE

* remove outside of task

* remove unused var

* whitespace

* more debug logging, handle cancelled read after dequeue

* comments

* more comments
2023-12-09 21:59:40 +00:00
Evgeny Poberezkin
691d318764 Merge branch 'master-ios' into stable-ios 2023-12-09 20:43:45 +00:00
Evgeny Poberezkin
2f7632a70f 5.4.1: ios 185, android 164, desktop 19 2023-12-07 21:01:14 +00:00
Evgeny Poberezkin
28b7bad69f Merge branch 'master-ghc8107' into master-ios 2023-12-07 15:13:12 +00:00
Evgeny Poberezkin
9f3d3e8ba4 Merge branch 'master' into master-ghc8107 2023-12-07 15:00:23 +00:00
Evgeny Poberezkin
27c14f32f1 core: 5.4.0.7 2023-12-07 14:30:42 +00:00
Stanislav Dmitrenko
13a32f7864 android: made minimum supported version of Android as 9 (#3525) 2023-12-07 10:49:16 +00:00
Stanislav Dmitrenko
b1652b8930 desktop: fix toasts theme (#3524) 2023-12-06 21:19:30 +00:00
Stanislav Dmitrenko
a9b36e8e39 desktop: fix onboarding when choosing random password (#3523) 2023-12-06 20:33:53 +00:00
Evgeny Poberezkin
ee163a6540 core: add missing field 2023-12-06 12:34:10 +00:00
Evgeny Poberezkin
4fd6405113 core: update simplexmq (better suspend agent) 2023-12-06 00:19:24 +00:00
Stanislav Dmitrenko
ccc62274ee android, desktop: crash handler addition (#3517)
* android, desktop: crash handler addition

* added
2023-12-05 22:50:25 +00:00
Stanislav Dmitrenko
4c6d52ba75 android, desktop: crash handler (#3516)
* android, desktop: crash handler

* test

* rename

* string

* Revert "test"

This reverts commit 530faf39c1.

---------

Co-authored-by: Evgeny Poberezkin <2769109+epoberezkin@users.noreply.github.com>
2023-12-05 21:31:49 +00:00
Evgeny Poberezkin
9df63160e5 ios: fix simplex address view (#3515)
* ios: fix simplex address view

* fix lib paths

* fix call
2023-12-05 09:48:04 +00:00
Stanislav Dmitrenko
c8e9788c29 desktop: enhancements to remote desktop connect UI (#3513)
* desktop: enhancements to remote desktop connect UI

* changes

* more changes

This reverts commit e8323e8bfa.

* color

* random port
2023-12-04 21:04:58 +00:00
spaced4ndy
7099776357 docs: fix typo 2023-12-04 19:17:24 +04:00
Evgeny Poberezkin
4efd505fd3 Merge branch 'master-ghc8107' into master-ios 2023-12-04 12:32:23 +00:00
Evgeny Poberezkin
087acd9180 changes to support GHC 8.10.7 (#3512)
* Revert "raise lower bound on mtl to a real version (#3499)"

This reverts commit f94c0311c1.

* Revert "core: expand ranges to fit ghc 8.10 & 9.6 (#3496)"

This reverts commit 9a1c7f41f7.

* update simplexmq

* remove netword-transport fork

* compatibility with GHC 8.10.7

* simplexmq

* fix test

* simplexmq, deps

* update sqlcipher deps in sha256nix

* fix index-state in cabal.project

* index-state

* remove import

* add cabal.project.freeze

* simplexmq

* remove freeze

* simplexmq

* bytestring,simplexmq

* template-haskell, simplexmq

* simplexmq

* simplexmq

* simplexmq

* mtl

* simplexmq

* remove duplicate index-state
2023-12-04 12:29:49 +00:00
Evgeny Poberezkin
0b822e4a5c Merge branch 'master' into master-ghc8107 2023-12-04 10:07:16 +00:00
Evgeny Poberezkin
3481d379c6 core: compatibility with GHC 8.10.7, narrow dependency ranges (#3503)
* Revert "raise lower bound on mtl to a real version (#3499)"

This reverts commit f94c0311c1.

* Revert "core: expand ranges to fit ghc 8.10 & 9.6 (#3496)"

This reverts commit 9a1c7f41f7.

* update simplexmq

* remove netword-transport fork

* simplexmq

* fix test

* fix index-state in cabal.project

* simplexmq

* simplexmq

* bytestring,simplexmq

* template-haskell, simplexmq

* simplexmq

* simplexmq

* mtl

* simplexmq
2023-12-04 10:01:37 +00:00
Evgeny Poberezkin
85c1e871dc Merge branch 'stable' 2023-12-04 00:06:53 +00:00
Evgeny Poberezkin
fec5ff3f15 docs: SimpleX address (#3508)
* docs: SimpleX address

* table

* header
2023-12-03 22:21:13 +00:00
Evgeny Poberezkin
acaa597c90 desktop, android: fix image not appearing in view when received (#3504)
* desktop, android: fix image not appearing in view when received

* change to KeyChangeEffect
2023-12-03 15:42:43 +00:00
Evgeny Poberezkin
6a9a67db14 cli: option to mark shown messages as read (off by default) (#3506)
* cli: option to mark shown messages as read (off by default)

* fix tests

* fix tests
2023-12-03 15:42:26 +00:00
Evgeny Poberezkin
f8a469488e Merge branch 'master' into master-ghc8107 2023-12-02 12:30:36 +00:00
Alexander Bondarenko
f94c0311c1 raise lower bound on mtl to a real version (#3499)
* raise lower bound on mtl to a real version

* simplexmq

---------

Co-authored-by: Evgeny Poberezkin <2769109+epoberezkin@users.noreply.github.com>
2023-12-02 12:24:29 +00:00
Stanislav Dmitrenko
e1ff7c88d7 desktop: allow changing listening ip and port of remote (#3498)
* desktop: allow changing listening ip and port of remote

* remove empty lines

---------

Co-authored-by: Evgeny Poberezkin <2769109+epoberezkin@users.noreply.github.com>
2023-12-01 20:41:08 +00:00
Evgeny Poberezkin
3b5e806418 Merge branch 'master' into master-ghc8107 2023-12-01 17:46:12 +00:00
Alexander Bondarenko
9a1c7f41f7 core: expand ranges to fit ghc 8.10 & 9.6 (#3496)
* expand ranges to fit ghc 8.10 & 9.6

* update nix

* use hashes from mq master

* fix more deps

* use network-transport from hackage
2023-12-01 16:52:47 +00:00
Stanislav Dmitrenko
40e69ae713 desktop: enable database operations (#3495)
* desktop: enable database operations

* disconnect hosts button

* not relaying on dev tools

* different logic

* different logic 2

* toggle placement
2023-12-01 15:04:00 +00:00
spaced4ndy
b74e33b958 docs: inactive group members rfc (#3419) 2023-12-01 19:02:50 +04:00
Stanislav Dmitrenko
540c8883a0 android: do not show alert too early in obboarding (#3493) 2023-11-30 19:39:16 +00:00
Stanislav Dmitrenko
0e18b13bea desktop: adapting onboarding process to linking devices (#3490)
* desktop: adapting onboarding process to linking devices

* show progress on long operations

* changes

* clearing chat cache logic

* lines

---------

Co-authored-by: Evgeny Poberezkin <2769109+epoberezkin@users.noreply.github.com>
2023-11-30 19:38:21 +00:00
spaced4ndy
bcb2e9fb9b Merge branch 'master-ghc8107' into master-ios 2023-11-30 21:11:07 +04:00
spaced4ndy
ef5c13b1c1 Merge branch 'master' into master-ghc8107 2023-11-30 21:10:51 +04:00
spaced4ndy
a4b44254bc core: update simplexmq (ghc 8.10.7 compatibility) (#3492) 2023-11-30 21:09:07 +04:00
spaced4ndy
48056d7452 Merge branch 'master-ghc8107' into master-ios 2023-11-30 20:57:16 +04:00
spaced4ndy
38533213d2 Merge branch 'master' into master-ghc8107 2023-11-30 20:56:51 +04:00
spaced4ndy
5819e42305 core: remove CRNewContactConnection response; mobile, desktop: create pending connections based on api responses (CRNewContactConnection was being used as "event" in UI) (#3489) 2023-11-30 20:31:32 +04:00
Jesse Horne
9580b4110d desktop: remember window position and size (#3465)
* initial work on storing desktop window position and size

* removed useless imports

* updated to use app preferences

* vars to vals

* defensive programming

* fixed default

* removed default json

* do nothing if encoding to json while storing fails

* names, clean up

* move comment

* changes

---------

Co-authored-by: Evgeny Poberezkin <2769109+epoberezkin@users.noreply.github.com>
Co-authored-by: Avently <7953703+avently@users.noreply.github.com>
2023-11-30 12:43:01 +00:00
Stanislav Dmitrenko
05a64c99a2 ios: moving webrtc commands processing to another mechanism (#3480)
* ios: moving webrtc commands processing to another mechanism

* async

* decide

* handle errors

* error alert

* await

---------

Co-authored-by: Avently <avently@local>
Co-authored-by: Evgeny Poberezkin <2769109+epoberezkin@users.noreply.github.com>
2023-11-28 17:36:05 +00:00
Alexander Bondarenko
6a21d5c7f1 add remote host bindings (#3471)
* add remote host bindings

* group iface/address together

* rename migration

* add implementation

* update view and api

* bump upstream

* add schema

---------

Co-authored-by: Evgeny Poberezkin <2769109+epoberezkin@users.noreply.github.com>
2023-11-28 16:32:33 +00:00
Stanislav Dmitrenko
950bbe19da ios: fix calls connecting state (#3475)
* ios: fix calls connecting state

* optimization

* changes

* removed relay protocol

* simplify

* use actor

* fix loop, better onChange, some questions

* remove extra iteration

---------

Co-authored-by: Avently <avently@local>
Co-authored-by: Evgeny Poberezkin <2769109+epoberezkin@users.noreply.github.com>
2023-11-27 22:20:51 +00:00
Stanislav Dmitrenko
f31054de4f desktop (windows): fix action (#3479) 2023-11-27 22:11:53 +00:00
Evgeny Poberezkin
05278e5a06 core: allow remote host commands without user (#3478) 2023-11-27 18:34:15 +00:00
spaced4ndy
b5a99b2b14 Merge branch 'master-ghc8107' into master-ios 2023-11-27 19:17:56 +04:00
spaced4ndy
b0002fe07d Merge branch 'master' into master-ghc8107 2023-11-27 19:17:39 +04:00
spaced4ndy
7a54d74517 Revert "ios: update libraries (#3474)"
This reverts commit bfcb2ac230.
2023-11-27 19:16:53 +04:00
spaced4ndy
bfcb2ac230 ios: update libraries (#3474) 2023-11-27 19:02:44 +04:00
spaced4ndy
3073c4a1d5 core: fix chat previews showing not the latest message, fix message ordering in direct chats; mobile: update group previews only on timestamp increase (#3473) 2023-11-27 17:14:12 +04:00
Evgeny Poberezkin
d4ac1c0cf2 core, ui: add remote host/controller stop reasons to events (#3472) 2023-11-26 23:23:37 +00:00
Evgeny Poberezkin
5899b8f734 Merge branch 'master-ghc8107' into master-ios 2023-11-26 20:00:03 +00:00
Evgeny Poberezkin
4a311b9578 fix for ghc 8.10.7 2023-11-26 19:34:39 +00:00
Evgeny Poberezkin
b8da5e225b Merge branch 'master' into master-ghc8107 2023-11-26 18:53:40 +00:00
Evgeny Poberezkin
d29f1bb0cf core: use fourmolu styles (#3470) 2023-11-26 18:16:37 +00:00
Jesse Horne
75c2de8a12 desktop: closing console window no longer closes entire application (#3466)
* closing the console now doesn't close all windows

* simplify

---------

Co-authored-by: Evgeny Poberezkin <2769109+epoberezkin@users.noreply.github.com>
2023-11-26 13:40:51 +00:00
Alexander Bondarenko
f20ac33e67 cli: remove clashing short option for device-name (#3468) 2023-11-26 13:16:32 +00:00
Evgeny Poberezkin
d9428db2f5 Merge branch 'master-ios' into stable-ios 2023-11-26 13:15:13 +00:00
Evgeny Poberezkin
9e9a6ac64e Merge branch 'master' into master-ios 2023-11-26 11:51:34 +00:00
Evgeny Poberezkin
5cc537f14c Merge branch 'master' into master-ghc8107 2023-11-26 11:50:50 +00:00
Evgeny Poberezkin
8cc0954430 Merge branch 'stable' 2023-11-26 11:50:30 +00:00
Evgeny Poberezkin
1e6891e222 blog: v5.4 announcement (#3457)
* blog: v5.4 announcement

* update

* corrections

Co-authored-by: spaced4ndy <8711996+spaced4ndy@users.noreply.github.com>

* add images, CLI section

* images

* preview, readme

* correction

---------

Co-authored-by: spaced4ndy <8711996+spaced4ndy@users.noreply.github.com>
2023-11-25 18:27:41 +00:00
Evgeny Poberezkin
962964a73d docs: update downloads page 2023-11-25 14:15:41 +00:00
Evgeny Poberezkin
b9dd2f45c9 rfc: post-quantum resistant augmented double ratchet algorithm (#3463)
* rfc: post-quantum resistant augmented double ratchet algorithm

* update doc

* replace Kyber with "some KEM"
2023-11-25 12:51:05 +00:00
Evgeny Poberezkin
de1c885501 ios: 5.4 build 184: switch to GHC 8.10.7 (9.6.3 crashes on older iPhone models), fix Connect to desktop closing when switching to QR code scan 2023-11-25 11:22:02 +00:00
Evgeny Poberezkin
1902b692f5 5.4: ios 183, android 162, desktop 18 2023-11-25 00:13:31 +00:00
Evgeny Poberezkin
6c05eb0ff3 directory: support group names with spaces (#3458) 2023-11-24 23:21:38 +00:00
Evgeny Poberezkin
d148ce4cbb ui: translations (#3459)
* Translated using Weblate (Russian)

Currently translated at 100.0% (1500 of 1500 strings)

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

* Translated using Weblate (Russian)

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

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

* Translated using Weblate (Russian)

Currently translated at 100.0% (1346 of 1346 strings)

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

* Translated using Weblate (Hungarian)

Currently translated at 22.1% (332 of 1500 strings)

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

* Translated using Weblate (German)

Currently translated at 100.0% (1346 of 1346 strings)

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

* Translated using Weblate (Hungarian)

Currently translated at 22.3% (335 of 1500 strings)

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

* Translated using Weblate (Polish)

Currently translated at 96.9% (1454 of 1500 strings)

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

* Translated using Weblate (French)

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

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

* Translated using Weblate (Dutch)

Currently translated at 100.0% (1346 of 1346 strings)

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

* Translated using Weblate (Polish)

Currently translated at 100.0% (1500 of 1500 strings)

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

* Translated using Weblate (Polish)

Currently translated at 100.0% (1346 of 1346 strings)

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

* Translated using Weblate (Hungarian)

Currently translated at 28.6% (429 of 1500 strings)

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

* 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/

* import/export/update

---------

Co-authored-by: Istvan Novak <easthvan@gmail.com>
Co-authored-by: mlanp <github@lang.xyz>
Co-authored-by: B.O.S.S <BxOxSxS@protonmail.com>
Co-authored-by: Ophiushi <41908476+ishi-sama@users.noreply.github.com>
Co-authored-by: M1K4 <oomikaoo@gmail.com>
Co-authored-by: Hosted Weblate <hosted@weblate.org>
2023-11-24 23:20:28 +00:00
Evgeny Poberezkin
3d09073bfc ios: update core lib to 5.4.0.6 2023-11-24 20:46:00 +00:00
Evgeny Poberezkin
da64b2e3cd android, desktop: fix translation 2023-11-24 20:37:32 +00:00
Stanislav Dmitrenko
4572fec61d desktop (windows): fix lib build (#3456) 2023-11-24 20:05:41 +00:00
Evgeny Poberezkin
1bbaffe0a6 Merge branch 'master-ghc8107' into master-ios 2023-11-24 20:02:30 +00:00
Alexander Bondarenko
fe9953fc49 desktop: remove GC flag when building on windows (#3455)
* desktop: remove GC flag when building on windows

* add correct define
2023-11-24 20:00:20 +00:00
Stanislav Dmitrenko
e91a1f151d desktop: hide profiles screen on remote host change (#3454) 2023-11-24 19:24:16 +00:00
Evgeny Poberezkin
0c096e2c89 Merge branch 'master' into master-ghc8107 2023-11-24 19:00:30 +00:00
Evgeny Poberezkin
34d7fe3744 core: 5.4.0.6 2023-11-24 18:59:41 +00:00
Alexander Bondarenko
4327b023ed terminal: add remote user information (#3448)
* terminal: add remote user information

* rename

---------

Co-authored-by: Evgeny Poberezkin <2769109+epoberezkin@users.noreply.github.com>
2023-11-24 18:44:12 +00:00
Stanislav Dmitrenko
50bada24af desktop: better status check of loaded remote files (#3453) 2023-11-24 18:43:28 +00:00
spaced4ndy
97934c8289 android, desktop: fix alert text for deleting received message 2023-11-24 21:10:03 +04:00
Evgeny Poberezkin
4a254560c0 desktop: fix user address changes on connected mobile (#3452)
* desktop: fix user address changes on connected mobile

* close user-specific views when remote host changes
2023-11-24 16:51:31 +00:00
Stanislav Dmitrenko
f9b5c673c5 android, desktop: better handling of URI's (#3450) 2023-11-24 16:19:31 +00:00
spaced4ndy
8ce9dd7ab6 android: don't show lock notice on first start (#3451) 2023-11-24 20:05:37 +04:00
spaced4ndy
9fb4b3cf40 desktop: don't show device specific network and database settings when connected to remote host (#3449) 2023-11-24 19:38:19 +04:00
Evgeny Poberezkin
7f9a490edb website: translations (#3447)
* Translated using Weblate (Arabic)

Currently translated at 100.0% (252 of 252 strings)

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

* Translated using Weblate (Arabic)

Currently translated at 100.0% (252 of 252 strings)

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

---------

Co-authored-by: jonnysemon <jonnysemon@users.noreply.hosted.weblate.org>
2023-11-24 14:21:13 +00:00
Evgeny Poberezkin
bfd13f059a ui: translations (#3446)
* Translated using Weblate (Dutch)

Currently translated at 100.0% (1502 of 1502 strings)

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

* Translated using Weblate (Dutch)

Currently translated at 100.0% (1341 of 1341 strings)

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

* Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (1503 of 1503 strings)

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

* Translated using Weblate (Dutch)

Currently translated at 100.0% (1503 of 1503 strings)

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

* 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 (Russian)

Currently translated at 97.7% (1459 of 1493 strings)

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

* Translated using Weblate (Russian)

Currently translated at 100.0% (1341 of 1341 strings)

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

* Translated using Weblate (Italian)

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

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

* Translated using Weblate (Dutch)

Currently translated at 100.0% (1502 of 1502 strings)

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

* Translated using Weblate (Dutch)

Currently translated at 100.0% (1341 of 1341 strings)

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

* Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (1503 of 1503 strings)

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

* Translated using Weblate (Dutch)

Currently translated at 100.0% (1503 of 1503 strings)

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

* 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 (Russian)

Currently translated at 97.7% (1459 of 1493 strings)

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

* Translated using Weblate (Russian)

Currently translated at 100.0% (1341 of 1341 strings)

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

* Translated using Weblate (Italian)

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

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

* Translated using Weblate (Russian)

Currently translated at 100.0% (1493 of 1493 strings)

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

* Translated using Weblate (Russian)

Currently translated at 99.8% (1339 of 1341 strings)

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

* Translated using Weblate (Arabic)

Currently translated at 92.4% (1380 of 1493 strings)

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

* Translated using Weblate (Dutch)

Currently translated at 100.0% (1494 of 1494 strings)

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

* Added translation using Weblate (Hungarian)

* Translated using Weblate (Dutch)

Currently translated at 100.0% (1495 of 1495 strings)

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

* Translated using Weblate (Hungarian)

Currently translated at 0.5% (8 of 1495 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 1.4% (21 of 1495 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 2.0% (30 of 1495 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 2.1% (32 of 1495 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 10.9% (163 of 1495 strings)

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

* Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (1495 of 1495 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 12.3% (184 of 1495 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 100.0% (1495 of 1495 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 14.8% (222 of 1495 strings)

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

* Translated using Weblate (Dutch)

Currently translated at 100.0% (1495 of 1495 strings)

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

* Translated using Weblate (Hungarian)

Currently translated at 21.6% (323 of 1495 strings)

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

* Translated using Weblate (German)

Currently translated at 97.7% (1461 of 1495 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 100.0% (1495 of 1495 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% (1341 of 1341 strings)

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

* Translated using Weblate (Hungarian)

Currently translated at 21.9% (328 of 1495 strings)

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

* Translated using Weblate (German)

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

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

* Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (1500 of 1500 strings)

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

* Translated using Weblate (Dutch)

Currently translated at 100.0% (1500 of 1500 strings)

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

* Translated using Weblate (Turkish)

Currently translated at 70.0% (1051 of 1500 strings)

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

* ru: corrections

* export/import

* ios: export

* ru: corrections

---------

Co-authored-by: M1K4 <oomikaoo@gmail.com>
Co-authored-by: Float <float.hu+@gmail.com>
Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: J R <jr@simplex.chat>
Co-authored-by: Random <random-r@users.noreply.hosted.weblate.org>
Co-authored-by: jonnysemon <jonnysemon@users.noreply.hosted.weblate.org>
Co-authored-by: Istvan Novak <easthvan@gmail.com>
Co-authored-by: Eric <zxmegaxqug@hldrive.com>
Co-authored-by: mlanp <github@lang.xyz>
Co-authored-by: Ophiushi <41908476+ishi-sama@users.noreply.github.com>
Co-authored-by: xe1st <dnzkckali@gmail.com>
2023-11-24 14:18:31 +00:00
Evgeny Poberezkin
c9aec88c39 desktop: fix sending videos via connected mobile 2023-11-24 13:14:52 +00:00
Evgeny Poberezkin
b1cf1656a0 core: cli remote control help section (#3445) 2023-11-24 10:48:14 +00:00
Alexander Bondarenko
74e80eb348 core: add remote stop reason and state (#3444)
* add remote stop reason and state

* rename

---------

Co-authored-by: Evgeny Poberezkin <2769109+epoberezkin@users.noreply.github.com>
2023-11-23 22:00:20 +00:00
Evgeny Poberezkin
6f3174d0a1 android, desktop: remove unnecessary serialization 2023-11-23 21:25:32 +00:00
Evgeny Poberezkin
8f0a9cd609 ios: connect remote desktop via multicast (#3436)
* ios: connect remote desktop via multicast

* works

* fix camera freeze when leaving linked devices view

* label

* fix linked devices

* fix compatible

* string
2023-11-23 21:22:29 +00:00
Stanislav Dmitrenko
b2dbb558f9 android, desktop: connect remote desktop via multicast (#3442)
* android, desktop: connect remote desktop via multicast

* changes

* string

---------

Co-authored-by: Evgeny Poberezkin <2769109+epoberezkin@users.noreply.github.com>
2023-11-23 21:00:11 +00:00
Stanislav Dmitrenko
f7903c5c83 desktop: close remote host connecting screen on stop of host (#3440) 2023-11-23 19:49:53 +00:00
Evgeny Poberezkin
4d3529a3e0 desktop: fix incorrect remote host for active user (#3441) 2023-11-23 17:00:13 +00:00
Evgeny Poberezkin
57eea0947f Merge branch 'master' into master-ios 2023-11-23 16:23:30 +00:00
Evgeny Poberezkin
1781495ee3 Merge branch 'master' into master-ghc8107 2023-11-23 16:22:46 +00:00
Alexander Bondarenko
d837f87f09 fix circular cancel at rcDiscoverCtrl (#3438) 2023-11-23 11:00:57 +00:00
Evgeny Poberezkin
d3f9616f9b core: report controller info when found via multicast (#3437)
* core: report controller info when found via multicast

* handle parse error
2023-11-23 10:07:26 +00:00
Evgeny Poberezkin
1b7baa244a core: track network statuses in CLI (#3434) 2023-11-23 08:39:08 +00:00
Alexander Bondarenko
954b7150af android, desktop: set RTS options for core (#3418)
* desktop: allow settings RTS options

* set initial heap and arena sizes

* add non-moving GC for even more productivity/less reallocs

* add RTS options for android too

---------

Co-authored-by: Evgeny Poberezkin <2769109+epoberezkin@users.noreply.github.com>
2023-11-22 22:37:33 +00:00
Evgeny Poberezkin
d0419df396 android: close Use from desktop when disconnecting 2023-11-22 22:34:30 +00:00
Evgeny Poberezkin
01f351e65a ios: haskell RTS options (#3433) 2023-11-22 22:12:42 +00:00
Evgeny Poberezkin
2d4e99d610 cli: set device name for remote control via CLI option (#3427)
* cli: set device name for remote control via CLI option

* fix

* add property in tests
2023-11-22 22:11:32 +00:00
Evgeny Poberezkin
4af4fbae2b ios: close sheet when disconnecting from desktop (#3435) 2023-11-22 22:10:41 +00:00
spaced4ndy
15fdab597b core: shuffle members when sending messages and introductions; send to admins and owners first (#3431)
* core: shuffle members when sending messages and introductions; send to admins and owners first

* refactor

---------

Co-authored-by: Evgeny Poberezkin <2769109+epoberezkin@users.noreply.github.com>
2023-11-22 21:36:52 +00:00
Stanislav Dmitrenko
0c1d78ab08 desktop: specifying port in connect remote host page (#3432)
* desktop: specifying port in connect remote host page

* shorter string

---------

Co-authored-by: Evgeny Poberezkin <2769109+epoberezkin@users.noreply.github.com>
2023-11-22 20:17:05 +00:00
Evgeny Poberezkin
324f614e00 core: return remote controller port to UI (#3430) 2023-11-22 17:40:10 +00:00
spaced4ndy
cec0fe2702 ios, android: add author group member role to fix decoding (hidden from UI) (#3429) 2023-11-22 18:47:46 +04:00
Stanislav Dmitrenko
48d7afc959 desktop: enhancements to remote hosts experience (#3428) 2023-11-22 14:35:32 +00:00
Evgeny Poberezkin
9442121efa desktop: do not switch remote host when inactive host is disconnected (#3426) 2023-11-22 12:14:49 +00:00
spaced4ndy
69acac5331 android: remove unused strings (#3424) 2023-11-22 10:19:39 +04:00
Evgeny Poberezkin
aade3d359f v5.4-beta.4: ios 182, android 161, desktop 17 2023-11-21 23:32:33 +00:00
Evgeny Poberezkin
c1d89f2c0f ios: move hs_init to background thread (#3411) 2023-11-21 22:21:01 +00:00
Stanislav Dmitrenko
c40bfb0f43 android, desktop: show remote host info (#3423)
* android, desktop: show remote host info

* hide alerts too
2023-11-21 21:49:39 +00:00
Evgeny Poberezkin
006ab7c46a Merge branch 'master-ghc8107' into master-ios 2023-11-21 21:15:39 +00:00
Evgeny Poberezkin
45102442f4 Merge branch 'master' into master-ghc8107 2023-11-21 21:15:10 +00:00
Evgeny Poberezkin
64520a4cf4 core: 5.4.0.5, update simplexmq 2023-11-21 21:12:43 +00:00
Evgeny Poberezkin
d0f43628ef ui: translations (#3421)
* Translated using Weblate (Italian)

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

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

* Translated using Weblate (Chinese (Simplified))

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

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

* Translated using Weblate (Dutch)

Currently translated at 100.0% (1483 of 1483 strings)

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

* Translated using Weblate (Dutch)

Currently translated at 100.0% (1332 of 1332 strings)

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

* android: fix formatted strings

* ios: imp/exp localizations

---------

Co-authored-by: Random <random-r@users.noreply.hosted.weblate.org>
Co-authored-by: Eric <zxmegaxqug@hldrive.com>
Co-authored-by: No name <CertainBot@users.noreply.hosted.weblate.org>
Co-authored-by: M1K4 <oomikaoo@gmail.com>
2023-11-21 20:30:21 +00:00
spaced4ndy
febf3e0a45 ui: v5.4 what's new (#3413)
* ios: v5.4 what's new

* android

* export localizations

* update

---------

Co-authored-by: Evgeny Poberezkin <2769109+epoberezkin@users.noreply.github.com>
2023-11-21 19:38:05 +00:00
Jesse Horne
097242e7a8 desktop: add image pasting from clipboard (#3378)
* first pass at desktop image pasting for multiplatform

* removed debug println

* fixed bug with pasting text

* temp files are deleted now following simplex conventions

* optimizations

---------

Co-authored-by: Avently <7953703+avently@users.noreply.github.com>
2023-11-21 19:37:15 +00:00
spaced4ndy
45026b6bf5 Merge branch 'master-ghc8107' into master-ios 2023-11-21 19:42:06 +04:00
spaced4ndy
3bdc6b5e28 Merge branch 'master' into master-ghc8107 2023-11-21 19:41:06 +04:00
spaced4ndy
a8576c2340 core: test forwarded message deduplication, mute terminal error (#3414) 2023-11-21 19:25:50 +04:00
Alexander Bondarenko
5a08a26c9a desktop: add exception handlers to startReceiver loop (#3417)
* desktop: add exception handlers to startReceiver loop

* simplify

* more exceptions

---------

Co-authored-by: Evgeny Poberezkin <2769109+epoberezkin@users.noreply.github.com>
Co-authored-by: Avently <7953703+avently@users.noreply.github.com>
2023-11-21 14:43:52 +00:00
Alexander Bondarenko
da8789ef4c desktop: fix RCP tag in AgentErrorType (#3416) 2023-11-21 12:20:04 +00:00
Evgeny Poberezkin
12f38028f3 Merge branch 'master-ghc8107' into master-ios 2023-11-21 00:01:53 +00:00
Evgeny Poberezkin
3597d34716 Merge branch 'master' into master-ghc8107 2023-11-21 00:00:59 +00:00
Evgeny Poberezkin
47cd7de1ae core: 5.4.0.4 2023-11-21 00:00:29 +00:00
Evgeny Poberezkin
624a3abba2 website: translations (#3412)
* Translated using Weblate (German)

Currently translated at 100.0% (252 of 252 strings)

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

* Translated using Weblate (Arabic)

Currently translated at 100.0% (252 of 252 strings)

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

---------

Co-authored-by: mlanp <github@lang.xyz>
Co-authored-by: jonnysemon <jonnysemon@users.noreply.hosted.weblate.org>
2023-11-20 22:29:18 +00:00
Evgeny Poberezkin
121985138a ios: export localizations 2023-11-20 22:24:19 +00:00
Evgeny Poberezkin
7f5efd8927 desktop: use correct remote host when creating/connecting via links (#3409) 2023-11-20 20:56:05 +00:00
Evgeny Poberezkin
96d3c9988c Merge pull request #3404 from simplex-chat/ep/core-add-remote-host
desktop: add remote host ID to entities
2023-11-20 17:21:56 +00:00
spaced4ndy
f6b786a187 get user index by remote host id 2023-11-20 20:31:35 +04:00
spaced4ndy
11478da6ef Revert "remoteHostId in backend"
This reverts commit 72654caca6.
2023-11-20 19:56:31 +04:00
spaced4ndy
72654caca6 remoteHostId in backend 2023-11-20 19:51:56 +04:00
Evgeny Poberezkin
55ead740cc update hpack 2023-11-20 14:43:05 +00:00
Evgeny Poberezkin
4fecfe825a update hpack 2023-11-20 14:34:25 +00:00
Evgeny Poberezkin
fad4cbf7e5 Merge branch 'master-ghc8107' into master-ios 2023-11-20 14:30:44 +00:00
Evgeny Poberezkin
49a9b0e7d6 update hpack version 2023-11-20 14:30:10 +00:00
Evgeny Poberezkin
b6b23d6ddd Merge branch 'master-ghc8107' into master-ios 2023-11-20 13:25:10 +00:00
Evgeny Poberezkin
307a1b3c5e fix for ghc 8.10.7 2023-11-20 13:23:45 +00:00
Evgeny Poberezkin
ed6b3bbead Merge branch 'master' into master-ghc8107 2023-11-20 13:01:22 +00:00
spaced4ndy
44c88badde remoteHostId in entities kotlin 2023-11-20 16:31:52 +04:00
Evgeny Poberezkin
53a31ec60e core: add remote host ID to entities 2023-11-20 11:51:40 +00:00
spaced4ndy
718436bf55 core: don't read all group members where unnecessary (#3403) 2023-11-20 15:27:15 +04:00
Evgeny Poberezkin
5bbf4d70a1 Merge pull request #3151 from simplex-chat/remote-desktop
use mobile from desktop
2023-11-20 11:12:01 +00:00
Evgeny Poberezkin
970ca3a409 Merge branch 'master' into remote-desktop 2023-11-20 10:35:20 +00:00
Evgeny Poberezkin
c536ca7f0f core: add events not sent to connected remote desktop (#3402) 2023-11-20 10:34:24 +00:00
Evgeny Poberezkin
07ef2a0b64 android: remove ACCESS_WIFI_STATE (#3391) 2023-11-20 10:20:31 +00:00
Evgeny Poberezkin
5b7de8f8c1 desktop, android: pass remote host to API from the loaded objects, to prevent race conditions (#3397)
* desktop, android: pass remote host explicitely to API calls

* use remote host ID in model updates

* add remote host to chat console

* add remote host to notifications functions
2023-11-20 10:20:10 +00:00
Alexander Bondarenko
68cbc605be add remote session sequence to prevent stale state updates (#3390)
* add remote session sequence to prevent stale state updates

* remote RHStateKey

* add StateSeq check to controller

* clean up

* simplify

* undo withRemoteXSession API change

* simplify

---------

Co-authored-by: Evgeny Poberezkin <2769109+epoberezkin@users.noreply.github.com>
2023-11-20 10:19:00 +00:00
spaced4ndy
9ecd5ff1b2 Merge branch 'master-ghc8107' into master-ios 2023-11-20 14:07:45 +04:00
spaced4ndy
7d4127c51d Merge branch 'master' into master-ghc8107 2023-11-20 14:07:08 +04:00
spaced4ndy
3a510eeaf0 core: rename forwarded fields (#3401) 2023-11-20 14:00:55 +04:00
Alexander Bondarenko
ba94f76a90 core: fix remote session stuck in Starting after crashed rcConnect (#3399) 2023-11-20 09:33:43 +00:00
spaced4ndy
85e44dcb77 core: split group message forwarding tests (#3400) 2023-11-20 13:05:59 +04:00
Evgeny Poberezkin
0297cc43d0 Merge branch 'master-ghc8107' into master-ios 2023-11-20 00:07:33 +00:00
Evgeny Poberezkin
e1a8099474 fix for GHC 8.10.7 2023-11-20 00:06:45 +00:00
Evgeny Poberezkin
daa8d9bb21 Merge branch 'master' into master-ghc8107 2023-11-19 23:42:13 +00:00
Evgeny Poberezkin
2a8d7b8926 core: add commands that will not be forwarded to connected mobile (#3398)
* core: add commands that will not be forwarded to connected mobile

* fail if command that must be executed locally sent to remote host
2023-11-19 20:48:25 +00:00
Evgeny Poberezkin
d9031cb209 Merge branch 'master' into remote-desktop 2023-11-19 11:18:08 +00:00
Evgeny Poberezkin
bf8457fb40 website: translations (#3396)
* Translated using Weblate (French)

Currently translated at 100.0% (252 of 252 strings)

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

* Translated using Weblate (Dutch)

Currently translated at 100.0% (252 of 252 strings)

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

* Translated using Weblate (Italian)

Currently translated at 100.0% (252 of 252 strings)

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

* Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (252 of 252 strings)

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

* Translated using Weblate (Polish)

Currently translated at 100.0% (252 of 252 strings)

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

* Translated using Weblate (Russian)

Currently translated at 100.0% (252 of 252 strings)

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

* Translated using Weblate (French)

Currently translated at 100.0% (252 of 252 strings)

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

* Translated using Weblate (Dutch)

Currently translated at 100.0% (252 of 252 strings)

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

* Translated using Weblate (Italian)

Currently translated at 100.0% (252 of 252 strings)

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

* Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (252 of 252 strings)

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

* Translated using Weblate (Polish)

Currently translated at 100.0% (252 of 252 strings)

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

* Translated using Weblate (Russian)

Currently translated at 100.0% (252 of 252 strings)

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

---------

Co-authored-by: Ophiushi <41908476+ishi-sama@users.noreply.github.com>
Co-authored-by: M1K4 <oomikaoo@gmail.com>
Co-authored-by: Random <random-r@users.noreply.hosted.weblate.org>
Co-authored-by: Eric <zxmegaxqug@hldrive.com>
Co-authored-by: B.O.S.S <BxOxSxS@protonmail.com>
Co-authored-by: Timur Bagautdinov <mr.bagautdinov14@gmail.com>
2023-11-19 11:14:09 +00:00
Evgeny Poberezkin
59392b361b ui: translations (#3392)
* Translated using Weblate (Polish)

Currently translated at 97.4% (1400 of 1437 strings)

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

* Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (1437 of 1437 strings)

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

* Translated using Weblate (Dutch)

Currently translated at 99.0% (1423 of 1437 strings)

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

* Translated using Weblate (Polish)

Currently translated at 100.0% (1437 of 1437 strings)

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

* Translated using Weblate (Polish)

Currently translated at 100.0% (1300 of 1300 strings)

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

* Translated using Weblate (Dutch)

Currently translated at 100.0% (1437 of 1437 strings)

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

* Translated using Weblate (Dutch)

Currently translated at 100.0% (1300 of 1300 strings)

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

* Translated using Weblate (French)

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

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

* Translated using Weblate (German)

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

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

* Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (1439 of 1439 strings)

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

* Translated using Weblate (Dutch)

Currently translated at 100.0% (1439 of 1439 strings)

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

* Translated using Weblate (Polish)

Currently translated at 100.0% (1439 of 1439 strings)

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

* Translated using Weblate (French)

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

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

* Translated using Weblate (Ukrainian)

Currently translated at 100.0% (1439 of 1439 strings)

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

* update de: Meine -> Ihre

* nl: Gebruiker -> Lid

* nl: gebruiker -> lid 2

* ios, nl: gebruiker -> lid

* ios, nl: gebruiker -> lid 2

* android: fix strings

* ios: export/import localizations

---------

Co-authored-by: B.O.S.S <BxOxSxS@protonmail.com>
Co-authored-by: Eric <zxmegaxqug@hldrive.com>
Co-authored-by: M1K4 <oomikaoo@gmail.com>
Co-authored-by: Ophiushi <41908476+ishi-sama@users.noreply.github.com>
Co-authored-by: Random <random-r@users.noreply.hosted.weblate.org>
Co-authored-by: mlanp <github@lang.xyz>
Co-authored-by: Eryk Michalak <gnu.ewm@protonmail.com>
Co-authored-by: Denys Rastiegaiev <daaren@gmail.com>
2023-11-19 11:06:49 +00:00
Stanislav Dmitrenko
8f0538e756 android: UI for remote connections (#3395)
* android: UI for remote connections

* camera permissions

* eol

---------

Co-authored-by: Evgeny Poberezkin <2769109+epoberezkin@users.noreply.github.com>
2023-11-19 01:07:42 +00:00
Moritz Angermann
b164cc2fa6 nix: fix lib:support for armv7a (#3394) 2023-11-19 00:31:29 +00:00
Evgeny Poberezkin
f9e5a56e1a ios: terminate session on network failure, add description for local network access 2023-11-18 22:20:22 +00:00
Evgeny Poberezkin
96e000e3ea ios: add user-defined device name for remote desktop connection 2023-11-18 20:28:55 +00:00
Evgeny Poberezkin
ca8833c0c1 desktop: sending and receiving files via connected mobile (#3365)
* desktop: support remote files (WIP)

* working with remote files locally

* better

* working with remote file downloads

* sending files

* fixes of loading files in some situations

* image compression

* constant for remote hosts

* refactor

---------

Co-authored-by: Avently <7953703+avently@users.noreply.github.com>
2023-11-18 20:11:30 +00:00
Evgeny Poberezkin
e95d9d0b49 core: rename migration to remote-control, comments (#3393) 2023-11-18 19:18:02 +00:00
Evgeny Poberezkin
cc434cda55 Merge branch 'master' into remote-desktop 2023-11-18 18:03:13 +00:00
spaced4ndy
c0e8740f50 core: group message forwarding (#3360)
* core: group message forwarding types

* xgrpmemcon

* rework xgrpmemcon to use intros table

* only forward w/t error

* forward msg

* xGrpMsgForward, check integrity outside

* deduplicate group messages

* test

* change error

* item forwarded flag

* intro_chat_protocol_version, bump version

* comment

* highly available client option

* more comments

* notify xgrpmemcon on deduplication

* member vrange

* encoding

* remove MsgForward

* remove import

* exclude files from forwarding

* refactor

* rename to align with protocol

* forward more message types

* add events

* remove unused error, function

* add x.file.cancel, x.info and x.grp.mem.new to forwarded messages

* remove unused x.msg.file.cancel

---------

Co-authored-by: Evgeny Poberezkin <2769109+epoberezkin@users.noreply.github.com>
2023-11-18 17:52:01 +00:00
Evgeny Poberezkin
80abc18371 core: update simplexmq (xrcp) 2023-11-18 15:35:06 +00:00
qvsojBJGiEnR
8f6a31ca07 Update app-settings.md (#3379) 2023-11-17 23:29:25 +00:00
Stanislav Dmitrenko
c9a1de6e4b msys2 setup in different place (#3389) 2023-11-17 19:20:44 +00:00
Alexander Bondarenko
42e0400014 core: add remote controller discovery with multicast (#3369)
* draft multicast chat api

* prepare tests

* Plug discovery into chat api

* Add discovery timeout

* post-merge fixes

* rename discovery state to match others

* update for unified invitation

* fix review notices

* rename, remove stack, update simplexmq

---------

Co-authored-by: Evgeny Poberezkin <2769109+epoberezkin@users.noreply.github.com>
2023-11-17 18:50:38 +00:00
Stanislav Dmitrenko
79064e149a desktop: enabled smooth scrolling again (#3388) 2023-11-17 18:19:38 +00:00
Stanislav Dmitrenko
84e09f195c desktop (windows): fix build of CLI (#3387) 2023-11-17 18:19:02 +00:00
Evgeny Poberezkin
f6c4e969e4 nix: add openssl to simplexmq, swift flag to simplex-chat (#3386)
* nix: add swift flag

* add openssl for simplexmq to nix

* add openssl to android simplemq, try iOS with enableKTLS = false flag

* fix android
2023-11-17 13:28:10 +00:00
Evgeny Poberezkin
86b916c169 Merge branch 'master' into remote-desktop 2023-11-17 13:02:54 +00:00
Evgeny Poberezkin
20dcfbbffe Merge branch 'master-ghc8107' into master-ios 2023-11-17 11:48:16 +00:00
Evgeny Poberezkin
3937ffa9a6 Merge branch 'master' into master-ghc8107 2023-11-17 11:47:52 +00:00
Alexander Bondarenko
cf102da4d3 remote: add test for rejected ca detection and stability (#3382)
* add test for rejected ca detection and stability

* update mq commit
2023-11-17 11:19:33 +00:00
Evgeny Poberezkin
0d7a048988 nix: patches for armv7a, fix segfault issues, etc (#3383)
* bump mobile-core-tools

* Update deps

* 🤦

* patch

* needs p

* 32bit patches

* bump haskell.nix

* bump again

* fix broken flake.lock

* bump haskell.nix

* bump haskell.nix (to fix darwin)

---------

Co-authored-by: Moritz Angermann <moritz.angermann@gmail.com>
2023-11-16 22:54:54 +00:00
Evgeny Poberezkin
d0f3a3d886 rfc: remote UI implementation (#3206) 2023-11-16 21:53:54 +00:00
Evgeny Poberezkin
64f0dbeb61 Merge branch 'master' into remote-desktop 2023-11-16 20:20:04 +00:00
Evgeny Poberezkin
909ff6516b Merge branch 'master-ghc8107' into master-ios 2023-11-16 18:55:39 +00:00
Evgeny Poberezkin
f6e66f1c53 Merge branch 'master' into master-ghc8107 2023-11-16 18:13:02 +00:00
Evgeny Poberezkin
0322b9708b desktop, ios: remote desktop/mobile connection (#3223)
* ui: remote desktop/mobile connection (WIP)

* add startRemoteCtrl and capability (does not work)

* re-add view

* update core library

* iOS connects to CLI

* ios: mobile ui

* multiplatform types

* update lib

* iOS and desktop connected

* fix controllers list on mobile

* remove iOS 16 paste button

* update device name

* connect existing device

* proposed model

* missing function names in exports

* unused

* remote host picker

* update type

* update lib, keep iOS session alive

* better UI

* update network statuses on switching remote/local hosts

* changes

* ios: prevent dismissing sheet/back when session is connected

* changes

* ios: fix back button asking to disconnect when not connected

* iOS: update type

* picker and session code

* multiplatform: update type

* menu fix

* ios: better ux

* desktop: better ux

* ios: options etc

* UI

* desktop: fix RemoteHostStopped event

* ios: open Use from desktop via picker

* desktop: "new mobile device"

* ios: load remote controllers synchronously, update on connect, fix alerts

* titles

* changes

* more changes to ui

* more and more changes in ui

* padding

* ios: show desktop version, handle errors

* fix stopped event

* refresh hosts always

* radical change

* optimization

* change

* ios: stop in progress session when closing window

---------

Co-authored-by: Avently <7953703+avently@users.noreply.github.com>
2023-11-16 16:53:44 +00:00
Alexander Bondarenko
c31ae39617 remote: fix circular error handling (#3380) 2023-11-16 14:56:39 +00:00
Alexander Bondarenko
339c3d2be1 Send CRRemote*Stopped on all errors (#3376)
* Send CRRemote*Stopped on all errors

Commands use the same action, made idempotent and don't send events.

* fix tests

* get http2 cancelling back
2023-11-15 17:31:36 +00:00
Alexander Bondarenko
a75fce8dfa Fix hostStore path and check before removing (#3375) 2023-11-15 15:57:29 +00:00
Evgeny Poberezkin
b71daed3ec core: include session code in all session states (#3374) 2023-11-15 13:17:31 +00:00
Alexander Bondarenko
fa9d61caa4 remove host store in deleteRemoteHost (#3373) 2023-11-15 13:09:52 +00:00
spaced4ndy
975f6d488e android: fix group join via invitation chat item (#3372) 2023-11-15 11:46:45 +04:00
Evgeny Poberezkin
3d617bce25 core: test JSON conversion (#3370) 2023-11-14 22:40:15 +00:00
Evgeny Poberezkin
d4ba1bbe69 core: update remote host session state (#3371) 2023-11-14 22:27:21 +00:00
Evgeny Poberezkin
0a4920daae core: encrypt stored/loaded remote files (#3366)
* core: encrypt stored/loaded remote files

* simplexmq

* constant
2023-11-14 16:44:12 +00:00
spaced4ndy
36509a6d79 ios, android: new message decryption error - ratchet synchronization (#3368) 2023-11-14 19:39:32 +04:00
Evgeny Poberezkin
4da1d21c81 Merge branch 'master' into remote-desktop 2023-11-14 14:43:58 +00:00
spaced4ndy
5bbde22ffa core: new message decryption error - ratchet synchronization (#3367) 2023-11-14 18:23:05 +04:00
Evgeny Poberezkin
1e8ae6d861 docs: update windows app link 2023-11-14 09:37:24 +00:00
Evgeny Poberezkin
f9df5aa41b Merge branch 'master' into remote-desktop 2023-11-13 20:41:51 +00:00
Evgeny Poberezkin
c91625b32a core: update remote host session state, terminate TLS in one more case (#3364)
* core: update remote host session state, terminate TLS in one more case

* name
2023-11-13 20:16:34 +00:00
Alexander Bondarenko
598b6659cc core: better handling of remote errors (#3358)
* Allow ExitCode exceptions to do their job

* Use appropriate error type

* Close TLS server when cancelling connected remote host

* Add timeout errors

* Bump simplexmq

* extract common timeout value
2023-11-13 18:39:41 +00:00
Evgeny Poberezkin
86bc70fa5a Merge branch 'master' into remote-desktop 2023-11-13 14:07:31 +00:00
Evgeny Poberezkin
72b25385ba core: event when new remote host added (#3355) 2023-11-12 21:43:43 +00:00
Evgeny Poberezkin
92e3f576ca core: return controller app info in response when connecting, validate ID key (#3353) 2023-11-12 14:40:49 +00:00
Evgeny Poberezkin
8e3e58cac8 core: update remote controller name (#3352) 2023-11-12 12:40:13 +00:00
Evgeny Poberezkin
8b67ff7a00 core: remote error handling (#3347)
* core: remote error handling

* fix test, show DB errors
2023-11-11 16:03:12 +00:00
Evgeny Poberezkin
bfb6dfb2c5 Merge branch 'master-ghc8107' into master-ios 2023-11-11 13:57:13 +00:00
Evgeny Poberezkin
1570bc2b99 Merge branch 'master' into master-ghc8107 2023-11-11 13:56:53 +00:00
Evgeny Poberezkin
beb22c6f87 Merge branch 'master' into remote-desktop 2023-11-11 13:53:51 +00:00
Evgeny Poberezkin
2f1c7400e9 Merge branch 'master-ghc8107' into master-ios 2023-11-11 09:52:27 +00:00
Evgeny Poberezkin
f3014f258d Merge branch 'master' into master-ghc8107 2023-11-11 09:51:42 +00:00
Evgeny Poberezkin
b1101fbce4 Merge branch 'master' into remote-desktop 2023-11-11 09:49:22 +00:00
Evgeny Poberezkin
97fd6a993e Merge branch 'master' into remote-desktop 2023-11-10 22:22:04 +00:00
Evgeny Poberezkin
168a31c9d7 Merge branch 'master-ghc8107' into master-ios 2023-11-10 21:22:56 +00:00
Evgeny Poberezkin
74b78a8d7b Merge branch 'master' into master-ghc8107 2023-11-10 21:11:08 +00:00
Evgeny Poberezkin
8e33b92f39 Merge branch 'master-ghc8107' into master-ios 2023-11-10 21:08:36 +00:00
Evgeny Poberezkin
fe4eb7b5af Merge branch 'master' into master-ghc8107 without changes, to skip update for ghc 9.6.3 2023-11-10 21:04:20 +00:00
Alexander Bondarenko
227007c8f6 add /switch remote host (#3342)
* Add SwitchRemoteHost

* Add message test

* Match remote prefix and the rest of the line

* Move prefix match to utils
2023-11-10 17:49:23 +00:00
Evgeny Poberezkin
02225df274 core: remote control command/response encryption and signing inside TLS (#3339)
* core: remote control command/response encryption inside TLS (except files, no signing)

* sign/verify

* update simplexmq

* fix lazy

* remove RSNone
2023-11-10 16:10:10 +00:00
Alexander Bondarenko
f41861c026 core: terminate remote control TLS connection on both sides (#3338)
* handle session setup errors

* add command/async wrapper

* move furniture around

* detect disconnects and force them with closeConnection

* simplify http server log

* close TLS in other cases

---------

Co-authored-by: Evgeny Poberezkin <2769109+epoberezkin@users.noreply.github.com>
2023-11-09 22:43:44 +00:00
Alexander Bondarenko
6d4febb669 core: handle remote control session setup errors (#3332)
* handle session setup errors

* add command/async wrapper

* move furniture around
2023-11-09 18:25:05 +00:00
Evgeny Poberezkin
3dd62ab05a core: remove Hello from the app remote protocol (#3336) 2023-11-09 09:37:56 +00:00
Alexander Bondarenko
b729144773 core: use xrcp protocol for desktop/mobile connection (#3305)
* WIP: start working on /connect remote ctrl

OOB is broken, requires fixing simplexmq bits.

* WIP: pull CtrlCryptoHandle from xrcp

* place xrcp stubs

* WIP: start switching to RemoteControl.Client types

* fix http2 sha

* fix sha256map.nix

* fix cabal.project

* update RC test

* WIP: add new remote session

* fix compilation

* simplify

* attach HTTP2 server to TLS

* starting host session in controller (WIP)

* more WIP

* compiles

* compiles2

* wip

* pass startRemote' test

* async to poll for events from host, test to send messages fails

* move xrcp handshake test to simplexmq

* detect session stops

* fix connectRemoteCtrl

* use step type

* app info

* WIP: pairing stores

* plug in hello/appInfo/pairings

* negotiate app version

* update simplexmw, remove KEM secrets from DB

* fix file tests

* tone down http2 shutdown errors

* Add stored session test

* bump simplexmq tag

* update simplexmq

* refactor, fix

* removed unused errors

* rename fields, remove unused file

* rename errors

---------

Co-authored-by: Evgeny Poberezkin <2769109+epoberezkin@users.noreply.github.com>
2023-11-08 20:13:52 +00:00
Evgeny Poberezkin
3839267f88 Merge branch 'master' into remote-desktop 2023-11-08 13:10:42 +00:00
Evgeny Poberezkin
2776d864a8 Merge branch 'master' into remote-desktop 2023-11-06 11:44:12 +00:00
Evgeny Poberezkin
3c35dcb4f2 Merge branch 'master-ghc8107' into master-ios 2023-11-06 11:27:10 +00:00
Evgeny Poberezkin
2516d5a393 Merge branch 'master' into master-ghc8107 2023-11-06 11:26:22 +00:00
spaced4ndy
552dc9ab64 Merge branch 'master-ghc8107' into master-ios 2023-11-06 11:42:23 +04:00
spaced4ndy
4253cd7fb9 Merge branch 'master' into master-ghc8107 2023-11-06 11:41:55 +04:00
Evgeny Poberezkin
177112ab18 update simplexmq 2023-11-04 19:04:40 +00:00
Evgeny Poberezkin
c2a99987f3 Merge branch 'master' into remote-desktop 2023-11-04 18:54:12 +00:00
Evgeny Poberezkin
916e14e44c Merge branch 'master-ghc8107' into master-ios 2023-11-04 13:39:57 +00:00
Evgeny Poberezkin
1f5b80d560 fix for ghc8107 2023-11-04 13:37:25 +00:00
Evgeny Poberezkin
2de111e76c Merge branch 'master' into master-ghc8107 2023-11-04 13:02:08 +00:00
Evgeny Poberezkin
0cc26d192d update sha256map.nix 2023-11-02 14:07:51 +00:00
Evgeny Poberezkin
8546c937b2 Merge branch 'master' into remote-desktop 2023-11-02 14:04:10 +00:00
Evgeny Poberezkin
8482dbfd99 core: update remote API commands/events (#3295)
* core: update remote API

* Add session verification event between tls and http2

* roll back char_ '@' parsers

* use more specific parser for verification codes

* cabal.project.local for mac

---------

Co-authored-by: IC Rainbow <aenor.realm@gmail.com>
2023-11-01 19:08:36 +00:00
Evgeny Poberezkin
b2f9270452 Merge branch 'master' into remote-desktop 2023-11-01 18:05:51 +00:00
Alexander Bondarenko
02c0cd5619 Cut at attaching http server/client (#3299)
* Cut at attaching http server/client

* switch to xrcp branch
2023-11-01 10:48:58 +00:00
spaced4ndy
c27e7fb68d Merge branch 'master-ghc8107' into master-ios 2023-10-30 21:00:55 +04:00
spaced4ndy
5dbe2b2745 Merge branch 'master' into master-ghc8107 2023-10-30 21:00:11 +04:00
spaced4ndy
b1fdc936a6 Merge branch 'master' into remote-desktop 2023-10-30 20:58:39 +04:00
Alexander Bondarenko
be44632b0b implement some of the robust discovery rfc (#3283)
* implement robust discovery

* remove qualified

---------

Co-authored-by: Evgeny Poberezkin <2769109+epoberezkin@users.noreply.github.com>
2023-10-30 14:00:54 +00:00
Evgeny Poberezkin
b48690dee6 Merge branch 'master' into remote-desktop 2023-10-29 19:15:08 +00:00
Evgeny Poberezkin
d90da57f12 core: store/get remote files (#3289)
* core: store remote files (wip)

* fix/test store remote file

* get remote file

* get file

* validate remote file metadata before sending to controller

* CLI commands, test

* update store method
2023-10-29 19:06:32 +00:00
Evgeny Poberezkin
c84d96b534 Merge branch 'master-ghc8107' into master-ios 2023-10-29 18:27:26 +00:00
Evgeny Poberezkin
6881600e06 Merge branch 'master' into master-ghc8107 2023-10-29 18:24:13 +00:00
Evgeny Poberezkin
9fb2b7fe73 Merge branch 'master' into remote-desktop 2023-10-29 18:05:03 +00:00
Evgeny Poberezkin
16bda26022 core: derive JSON with TH (#3275)
* core: derive JSON with TH

* fix tests

* simplify events

* reduce diff

* fix

* update simplexmq

* update simplexmq
2023-10-26 15:44:50 +01:00
Evgeny Poberezkin
3790752378 Merge branch 'master' into remote-desktop 2023-10-26 00:00:58 +01:00
Alexander Bondarenko
cd98fabe43 robust discovery RFC (#3276)
* add new discovery RFC

* update

* update

* update ports

---------

Co-authored-by: Evgeny Poberezkin <2769109+epoberezkin@users.noreply.github.com>
2023-10-25 16:39:46 +01:00
spaced4ndy
e2a6ff28fb Merge branch 'master-ghc8107' into master-ios 2023-10-25 10:47:53 +04:00
spaced4ndy
9ded1c9821 Merge branch 'master' into master-ghc8107 2023-10-25 10:47:35 +04:00
Evgeny Poberezkin
6185971827 Merge branch 'master' into remote-desktop 2023-10-24 23:19:49 +01:00
spaced4ndy
aaab15175d Merge branch 'master-ghc8107' into master-ios 2023-10-24 18:14:10 +04:00
spaced4ndy
c3e82a6a4e Merge branch 'master' into master-ghc8107 2023-10-24 18:13:56 +04:00
spaced4ndy
64b4d6c6f6 Merge branch 'master-ghc8107' into master-ios 2023-10-24 17:41:36 +04:00
spaced4ndy
e7e66ff873 Merge branch 'master' into master-ghc8107 2023-10-24 17:40:55 +04:00
Alexander Bondarenko
e1bd6a93af use multicast address for announce (#3241)
* use multicast address for announce

* Add explicit multicast group membership

* join multicast group on a correct side

---------

Co-authored-by: Evgeny Poberezkin <2769109+epoberezkin@users.noreply.github.com>
2023-10-23 13:44:04 +01:00
Evgeny Poberezkin
93800268e4 Merge branch 'master' into remote-desktop 2023-10-23 10:04:51 +01:00
Evgeny Poberezkin
567ba1974e Merge branch 'master-ghc8107' into master-ios 2023-10-22 15:35:27 +01:00
Evgeny Poberezkin
d6b9a45a39 Merge branch 'master' into master-ghc8107 2023-10-22 15:10:33 +01:00
Evgeny Poberezkin
b5e114d834 Merge branch 'master' into remote-desktop 2023-10-22 13:04:15 +01:00
Alexander Bondarenko
0d1a080a6e remote protocol (#3225)
* draft remote protocol types and external api

* types (it compiles)

* add error

* move remote controller from http to remote host client protocol

* refactor (doesnt compile)

* fix compile

* Connect remote session

* WIP: wire in remote protocol

* add commands and events

* cleanup

* fix desktop shutdown

* prepare for testing remote files

* Add file IO

* update simplexmq to master

with http2 to 4.1.4

* use json transcoder

* update simplexmq

* collapse RemoteHostSession states

* fold RemoteHello back into the protocol command
move http-command-response-http wrapper to protocol

* use sendRemoteCommand with optional attachments
use streaming request/response

* ditch lazy body streaming

* fix formatting

* put body builder/processor closer together

* wrap handleRemoteCommand around sending files

* handle ChatError's too

* remove binary, use 32-bit encoding for JSON bodies

* enable tests

* refactor

* refactor request handling

* return ChatError

* Flatten remote host

---------

Co-authored-by: Evgeny Poberezkin <2769109+epoberezkin@users.noreply.github.com>
2023-10-22 09:42:19 +01:00
Evgeny Poberezkin
0444367002 Merge branch 'master' into remote-desktop 2023-10-21 19:07:30 +01:00
Evgeny Poberezkin
64f429f4d2 Merge branch 'master-ghc8107' into master-ios 2023-10-18 22:44:49 +01:00
Evgeny Poberezkin
4004aafbc5 Merge branch 'master' into master-ghc8107 2023-10-18 22:44:27 +01:00
Evgeny Poberezkin
92eae012b3 Merge branch 'master' into remote-desktop 2023-10-16 21:38:54 +01:00
spaced4ndy
b30b1d67d5 Merge branch 'master-ghc8107' into master-ios 2023-10-16 20:05:35 +04:00
spaced4ndy
c7a8992043 core: fix compilation for ghc 8.10.7 2023-10-16 20:05:13 +04:00
spaced4ndy
48e7418c3a Merge branch 'master-ghc8107' into master-ios 2023-10-16 19:28:31 +04:00
spaced4ndy
ed9f277421 Merge branch 'master' into master-ghc8107 2023-10-16 19:28:06 +04:00
Evgeny Poberezkin
e0d71dd784 Merge branch 'master-ghc8107' into master-ios 2023-10-15 18:53:52 +01:00
Evgeny Poberezkin
d8fb31f167 Merge branch 'master' into master-ghc8107 2023-10-15 18:53:23 +01:00
Evgeny Poberezkin
fc1bba8817 remote: refactor (WIP) (#3222)
* remote: refactor (WIP)

* refactor discoverRemoteCtrls

* refactor processRemoteCommand, storeRemoteFile

* refactor fetchRemoteFile

* refactor startRemoteHost, receiving files

* refactor relayCommand
2023-10-15 14:17:36 +01:00
Evgeny Poberezkin
41b86e07f1 core: update api (#3221) 2023-10-15 00:18:04 +01:00
Evgeny Poberezkin
f5e9bd4f8b core: add set display name (#3216)
* core: add set display name

* enable all tests
2023-10-14 13:10:06 +01:00
Evgeny Poberezkin
5e6aaffb09 simplify remote api, add ios api (#3213) 2023-10-13 22:35:30 +01:00
Alexander Bondarenko
193361c09a core: fix remote handshake test (#3209)
* Fix remoteHandshakeTest

Sidesteps some yet to be uncovered bug when
mobile stops its side before the desktop.

* remove ambiguous update warning

---------

Co-authored-by: Evgeny Poberezkin <2769109+epoberezkin@users.noreply.github.com>
2023-10-13 18:53:04 +01:00
Evgeny Poberezkin
392447ea33 core: fix test 2023-10-13 17:52:27 +01:00
Evgeny Poberezkin
5d4006f291 Merge branch 'master' into remote-desktop 2023-10-13 17:46:14 +01:00
Alexander Bondarenko
fe6c65f75c rfc: remote profile (#3051)
* Add session UX for mobile and desktop

* Resolve some feedback

* Resolve more feedback

Add QR note for desktops.
Add TLS handshake notice.

* Add details
2023-10-12 15:19:19 +01:00
Evgeny Poberezkin
6dca71cc87 Merge branch 'master' into remote-desktop 2023-10-12 11:40:23 +01:00
Alexander Bondarenko
adc1f8c983 android, desktop: remote kotlin types (#3200)
* Add remote types to Kotlin

* update response info for chat console

---------

Co-authored-by: Evgeny Poberezkin <2769109+epoberezkin@users.noreply.github.com>
2023-10-12 10:58:59 +01:00
Evgeny Poberezkin
73652e4bba Merge branch 'master' into remote-desktop 2023-10-12 10:43:59 +01:00
Evgeny Poberezkin
a4e07cbbb3 Merge branch 'master-ghc8107' into master-ios 2023-10-11 21:58:42 +01:00
Evgeny Poberezkin
7692195bfa core: fix for ghc 8.10.7 2023-10-11 21:57:53 +01:00
Evgeny Poberezkin
b4a72fafaa Merge branch 'master-ghc8107' into master-ios 2023-10-11 21:27:37 +01:00
Evgeny Poberezkin
effc281271 Merge branch 'master' into master-ghc8107 2023-10-11 21:27:21 +01:00
Evgeny Poberezkin
c2a858b06e core: convert single-field to tagged JSON encoding (#3183)
* core: convert single-field to tagged JSON encoding

* rename

* rename

* fixes, test

* refactor
2023-10-11 19:11:01 +01:00
spaced4ndy
a5c81d8c77 Merge branch 'master-ghc8107' into master-ios 2023-10-11 13:22:10 +04:00
spaced4ndy
67d74a0a27 Merge branch 'master' into master-ghc8107 2023-10-11 13:21:46 +04:00
Alexander Bondarenko
6f5ba54f7b core: remote session files (#3189)
* Receiving files on CRRcvFileComplete

* Add remote /fr test

* Add broken startFileTransfer notice

* Sending files with SendFile/SendImage

With tests for SendFile.

* Add APISendMessage handling

* Test file preconditions

No files should be in stores before actual sending.

* Fix mobile paths in storeFile
2023-10-11 09:45:05 +01:00
Evgeny Poberezkin
3309a3fe4f Merge branch 'stable' into stable-ios 2023-10-09 19:57:27 +01:00
Evgeny Poberezkin
bae6a53ec8 Merge branch 'master-ghc8107' into master-ios 2023-10-09 17:32:16 +01:00
Evgeny Poberezkin
74d186af16 Merge branch 'master' into master-ghc8107 2023-10-09 17:31:27 +01:00
Evgeny Poberezkin
2b228a893a Merge branch 'master' into remote-desktop 2023-10-09 17:21:47 +01:00
Evgeny Poberezkin
4d4dc44302 Merge branch 'stable' into stable-ios 2023-10-09 14:36:32 +01:00
Evgeny Poberezkin
373da2b528 Merge branch 'master-ghc8107' into master-ios 2023-10-09 14:05:41 +01:00
Evgeny Poberezkin
4782cab507 Merge branch 'master' into master-ghc8107 2023-10-09 14:05:04 +01:00
Evgeny Poberezkin
2eb213741c Merge branch 'master' into remote-desktop 2023-10-09 10:35:38 +01:00
Evgeny Poberezkin
5246445400 Merge branch 'stable-android' into stable-ios 2023-10-08 17:32:06 +01:00
Evgeny Poberezkin
cb52d75ff0 Merge branch 'stable' into stable-android 2023-10-08 17:31:23 +01:00
Evgeny Poberezkin
d19d2d58a3 Merge branch 'master-ghc8107' into master-ios 2023-10-08 08:41:36 +01:00
Evgeny Poberezkin
2501cbe55d Merge branch 'master' into master-ghc8107 2023-10-08 08:38:02 +01:00
Evgeny Poberezkin
48158a9db1 Merge branch 'master-ghc8107' into master-ios 2023-10-07 21:10:44 +01:00
Evgeny Poberezkin
6b8b9ab4fd Merge branch 'master' into master-ghc8107 2023-10-07 19:06:38 +01:00
Alexander Bondarenko
91561da351 core: http transport for remote session (#3178)
* Wire some of the session endpoints

* Start sending remote commands

* Expand remote controller

- Fix queues for pumping to remote
- Add 3-way test
- WIP: Add TTY wrapper for remote hosts
- Stop remote controller w/o ids to match starting

* Fix view events

* Drop notifications, add message test

* refactor, receive test

* hunt down stray asyncs

* Take discovery sockets in brackets

---------

Co-authored-by: Evgeny Poberezkin <2769109+epoberezkin@users.noreply.github.com>
2023-10-07 14:23:24 +01:00
Evgeny Poberezkin
3ac342782b Merge branch 'master' into remote-desktop 2023-10-07 13:05:22 +01:00
Evgeny Poberezkin
a273c68596 core: rename migration, pin dependencies 2023-10-05 22:33:48 +01:00
Alexander Bondarenko
fc9db9c381 core: add FromJSON instance to ChatResponse (#3129)
* Start adding FromJSON instances to ChatResponse

* progress

* FromJSON instance for ChatResponse compiles

* restore removed encodings

* remove comment

* diff

* update simplexmq, use TH for JSON

---------

Co-authored-by: Evgeny Poberezkin <2769109+epoberezkin@users.noreply.github.com>
2023-10-05 19:49:20 +01:00
Evgeny Poberezkin
27e8a81c9f Merge branch 'master' into remote-desktop 2023-10-05 14:15:25 +01:00
Evgeny Poberezkin
7959c75df7 Merge branch 'master' into remote-desktop 2023-10-04 16:37:15 +01:00
Alexander Bondarenko
0bcf5c9c66 Add commands for remote session credentials (#3161)
* Add remote host commands

* Make startRemoteHost async

* Add tests

* Trim randomStorePath to 16 chars

* Add chat command tests

* add view, use view output in test

* enable all tests

* Fix discovery listener host

Must use any, not broadcast on macos.

* Fix missing do

* address, names

* Fix session host flow

* fix test

---------

Co-authored-by: Evgeny Poberezkin <2769109+epoberezkin@users.noreply.github.com>
2023-10-04 16:36:10 +01:00
Evgeny Poberezkin
25972f8f6c Merge branch 'master-ghc8107' into master-ios 2023-10-02 23:05:10 +01:00
Evgeny Poberezkin
316d605899 Merge branch 'master' into master-ghc8107 2023-10-02 23:04:13 +01:00
Evgeny Poberezkin
8ac12a58c6 Merge branch 'master-ghc8107' into master-ios 2023-10-01 13:22:14 +01:00
Evgeny Poberezkin
a3f2d5c919 Merge branch 'master' into master-ghc8107 2023-10-01 13:20:06 +01:00
Evgeny Poberezkin
4de3d6a8f4 Merge branch 'master-ghc8107' into master-ios 2023-10-01 11:20:19 +01:00
Evgeny Poberezkin
0312fde818 Merge branch 'master' into master-ghc8107 2023-10-01 11:19:27 +01:00
Evgeny Poberezkin
39bbea1e18 Merge branch 'stable-android' into stable-ios 2023-10-01 11:04:46 +01:00
IC Rainbow
bf7917bd67 Merge remote-tracking branch 'origin/master' into ab/remote-discover-upd 2023-09-29 18:42:59 +03:00
IC Rainbow
6c0d1b5f15 Notify about handover errors 2023-09-29 16:53:05 +03:00
Evgeny Poberezkin
f7478f5699 Merge branch 'master-ghc8107' into master-ios 2023-09-29 13:15:50 +01:00
Evgeny Poberezkin
915b53054c Merge branch 'master' into master-ghc8107 2023-09-29 13:14:57 +01:00
IC Rainbow
af2df8d489 Rewrite remote controller 2023-09-29 15:01:05 +03:00
Evgeny Poberezkin
dce29e91d4 Merge branch 'master-ghc8107' into master-ios 2023-09-27 22:10:30 +01:00
Evgeny Poberezkin
e273bd1239 Merge branch 'master' into master-ghc8107 2023-09-27 22:04:00 +01:00
spaced4ndy
760ab4a45c Merge branch 'master-ghc8107' into master-ios 2023-09-27 20:38:19 +04:00
spaced4ndy
e7f0234134 Merge branch 'master' into master-ghc8107 2023-09-27 20:11:39 +04:00
IC Rainbow
cccb3e33fb Plug discovery into remote controller UI 2023-09-27 18:24:38 +03:00
Evgeny Poberezkin
9c99e4fae2 Merge branch 'master-ghc8107' into master-ios 2023-09-27 16:07:08 +01:00
Evgeny Poberezkin
98a3fc214d Merge branch 'master' into master-ghc8107 2023-09-27 16:04:25 +01:00
IC Rainbow
77410e5d5e Add remote host discovery 2023-09-27 13:40:19 +03:00
Alexander Bondarenko
3e29c664ac core: remote host/controller types (#3104)
* Start sprinkling ZoneId everywhere

* Draft zone/satellite/host api

* Add zone dispatching

* Add command relaying handler

* Parse commands and begin DB

* Implement discussed things

* Resolve some comments

* Resolve more stuff

* Make bots ignore remoteHostId from queues

* Fix tests and stub more

* Untangle cmd relaying

* Resolve comments

* Add more http2 client funs

* refactor, rename

* rename

* remove empty tests

---------

Co-authored-by: Evgeny Poberezkin <2769109+epoberezkin@users.noreply.github.com>
2023-09-27 09:41:02 +01:00
Evgeny Poberezkin
6a578cfe3c Merge branch 'master-ghc8107' into master-android 2023-09-25 16:53:04 +01:00
Evgeny Poberezkin
dacc075fe8 Merge branch 'master' into master-ghc8107 2023-09-25 16:52:33 +01:00
spaced4ndy
c931f52631 Merge branch 'master-ghc8107' into master-ios 2023-09-25 17:44:12 +04:00
spaced4ndy
55418e2bc0 Merge branch 'master-ghc8107' into master-android 2023-09-25 17:43:59 +04:00
spaced4ndy
f2b5c0f3a8 Merge branch 'master' into master-ghc8107 2023-09-25 17:43:37 +04:00
spaced4ndy
2d8739dec2 Merge branch 'master-ghc8107' into master-ios 2023-09-25 17:07:43 +04:00
spaced4ndy
5ebdf5dba9 Merge branch 'master-ghc8107' into master-android 2023-09-25 17:07:14 +04:00
spaced4ndy
8e045764df Merge branch 'master' into master-ghc8107 2023-09-25 16:40:08 +04:00
Evgeny Poberezkin
503d3d77e6 Merge branch 'master' into master-ghc8107 2023-09-23 08:47:28 +01:00
Evgeny Poberezkin
87aff89d5e Merge branch 'master-ghc8107' into master-ios 2023-09-22 17:23:28 +01:00
Evgeny Poberezkin
81bd7d97c5 Merge branch 'master' into master-ghc8107 2023-09-22 17:21:54 +01:00
Evgeny Poberezkin
ff182c97ee Merge branch 'master-ghc8107' into master-ios 2023-09-22 14:15:01 +01:00
Evgeny Poberezkin
8f57925067 compatibility with GHC 8.10.7 2023-09-22 14:01:25 +01:00
Evgeny Poberezkin
9bf99db82e Merge branch 'master' into master-ghc8107 2023-09-22 13:46:50 +01:00
Evgeny Poberezkin
9f117a30db Merge branch 'master-android' into master-ios 2023-09-21 17:05:05 +01:00
Evgeny Poberezkin
5615cdbf1a Merge branch 'master' into master-android 2023-09-21 17:04:47 +01:00
Evgeny Poberezkin
2cab235888 Merge branch 'master-android' into master-ios 2023-09-21 12:06:35 +01:00
Evgeny Poberezkin
d802ae0058 Merge branch 'master' into master-android 2023-09-21 12:06:10 +01:00
Evgeny Poberezkin
d4201071e0 Merge branch 'master-android' into master-ios 2023-09-20 14:56:57 +01:00
Evgeny Poberezkin
8f2278198c Merge branch 'master' into master-android 2023-09-20 14:55:25 +01:00
spaced4ndy
10937a5a4e Merge branch 'master' into master-android 2023-09-20 17:36:53 +04:00
Evgeny Poberezkin
c0e666770b Merge branch 'master-android' into master-ios 2023-09-18 21:58:07 +01:00
Evgeny Poberezkin
6aff6e9804 Merge branch 'master-ghc9' into master-ghc8107 2023-09-18 21:56:35 +01:00
Evgeny Poberezkin
95477cae7e core: use commit from simplexmq branch master-ghc8107 2023-09-18 21:45:50 +01:00
Evgeny Poberezkin
016f3c9670 Merge branch 'master' into master-ios 2023-09-18 21:30:32 +01:00
spaced4ndy
49116233a8 Merge branch 'master' into master-ios 2023-09-18 14:12:37 +04:00
Evgeny Poberezkin
51621ba11d Merge branch 'stable' into stable-ios 2023-09-17 23:21:46 +01:00
Evgeny Poberezkin
e54419e4f0 Merge branch 'master' into master-ios 2023-09-17 22:41:16 +01:00
spaced4ndy
d6c6da6edf Merge branch 'master' into master-ios 2023-09-12 18:14:58 +04:00
spaced4ndy
e5828f4495 Merge branch 'master' into master-ios 2023-09-11 18:39:29 +04:00
Evgeny Poberezkin
5e23bbecf1 Merge branch 'master' into master-ios 2023-09-10 21:13:18 +01:00
Evgeny Poberezkin
17c734dcb9 Merge branch 'master' into master-ios 2023-09-07 20:19:20 +01:00
Evgeny Poberezkin
85adf2951e Merge branch 'master' into master-ios 2023-09-07 13:45:06 +01:00
Evgeny Poberezkin
a250a8e6ca Merge branch 'master' into master-ios 2023-09-06 20:22:00 +01:00
Evgeny Poberezkin
38e10d843b Merge branch 'master' into master-ios 2023-09-06 19:54:48 +01:00
Evgeny Poberezkin
9153cb93de Merge branch 'master' into master-ios 2023-09-05 21:07:22 +01:00
Evgeny Poberezkin
f978198fe6 Merge branch 'master' into master-ios 2023-09-04 23:20:27 +01:00
Evgeny Poberezkin
7b434d9f97 Merge branch 'master' into master-ios 2023-09-04 18:29:53 +01:00
Evgeny Poberezkin
aaf6dd57c7 Merge branch 'master' into master-ios 2023-09-02 23:34:35 +01:00
Evgeny Poberezkin
dc2272ac6e Merge branch 'master' into master-ios 2023-09-01 22:27:15 +01:00
Evgeny Poberezkin
4c172ac680 Merge branch 'master' into master-ios 2023-09-01 20:40:14 +01:00
Evgeny Poberezkin
096bd9ea72 Merge branch 'master' into master-ios 2023-08-26 18:37:12 +01:00
Evgeny Poberezkin
f8b757ddf9 Merge branch 'master' into master-ios 2023-08-25 14:11:13 +01:00
Evgeny Poberezkin
62a4fd2c7c Merge branch 'master' into master-ios 2023-08-25 11:32:07 +01:00
Evgeny Poberezkin
d6dba0e26a Merge branch 'master' into master-ios 2023-08-24 20:43:20 +01:00
Evgeny Poberezkin
20ebccdbf2 Merge branch 'master' into master-ios 2023-08-22 16:14:32 +01:00
Evgeny Poberezkin
2ac6c2dec9 Merge branch 'master' into master-ios 2023-08-18 21:36:18 +01:00
Evgeny Poberezkin
2babe6d548 Merge branch 'master' into master-ios 2023-08-17 23:16:40 +01:00
spaced4ndy
0a3f2444d9 Merge branch 'master' into master-ios 2023-08-16 10:44:15 +04:00
Evgeny Poberezkin
ebfa9e699b Merge branch 'master' into master-ios 2023-08-12 22:00:40 +01:00
Evgeny Poberezkin
2cf07ae0a7 Merge branch 'master' into master-ios 2023-08-12 18:16:16 +01:00
Evgeny Poberezkin
5199cb9e82 Merge branch 'master' into master-ios 2023-08-12 15:26:18 +01:00
Evgeny Poberezkin
c42b8373b0 Merge branch 'stable' into stable-ios 2023-08-12 14:33:39 +01:00
spaced4ndy
4bf43c3cde Merge branch 'master' into master-ios 2023-08-08 19:05:23 +04:00
Evgeny Poberezkin
fe8c98d69a Merge branch 'stable' into stable-ios 2023-08-06 22:14:33 +01:00
Evgeny Poberezkin
b2523e07f8 Merge branch 'master' into master-ios 2023-08-05 15:16:34 +01:00
spaced4ndy
deb4fae07c Merge branch 'master' into master-ios 2023-08-03 18:28:23 +04:00
Evgeny Poberezkin
1f4e99f291 Merge branch 'master' into master-ios 2023-08-02 16:23:36 +01:00
Evgeny Poberezkin
439900dbdb Merge branch 'stable' into stable-ios 2023-08-02 16:22:58 +01:00
Evgeny Poberezkin
0f2ac69562 Merge branch 'master' into master-ios 2023-07-31 16:13:41 +01:00
spaced4ndy
8704a23c6f Merge branch 'stable' into stable-ios 2023-07-31 17:00:48 +04:00
spaced4ndy
2ee528c81c Merge branch 'stable' into stable-ios 2023-07-31 15:27:17 +04:00
spaced4ndy
5e1e6aed6b Merge branch 'stable' into stable-ios 2023-07-31 14:21:30 +04:00
spaced4ndy
96128dbf33 Merge branch 'stable' into stable-ios 2023-07-31 12:19:19 +04:00
spaced4ndy
4c3bab1402 Merge branch 'master' into master-ios 2023-07-28 11:10:08 +04:00
spaced4ndy
281f6d0bf9 Merge branch 'master' into master-ios 2023-07-26 15:03:26 +04:00
Evgeny Poberezkin
065bd27b36 Merge branch 'stable' into stable-ios 2023-07-22 16:27:13 +01:00
Evgeny Poberezkin
46043acb85 Merge branch 'stable' into stable-ios 2023-07-22 15:30:21 +01:00
Evgeny Poberezkin
e956690390 Merge branch 'stable' into stable-ios 2023-07-22 13:30:47 +01:00
Evgeny Poberezkin
1022124f69 Merge branch 'stable' into master-ios 2023-07-21 23:31:58 +01:00
Evgeny Poberezkin
5803274950 Merge branch 'master' into master-ios 2023-07-20 18:20:12 +01:00
spaced4ndy
444c5e2fc4 Merge branch 'master' into master-ios 2023-07-20 18:44:13 +04:00
Evgeny Poberezkin
1038305802 Merge branch 'master' into master-ios 2023-07-17 14:45:16 +01:00
Evgeny Poberezkin
f9530c70fc Merge branch 'master' into master-ios 2023-07-17 13:34:22 +01:00
Evgeny Poberezkin
5e0b2a8706 Merge branch 'master' into master-ios 2023-07-13 23:48:55 +01:00
spaced4ndy
7e9990d710 Merge branch 'master' into master-ios 2023-07-11 20:57:44 +04:00
spaced4ndy
27244da82a Merge branch 'master' into master-ios 2023-07-10 17:40:43 +04:00
Evgeny Poberezkin
d89c6ae672 Merge branch 'master' into master-ios 2023-07-09 23:25:16 +01:00
spaced4ndy
121e0ede6c Merge branch 'master' into master-ios 2023-07-05 19:45:23 +04:00
Evgeny Poberezkin
ae7a71c4a4 Merge branch 'master' into master-ios 2023-07-05 09:10:43 +01:00
spaced4ndy
8df46c8630 Merge branch 'master' into master-ios 2023-07-03 20:16:45 +04:00
spaced4ndy
55a17a564e Merge branch 'master' into master-ios 2023-06-28 16:49:43 +04:00
spaced4ndy
e0956b656c Merge branch 'master' into master-ios 2023-06-28 16:13:45 +04:00
spaced4ndy
ca0192abfc Merge branch 'master' into master-ios 2023-06-26 21:48:51 +04:00
Evgeny Poberezkin
3eec371c3f Merge branch 'master' into master-ios 2023-06-24 17:40:05 +01:00
spaced4ndy
1c21afddff Merge branch 'master' into master-ios 2023-06-20 10:19:40 +04:00
spaced4ndy
94b3adb515 Merge branch 'master' into master-ios 2023-06-19 16:07:45 +04:00
spaced4ndy
4c7784c9dc Merge branch 'master' into master-ios 2023-06-16 19:06:31 +04:00
spaced4ndy
99b39fda91 Merge branch 'master' into master-ios 2023-06-12 13:47:27 +04:00
spaced4ndy
c16bd3f7b1 Merge branch 'master' into master-ios 2023-06-09 17:31:57 +04:00
spaced4ndy
1c49ba9eaf Merge branch 'master' into master-ios 2023-05-29 15:22:06 +04:00
Evgeny Poberezkin
b83fb77b9e Merge branch 'master' into master-ios 2023-05-27 19:36:22 +01:00
spaced4ndy
5cac9c4594 Merge branch 'master' into master-ios 2023-05-26 17:36:58 +04:00
spaced4ndy
d17623d20b Merge branch 'master' into master-ios 2023-05-26 14:06:07 +04:00
spaced4ndy
3b452ae4af Merge branch 'master' into master-ios 2023-05-26 14:04:05 +04:00
spaced4ndy
08ba0b2755 Merge branch 'master' into master-ios 2023-05-25 20:55:25 +04:00
spaced4ndy
abd362f10a Merge branch 'master' into master-ios 2023-05-24 16:17:05 +04:00
spaced4ndy
31b47746e5 Merge branch 'master' into master-ios 2023-05-23 19:12:25 +04:00
spaced4ndy
76ce8bec1d Merge branch 'master' into master-ios 2023-05-23 18:40:52 +04:00
spaced4ndy
eeb2fee659 Merge branch 'master' into master-ios 2023-05-23 15:55:11 +04:00
spaced4ndy
d034cb08f9 Merge branch 'master' into master-ios 2023-05-23 13:51:52 +04:00
Evgeny Poberezkin
9d9761ad98 Merge branch 'master' into master-ios 2023-05-20 23:09:20 +01:00
spaced4ndy
ffdd598a9c Merge branch 'master' into master-ios 2023-05-19 17:00:44 +04:00
Evgeny Poberezkin
e4649c4776 Merge branch 'master' into master-ios 2023-05-19 13:53:30 +01:00
Evgeny Poberezkin
3e9df58955 Merge branch 'master' into master-ios 2023-05-18 17:13:13 +01:00
spaced4ndy
b014bfcdb4 Merge branch 'master' into master-ios 2023-05-17 16:14:18 +04:00
Evgeny Poberezkin
b8b4ef39e9 Merge branch 'master' into master-ios 2023-05-17 00:23:36 +01:00
spaced4ndy
2a9f98e43f Merge branch 'master' into master-ios 2023-05-16 15:06:01 +04:00
spaced4ndy
6e0ec89fdc Merge branch 'master' into master-ios 2023-05-15 21:23:22 +04:00
Evgeny Poberezkin
080ab90e26 Merge branch 'master' into master-ios 2023-05-15 13:28:27 +01:00
spaced4ndy
a6d1f7d449 Merge branch 'master' into master-ios 2023-05-11 16:00:32 +04:00
Evgeny Poberezkin
19c94e59e6 Merge branch 'master' into master-ios 2023-05-09 09:34:05 +01:00
spaced4ndy
1bb4672815 Merge branch 'master' into master-ios 2023-05-09 11:00:46 +04:00
spaced4ndy
371db95950 Merge branch 'master' into master-ios 2023-05-05 15:55:54 +04:00
Evgeny Poberezkin
672c807e47 Merge branch 'master' into master-ios 2023-05-04 13:28:20 +01:00
spaced4ndy
512394b8a6 Merge branch 'master' into master-ios 2023-05-03 20:26:46 +04:00
spaced4ndy
7d3c188cd2 Merge branch 'master' into master-ios 2023-05-03 15:31:03 +04:00
spaced4ndy
2fe765b0bc Merge branch 'master' into master-ios 2023-05-02 10:25:26 +04:00
Evgeny Poberezkin
40cf101148 Merge branch 'master' into master-ios 2023-05-01 11:34:16 +01:00
spaced4ndy
680903a763 Merge branch 'master' into master-ios 2023-04-26 14:35:44 +04:00
spaced4ndy
6b6eff6b52 Merge branch 'master' into master-ios 2023-04-21 13:48:21 +04:00
spaced4ndy
e949b4fc3c Merge branch 'master' into master-ios 2023-04-20 20:28:49 +04:00
Evgeny Poberezkin
6790362036 Merge branch 'master' into master-ios 2023-04-20 14:19:27 +01:00
spaced4ndy
623b84d3e1 Merge branch 'master' into master-ios 2023-04-19 15:21:51 +04:00
Evgeny Poberezkin
101ab76a33 Merge branch 'master' into master-ios 2023-04-18 21:04:45 +01:00
spaced4ndy
c1909b91d0 Merge branch 'master' into master-ios 2023-04-18 19:49:26 +04:00
spaced4ndy
cb9cf6229c Merge branch 'master' into master-ios 2023-04-18 13:49:47 +04:00
spaced4ndy
1561268c5e Merge branch 'master' into master-ios 2023-04-18 12:49:17 +04:00
Evgeny Poberezkin
80368f97ef Merge branch 'master' into master-ios 2023-04-17 10:18:27 +01:00
Evgeny Poberezkin
7ec6f2b421 Merge branch 'master' into master-ios 2023-04-16 18:31:05 +01:00
Evgeny Poberezkin
d3a1aec7ad Merge branch 'master' into master-ios 2023-04-16 15:04:35 +01:00
spaced4ndy
990f96a19f Merge branch 'master' into master-ios 2023-04-14 18:06:36 +04:00
spaced4ndy
330c9afc1b Merge branch 'master' into master-ios 2023-04-14 15:55:38 +04:00
spaced4ndy
93922a592c Merge branch 'master' into master-ios 2023-04-13 20:49:23 +04:00
Evgeny Poberezkin
a9b08e5c2f Merge branch 'master' into master-ios 2023-04-07 23:23:26 +01:00
Evgeny Poberezkin
c677baaa22 Merge branch 'master' into master-ios 2023-04-06 23:16:48 +01:00
Evgeny Poberezkin
5448573d0b Merge branch 'master' into master-ios 2023-04-06 22:49:53 +01:00
Evgeny Poberezkin
1a1b5aade5 Merge branch 'master' into master-ios 2023-04-06 21:07:07 +01:00
Evgeny Poberezkin
bd9a60af5a Merge branch 'master' into master-ios 2023-04-05 22:00:08 +01:00
Evgeny Poberezkin
617e12a3d4 Merge branch 'master' into master-ios 2023-04-04 18:43:42 +01:00
spaced4ndy
8c625faa5e Merge branch 'master' into master-ios 2023-03-31 19:20:03 +04:00
spaced4ndy
cab7201b72 Merge branch 'master' into master-ios 2023-03-31 17:36:32 +04:00
spaced4ndy
c2fd1d5d29 Merge branch 'master' into master-ios 2023-03-30 19:45:49 +04:00
spaced4ndy
5b541e296b Merge branch 'master' into master-ios 2023-03-30 18:42:13 +04:00
Evgeny Poberezkin
daaecf11ec Merge branch 'master' into master-ios 2023-03-29 20:46:34 +01:00
spaced4ndy
9c4df591a7 Merge branch 'master' into master-ios 2023-03-29 19:17:15 +04:00
Evgeny Poberezkin
c339e8290b Merge branch 'master' into master-ios 2023-03-28 19:26:26 +01:00
spaced4ndy
ac606336ed Merge branch 'master' into master-ios 2023-03-28 19:29:30 +04:00
Evgeny Poberezkin
f79e6fddec Merge branch 'master' into master-ios 2023-03-27 23:22:16 +01:00
Evgeny Poberezkin
2aab931589 nix: revert changes from 05c4a6c (support for ARMv7a and Android 8+) 2023-03-27 20:48:49 +01:00
432 changed files with 26597 additions and 7428 deletions

View File

@@ -9,6 +9,7 @@ on:
tags:
- "v*"
- "!*-fdroid"
- "!*-armv7a"
pull_request:
jobs:
@@ -79,10 +80,10 @@ jobs:
uses: actions/checkout@v3
- name: Setup Haskell
uses: haskell-actions/setup@v2
uses: haskell/actions/setup@v2
with:
ghc-version: "9.6.3"
cabal-version: "3.10.1.0"
ghc-version: "8.10.7"
cabal-version: "latest"
- name: Cache dependencies
uses: actions/cache@v3
@@ -188,7 +189,7 @@ jobs:
APPLE_SIMPLEX_NOTARIZATION_APPLE_ID: ${{ secrets.APPLE_SIMPLEX_NOTARIZATION_APPLE_ID }}
APPLE_SIMPLEX_NOTARIZATION_PASSWORD: ${{ secrets.APPLE_SIMPLEX_NOTARIZATION_PASSWORD }}
run: |
scripts/ci/build-desktop-mac.sh
scripts/build-desktop-mac.sh
path=$(echo $PWD/apps/multiplatform/release/main/dmg/SimpleX-*.dmg)
echo "package_path=$path" >> $GITHUB_OUTPUT
echo "package_hash=$(echo SHA2-512\(${{ matrix.desktop_asset_name }}\)= $(openssl sha512 $path | cut -d' ' -f 2))" >> $GITHUB_OUTPUT
@@ -259,13 +260,40 @@ jobs:
# Unix /
# / Windows
# rm -rf dist-newstyle/src/direct-sq* is here because of the bug in cabal's dependency which prevents second build from finishing
# * In powershell multiline commands do not fail if individual commands fail - https://github.community/t/multiline-commands-on-windows-do-not-fail-if-individual-commands-fail/16753
# * And GitHub Actions does not support parameterizing shell in a matrix job - https://github.community/t/using-matrix-to-specify-shell-is-it-possible/17065
- name: 'Setup MSYS2'
if: matrix.os == 'windows-latest'
uses: msys2/setup-msys2@v2
with:
msystem: ucrt64
update: true
install: >-
git
perl
make
pacboy: >-
toolchain:p
cmake:p
- name: Windows build
id: windows_build
if: matrix.os == 'windows-latest'
shell: bash
shell: msys2 {0}
run: |
export PATH=$PATH:/c/ghcup/bin
scripts/desktop/prepare-openssl-windows.sh
openssl_windows_style_path=$(echo `pwd`/dist-newstyle/openssl-1.1.1w | sed 's#/\([a-zA-Z]\)#\1:#' | sed 's#/#\\#g')
rm cabal.project.local 2>/dev/null || true
echo "ignore-project: False" >> cabal.project.local
echo "package direct-sqlcipher" >> cabal.project.local
echo " flags: +openssl" >> cabal.project.local
echo " extra-include-dirs: $openssl_windows_style_path\include" >> cabal.project.local
echo " extra-lib-dirs: $openssl_windows_style_path" >> cabal.project.local
rm -rf dist-newstyle/src/direct-sq*
sed -i "s/, unix /--, unix /" simplex-chat.cabal
cabal build --enable-tests
@@ -293,20 +321,6 @@ jobs:
body: |
${{ steps.windows_build.outputs.bin_hash }}
- name: 'Setup MSYS2'
if: startsWith(github.ref, 'refs/tags/v') && matrix.os == 'windows-latest'
uses: msys2/setup-msys2@v2
with:
msystem: ucrt64
update: true
install: >-
git
perl
make
pacboy: >-
toolchain:p
cmake:p
- name: Windows build desktop
id: windows_desktop_build
if: startsWith(github.ref, 'refs/tags/v') && matrix.os == 'windows-latest'

View File

@@ -232,6 +232,8 @@ You can use SimpleX with your own servers and still communicate with people usin
Recent and important updates:
[Nov 25, 2023. SimpleX Chat v5.4 released: link mobile and desktop apps via quantum resistant protocol, and much better groups](./blog/20231125-simplex-chat-v5-4-link-mobile-desktop-quantum-resistant-better-groups.md).
[Sep 25, 2023. SimpleX Chat v5.3 released: desktop app, local file encryption, improved groups and directory service](./blog/20230925-simplex-chat-v5-3-desktop-app-local-file-encryption-directory-service.md).
[Jul 22, 2023. SimpleX Chat: v5.2 released with message delivery receipts](./blog/20230722-simplex-chat-v5-2-message-delivery-receipts.md).
@@ -366,13 +368,13 @@ Please also join [#simplex-devs](https://simplex.chat/contact#/?v=1-2&smp=smp%3A
- ✅ Message delivery confirmation (with sender opt-out per contact).
- ✅ Desktop client.
- ✅ Encryption of local files stored in the app.
- 🏗 Using mobile profiles from the desktop app.
- Using mobile profiles from the desktop app.
- 🏗 Improve experience for the new users.
- 🏗 Post-quantum resistant key exchange in double ratchet protocol.
- 🏗 Large groups, communities and public channels.
- Message delivery relay for senders (to conceal IP address from the recipients' servers and to reduce the traffic).
- Post-quantum resistant key exchange in double ratchet protocol.
- Large groups, communities and public channels.
- Privacy & security slider - a simple way to set all settings at once.
- Improve sending videos (including encryption of locally stored videos).
- Improve experience for the new users.
- SMP queue redundancy and rotation (manual is supported).
- Include optional message into connection request sent via contact address.
- Improved navigation and search in the conversation (expand and scroll to quoted message, scroll to search results, etc.).

View File

@@ -42,6 +42,7 @@ class AppDelegate: NSObject, UIApplicationDelegate {
let m = ChatModel.shared
let deviceToken = DeviceToken(pushProvider: PushProvider(env: pushEnvironment), token: token)
m.deviceToken = deviceToken
// savedToken is set in startChat, when it is started before this method is called
if m.savedToken != nil {
registerToken(token: deviceToken)
}
@@ -80,7 +81,7 @@ class AppDelegate: NSObject, UIApplicationDelegate {
}
} else if let checkMessages = ntfData["checkMessages"] as? Bool, checkMessages {
logger.debug("AppDelegate: didReceiveRemoteNotification: checkMessages")
if appStateGroupDefault.get().inactive && m.ntfEnablePeriodic {
if m.ntfEnablePeriodic && allowBackgroundRefresh() && BGManager.shared.lastRanLongAgo {
receiveMessages(completionHandler)
} else {
completionHandler(.noData)

View File

@@ -14,11 +14,14 @@ struct ContentView: View {
@ObservedObject var alertManager = AlertManager.shared
@ObservedObject var callController = CallController.shared
@Environment(\.colorScheme) var colorScheme
@Binding var doAuthenticate: Bool
@Binding var userAuthorized: Bool?
@Binding var canConnectCall: Bool
@Binding var lastSuccessfulUnlock: TimeInterval?
@Binding var showInitializationView: Bool
var contentAccessAuthenticationExtended: Bool
@Environment(\.scenePhase) var scenePhase
@State private var automaticAuthenticationAttempted = false
@State private var canConnectViewCall = false
@State private var lastSuccessfulUnlock: TimeInterval? = nil
@AppStorage(DEFAULT_SHOW_LA_NOTICE) private var prefShowLANotice = false
@AppStorage(DEFAULT_LA_NOTICE_SHOWN) private var prefLANoticeShown = false
@AppStorage(DEFAULT_PERFORM_LA) private var prefPerformLA = false
@@ -40,9 +43,19 @@ struct ContentView: View {
}
}
private var accessAuthenticated: Bool {
chatModel.contentViewAccessAuthenticated || contentAccessAuthenticationExtended
}
var body: some View {
ZStack {
contentView()
// contentView() has to be in a single branch, so that enabling authentication doesn't trigger re-rendering and close settings.
// i.e. with separate branches like this settings are closed: `if prefPerformLA { ... contentView() ... } else { contentView() }
if !prefPerformLA || accessAuthenticated {
contentView()
} else {
lockButton()
}
if chatModel.showCallView, let call = chatModel.activeCall {
callView(call)
}
@@ -50,6 +63,7 @@ struct ContentView: View {
LocalAuthView(authRequest: la)
} else if showSetPasscode {
SetAppPasscodeView {
chatModel.contentViewAccessAuthenticated = true
prefPerformLA = true
showSetPasscode = false
privacyLocalAuthModeDefault.set(.passcode)
@@ -60,13 +74,9 @@ struct ContentView: View {
alertManager.showAlert(laPasscodeNotSetAlert())
}
}
}
.onAppear {
if prefPerformLA { requestNtfAuthorization() }
initAuthenticate()
}
.onChange(of: doAuthenticate) { _ in
initAuthenticate()
if chatModel.chatDbStatus == nil {
initializationView()
}
}
.alert(isPresented: $alertManager.presentAlert) { alertManager.alertView! }
.sheet(isPresented: $showSettings) {
@@ -76,14 +86,44 @@ struct ContentView: View {
Button("System authentication") { initialEnableLA() }
Button("Passcode entry") { showSetPasscode = true }
}
.onChange(of: scenePhase) { phase in
logger.debug("scenePhase was \(String(describing: scenePhase)), now \(String(describing: phase))")
switch (phase) {
case .background:
// also see .onChange(of: scenePhase) in SimpleXApp: on entering background
// it remembers enteredBackgroundAuthenticated and sets chatModel.contentViewAccessAuthenticated to false
automaticAuthenticationAttempted = false
canConnectViewCall = false
case .active:
canConnectViewCall = !prefPerformLA || contentAccessAuthenticationExtended || unlockedRecently()
// condition `!chatModel.contentViewAccessAuthenticated` is required for when authentication is enabled in settings or on initial notice
if prefPerformLA && !chatModel.contentViewAccessAuthenticated {
if AppChatState.shared.value != .stopped {
if contentAccessAuthenticationExtended {
chatModel.contentViewAccessAuthenticated = true
} else {
if !automaticAuthenticationAttempted {
automaticAuthenticationAttempted = true
// authenticate if call kit call is not in progress
if !(CallController.useCallKit() && chatModel.showCallView && chatModel.activeCall != nil) {
authenticateContentViewAccess()
}
}
}
} else {
// when app is stopped automatic authentication is not attempted
chatModel.contentViewAccessAuthenticated = contentAccessAuthenticationExtended
}
}
default:
break
}
}
}
@ViewBuilder private func contentView() -> some View {
if prefPerformLA && userAuthorized != true {
lockButton()
} else if chatModel.chatDbStatus == nil && showInitializationView {
initializationView()
} else if let status = chatModel.chatDbStatus, status != .ok {
if let status = chatModel.chatDbStatus, status != .ok {
DatabaseErrorView(status: status)
} else if !chatModel.v3DBMigration.startChat {
MigrateToAppGroupView()
@@ -106,11 +146,11 @@ struct ContentView: View {
if CallController.useCallKit() {
ActiveCallView(call: call, canConnectCall: Binding.constant(true))
.onDisappear {
if userAuthorized == false && doAuthenticate { runAuthenticate() }
if prefPerformLA && !accessAuthenticated { authenticateContentViewAccess() }
}
} else {
ActiveCallView(call: call, canConnectCall: $canConnectCall)
if prefPerformLA && userAuthorized != true {
ActiveCallView(call: call, canConnectCall: $canConnectViewCall)
if prefPerformLA && !accessAuthenticated {
Rectangle()
.fill(colorScheme == .dark ? .black : .white)
.frame(maxWidth: .infinity, maxHeight: .infinity)
@@ -120,22 +160,27 @@ struct ContentView: View {
}
private func lockButton() -> some View {
Button(action: runAuthenticate) { Label("Unlock", systemImage: "lock") }
Button(action: authenticateContentViewAccess) { Label("Unlock", systemImage: "lock") }
}
private func initializationView() -> some View {
VStack {
ProgressView().scaleEffect(2)
Text("Opening database")
Text("Opening app")
.padding()
}
.frame(maxWidth: .infinity, maxHeight: .infinity )
.background(
Rectangle()
.fill(.background)
)
}
private func mainView() -> some View {
ZStack(alignment: .top) {
ChatListView(showSettings: $showSettings).privacySensitive(protectScreen)
.onAppear {
if !prefPerformLA { requestNtfAuthorization() }
requestNtfAuthorization()
// Local Authentication notice is to be shown on next start after onboarding is complete
if (!prefLANoticeShown && prefShowLANotice && !chatModel.chats.isEmpty) {
prefLANoticeShown = true
@@ -187,48 +232,37 @@ struct ContentView: View {
}
}
private func initAuthenticate() {
logger.debug("initAuthenticate")
if CallController.useCallKit() && chatModel.showCallView && chatModel.activeCall != nil {
userAuthorized = false
} else if doAuthenticate {
runAuthenticate()
}
}
private func runAuthenticate() {
logger.debug("DEBUGGING: runAuthenticate")
if !prefPerformLA {
userAuthorized = true
private func unlockedRecently() -> Bool {
if let lastSuccessfulUnlock = lastSuccessfulUnlock {
return ProcessInfo.processInfo.systemUptime - lastSuccessfulUnlock < 2
} else {
logger.debug("DEBUGGING: before dismissAllSheets")
dismissAllSheets(animated: false) {
logger.debug("DEBUGGING: in dismissAllSheets callback")
chatModel.chatId = nil
justAuthenticate()
}
return false
}
}
private func justAuthenticate() {
userAuthorized = false
let laMode = privacyLocalAuthModeDefault.get()
authenticate(reason: NSLocalizedString("Unlock app", comment: "authentication reason"), selfDestruct: true) { laResult in
logger.debug("DEBUGGING: authenticate callback: \(String(describing: laResult))")
switch (laResult) {
case .success:
userAuthorized = true
canConnectCall = true
lastSuccessfulUnlock = ProcessInfo.processInfo.systemUptime
case .failed:
if laMode == .passcode {
AlertManager.shared.showAlert(laFailedAlert())
private func authenticateContentViewAccess() {
logger.debug("DEBUGGING: authenticateContentViewAccess")
dismissAllSheets(animated: false) {
logger.debug("DEBUGGING: authenticateContentViewAccess, in dismissAllSheets callback")
chatModel.chatId = nil
authenticate(reason: NSLocalizedString("Unlock app", comment: "authentication reason"), selfDestruct: true) { laResult in
logger.debug("DEBUGGING: authenticate callback: \(String(describing: laResult))")
switch (laResult) {
case .success:
chatModel.contentViewAccessAuthenticated = true
canConnectViewCall = true
lastSuccessfulUnlock = ProcessInfo.processInfo.systemUptime
case .failed:
chatModel.contentViewAccessAuthenticated = false
if privacyLocalAuthModeDefault.get() == .passcode {
AlertManager.shared.showAlert(laFailedAlert())
}
case .unavailable:
prefPerformLA = false
canConnectViewCall = true
AlertManager.shared.showAlert(laUnavailableTurningOffAlert())
}
case .unavailable:
userAuthorized = true
prefPerformLA = false
canConnectCall = true
AlertManager.shared.showAlert(laUnavailableTurningOffAlert())
}
}
}
@@ -259,6 +293,7 @@ struct ContentView: View {
authenticate(reason: NSLocalizedString("Enable SimpleX Lock", comment: "authentication reason")) { laResult in
switch laResult {
case .success:
chatModel.contentViewAccessAuthenticated = true
prefPerformLA = true
alertManager.showAlert(laTurnedOnAlert())
case .failed:

View File

@@ -15,7 +15,13 @@ private let receiveTaskId = "chat.simplex.app.receive"
// TCP timeout + 2 sec
private let waitForMessages: TimeInterval = 6
private let bgRefreshInterval: TimeInterval = 450
// This is the smallest interval between refreshes, and also target interval in "off" mode
private let bgRefreshInterval: TimeInterval = 600 // 10 minutes
// This intervals are used for background refresh in instant and periodic modes
private let periodicBgRefreshInterval: TimeInterval = 1200 // 20 minutes
private let maxBgRefreshInterval: TimeInterval = 2400 // 40 minutes
private let maxTimerCount = 9
@@ -33,14 +39,14 @@ class BGManager {
}
}
func schedule() {
func schedule(interval: TimeInterval? = nil) {
if !ChatModel.shared.ntfEnableLocal {
logger.debug("BGManager.schedule: disabled")
return
}
logger.debug("BGManager.schedule")
let request = BGAppRefreshTaskRequest(identifier: receiveTaskId)
request.earliestBeginDate = Date(timeIntervalSinceNow: bgRefreshInterval)
request.earliestBeginDate = Date(timeIntervalSinceNow: interval ?? runInterval)
do {
try BGTaskScheduler.shared.submit(request)
} catch {
@@ -48,20 +54,34 @@ class BGManager {
}
}
var runInterval: TimeInterval {
switch ChatModel.shared.notificationMode {
case .instant: maxBgRefreshInterval
case .periodic: periodicBgRefreshInterval
case .off: bgRefreshInterval
}
}
var lastRanLongAgo: Bool {
Date.now.timeIntervalSince(chatLastBackgroundRunGroupDefault.get()) > runInterval
}
private func handleRefresh(_ task: BGAppRefreshTask) {
if !ChatModel.shared.ntfEnableLocal {
logger.debug("BGManager.handleRefresh: disabled")
return
}
logger.debug("BGManager.handleRefresh")
schedule()
if appStateGroupDefault.get().inactive {
let shouldRun_ = lastRanLongAgo
if allowBackgroundRefresh() && shouldRun_ {
schedule()
let completeRefresh = completionHandler {
task.setTaskCompleted(success: true)
}
task.expirationHandler = { completeRefresh("expirationHandler") }
receiveMessages(completeRefresh)
} else {
schedule(interval: shouldRun_ ? bgRefreshInterval : runInterval)
logger.debug("BGManager.completionHandler: already active, not started")
task.setTaskCompleted(success: true)
}
@@ -90,20 +110,22 @@ class BGManager {
}
self.completed = false
DispatchQueue.main.async {
chatLastBackgroundRunGroupDefault.set(Date.now)
let m = ChatModel.shared
if (!m.chatInitialized) {
setAppState(.bgRefresh)
do {
try initializeChat(start: true)
} catch let error {
fatalError("Failed to start or load chats: \(responseError(error))")
}
}
activateChat(appState: .bgRefresh)
if m.currentUser == nil {
completeReceiving("no current user")
return
}
logger.debug("BGManager.receiveMessages: starting chat")
activateChat(appState: .bgRefresh)
let cr = ChatReceiver()
self.chatReceiver = cr
cr.start()

View File

@@ -54,6 +54,8 @@ final class ChatModel: ObservableObject {
@Published var chatDbChanged = false
@Published var chatDbEncrypted: Bool?
@Published var chatDbStatus: DBMigrationResult?
// local authentication
@Published var contentViewAccessAuthenticated: Bool = false
@Published var laRequest: LocalAuthRequest?
// list of chat "previews"
@Published var chats: [Chat] = []
@@ -83,8 +85,10 @@ final class ChatModel: ObservableObject {
// current WebRTC call
@Published var callInvitations: Dictionary<ChatId, RcvCallInvitation> = [:]
@Published var activeCall: Call?
@Published var callCommand: WCallCommand?
let callCommand: WebRTCCommandProcessor = WebRTCCommandProcessor()
@Published var showCallView = false
// remote desktop
@Published var remoteCtrlSession: RemoteCtrlSession?
// currently showing QR code
@Published var connReqInv: String?
// audio recording and playback
@@ -102,12 +106,14 @@ final class ChatModel: ObservableObject {
static var ok: Bool { ChatModel.shared.chatDbStatus == .ok }
var ntfEnableLocal: Bool {
notificationMode == .off || ntfEnableLocalGroupDefault.get()
}
let ntfEnableLocal = true
var ntfEnablePeriodic: Bool {
notificationMode == .periodic || ntfEnablePeriodicGroupDefault.get()
notificationMode != .off
}
var activeRemoteCtrl: Bool {
remoteCtrlSession?.active ?? false
}
func getUser(_ userId: Int64) -> User? {
@@ -261,7 +267,20 @@ final class ChatModel: ObservableObject {
func addChatItem(_ cInfo: ChatInfo, _ cItem: ChatItem) {
// update previews
if let i = getChatIndex(cInfo.id) {
chats[i].chatItems = [cItem]
chats[i].chatItems = switch cInfo {
case .group:
if let currentPreviewItem = chats[i].chatItems.first {
if cItem.meta.itemTs >= currentPreviewItem.meta.itemTs {
[cItem]
} else {
[currentPreviewItem]
}
} else {
[cItem]
}
default:
[cItem]
}
if case .rcvNew = cItem.meta.itemStatus {
chats[i].chatStats.unreadCount = chats[i].chatStats.unreadCount + 1
increaseUnreadCounter(user: currentUser!)
@@ -762,3 +781,38 @@ final class GMember: ObservableObject, Identifiable {
var viewId: String { get { "\(wrapped.id) \(created.timeIntervalSince1970)" } }
static let sampleData = GMember(GroupMember.sampleData)
}
struct RemoteCtrlSession {
var ctrlAppInfo: CtrlAppInfo?
var appVersion: String
var sessionState: UIRemoteCtrlSessionState
func updateState(_ state: UIRemoteCtrlSessionState) -> RemoteCtrlSession {
RemoteCtrlSession(ctrlAppInfo: ctrlAppInfo, appVersion: appVersion, sessionState: state)
}
var active: Bool {
if case .connected = sessionState { true } else { false }
}
var discovery: Bool {
if case .searching = sessionState { true } else { false }
}
var sessionCode: String? {
switch sessionState {
case let .pendingConfirmation(_, sessionCode): sessionCode
case let .connected(_, sessionCode): sessionCode
default: nil
}
}
}
enum UIRemoteCtrlSessionState {
case starting
case searching
case found(remoteCtrl: RemoteCtrlInfo, compatible: Bool)
case connecting(remoteCtrl_: RemoteCtrlInfo?)
case pendingConfirmation(remoteCtrl_: RemoteCtrlInfo?, sessionCode: String)
case connected(remoteCtrl: RemoteCtrlInfo, sessionCode: String)
}

View File

@@ -195,18 +195,18 @@ func moveTempFileFromURL(_ url: URL) -> CryptoFile? {
}
}
func generateNewFileName(_ prefix: String, _ ext: String) -> String {
uniqueCombine("\(prefix)_\(getTimestamp()).\(ext)")
func generateNewFileName(_ prefix: String, _ ext: String, fullPath: Bool = false) -> String {
uniqueCombine("\(prefix)_\(getTimestamp()).\(ext)", fullPath: fullPath)
}
private func uniqueCombine(_ fileName: String) -> String {
private func uniqueCombine(_ fileName: String, fullPath: Bool = false) -> String {
func tryCombine(_ fileName: String, _ n: Int) -> String {
let ns = fileName as NSString
let name = ns.deletingPathExtension
let ext = ns.pathExtension
let suffix = (n == 0) ? "" : "_\(n)"
let f = "\(name)\(suffix).\(ext)"
return (FileManager.default.fileExists(atPath: getAppFilePath(f).path)) ? tryCombine(fileName, n + 1) : f
return (FileManager.default.fileExists(atPath: fullPath ? f : getAppFilePath(f).path)) ? tryCombine(fileName, n + 1) : f
}
return tryCombine(fileName, 0)
}

View File

@@ -0,0 +1,83 @@
//
// NSESubscriber.swift
// SimpleXChat
//
// Created by Evgeny on 09/12/2023.
// Copyright © 2023 SimpleX Chat. All rights reserved.
//
import Foundation
import SimpleXChat
private var nseSubscribers: [UUID:NSESubscriber] = [:]
// timeout for active notification service extension going into "suspending" state.
// If in two seconds the state does not change, we assume that it was not running and proceed with app activation/answering call.
private let SUSPENDING_TIMEOUT: TimeInterval = 2
// timeout should be larger than SUSPENDING_TIMEOUT
func waitNSESuspended(timeout: TimeInterval, suspended: @escaping (Bool) -> Void) {
if timeout <= SUSPENDING_TIMEOUT {
logger.warning("waitNSESuspended: small timeout \(timeout), using \(SUSPENDING_TIMEOUT + 1)")
}
var state = nseStateGroupDefault.get()
if case .suspended = state {
DispatchQueue.main.async { suspended(true) }
return
}
let id = UUID()
var suspendedCalled = false
checkTimeout()
nseSubscribers[id] = nseMessageSubscriber { msg in
if case let .state(newState) = msg {
state = newState
logger.debug("waitNSESuspended state: \(state.rawValue)")
if case .suspended = newState {
notifySuspended(true)
}
}
}
return
func notifySuspended(_ ok: Bool) {
logger.debug("waitNSESuspended notifySuspended: \(ok)")
if !suspendedCalled {
logger.debug("waitNSESuspended notifySuspended: calling suspended(\(ok))")
suspendedCalled = true
nseSubscribers.removeValue(forKey: id)
DispatchQueue.main.async { suspended(ok) }
}
}
func checkTimeout() {
if !suspending() {
checkSuspendingTimeout()
} else if state == .suspending {
checkSuspendedTimeout()
}
}
func suspending() -> Bool {
suspendedCalled || state == .suspended || state == .suspending
}
func checkSuspendingTimeout() {
DispatchQueue.global().asyncAfter(deadline: .now() + SUSPENDING_TIMEOUT) {
logger.debug("waitNSESuspended check suspending timeout")
if !suspending() {
notifySuspended(false)
} else if state != .suspended {
checkSuspendedTimeout()
}
}
}
func checkSuspendedTimeout() {
DispatchQueue.global().asyncAfter(deadline: .now() + min(timeout - SUSPENDING_TIMEOUT, 1)) {
logger.debug("waitNSESuspended check suspended timeout")
if state != .suspended {
notifySuspended(false)
}
}
}
}

View File

@@ -211,7 +211,7 @@ func apiDeleteUser(_ userId: Int64, _ delSMPQueues: Bool, viewPwd: String?) asyn
}
func apiStartChat() throws -> Bool {
let r = chatSendCmdSync(.startChat(subscribe: true, expire: true, xftp: true))
let r = chatSendCmdSync(.startChat(mainApp: true))
switch r {
case .chatStarted: return true
case .chatRunning: return false
@@ -228,7 +228,8 @@ func apiStopChat() async throws {
}
func apiActivateChat() {
let r = chatSendCmdSync(.apiActivateChat)
chatReopenStore()
let r = chatSendCmdSync(.apiActivateChat(restoreChat: true))
if case .cmdOk = r { return }
logger.error("apiActivateChat error: \(String(describing: r))")
}
@@ -402,7 +403,7 @@ func apiGetNtfToken() -> (DeviceToken?, NtfTknStatus?, NotificationsMode) {
case let .ntfToken(token, status, ntfMode): return (token, status, ntfMode)
case .chatCmdError(_, .errorAgent(.CMD(.PROHIBITED))): return (nil, nil, .off)
default:
logger.debug("apiGetNtfToken response: \(String(describing: r), privacy: .public)")
logger.debug("apiGetNtfToken response: \(String(describing: r))")
return (nil, nil, .off)
}
}
@@ -605,27 +606,29 @@ func apiConnectPlan(connReq: String) async throws -> ConnectionPlan {
throw r
}
func apiConnect(incognito: Bool, connReq: String) async -> ConnReqType? {
let (connReqType, alert) = await apiConnect_(incognito: incognito, connReq: connReq)
func apiConnect(incognito: Bool, connReq: String) async -> (ConnReqType, PendingContactConnection)? {
let (r, alert) = await apiConnect_(incognito: incognito, connReq: connReq)
if let alert = alert {
AlertManager.shared.showAlert(alert)
return nil
} else {
return connReqType
return r
}
}
func apiConnect_(incognito: Bool, connReq: String) async -> (ConnReqType?, Alert?) {
func apiConnect_(incognito: Bool, connReq: String) async -> ((ConnReqType, PendingContactConnection)?, Alert?) {
guard let userId = ChatModel.shared.currentUser?.userId else {
logger.error("apiConnect: no current user")
return (nil, nil)
}
let r = await chatSendCmd(.apiConnect(userId: userId, incognito: incognito, connReq: connReq))
let m = ChatModel.shared
switch r {
case .sentConfirmation: return (.invitation, nil)
case .sentInvitation: return (.contact, nil)
case let .sentConfirmation(_, connection):
return ((.invitation, connection), nil)
case let .sentInvitation(_, connection):
return ((.contact, connection), nil)
case let .contactAlreadyExists(_, contact):
let m = ChatModel.shared
if let c = m.getContactChat(contact.contactId) {
await MainActor.run { m.chatId = c.id }
}
@@ -905,6 +908,46 @@ func apiCancelFile(fileId: Int64) async -> AChatItem? {
}
}
func setLocalDeviceName(_ displayName: String) throws {
try sendCommandOkRespSync(.setLocalDeviceName(displayName: displayName))
}
func connectRemoteCtrl(desktopAddress: String) async throws -> (RemoteCtrlInfo?, CtrlAppInfo, String) {
let r = await chatSendCmd(.connectRemoteCtrl(xrcpInvitation: desktopAddress))
if case let .remoteCtrlConnecting(rc_, ctrlAppInfo, v) = r { return (rc_, ctrlAppInfo, v) }
throw r
}
func findKnownRemoteCtrl() async throws {
try await sendCommandOkResp(.findKnownRemoteCtrl)
}
func confirmRemoteCtrl(_ rcId: Int64) async throws -> (RemoteCtrlInfo?, CtrlAppInfo, String) {
let r = await chatSendCmd(.confirmRemoteCtrl(remoteCtrlId: rcId))
if case let .remoteCtrlConnecting(rc_, ctrlAppInfo, v) = r { return (rc_, ctrlAppInfo, v) }
throw r
}
func verifyRemoteCtrlSession(_ sessCode: String) async throws -> RemoteCtrlInfo {
let r = await chatSendCmd(.verifyRemoteCtrlSession(sessionCode: sessCode))
if case let .remoteCtrlConnected(rc) = r { return rc }
throw r
}
func listRemoteCtrls() throws -> [RemoteCtrlInfo] {
let r = chatSendCmdSync(.listRemoteCtrls)
if case let .remoteCtrlList(rcInfo) = r { return rcInfo }
throw r
}
func stopRemoteCtrl() async throws {
try await sendCommandOkResp(.stopRemoteCtrl)
}
func deleteRemoteCtrl(_ rcId: Int64) async throws {
try await sendCommandOkResp(.deleteRemoteCtrl(remoteCtrlId: rcId))
}
func networkErrorAlert(_ r: ChatResponse) -> Alert? {
switch r {
case let .chatCmdError(_, .errorAgent(.BROKER(addr, .TIMEOUT))):
@@ -1033,6 +1076,12 @@ private func sendCommandOkResp(_ cmd: ChatCommand) async throws {
throw r
}
private func sendCommandOkRespSync(_ cmd: ChatCommand) throws {
let r = chatSendCmdSync(cmd)
if case .cmdOk = r { return }
throw r
}
func apiNewGroup(incognito: Bool, groupProfile: GroupProfile) throws -> GroupInfo {
let userId = try currentUserId("apiNewGroup")
let r = chatSendCmdSync(.apiNewGroup(userId: userId, incognito: incognito, groupProfile: groupProfile))
@@ -1186,6 +1235,9 @@ func initializeChat(start: Bool, dbKey: String? = nil, refreshInvitations: Bool
try startChat(refreshInvitations: refreshInvitations)
} else {
m.chatRunning = false
try getUserChatData()
NtfManager.shared.setNtfBadgeCount(m.totalUnreadCountForAllUsers())
m.onboardingStage = onboardingStageDefault.get()
}
}
@@ -1202,6 +1254,8 @@ func startChat(refreshInvitations: Bool = true) throws {
try refreshCallInvitations()
}
(m.savedToken, m.tokenStatus, m.notificationMode) = apiGetNtfToken()
// deviceToken is set when AppDelegate.application(didRegisterForRemoteNotificationsWithDeviceToken:) is called,
// when it is called before startChat
if let token = m.deviceToken {
registerToken(token: token)
}
@@ -1316,18 +1370,6 @@ func processReceivedMsg(_ res: ChatResponse) async {
let m = ChatModel.shared
logger.debug("processReceivedMsg: \(res.responseType)")
switch res {
case let .newContactConnection(user, connection):
if active(user) {
await MainActor.run {
m.updateContactConnection(connection)
}
}
case let .contactConnectionDeleted(user, connection):
if active(user) {
await MainActor.run {
m.removeChat(connection.id)
}
}
case let .contactDeletedByContact(user, contact):
if active(user) && contact.directOrUsed {
await MainActor.run {
@@ -1620,36 +1662,40 @@ func processReceivedMsg(_ res: ChatResponse) async {
activateCall(invitation)
case let .callOffer(_, contact, callType, offer, sharedKey, _):
await withCall(contact) { call in
call.callState = .offerReceived
call.peerMedia = callType.media
call.sharedKey = sharedKey
await MainActor.run {
call.callState = .offerReceived
call.peerMedia = callType.media
call.sharedKey = sharedKey
}
let useRelay = UserDefaults.standard.bool(forKey: DEFAULT_WEBRTC_POLICY_RELAY)
let iceServers = getIceServers()
logger.debug(".callOffer useRelay \(useRelay)")
logger.debug(".callOffer iceServers \(String(describing: iceServers))")
m.callCommand = .offer(
await m.callCommand.processCommand(.offer(
offer: offer.rtcSession,
iceCandidates: offer.rtcIceCandidates,
media: callType.media, aesKey: sharedKey,
iceServers: iceServers,
relay: useRelay
)
))
}
case let .callAnswer(_, contact, answer):
await withCall(contact) { call in
call.callState = .answerReceived
m.callCommand = .answer(answer: answer.rtcSession, iceCandidates: answer.rtcIceCandidates)
await MainActor.run {
call.callState = .answerReceived
}
await m.callCommand.processCommand(.answer(answer: answer.rtcSession, iceCandidates: answer.rtcIceCandidates))
}
case let .callExtraInfo(_, contact, extraInfo):
await withCall(contact) { _ in
m.callCommand = .ice(iceCandidates: extraInfo.rtcIceCandidates)
await m.callCommand.processCommand(.ice(iceCandidates: extraInfo.rtcIceCandidates))
}
case let .callEnded(_, contact):
if let invitation = await MainActor.run(body: { m.callInvitations.removeValue(forKey: contact.id) }) {
CallController.shared.reportCallRemoteEnded(invitation: invitation)
}
await withCall(contact) { call in
m.callCommand = .end
await m.callCommand.processCommand(.end)
CallController.shared.reportCallRemoteEnded(call: call)
}
case .chatSuspended:
@@ -1670,19 +1716,67 @@ func processReceivedMsg(_ res: ChatResponse) async {
await MainActor.run {
m.updateGroupMemberConnectionStats(groupInfo, member, ratchetSyncProgress.connectionStats)
}
case let .remoteCtrlFound(remoteCtrl, ctrlAppInfo_, appVersion, compatible):
await MainActor.run {
if let sess = m.remoteCtrlSession, case .searching = sess.sessionState {
let state = UIRemoteCtrlSessionState.found(remoteCtrl: remoteCtrl, compatible: compatible)
m.remoteCtrlSession = RemoteCtrlSession(
ctrlAppInfo: ctrlAppInfo_,
appVersion: appVersion,
sessionState: state
)
}
}
case let .remoteCtrlSessionCode(remoteCtrl_, sessionCode):
await MainActor.run {
let state = UIRemoteCtrlSessionState.pendingConfirmation(remoteCtrl_: remoteCtrl_, sessionCode: sessionCode)
m.remoteCtrlSession = m.remoteCtrlSession?.updateState(state)
}
case let .remoteCtrlConnected(remoteCtrl):
// TODO currently it is returned in response to command, so it is redundant
await MainActor.run {
let state = UIRemoteCtrlSessionState.connected(remoteCtrl: remoteCtrl, sessionCode: m.remoteCtrlSession?.sessionCode ?? "")
m.remoteCtrlSession = m.remoteCtrlSession?.updateState(state)
}
case .remoteCtrlStopped:
// This delay is needed to cancel the session that fails on network failure,
// e.g. when user did not grant permission to access local network yet.
if let sess = m.remoteCtrlSession {
await MainActor.run {
m.remoteCtrlSession = nil
}
if case .connected = sess.sessionState {
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
switchToLocalSession()
}
}
}
default:
logger.debug("unsupported event: \(res.responseType)")
}
func withCall(_ contact: Contact, _ perform: (Call) -> Void) async {
func withCall(_ contact: Contact, _ perform: (Call) async -> Void) async {
if let call = m.activeCall, call.contact.apiId == contact.apiId {
await MainActor.run { perform(call) }
await perform(call)
} else {
logger.debug("processReceivedMsg: ignoring \(res.responseType), not in call with the contact \(contact.id)")
}
}
}
func switchToLocalSession() {
let m = ChatModel.shared
m.remoteCtrlSession = nil
do {
m.users = try listUsers()
try getUserChatData()
let statuses = (try apiGetNetworkStatuses()).map { s in (s.agentConnId, s.networkStatus) }
m.networkStatuses = Dictionary(uniqueKeysWithValues: statuses)
} catch let error {
logger.debug("error updating chat data: \(responseError(error))")
}
}
func active(_ user: any UserLike) -> Bool {
user.userId == ChatModel.shared.currentUser?.id
}

View File

@@ -9,27 +9,30 @@
import Foundation
import UIKit
import SimpleXChat
import SwiftUI
private let suspendLockQueue = DispatchQueue(label: "chat.simplex.app.suspend.lock")
let appSuspendTimeout: Int = 15 // seconds
let bgSuspendTimeout: Int = 5 // seconds
let terminationTimeout: Int = 3 // seconds
let activationDelay: TimeInterval = 1.5
let nseSuspendTimeout: TimeInterval = 5
private func _suspendChat(timeout: Int) {
// this is a redundant check to prevent logical errors, like the one fixed in this PR
let state = appStateGroupDefault.get()
let state = AppChatState.shared.value
if !state.canSuspend {
logger.error("_suspendChat called, current state: \(state.rawValue, privacy: .public)")
logger.error("_suspendChat called, current state: \(state.rawValue)")
} else if ChatModel.ok {
appStateGroupDefault.set(.suspending)
AppChatState.shared.set(.suspending)
apiSuspendChat(timeoutMicroseconds: timeout * 1000000)
let endTask = beginBGTask(chatSuspended)
DispatchQueue.global().asyncAfter(deadline: .now() + Double(timeout) + 1, execute: endTask)
} else {
appStateGroupDefault.set(.suspended)
AppChatState.shared.set(.suspended)
}
}
@@ -41,18 +44,16 @@ func suspendChat() {
func suspendBgRefresh() {
suspendLockQueue.sync {
if case .bgRefresh = appStateGroupDefault.get() {
if case .bgRefresh = AppChatState.shared.value {
_suspendChat(timeout: bgSuspendTimeout)
}
}
}
private var terminating = false
func terminateChat() {
logger.debug("terminateChat")
suspendLockQueue.sync {
switch appStateGroupDefault.get() {
switch AppChatState.shared.value {
case .suspending:
// suspend instantly if already suspending
_chatSuspended()
@@ -64,7 +65,6 @@ func terminateChat() {
case .stopped:
chatCloseStore()
default:
terminating = true
// the store will be closed in _chatSuspended when event is received
_suspendChat(timeout: terminationTimeout)
}
@@ -73,7 +73,7 @@ func terminateChat() {
func chatSuspended() {
suspendLockQueue.sync {
if case .suspending = appStateGroupDefault.get() {
if case .suspending = AppChatState.shared.value {
_chatSuspended()
}
}
@@ -81,48 +81,121 @@ func chatSuspended() {
private func _chatSuspended() {
logger.debug("_chatSuspended")
appStateGroupDefault.set(.suspended)
AppChatState.shared.set(.suspended)
if ChatModel.shared.chatRunning == true {
ChatReceiver.shared.stop()
}
if terminating {
chatCloseStore()
chatCloseStore()
}
func setAppState(_ appState: AppState) {
suspendLockQueue.sync {
AppChatState.shared.set(appState)
}
}
func activateChat(appState: AppState = .active) {
logger.debug("DEBUGGING: activateChat")
terminating = false
suspendLockQueue.sync {
appStateGroupDefault.set(appState)
AppChatState.shared.set(appState)
if ChatModel.ok { apiActivateChat() }
logger.debug("DEBUGGING: activateChat: after apiActivateChat")
}
}
func initChatAndMigrate(refreshInvitations: Bool = true) {
terminating = false
let m = ChatModel.shared
if (!m.chatInitialized) {
m.v3DBMigration = v3DBMigrationDefault.get()
if AppChatState.shared.value == .stopped {
AlertManager.shared.showAlert(Alert(
title: Text("Start chat?"),
message: Text("Chat is stopped. If you already used this database on another device, you should transfer it back before starting chat."),
primaryButton: .default(Text("Ok")) {
AppChatState.shared.set(.active)
initialize(start: true)
},
secondaryButton: .cancel {
initialize(start: false)
}
))
} else {
initialize(start: true)
}
}
func initialize(start: Bool) {
do {
m.v3DBMigration = v3DBMigrationDefault.get()
try initializeChat(start: m.v3DBMigration.startChat, refreshInvitations: refreshInvitations)
try initializeChat(start: m.v3DBMigration.startChat && start, refreshInvitations: refreshInvitations)
} catch let error {
fatalError("Failed to start or load chats: \(responseError(error))")
AlertManager.shared.showAlertMsg(
title: start ? "Error starting chat" : "Error opening chat",
message: "Please contact developers.\nError: \(responseError(error))"
)
}
}
}
func startChatAndActivate() {
terminating = false
func startChatForCall() {
logger.debug("DEBUGGING: startChatForCall")
if ChatModel.shared.chatRunning == true {
ChatReceiver.shared.start()
logger.debug("DEBUGGING: startChatForCall: after ChatReceiver.shared.start")
}
if .active != AppChatState.shared.value {
logger.debug("DEBUGGING: startChatForCall: before activateChat")
activateChat()
logger.debug("DEBUGGING: startChatForCall: after activateChat")
}
}
func startChatAndActivate(_ completion: @escaping () -> Void) {
logger.debug("DEBUGGING: startChatAndActivate")
if ChatModel.shared.chatRunning == true {
ChatReceiver.shared.start()
logger.debug("DEBUGGING: startChatAndActivate: after ChatReceiver.shared.start")
}
if .active != appStateGroupDefault.get() {
if case .active = AppChatState.shared.value {
completion()
} else if nseStateGroupDefault.get().inactive {
activate()
} else {
// setting app state to "activating" to notify NSE that it should suspend
setAppState(.activating)
waitNSESuspended(timeout: nseSuspendTimeout) { ok in
if !ok {
// if for some reason NSE failed to suspend,
// e.g., it crashed previously without setting its state to "suspended",
// set it to "suspended" state anyway, so that next time app
// does not have to wait when activating.
nseStateGroupDefault.set(.suspended)
}
if AppChatState.shared.value == .activating {
activate()
}
}
}
func activate() {
logger.debug("DEBUGGING: startChatAndActivate: before activateChat")
activateChat()
completion()
logger.debug("DEBUGGING: startChatAndActivate: after activateChat")
}
}
// appStateGroupDefault must not be used in the app directly, only via this singleton
class AppChatState {
static let shared = AppChatState()
private var value_ = appStateGroupDefault.get()
var value: AppState {
value_
}
func set(_ state: AppState) {
appStateGroupDefault.set(state)
sendAppState(state)
value_ = state
}
}

View File

@@ -16,17 +16,15 @@ struct SimpleXApp: App {
@UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
@StateObject private var chatModel = ChatModel.shared
@ObservedObject var alertManager = AlertManager.shared
@Environment(\.scenePhase) var scenePhase
@AppStorage(DEFAULT_PERFORM_LA) private var prefPerformLA = false
@State private var userAuthorized: Bool?
@State private var doAuthenticate = false
@State private var enteredBackground: TimeInterval? = nil
@State private var canConnectCall = false
@State private var lastSuccessfulUnlock: TimeInterval? = nil
@State private var showInitializationView = false
@State private var enteredBackgroundAuthenticated: TimeInterval? = nil
init() {
hs_init(0, nil)
DispatchQueue.global(qos: .background).sync {
haskell_init()
// hs_init(0, nil)
}
UserDefaults.standard.register(defaults: appDefaults)
setGroupDefaults()
registerGroupDefaults()
@@ -36,22 +34,17 @@ struct SimpleXApp: App {
}
var body: some Scene {
return WindowGroup {
ContentView(
doAuthenticate: $doAuthenticate,
userAuthorized: $userAuthorized,
canConnectCall: $canConnectCall,
lastSuccessfulUnlock: $lastSuccessfulUnlock,
showInitializationView: $showInitializationView
)
WindowGroup {
// contentAccessAuthenticationExtended has to be passed to ContentView on view initialization,
// so that it's computed by the time view renders, and not on event after rendering
ContentView(contentAccessAuthenticationExtended: !authenticationExpired())
.environmentObject(chatModel)
.onOpenURL { url in
logger.debug("ContentView.onOpenURL: \(url)")
chatModel.appOpenUrl = url
}
.onAppear() {
showInitializationView = true
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
DispatchQueue.main.asyncAfter(deadline: .now() + 0.15) {
initChatAndMigrate()
}
}
@@ -59,30 +52,35 @@ struct SimpleXApp: App {
logger.debug("scenePhase was \(String(describing: scenePhase)), now \(String(describing: phase))")
switch (phase) {
case .background:
// --- authentication
// see ContentView .onChange(of: scenePhase) for remaining authentication logic
if chatModel.contentViewAccessAuthenticated {
enteredBackgroundAuthenticated = ProcessInfo.processInfo.systemUptime
}
chatModel.contentViewAccessAuthenticated = false
// authentication ---
if CallController.useCallKit() && chatModel.activeCall != nil {
CallController.shared.shouldSuspendChat = true
} else {
suspendChat()
BGManager.shared.schedule()
}
if userAuthorized == true {
enteredBackground = ProcessInfo.processInfo.systemUptime
}
doAuthenticate = false
canConnectCall = false
NtfManager.shared.setNtfBadgeCount(chatModel.totalUnreadCountForAllUsers())
case .active:
CallController.shared.shouldSuspendChat = false
let appState = appStateGroupDefault.get()
startChatAndActivate()
if appState.inactive && chatModel.chatRunning == true {
updateChats()
if !chatModel.showCallView && !CallController.shared.hasActiveCalls() {
updateCallInvitations()
let appState = AppChatState.shared.value
if appState != .stopped {
startChatAndActivate {
if appState.inactive && chatModel.chatRunning == true {
updateChats()
if !chatModel.showCallView && !CallController.shared.hasActiveCalls() {
updateCallInvitations()
}
}
}
}
doAuthenticate = authenticationExpired()
canConnectCall = !(doAuthenticate && prefPerformLA) || unlockedRecently()
default:
break
}
@@ -100,12 +98,12 @@ struct SimpleXApp: App {
if legacyDatabase, case .documents = dbContainerGroupDefault.get() {
dbContainerGroupDefault.set(.documents)
setMigrationState(.offer)
logger.debug("SimpleXApp init: using legacy DB in documents folder: \(getAppDatabasePath(), privacy: .public)*.db")
logger.debug("SimpleXApp init: using legacy DB in documents folder: \(getAppDatabasePath())*.db")
} else {
dbContainerGroupDefault.set(.group)
setMigrationState(.ready)
logger.debug("SimpleXApp init: using DB in app group container: \(getAppDatabasePath(), privacy: .public)*.db")
logger.debug("SimpleXApp init: legacy DB\(legacyDatabase ? "" : " not", privacy: .public) present")
logger.debug("SimpleXApp init: using DB in app group container: \(getAppDatabasePath())*.db")
logger.debug("SimpleXApp init: legacy DB\(legacyDatabase ? "" : " not") present")
}
}
@@ -115,22 +113,14 @@ struct SimpleXApp: App {
}
private func authenticationExpired() -> Bool {
if let enteredBackground = enteredBackground {
if let enteredBackgroundAuthenticated = enteredBackgroundAuthenticated {
let delay = Double(UserDefaults.standard.integer(forKey: DEFAULT_LA_LOCK_DELAY))
return ProcessInfo.processInfo.systemUptime - enteredBackground >= delay
return ProcessInfo.processInfo.systemUptime - enteredBackgroundAuthenticated >= delay
} else {
return true
}
}
private func unlockedRecently() -> Bool {
if let lastSuccessfulUnlock = lastSuccessfulUnlock {
return ProcessInfo.processInfo.systemUptime - lastSuccessfulUnlock < 2
} else {
return false
}
}
private func updateChats() {
do {
let chats = try apiGetChats()

View File

@@ -38,21 +38,21 @@ struct ActiveCallView: View {
}
}
.onAppear {
logger.debug("ActiveCallView: appear client is nil \(client == nil), scenePhase \(String(describing: scenePhase), privacy: .public), canConnectCall \(canConnectCall)")
logger.debug("ActiveCallView: appear client is nil \(client == nil), scenePhase \(String(describing: scenePhase)), canConnectCall \(canConnectCall)")
AppDelegate.keepScreenOn(true)
createWebRTCClient()
dismissAllSheets()
}
.onChange(of: canConnectCall) { _ in
logger.debug("ActiveCallView: canConnectCall changed to \(canConnectCall, privacy: .public)")
logger.debug("ActiveCallView: canConnectCall changed to \(canConnectCall)")
createWebRTCClient()
}
.onDisappear {
logger.debug("ActiveCallView: disappear")
Task { await m.callCommand.setClient(nil) }
AppDelegate.keepScreenOn(false)
client?.endCall()
}
.onChange(of: m.callCommand) { _ in sendCommandToClient()}
.background(.black)
.preferredColorScheme(.dark)
}
@@ -60,19 +60,8 @@ struct ActiveCallView: View {
private func createWebRTCClient() {
if client == nil && canConnectCall {
client = WebRTCClient($activeCall, { msg in await MainActor.run { processRtcMessage(msg: msg) } }, $localRendererAspectRatio)
sendCommandToClient()
}
}
private func sendCommandToClient() {
if call == m.activeCall,
m.activeCall != nil,
let client = client,
let cmd = m.callCommand {
m.callCommand = nil
logger.debug("sendCallCommand: \(cmd.cmdType)")
Task {
await client.sendCallCommand(command: cmd)
await m.callCommand.setClient(client)
}
}
}
@@ -168,8 +157,10 @@ struct ActiveCallView: View {
}
case let .error(message):
logger.debug("ActiveCallView: command error: \(message)")
AlertManager.shared.showAlert(Alert(title: Text("Error"), message: Text(message)))
case let .invalid(type):
logger.debug("ActiveCallView: invalid response: \(type)")
AlertManager.shared.showAlert(Alert(title: Text("Invalid response"), message: Text(type)))
}
}
}
@@ -255,7 +246,6 @@ struct ActiveCallOverlay: View {
HStack {
Text(call.encryptionStatus)
if let connInfo = call.connectionInfo {
// Text("(") + Text(connInfo.text) + Text(", \(connInfo.protocolText))")
Text("(") + Text(connInfo.text) + Text(")")
}
}

View File

@@ -130,7 +130,7 @@ class CallController: NSObject, CXProviderDelegate, PKPushRegistryDelegate, Obse
// The delay allows to accept the second call before suspending a chat
// see `.onChange(of: scenePhase)` in SimpleXApp
DispatchQueue.main.asyncAfter(deadline: .now() + 3) { [weak self] in
logger.debug("CallController: shouldSuspendChat \(String(describing: self?.shouldSuspendChat), privacy: .public)")
logger.debug("CallController: shouldSuspendChat \(String(describing: self?.shouldSuspendChat))")
if ChatModel.shared.activeCall == nil && self?.shouldSuspendChat == true {
self?.shouldSuspendChat = false
suspendChat()
@@ -142,33 +142,46 @@ class CallController: NSObject, CXProviderDelegate, PKPushRegistryDelegate, Obse
@objc(pushRegistry:didUpdatePushCredentials:forType:)
func pushRegistry(_ registry: PKPushRegistry, didUpdate pushCredentials: PKPushCredentials, for type: PKPushType) {
logger.debug("CallController: didUpdate push credentials for type \(type.rawValue, privacy: .public)")
logger.debug("CallController: didUpdate push credentials for type \(type.rawValue)")
}
func pushRegistry(_ registry: PKPushRegistry, didReceiveIncomingPushWith payload: PKPushPayload, for type: PKPushType, completion: @escaping () -> Void) {
logger.debug("CallController: did receive push with type \(type.rawValue, privacy: .public)")
logger.debug("CallController: did receive push with type \(type.rawValue)")
if type != .voIP {
completion()
return
}
logger.debug("CallController: initializing chat")
if (!ChatModel.shared.chatInitialized) {
initChatAndMigrate(refreshInvitations: false)
if AppChatState.shared.value == .stopped {
self.reportExpiredCall(payload: payload, completion)
return
}
startChatAndActivate()
shouldSuspendChat = true
if (!ChatModel.shared.chatInitialized) {
logger.debug("CallController: initializing chat")
do {
try initializeChat(start: true, refreshInvitations: false)
} catch let error {
logger.error("CallController: initializing chat error: \(error)")
self.reportExpiredCall(payload: payload, completion)
return
}
}
logger.debug("CallController: initialized chat")
startChatForCall()
logger.debug("CallController: started chat")
self.shouldSuspendChat = true
// There are no invitations in the model, as it was processed by NSE
_ = try? justRefreshCallInvitations()
logger.debug("CallController: updated call invitations chat")
// logger.debug("CallController justRefreshCallInvitations: \(String(describing: m.callInvitations))")
// Extract the call information from the push notification payload
let m = ChatModel.shared
if let contactId = payload.dictionaryPayload["contactId"] as? String,
let invitation = m.callInvitations[contactId] {
let update = cxCallUpdate(invitation: invitation)
let update = self.cxCallUpdate(invitation: invitation)
if let uuid = invitation.callkitUUID {
logger.debug("CallController: report pushkit call via CallKit")
let update = cxCallUpdate(invitation: invitation)
provider.reportNewIncomingCall(with: uuid, update: update) { error in
let update = self.cxCallUpdate(invitation: invitation)
self.provider.reportNewIncomingCall(with: uuid, update: update) { error in
if error != nil {
m.callInvitations.removeValue(forKey: contactId)
}
@@ -176,10 +189,10 @@ class CallController: NSObject, CXProviderDelegate, PKPushRegistryDelegate, Obse
completion()
}
} else {
reportExpiredCall(update: update, completion)
self.reportExpiredCall(update: update, completion)
}
} else {
reportExpiredCall(payload: payload, completion)
self.reportExpiredCall(payload: payload, completion)
}
}
@@ -210,7 +223,7 @@ class CallController: NSObject, CXProviderDelegate, PKPushRegistryDelegate, Obse
}
func reportNewIncomingCall(invitation: RcvCallInvitation, completion: @escaping (Error?) -> Void) {
logger.debug("CallController.reportNewIncomingCall, UUID=\(String(describing: invitation.callkitUUID), privacy: .public)")
logger.debug("CallController.reportNewIncomingCall, UUID=\(String(describing: invitation.callkitUUID))")
if CallController.useCallKit(), let uuid = invitation.callkitUUID {
if invitation.callTs.timeIntervalSinceNow >= -180 {
let update = cxCallUpdate(invitation: invitation)
@@ -350,7 +363,7 @@ class CallController: NSObject, CXProviderDelegate, PKPushRegistryDelegate, Obse
private func requestTransaction(with action: CXAction, onSuccess: @escaping () -> Void = {}) {
controller.request(CXTransaction(action: action)) { error in
if let error = error {
logger.error("CallController.requestTransaction error requesting transaction: \(error.localizedDescription, privacy: .public)")
logger.error("CallController.requestTransaction error requesting transaction: \(error.localizedDescription)")
} else {
logger.debug("CallController.requestTransaction requested transaction successfully")
onSuccess()

View File

@@ -22,7 +22,7 @@ class CallManager {
let m = ChatModel.shared
if let call = m.activeCall, call.callkitUUID == callUUID {
m.showCallView = true
m.callCommand = .capabilities(media: call.localMedia)
Task { await m.callCommand.processCommand(.capabilities(media: call.localMedia)) }
return true
}
return false
@@ -57,19 +57,21 @@ class CallManager {
m.activeCall = call
m.showCallView = true
m.callCommand = .start(
Task {
await m.callCommand.processCommand(.start(
media: invitation.callType.media,
aesKey: invitation.sharedKey,
iceServers: iceServers,
relay: useRelay
)
))
}
}
}
func enableMedia(media: CallMediaType, enable: Bool, callUUID: UUID) -> Bool {
if let call = ChatModel.shared.activeCall, call.callkitUUID == callUUID {
let m = ChatModel.shared
m.callCommand = .media(media: media, enable: enable)
Task { await m.callCommand.processCommand(.media(media: media, enable: enable)) }
return true
}
return false
@@ -94,11 +96,13 @@ class CallManager {
completed()
} else {
logger.debug("CallManager.endCall: ending call...")
m.callCommand = .end
m.activeCall = nil
m.showCallView = false
completed()
Task {
await m.callCommand.processCommand(.end)
await MainActor.run {
m.activeCall = nil
m.showCallView = false
completed()
}
do {
try await apiEndCall(call.contact)
} catch {

View File

@@ -335,6 +335,50 @@ extension WCallResponse: Encodable {
}
}
actor WebRTCCommandProcessor {
private var client: WebRTCClient? = nil
private var commands: [WCallCommand] = []
private var running: Bool = false
func setClient(_ client: WebRTCClient?) async {
logger.debug("WebRTC: setClient, commands count \(self.commands.count)")
self.client = client
if client != nil {
await processAllCommands()
} else {
commands.removeAll()
}
}
func processCommand(_ c: WCallCommand) async {
// logger.debug("WebRTC: process command \(c.cmdType)")
commands.append(c)
if !running && client != nil {
await processAllCommands()
}
}
func processAllCommands() async {
logger.debug("WebRTC: process all commands, commands count \(self.commands.count), client == nil \(self.client == nil)")
if let client = client {
running = true
while let c = commands.first, shouldRunCommand(client, c) {
commands.remove(at: 0)
await client.sendCallCommand(command: c)
logger.debug("WebRTC: processed cmd \(c.cmdType)")
}
running = false
}
}
func shouldRunCommand(_ client: WebRTCClient, _ c: WCallCommand) -> Bool {
switch c {
case .capabilities, .start, .offer, .end: true
default: client.activeCall.wrappedValue != nil
}
}
}
struct ConnectionState: Codable, Equatable {
var connectionState: String
var iceConnectionState: String
@@ -358,26 +402,12 @@ struct ConnectionInfo: Codable, Equatable {
return "\(local?.rawValue ?? unknown) / \(remote?.rawValue ?? unknown)"
}
}
var protocolText: String {
let unknown = NSLocalizedString("unknown", comment: "connection info")
let local = localCandidate?.protocol?.uppercased() ?? unknown
let localRelay = localCandidate?.relayProtocol?.uppercased() ?? unknown
let remote = remoteCandidate?.protocol?.uppercased() ?? unknown
let localText = localRelay == local || localCandidate?.relayProtocol == nil
? local
: "\(local) (\(localRelay))"
return local == remote
? localText
: "\(localText) / \(remote)"
}
}
// https://developer.mozilla.org/en-US/docs/Web/API/RTCIceCandidate
struct RTCIceCandidate: Codable, Equatable {
var candidateType: RTCIceCandidateType?
var `protocol`: String?
var relayProtocol: String?
var sdpMid: String?
var sdpMLineIndex: Int?
var candidate: String

View File

@@ -18,10 +18,11 @@ final class WebRTCClient: NSObject, RTCVideoViewDelegate, RTCFrameEncryptorDeleg
}()
private static let ivTagBytes: Int = 28
private static let enableEncryption: Bool = true
private var chat_ctrl = getChatCtrl()
struct Call {
var connection: RTCPeerConnection
var iceCandidates: [RTCIceCandidate]
var iceCandidates: IceCandidates
var localMedia: CallMediaType
var localCamera: RTCVideoCapturer?
var localVideoSource: RTCVideoSource?
@@ -33,10 +34,24 @@ final class WebRTCClient: NSObject, RTCVideoViewDelegate, RTCFrameEncryptorDeleg
var frameDecryptor: RTCFrameDecryptor?
}
actor IceCandidates {
private var candidates: [RTCIceCandidate] = []
func getAndClear() async -> [RTCIceCandidate] {
let cs = candidates
candidates = []
return cs
}
func append(_ c: RTCIceCandidate) async {
candidates.append(c)
}
}
private let rtcAudioSession = RTCAudioSession.sharedInstance()
private let audioQueue = DispatchQueue(label: "audio")
private var sendCallResponse: (WVAPIMessage) async -> Void
private var activeCall: Binding<Call?>
var activeCall: Binding<Call?>
private var localRendererAspectRatio: Binding<CGFloat?>
@available(*, unavailable)
@@ -60,7 +75,7 @@ final class WebRTCClient: NSObject, RTCVideoViewDelegate, RTCFrameEncryptorDeleg
WebRTC.RTCIceServer(urlStrings: ["turn:turn.simplex.im:443?transport=tcp"], username: "private", credential: "yleob6AVkiNI87hpR94Z"),
]
func initializeCall(_ iceServers: [WebRTC.RTCIceServer]?, _ remoteIceCandidates: [RTCIceCandidate], _ mediaType: CallMediaType, _ aesKey: String?, _ relay: Bool?) -> Call {
func initializeCall(_ iceServers: [WebRTC.RTCIceServer]?, _ mediaType: CallMediaType, _ aesKey: String?, _ relay: Bool?) -> Call {
let connection = createPeerConnection(iceServers ?? getWebRTCIceServers() ?? defaultIceServers, relay)
connection.delegate = self
createAudioSender(connection)
@@ -87,7 +102,7 @@ final class WebRTCClient: NSObject, RTCVideoViewDelegate, RTCFrameEncryptorDeleg
}
return Call(
connection: connection,
iceCandidates: remoteIceCandidates,
iceCandidates: IceCandidates(),
localMedia: mediaType,
localCamera: localCamera,
localVideoSource: localVideoSource,
@@ -144,26 +159,18 @@ final class WebRTCClient: NSObject, RTCVideoViewDelegate, RTCFrameEncryptorDeleg
logger.debug("starting incoming call - create webrtc session")
if activeCall.wrappedValue != nil { endCall() }
let encryption = WebRTCClient.enableEncryption
let call = initializeCall(iceServers?.toWebRTCIceServers(), [], media, encryption ? aesKey : nil, relay)
let call = initializeCall(iceServers?.toWebRTCIceServers(), media, encryption ? aesKey : nil, relay)
activeCall.wrappedValue = call
call.connection.offer { answer in
Task {
let gotCandidates = await self.waitWithTimeout(10_000, stepMs: 1000, until: { self.activeCall.wrappedValue?.iceCandidates.count ?? 0 > 0 })
if gotCandidates {
await self.sendCallResponse(.init(
corrId: nil,
resp: .offer(
offer: compressToBase64(input: encodeJSON(CustomRTCSessionDescription(type: answer.type.toSdpType(), sdp: answer.sdp))),
iceCandidates: compressToBase64(input: encodeJSON(self.activeCall.wrappedValue?.iceCandidates ?? [])),
capabilities: CallCapabilities(encryption: encryption)
),
command: command)
)
} else {
self.endCall()
}
}
let (offer, error) = await call.connection.offer()
if let offer = offer {
resp = .offer(
offer: compressToBase64(input: encodeJSON(CustomRTCSessionDescription(type: offer.type.toSdpType(), sdp: offer.sdp))),
iceCandidates: compressToBase64(input: encodeJSON(await self.getInitialIceCandidates())),
capabilities: CallCapabilities(encryption: encryption)
)
self.waitForMoreIceCandidates()
} else {
resp = .error(message: "offer error: \(error?.localizedDescription ?? "unknown error")")
}
case let .offer(offer, iceCandidates, media, aesKey, iceServers, relay):
if activeCall.wrappedValue != nil {
@@ -172,26 +179,21 @@ final class WebRTCClient: NSObject, RTCVideoViewDelegate, RTCFrameEncryptorDeleg
resp = .error(message: "accept: encryption is not supported")
} else if let offer: CustomRTCSessionDescription = decodeJSON(decompressFromBase64(input: offer)),
let remoteIceCandidates: [RTCIceCandidate] = decodeJSON(decompressFromBase64(input: iceCandidates)) {
let call = initializeCall(iceServers?.toWebRTCIceServers(), remoteIceCandidates, media, WebRTCClient.enableEncryption ? aesKey : nil, relay)
let call = initializeCall(iceServers?.toWebRTCIceServers(), media, WebRTCClient.enableEncryption ? aesKey : nil, relay)
activeCall.wrappedValue = call
let pc = call.connection
if let type = offer.type, let sdp = offer.sdp {
if (try? await pc.setRemoteDescription(RTCSessionDescription(type: type.toWebRTCSdpType(), sdp: sdp))) != nil {
pc.answer { answer in
let (answer, error) = await pc.answer()
if let answer = answer {
self.addIceCandidates(pc, remoteIceCandidates)
// Task {
// try? await Task.sleep(nanoseconds: 32_000 * 1000000)
Task {
await self.sendCallResponse(.init(
corrId: nil,
resp: .answer(
answer: compressToBase64(input: encodeJSON(CustomRTCSessionDescription(type: answer.type.toSdpType(), sdp: answer.sdp))),
iceCandidates: compressToBase64(input: encodeJSON(call.iceCandidates))
),
command: command)
)
}
// }
resp = .answer(
answer: compressToBase64(input: encodeJSON(CustomRTCSessionDescription(type: answer.type.toSdpType(), sdp: answer.sdp))),
iceCandidates: compressToBase64(input: encodeJSON(await self.getInitialIceCandidates()))
)
self.waitForMoreIceCandidates()
} else {
resp = .error(message: "answer error: \(error?.localizedDescription ?? "unknown error")")
}
} else {
resp = .error(message: "accept: remote description is not set")
@@ -234,6 +236,7 @@ final class WebRTCClient: NSObject, RTCVideoViewDelegate, RTCFrameEncryptorDeleg
resp = .ok
}
case .end:
// TODO possibly, endCall should be called before returning .ok
await sendCallResponse(.init(corrId: nil, resp: .ok, command: command))
endCall()
}
@@ -242,6 +245,33 @@ final class WebRTCClient: NSObject, RTCVideoViewDelegate, RTCFrameEncryptorDeleg
}
}
func getInitialIceCandidates() async -> [RTCIceCandidate] {
await untilIceComplete(timeoutMs: 750, stepMs: 150) {}
let candidates = await activeCall.wrappedValue?.iceCandidates.getAndClear() ?? []
logger.debug("WebRTCClient: sending initial ice candidates: \(candidates.count)")
return candidates
}
func waitForMoreIceCandidates() {
Task {
await untilIceComplete(timeoutMs: 12000, stepMs: 1500) {
let candidates = await self.activeCall.wrappedValue?.iceCandidates.getAndClear() ?? []
if candidates.count > 0 {
logger.debug("WebRTCClient: sending more ice candidates: \(candidates.count)")
await self.sendIceCandidates(candidates)
}
}
}
}
func sendIceCandidates(_ candidates: [RTCIceCandidate]) async {
await self.sendCallResponse(.init(
corrId: nil,
resp: .ice(iceCandidates: compressToBase64(input: encodeJSON(candidates))),
command: nil)
)
}
func enableMedia(_ media: CallMediaType, _ enable: Bool) {
logger.debug("WebRTCClient: enabling media \(media.rawValue) \(enable)")
media == .video ? setVideoEnabled(enable) : setAudioEnabled(enable)
@@ -279,7 +309,7 @@ final class WebRTCClient: NSObject, RTCVideoViewDelegate, RTCFrameEncryptorDeleg
memcpy(pointer, (unencrypted as NSData).bytes, unencrypted.count)
let isKeyFrame = unencrypted[0] & 1 == 0
let clearTextBytesSize = mediaType.rawValue == 0 ? 1 : isKeyFrame ? 10 : 3
logCrypto("encrypt", chat_encrypt_media(&key, pointer.advanced(by: clearTextBytesSize), Int32(unencrypted.count + WebRTCClient.ivTagBytes - clearTextBytesSize)))
logCrypto("encrypt", chat_encrypt_media(chat_ctrl, &key, pointer.advanced(by: clearTextBytesSize), Int32(unencrypted.count + WebRTCClient.ivTagBytes - clearTextBytesSize)))
return Data(bytes: pointer, count: unencrypted.count + WebRTCClient.ivTagBytes)
} else {
return nil
@@ -387,12 +417,13 @@ final class WebRTCClient: NSObject, RTCVideoViewDelegate, RTCFrameEncryptorDeleg
audioSessionToDefaults()
}
func waitWithTimeout(_ timeoutMs: UInt64, stepMs: UInt64, until success: () -> Bool) async -> Bool {
let startedAt = DispatchTime.now()
while !success() && startedAt.uptimeNanoseconds + timeoutMs * 1000000 > DispatchTime.now().uptimeNanoseconds {
guard let _ = try? await Task.sleep(nanoseconds: stepMs * 1000000) else { break }
}
return success()
func untilIceComplete(timeoutMs: UInt64, stepMs: UInt64, action: @escaping () async -> Void) async {
var t: UInt64 = 0
repeat {
_ = try? await Task.sleep(nanoseconds: stepMs * 1000000)
t += stepMs
await action()
} while t < timeoutMs && activeCall.wrappedValue?.connection.iceGatheringState != .complete
}
}
@@ -405,25 +436,33 @@ extension WebRTC.RTCPeerConnection {
optionalConstraints: nil)
}
func offer(_ completion: @escaping (_ sdp: RTCSessionDescription) -> Void) {
offer(for: mediaConstraints()) { (sdp, error) in
guard let sdp = sdp else {
return
func offer() async -> (RTCSessionDescription?, Error?) {
await withCheckedContinuation { cont in
offer(for: mediaConstraints()) { (sdp, error) in
self.processSDP(cont, sdp, error)
}
self.setLocalDescription(sdp, completionHandler: { (error) in
completion(sdp)
})
}
}
func answer(_ completion: @escaping (_ sdp: RTCSessionDescription) -> Void) {
answer(for: mediaConstraints()) { (sdp, error) in
guard let sdp = sdp else {
return
func answer() async -> (RTCSessionDescription?, Error?) {
await withCheckedContinuation { cont in
answer(for: mediaConstraints()) { (sdp, error) in
self.processSDP(cont, sdp, error)
}
}
}
private func processSDP(_ cont: CheckedContinuation<(RTCSessionDescription?, Error?), Never>, _ sdp: RTCSessionDescription?, _ error: Error?) {
if let sdp = sdp {
self.setLocalDescription(sdp, completionHandler: { (error) in
completion(sdp)
if let error = error {
cont.resume(returning: (nil, error))
} else {
cont.resume(returning: (sdp, nil))
}
})
} else {
cont.resume(returning: (nil, error))
}
}
}
@@ -479,6 +518,7 @@ extension WebRTCClient: RTCPeerConnectionDelegate {
default: enableSpeaker = false
}
setSpeakerEnabledAndConfigureSession(enableSpeaker)
case .connected: sendConnectedEvent(connection)
case .disconnected, .failed: endCall()
default: do {}
}
@@ -491,7 +531,9 @@ extension WebRTCClient: RTCPeerConnectionDelegate {
func peerConnection(_ connection: RTCPeerConnection, didGenerate candidate: WebRTC.RTCIceCandidate) {
// logger.debug("Connection generated candidate \(candidate.debugDescription)")
activeCall.wrappedValue?.iceCandidates.append(candidate.toCandidate(nil, nil, nil))
Task {
await self.activeCall.wrappedValue?.iceCandidates.append(candidate.toCandidate(nil, nil))
}
}
func peerConnection(_ connection: RTCPeerConnection, didRemove candidates: [WebRTC.RTCIceCandidate]) {
@@ -506,10 +548,9 @@ extension WebRTCClient: RTCPeerConnectionDelegate {
lastReceivedMs lastDataReceivedMs: Int32,
changeReason reason: String) {
// logger.debug("Connection changed candidate \(reason) \(remote.debugDescription) \(remote.description)")
sendConnectedEvent(connection, local: local, remote: remote)
}
func sendConnectedEvent(_ connection: WebRTC.RTCPeerConnection, local: WebRTC.RTCIceCandidate, remote: WebRTC.RTCIceCandidate) {
func sendConnectedEvent(_ connection: WebRTC.RTCPeerConnection) {
connection.statistics { (stats: RTCStatisticsReport) in
stats.statistics.values.forEach { stat in
// logger.debug("Stat \(stat.debugDescription)")
@@ -517,24 +558,25 @@ extension WebRTCClient: RTCPeerConnectionDelegate {
let localId = stat.values["localCandidateId"] as? String,
let remoteId = stat.values["remoteCandidateId"] as? String,
let localStats = stats.statistics[localId],
let remoteStats = stats.statistics[remoteId],
local.sdp.contains("\((localStats.values["ip"] as? String ?? "--")) \((localStats.values["port"] as? String ?? "--"))") &&
remote.sdp.contains("\((remoteStats.values["ip"] as? String ?? "--")) \((remoteStats.values["port"] as? String ?? "--"))")
let remoteStats = stats.statistics[remoteId]
{
Task {
await self.sendCallResponse(.init(
corrId: nil,
resp: .connected(connectionInfo: ConnectionInfo(
localCandidate: local.toCandidate(
RTCIceCandidateType.init(rawValue: localStats.values["candidateType"] as! String),
localStats.values["protocol"] as? String,
localStats.values["relayProtocol"] as? String
localCandidate: RTCIceCandidate(
candidateType: RTCIceCandidateType.init(rawValue: localStats.values["candidateType"] as! String),
protocol: localStats.values["protocol"] as? String,
sdpMid: nil,
sdpMLineIndex: nil,
candidate: ""
),
remoteCandidate: remote.toCandidate(
RTCIceCandidateType.init(rawValue: remoteStats.values["candidateType"] as! String),
remoteStats.values["protocol"] as? String,
remoteStats.values["relayProtocol"] as? String
))),
remoteCandidate: RTCIceCandidate(
candidateType: RTCIceCandidateType.init(rawValue: remoteStats.values["candidateType"] as! String),
protocol: remoteStats.values["protocol"] as? String,
sdpMid: nil,
sdpMLineIndex: nil,
candidate: ""))),
command: nil)
)
}
@@ -634,11 +676,10 @@ extension RTCIceCandidate {
}
extension WebRTC.RTCIceCandidate {
func toCandidate(_ candidateType: RTCIceCandidateType?, _ protocol: String?, _ relayProtocol: String?) -> RTCIceCandidate {
func toCandidate(_ candidateType: RTCIceCandidateType?, _ protocol: String?) -> RTCIceCandidate {
RTCIceCandidate(
candidateType: candidateType,
protocol: `protocol`,
relayProtocol: relayProtocol,
sdpMid: sdpMid,
sdpMLineIndex: Int(sdpMLineIndex),
candidate: sdp

View File

@@ -165,6 +165,8 @@ struct CIRcvDecryptionError: View {
message = Text("\(msgCount) messages failed to decrypt.") + Text("\n") + why
case .other:
message = Text("\(msgCount) messages failed to decrypt.") + Text("\n") + why
case .ratchetSync:
message = Text("Encryption re-negotiation failed.")
}
return message
}

View File

@@ -723,9 +723,14 @@ struct ChatView: View {
if ci.meta.itemDeleted == nil && !ci.isLiveDummy && !live {
menu.append(replyUIAction(ci))
}
menu.append(shareUIAction(ci))
menu.append(copyUIAction(ci))
if let fileSource = getLoadedFileSource(ci.file) {
let fileSource = getLoadedFileSource(ci.file)
let fileExists = if let fs = fileSource, FileManager.default.fileExists(atPath: getAppFilePath(fs.filePath).path) { true } else { false }
let copyAndShareAllowed = !ci.content.text.isEmpty || (ci.content.msgContent?.isImage == true && fileExists)
if copyAndShareAllowed {
menu.append(shareUIAction(ci))
menu.append(copyUIAction(ci))
}
if let fileSource = fileSource, fileExists {
if case .image = ci.content.msgContent, let image = getLoadedImage(ci.file) {
if image.imageData != nil {
menu.append(saveFileAction(fileSource))

View File

@@ -104,7 +104,7 @@ struct ComposeState {
var sendEnabled: Bool {
switch preview {
case .mediaPreviews: return true
case let .mediaPreviews(media): return !media.isEmpty
case .voicePreview: return voiceMessageRecordingState == .finished
case .filePreview: return true
default: return !message.isEmpty || liveMessage != nil
@@ -384,10 +384,10 @@ struct ComposeView: View {
}
}
.sheet(isPresented: $showMediaPicker) {
LibraryMediaListPicker(media: $chosenMedia, selectionLimit: 10) { itemsSelected in
showMediaPicker = false
if itemsSelected {
DispatchQueue.main.async {
LibraryMediaListPicker(addMedia: addMediaContent, selectionLimit: 10, finishedPreprocessing: finishedPreprocessingMediaContent) { itemsSelected in
await MainActor.run {
showMediaPicker = false
if itemsSelected {
composeState = composeState.copy(preview: .mediaPreviews(mediaPreviews: []))
}
}
@@ -488,6 +488,30 @@ struct ComposeView: View {
}
}
private func addMediaContent(_ content: UploadContent) async {
if let img = resizeImageToStrSize(content.uiImage, maxDataSize: 14000) {
var newMedia: [(String, UploadContent?)] = []
if case var .mediaPreviews(media) = composeState.preview {
media.append((img, content))
newMedia = media
} else {
newMedia = [(img, content)]
}
await MainActor.run {
composeState = composeState.copy(preview: .mediaPreviews(mediaPreviews: newMedia))
}
}
}
// When error occurs while converting video, remove media preview
private func finishedPreprocessingMediaContent() {
if case let .mediaPreviews(media) = composeState.preview, media.isEmpty {
DispatchQueue.main.async {
composeState = composeState.copy(preview: .noPreview)
}
}
}
private var maxFileSize: Int64 {
getMaxFileSize(.xftp)
}

View File

@@ -157,7 +157,7 @@ struct AddGroupMembersViewCommon: View {
private func rolePicker() -> some View {
Picker("New member role", selection: $selectedRole) {
ForEach(GroupMemberRole.allCases) { role in
if role <= groupInfo.membership.memberRole {
if role <= groupInfo.membership.memberRole && role != .author {
Text(role.text)
}
}

View File

@@ -16,7 +16,6 @@ struct GroupChatInfoView: View {
@Environment(\.dismiss) var dismiss: DismissAction
@ObservedObject var chat: Chat
@Binding var groupInfo: GroupInfo
@ObservedObject private var alertManager = AlertManager.shared
@State private var alert: GroupChatInfoViewAlert? = nil
@State private var groupLink: String?
@State private var groupLinkMemberRole: GroupMemberRole = .member

View File

@@ -188,17 +188,19 @@ struct GroupMemberInfoView: View {
// this condition prevents re-setting picker
if !justOpened { return }
}
newRole = member.memberRole
do {
let (_, stats) = try apiGroupMemberInfo(groupInfo.apiId, member.groupMemberId)
let (mem, code) = member.memberActive ? try apiGetGroupMemberCode(groupInfo.apiId, member.groupMemberId) : (member, nil)
_ = chatModel.upsertGroupMember(groupInfo, mem)
connectionStats = stats
connectionCode = code
} catch let error {
logger.error("apiGroupMemberInfo or apiGetGroupMemberCode error: \(responseError(error))")
}
justOpened = false
DispatchQueue.main.async {
newRole = member.memberRole
do {
let (_, stats) = try apiGroupMemberInfo(groupInfo.apiId, member.groupMemberId)
let (mem, code) = member.memberActive ? try apiGetGroupMemberCode(groupInfo.apiId, member.groupMemberId) : (member, nil)
_ = chatModel.upsertGroupMember(groupInfo, mem)
connectionStats = stats
connectionCode = code
} catch let error {
logger.error("apiGroupMemberInfo or apiGetGroupMemberCode error: \(responseError(error))")
}
}
}
.onChange(of: newRole) { newRole in
if newRole != member.memberRole {

View File

@@ -103,8 +103,10 @@ struct GroupProfileView: View {
}
}
.sheet(isPresented: $showImagePicker) {
LibraryImagePicker(image: $chosenImage) {
didSelectItem in showImagePicker = false
LibraryImagePicker(image: $chosenImage) { _ in
await MainActor.run {
showImagePicker = false
}
}
}
.onChange(of: chosenImage) { image in

View File

@@ -17,7 +17,7 @@ struct ScanCodeView: View {
var body: some View {
VStack(alignment: .leading) {
CodeScannerView(codeTypes: [.qr], completion: processQRCode)
CodeScannerView(codeTypes: [.qr], scanMode: .oncePerCode, completion: processQRCode)
.aspectRatio(1, contentMode: .fit)
.cornerRadius(12)
Text("Scan security code from your contact's app.")

View File

@@ -15,6 +15,7 @@ struct ChatListView: View {
@State private var searchText = ""
@State private var showAddChat = false
@State private var userPickerVisible = false
@State private var showConnectDesktop = false
@AppStorage(DEFAULT_SHOW_UNREAD_AND_FAVORITES) private var showUnreadAndFavorites = false
var body: some View {
@@ -48,7 +49,14 @@ struct ChatListView: View {
}
}
}
UserPicker(showSettings: $showSettings, userPickerVisible: $userPickerVisible)
UserPicker(
showSettings: $showSettings,
showConnectDesktop: $showConnectDesktop,
userPickerVisible: $userPickerVisible
)
}
.sheet(isPresented: $showConnectDesktop) {
ConnectDesktopView()
}
}

View File

@@ -13,6 +13,7 @@ struct UserPicker: View {
@EnvironmentObject var m: ChatModel
@Environment(\.colorScheme) var colorScheme
@Binding var showSettings: Bool
@Binding var showConnectDesktop: Bool
@Binding var userPickerVisible: Bool
@State var scrollViewContentSize: CGSize = .zero
@State var disableScrolling: Bool = true
@@ -62,6 +63,13 @@ struct UserPicker: View {
.simultaneousGesture(DragGesture(minimumDistance: disableScrolling ? 0 : 10000000))
.frame(maxHeight: scrollViewContentSize.height)
menuButton("Use from desktop", icon: "desktopcomputer") {
showConnectDesktop = true
withAnimation {
userPickerVisible.toggle()
}
}
Divider()
menuButton("Settings", icon: "gearshape") {
showSettings = true
withAnimation {
@@ -85,7 +93,7 @@ struct UserPicker: View {
do {
m.users = try listUsers()
} catch let error {
logger.error("Error updating users \(responseError(error))")
logger.error("Error loading users \(responseError(error))")
}
}
}
@@ -144,7 +152,8 @@ struct UserPicker: View {
.overlay(DetermineWidth())
Spacer()
Image(systemName: icon)
// .frame(width: 24, alignment: .center)
.symbolRenderingMode(.monochrome)
.foregroundColor(.secondary)
}
.padding(.horizontal)
.padding(.vertical, 22)
@@ -170,6 +179,7 @@ struct UserPicker_Previews: PreviewProvider {
m.users = [UserInfo.sampleData, UserInfo.sampleData]
return UserPicker(
showSettings: Binding.constant(false),
showConnectDesktop: Binding.constant(false),
userPickerVisible: Binding.constant(true)
)
.environmentObject(m)

View File

@@ -415,7 +415,7 @@ struct DatabaseView: View {
do {
try initializeChat(start: true)
m.chatDbChanged = false
appStateGroupDefault.set(.active)
AppChatState.shared.set(.active)
} catch let error {
fatalError("Error starting chat \(responseError(error))")
}
@@ -427,7 +427,7 @@ struct DatabaseView: View {
m.chatRunning = true
ChatReceiver.shared.start()
chatLastStartGroupDefault.set(Date.now)
appStateGroupDefault.set(.active)
AppChatState.shared.set(.active)
} catch let error {
runChat = false
alert = .error(title: "Error starting chat", error: responseError(error))
@@ -477,7 +477,7 @@ func stopChatAsync() async throws {
try await apiStopChat()
ChatReceiver.shared.stop()
await MainActor.run { ChatModel.shared.chatRunning = false }
appStateGroupDefault.set(.stopped)
AppChatState.shared.set(.stopped)
}
func deleteChatAsync() async throws {

View File

@@ -13,112 +13,130 @@ import SimpleXChat
struct LibraryImagePicker: View {
@Binding var image: UIImage?
var didFinishPicking: (_ didSelectItems: Bool) -> Void
@State var images: [UploadContent] = []
var didFinishPicking: (_ didSelectImage: Bool) async -> Void
@State var mediaAdded = false
var body: some View {
LibraryMediaListPicker(media: $images, selectionLimit: 1, didFinishPicking: didFinishPicking)
.onChange(of: images) { _ in
if let img = images.first {
image = img.uiImage
}
}
LibraryMediaListPicker(addMedia: addMedia, selectionLimit: 1, didFinishPicking: didFinishPicking)
}
private func addMedia(_ content: UploadContent) async {
if mediaAdded { return }
await MainActor.run {
mediaAdded = true
image = content.uiImage
}
}
}
struct LibraryMediaListPicker: UIViewControllerRepresentable {
typealias UIViewControllerType = PHPickerViewController
@Binding var media: [UploadContent]
var addMedia: (_ content: UploadContent) async -> Void
var selectionLimit: Int
var didFinishPicking: (_ didSelectItems: Bool) -> Void
var finishedPreprocessing: () -> Void = {}
var didFinishPicking: (_ didSelectItems: Bool) async -> Void
class Coordinator: PHPickerViewControllerDelegate {
let parent: LibraryMediaListPicker
let dispatchQueue = DispatchQueue(label: "chat.simplex.app.LibraryMediaListPicker")
var media: [UploadContent] = []
var mediaCount: Int = 0
init(_ parent: LibraryMediaListPicker) {
self.parent = parent
}
func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {
parent.didFinishPicking(!results.isEmpty)
guard !results.isEmpty else {
return
Task {
await parent.didFinishPicking(!results.isEmpty)
if results.isEmpty { return }
for r in results {
await loadItem(r.itemProvider)
}
parent.finishedPreprocessing()
}
}
parent.media = []
media = []
mediaCount = results.count
for result in results {
logger.log("LibraryMediaListPicker result")
let p = result.itemProvider
if p.hasItemConformingToTypeIdentifier(UTType.movie.identifier) {
p.loadFileRepresentation(forTypeIdentifier: UTType.movie.identifier) { url, error in
if let url = url {
let tempUrl = URL(fileURLWithPath: getTempFilesDirectory().path + "/" + generateNewFileName("video", url.pathExtension))
if ((try? FileManager.default.copyItem(at: url, to: tempUrl)) != nil) {
ChatModel.shared.filesToDelete.insert(tempUrl)
self.loadVideo(url: tempUrl, error: error)
private func loadItem(_ p: NSItemProvider) async {
logger.debug("LibraryMediaListPicker result")
if p.hasItemConformingToTypeIdentifier(UTType.movie.identifier) {
if let video = await loadVideo(p) {
await self.parent.addMedia(video)
logger.debug("LibraryMediaListPicker: added video")
}
} else if p.hasItemConformingToTypeIdentifier(UTType.data.identifier) {
if let img = await loadImageData(p) {
await self.parent.addMedia(img)
logger.debug("LibraryMediaListPicker: added image")
}
} else if p.canLoadObject(ofClass: UIImage.self) {
if let img = await loadImage(p) {
await self.parent.addMedia(.simpleImage(image: img))
logger.debug("LibraryMediaListPicker: added image")
}
}
}
private func loadImageData(_ p: NSItemProvider) async -> UploadContent? {
await withCheckedContinuation { cont in
loadFileURL(p, type: UTType.data) { url in
if let url = url {
let img = UploadContent.loadFromURL(url: url)
cont.resume(returning: img)
} else {
cont.resume(returning: nil)
}
}
}
}
private func loadImage(_ p: NSItemProvider) async -> UIImage? {
await withCheckedContinuation { cont in
p.loadObject(ofClass: UIImage.self) { obj, err in
if let err = err {
logger.error("LibraryMediaListPicker result image error: \(err.localizedDescription)")
cont.resume(returning: nil)
} else {
cont.resume(returning: obj as? UIImage)
}
}
}
}
private func loadVideo(_ p: NSItemProvider) async -> UploadContent? {
await withCheckedContinuation { cont in
loadFileURL(p, type: UTType.movie) { url in
if let url = url {
let tempUrl = URL(fileURLWithPath: generateNewFileName(getTempFilesDirectory().path + "/" + "rawvideo", url.pathExtension, fullPath: true))
let convertedVideoUrl = URL(fileURLWithPath: generateNewFileName(getTempFilesDirectory().path + "/" + "video", "mp4", fullPath: true))
do {
// logger.debug("LibraryMediaListPicker copyItem \(url) to \(tempUrl)")
try FileManager.default.copyItem(at: url, to: tempUrl)
} catch let err {
logger.error("LibraryMediaListPicker copyItem error: \(err.localizedDescription)")
return cont.resume(returning: nil)
}
Task {
let success = await makeVideoQualityLower(tempUrl, outputUrl: convertedVideoUrl)
try? FileManager.default.removeItem(at: tempUrl)
if success {
_ = ChatModel.shared.filesToDelete.insert(convertedVideoUrl)
let video = UploadContent.loadVideoFromURL(url: convertedVideoUrl)
return cont.resume(returning: video)
}
try? FileManager.default.removeItem(at: convertedVideoUrl)
cont.resume(returning: nil)
}
}
} else if p.hasItemConformingToTypeIdentifier(UTType.data.identifier) {
p.loadFileRepresentation(forTypeIdentifier: UTType.data.identifier) { url, error in
self.loadImage(object: url, error: error)
}
} else if p.canLoadObject(ofClass: UIImage.self) {
p.loadObject(ofClass: UIImage.self) { image, error in
DispatchQueue.main.async {
self.loadImage(object: image, error: error)
}
}
}
}
}
private func loadFileURL(_ p: NSItemProvider, type: UTType, completion: @escaping (URL?) -> Void) {
p.loadFileRepresentation(forTypeIdentifier: type.identifier) { url, err in
if let err = err {
logger.error("LibraryMediaListPicker loadFileURL error: \(err.localizedDescription)")
completion(nil)
} else {
dispatchQueue.sync { self.mediaCount -= 1}
}
}
DispatchQueue.main.asyncAfter(deadline: .now() + 10) {
self.dispatchQueue.sync {
if self.parent.media.count == 0 {
logger.log("LibraryMediaListPicker: added \(self.media.count) images out of \(results.count)")
self.parent.media = self.media
}
}
}
}
func loadImage(object: Any?, error: Error? = nil) {
if let error = error {
logger.error("LibraryMediaListPicker: couldn't load image with error: \(error.localizedDescription)")
} else if let image = object as? UIImage {
media.append(.simpleImage(image: image))
logger.log("LibraryMediaListPicker: added image")
} else if let url = object as? URL, let image = UploadContent.loadFromURL(url: url) {
media.append(image)
}
dispatchQueue.sync {
self.mediaCount -= 1
if self.mediaCount == 0 && self.parent.media.count == 0 {
logger.log("LibraryMediaListPicker: added all media")
self.parent.media = self.media
self.media = []
}
}
}
func loadVideo(url: URL?, error: Error? = nil) {
if let error = error {
logger.error("LibraryMediaListPicker: couldn't load video with error: \(error.localizedDescription)")
} else if let url = url as URL?, let video = UploadContent.loadVideoFromURL(url: url) {
media.append(video)
}
dispatchQueue.sync {
self.mediaCount -= 1
if self.mediaCount == 0 && self.parent.media.count == 0 {
logger.log("LibraryMediaListPicker: added all media")
self.parent.media = self.media
self.media = []
completion(url)
}
}
}

View File

@@ -0,0 +1,26 @@
//
// VideoUtils.swift
// SimpleX (iOS)
//
// Created by Avently on 25.12.2023.
// Copyright © 2023 SimpleX Chat. All rights reserved.
//
import AVFoundation
import Foundation
import SimpleXChat
func makeVideoQualityLower(_ input: URL, outputUrl: URL) async -> Bool {
let asset: AVURLAsset = AVURLAsset(url: input, options: nil)
if let s = AVAssetExportSession(asset: asset, presetName: AVAssetExportPreset640x480) {
s.outputURL = outputUrl
s.outputFileType = .mp4
s.metadataItemFilter = AVMetadataItemFilter.forSharing()
await s.export()
if let err = s.error {
logger.error("Failed to export video with error: \(err)")
}
return s.status == .completed
}
return false
}

View File

@@ -52,7 +52,7 @@ struct LocalAuthView: View {
resetChatCtrl()
try initializeChat(start: true)
m.chatDbChanged = false
appStateGroupDefault.set(.active)
AppChatState.shared.set(.active)
if m.currentUser != nil { return }
var profile: Profile? = nil
if let displayName = displayName, displayName != "" {

View File

@@ -130,8 +130,10 @@ struct AddGroupView: View {
}
}
.sheet(isPresented: $showImagePicker) {
LibraryImagePicker(image: $chosenImage) {
didSelectItem in showImagePicker = false
LibraryImagePicker(image: $chosenImage) { _ in
await MainActor.run {
showImagePicker = false
}
}
}
.alert(isPresented: $showInvalidNameAlert) {

View File

@@ -73,6 +73,7 @@ struct CreateLinkView: View {
Task {
if let (connReq, pcc) = await apiAddContact(incognito: incognitoGroupDefault.get()) {
await MainActor.run {
m.updateContactConnection(pcc)
connReqInvitation = connReq
contactConnection = pcc
m.connReqInv = connReq

View File

@@ -52,6 +52,9 @@ struct NewChatButton: View {
func addContactAction() {
Task {
if let (connReq, pcc) = await apiAddContact(incognito: incognitoGroupDefault.get()) {
await MainActor.run {
ChatModel.shared.updateContactConnection(pcc)
}
actionSheet = .createLink(link: connReq, connection: pcc)
}
}
@@ -346,7 +349,10 @@ private func connectContactViaAddress_(_ contact: Contact, dismiss: Bool, incogn
private func connectViaLink(_ connectionLink: String, connectionPlan: ConnectionPlan?, dismiss: Bool, incognito: Bool) {
Task {
if let connReqType = await apiConnect(incognito: incognito, connReq: connectionLink) {
if let (connReqType, pcc) = await apiConnect(incognito: incognito, connReq: connectionLink) {
await MainActor.run {
ChatModel.shared.updateContactConnection(pcc)
}
let crt: ConnReqType
if let plan = connectionPlan {
crt = planToConnReqType(plan)

View File

@@ -11,20 +11,12 @@ import CoreImage.CIFilterBuiltins
struct MutableQRCode: View {
@Binding var uri: String
@State private var image: UIImage?
var withLogo: Bool = true
var tintColor = UIColor(red: 0.023, green: 0.176, blue: 0.337, alpha: 1)
var body: some View {
ZStack {
if let image = image {
qrCodeImage(image)
}
}
.onAppear {
image = generateImage(uri)
}
.onChange(of: uri) { _ in
image = generateImage(uri)
}
QRCode(uri: uri, withLogo: withLogo, tintColor: tintColor)
.id("simplex-qrcode-view-for-\(uri)")
}
}
@@ -49,7 +41,7 @@ struct QRCode: View {
var withLogo: Bool = true
var tintColor = UIColor(red: 0.023, green: 0.176, blue: 0.337, alpha: 1)
@State private var image: UIImage? = nil
@State private var makeScreenshotBinding: () -> Void = {}
@State private var makeScreenshotFunc: () -> Void = {}
var body: some View {
ZStack {
@@ -70,18 +62,19 @@ struct QRCode: View {
}
}
.onAppear {
makeScreenshotBinding = {
makeScreenshotFunc = {
let size = CGSizeMake(1024 / UIScreen.main.scale, 1024 / UIScreen.main.scale)
showShareSheet(items: [makeScreenshot(geo.frame(in: .local).origin, size)])}
showShareSheet(items: [makeScreenshot(geo.frame(in: .local).origin, size)])
}
}
.frame(width: geo.size.width, height: geo.size.height)
}
}
.onTapGesture(perform: makeScreenshotBinding)
.onTapGesture(perform: makeScreenshotFunc)
.onAppear {
image = image ?? generateImage(uri)?.replaceColor(UIColor.black, tintColor)
image = image ?? generateImage(uri, tintColor: tintColor)
}
.frame(maxWidth: .infinity, maxHeight: .infinity)
}
}
@@ -93,13 +86,13 @@ private func qrCodeImage(_ image: UIImage) -> some View {
.textSelection(.enabled)
}
private func generateImage(_ uri: String) -> UIImage? {
private func generateImage(_ uri: String, tintColor: UIColor) -> UIImage? {
let context = CIContext()
let filter = CIFilter.qrCodeGenerator()
filter.message = Data(uri.utf8)
if let outputImage = filter.outputImage,
let cgImage = context.createCGImage(outputImage, from: outputImage.extent) {
return UIImage(cgImage: cgImage)
return UIImage(cgImage: cgImage).replaceColor(UIColor.black, tintColor)
}
return nil
}

View File

@@ -25,7 +25,7 @@ struct ScanToConnectView: View {
.fixedSize(horizontal: false, vertical: true)
.padding(.vertical)
CodeScannerView(codeTypes: [.qr], completion: processQRCode)
CodeScannerView(codeTypes: [.qr], scanMode: .continuous, completion: processQRCode)
.aspectRatio(1, contentMode: .fit)
.cornerRadius(12)

View File

@@ -81,11 +81,6 @@ struct CreateSimpleXAddress: View {
DispatchQueue.main.async {
m.userAddress = UserContactLink(connReqContact: connReqContact)
}
if let u = try await apiSetProfileAddress(on: true) {
DispatchQueue.main.async {
m.updateUser(u)
}
}
await MainActor.run { progressIndicator = false }
} catch let error {
logger.error("CreateSimpleXAddress create address: \(responseError(error))")
@@ -100,7 +95,7 @@ struct CreateSimpleXAddress: View {
} label: {
Text("Create SimpleX address").font(.title)
}
Text("Your contacts in SimpleX will see it.\nYou can change it in Settings.")
Text("You can make it visible to your SimpleX contacts via Settings.")
.multilineTextAlignment(.center)
.font(.footnote)
.padding(.horizontal, 32)

View File

@@ -283,6 +283,37 @@ private let versionDescriptions: [VersionDescription] = [
),
]
),
VersionDescription(
version: "v5.4",
post: URL(string: "https://simplex.chat/blog/20231125-simplex-chat-v5-4-link-mobile-desktop-quantum-resistant-better-groups.html"),
features: [
FeatureDescription(
icon: "desktopcomputer",
title: "Link mobile and desktop apps! 🔗",
description: "Via secure quantum resistant protocol."
),
FeatureDescription(
icon: "person.2",
title: "Better groups",
description: "Faster joining and more reliable messages."
),
FeatureDescription(
icon: "theatermasks",
title: "Incognito groups",
description: "Create a group using a random profile."
),
FeatureDescription(
icon: "hand.raised",
title: "Block group members",
description: "To hide unwanted messages."
),
FeatureDescription(
icon: "gift",
title: "A few more things",
description: "- optionally notify deleted contacts.\n- profile names with spaces.\n- and more!"
),
]
),
]
private let lastVersion = versionDescriptions.last!.version

View File

@@ -0,0 +1,556 @@
//
// ConnectDesktopView.swift
// SimpleX (iOS)
//
// Created by Evgeny on 13/10/2023.
// Copyright © 2023 SimpleX Chat. All rights reserved.
//
import SwiftUI
import SimpleXChat
import CodeScanner
struct ConnectDesktopView: View {
@EnvironmentObject var m: ChatModel
@Environment(\.dismiss) var dismiss: DismissAction
var viaSettings = false
@AppStorage(DEFAULT_DEVICE_NAME_FOR_REMOTE_ACCESS) private var deviceName = UIDevice.current.name
@AppStorage(DEFAULT_CONFIRM_REMOTE_SESSIONS) private var confirmRemoteSessions = false
@AppStorage(DEFAULT_CONNECT_REMOTE_VIA_MULTICAST) private var connectRemoteViaMulticast = true
@AppStorage(DEFAULT_CONNECT_REMOTE_VIA_MULTICAST_AUTO) private var connectRemoteViaMulticastAuto = true
@AppStorage(DEFAULT_DEVELOPER_TOOLS) private var developerTools = false
@State private var sessionAddress: String = ""
@State private var remoteCtrls: [RemoteCtrlInfo] = []
@State private var alert: ConnectDesktopAlert?
@State private var showConnectScreen = true
@State private var showQRCodeScanner = true
@State private var firstAppearance = true
private var useMulticast: Bool {
connectRemoteViaMulticast && !remoteCtrls.isEmpty
}
private enum ConnectDesktopAlert: Identifiable {
case unlinkDesktop(rc: RemoteCtrlInfo)
case disconnectDesktop(action: UserDisconnectAction)
case badInvitationError
case badVersionError(version: String?)
case desktopDisconnectedError
case error(title: LocalizedStringKey, error: LocalizedStringKey = "")
var id: String {
switch self {
case let .unlinkDesktop(rc): "unlinkDesktop \(rc.remoteCtrlId)"
case let .disconnectDesktop(action): "disconnectDecktop \(action)"
case .badInvitationError: "badInvitationError"
case let .badVersionError(v): "badVersionError \(v ?? "")"
case .desktopDisconnectedError: "desktopDisconnectedError"
case let .error(title, _): "error \(title)"
}
}
}
private enum UserDisconnectAction: String {
case back
case dismiss // TODO dismiss settings after confirmation
}
var body: some View {
if viaSettings {
viewBody
.modifier(BackButton(label: "Back") {
if m.activeRemoteCtrl {
alert = .disconnectDesktop(action: .back)
} else {
dismiss()
}
})
} else {
NavigationView {
viewBody
}
}
}
var viewBody: some View {
Group {
let discovery = m.remoteCtrlSession?.discovery
if discovery == true || (discovery == nil && !showConnectScreen) {
searchingDesktopView()
} else if let session = m.remoteCtrlSession {
switch session.sessionState {
case .starting: connectingDesktopView(session, nil)
case .searching: searchingDesktopView()
case let .found(rc, compatible): foundDesktopView(session, rc, compatible)
case let .connecting(rc_): connectingDesktopView(session, rc_)
case let .pendingConfirmation(rc_, sessCode):
if confirmRemoteSessions || rc_ == nil {
verifySessionView(session, rc_, sessCode)
} else {
connectingDesktopView(session, rc_).onAppear {
verifyDesktopSessionCode(sessCode)
}
}
case let .connected(rc, _): activeSessionView(session, rc)
}
// The hack below prevents camera freezing when exiting linked devices view.
// Using showQRCodeScanner inside connectDesktopView or passing it as parameter still results in freezing.
} else if showQRCodeScanner || firstAppearance {
connectDesktopView()
} else {
connectDesktopView(showScanner: false)
}
}
.onAppear {
setDeviceName(deviceName)
updateRemoteCtrls()
showConnectScreen = !useMulticast
if m.remoteCtrlSession != nil {
disconnectDesktop()
} else if useMulticast {
findKnownDesktop()
}
// The hack below prevents camera freezing when exiting linked devices view.
// `firstAppearance` prevents camera flicker when the view first opens.
// moving `showQRCodeScanner = false` to `onDisappear` (to avoid `firstAppearance`) does not prevent freeze.
showQRCodeScanner = false
DispatchQueue.main.asyncAfter(deadline: .now() + 0.25) {
firstAppearance = false
showQRCodeScanner = true
}
}
.onDisappear {
if m.remoteCtrlSession != nil {
showConnectScreen = false
disconnectDesktop()
}
}
.onChange(of: deviceName) {
setDeviceName($0)
}
.onChange(of: m.activeRemoteCtrl) {
UIApplication.shared.isIdleTimerDisabled = $0
}
.alert(item: $alert) { a in
switch a {
case let .unlinkDesktop(rc):
Alert(
title: Text("Unlink desktop?"),
primaryButton: .destructive(Text("Unlink")) {
unlinkDesktop(rc)
},
secondaryButton: .cancel()
)
case let .disconnectDesktop(action):
Alert(
title: Text("Disconnect desktop?"),
primaryButton: .destructive(Text("Disconnect")) {
disconnectDesktop(action)
},
secondaryButton: .cancel()
)
case .badInvitationError:
Alert(title: Text("Bad desktop address"))
case let .badVersionError(v):
Alert(
title: Text("Incompatible version"),
message: Text("Desktop app version \(v ?? "") is not compatible with this app.")
)
case .desktopDisconnectedError:
Alert(title: Text("Connection terminated"))
case let .error(title, error):
Alert(title: Text(title), message: Text(error))
}
}
.interactiveDismissDisabled(m.activeRemoteCtrl)
}
private func connectDesktopView(showScanner: Bool = true) -> some View {
List {
Section("This device name") {
devicesView()
}
if showScanner {
scanDesctopAddressView()
}
if developerTools {
desktopAddressView()
}
}
.navigationTitle("Connect to desktop")
}
private func connectingDesktopView(_ session: RemoteCtrlSession, _ rc: RemoteCtrlInfo?) -> some View {
List {
Section("Connecting to desktop") {
ctrlDeviceNameText(session, rc)
ctrlDeviceVersionText(session)
}
if let sessCode = session.sessionCode {
Section("Session code") {
sessionCodeText(sessCode)
}
}
Section {
disconnectButton()
}
}
.navigationTitle("Connecting to desktop")
}
private func searchingDesktopView() -> some View {
List {
Section("This device name") {
devicesView()
}
Section("Found desktop") {
Text("Waiting for desktop...").italic()
Button {
disconnectDesktop()
} label: {
Label("Scan QR code", systemImage: "qrcode")
}
}
}
.navigationTitle("Connecting to desktop")
}
@ViewBuilder private func foundDesktopView(_ session: RemoteCtrlSession, _ rc: RemoteCtrlInfo, _ compatible: Bool) -> some View {
let v = List {
Section("This device name") {
devicesView()
}
Section("Found desktop") {
ctrlDeviceNameText(session, rc)
ctrlDeviceVersionText(session)
if !compatible {
Text("Not compatible!").foregroundColor(.red)
} else if !connectRemoteViaMulticastAuto {
Button {
confirmKnownDesktop(rc)
} label: {
Label("Connect", systemImage: "checkmark")
}
}
}
if !compatible && !connectRemoteViaMulticastAuto {
Section {
disconnectButton("Cancel")
}
}
}
.navigationTitle("Found desktop")
if compatible && connectRemoteViaMulticastAuto {
v.onAppear { confirmKnownDesktop(rc) }
} else {
v
}
}
private func verifySessionView(_ session: RemoteCtrlSession, _ rc: RemoteCtrlInfo?, _ sessCode: String) -> some View {
List {
Section("Connected to desktop") {
ctrlDeviceNameText(session, rc)
ctrlDeviceVersionText(session)
}
Section("Verify code with desktop") {
sessionCodeText(sessCode)
Button {
verifyDesktopSessionCode(sessCode)
} label: {
Label("Confirm", systemImage: "checkmark")
}
}
Section {
disconnectButton()
}
}
.navigationTitle("Verify connection")
}
private func ctrlDeviceNameText(_ session: RemoteCtrlSession, _ rc: RemoteCtrlInfo?) -> Text {
var t = Text(rc?.deviceViewName ?? session.ctrlAppInfo?.deviceName ?? "")
if (rc == nil) {
t = t + Text(" ") + Text("(new)").italic()
}
return t
}
private func ctrlDeviceVersionText(_ session: RemoteCtrlSession) -> Text {
let v = session.ctrlAppInfo?.appVersionRange.maxVersion
var t = Text("v\(v ?? "")")
if v != session.appVersion {
t = t + Text(" ") + Text("(this device v\(session.appVersion))").italic()
}
return t
}
private func activeSessionView(_ session: RemoteCtrlSession, _ rc: RemoteCtrlInfo) -> some View {
List {
Section("Connected desktop") {
Text(rc.deviceViewName)
ctrlDeviceVersionText(session)
}
if let sessCode = session.sessionCode {
Section("Session code") {
sessionCodeText(sessCode)
}
}
Section {
disconnectButton()
} footer: {
// This is specific to iOS
Text("Keep the app open to use it from desktop")
}
}
.navigationTitle("Connected to desktop")
}
private func sessionCodeText(_ code: String) -> some View {
Text(code.prefix(23))
}
private func devicesView() -> some View {
Group {
TextField("Enter this device name…", text: $deviceName)
if !remoteCtrls.isEmpty {
NavigationLink {
linkedDesktopsView()
} label: {
Text("Linked desktops")
}
}
}
}
private func scanDesctopAddressView() -> some View {
Section("Scan QR code from desktop") {
CodeScannerView(codeTypes: [.qr], scanMode: .oncePerCode, completion: processDesktopQRCode)
.aspectRatio(1, contentMode: .fit)
.cornerRadius(12)
.listRowBackground(Color.clear)
.listRowSeparator(.hidden)
.listRowInsets(EdgeInsets(top: 0, leading: 0, bottom: 0, trailing: 0))
.padding(.horizontal)
}
}
private func desktopAddressView() -> some View {
Section("Desktop address") {
if sessionAddress.isEmpty {
Button {
sessionAddress = UIPasteboard.general.string ?? ""
} label: {
Label("Paste desktop address", systemImage: "doc.plaintext")
}
.disabled(!UIPasteboard.general.hasStrings)
} else {
HStack {
Text(sessionAddress).lineLimit(1)
Spacer()
Image(systemName: "multiply.circle.fill")
.foregroundColor(.secondary)
.onTapGesture { sessionAddress = "" }
}
}
Button {
connectDesktopAddress(sessionAddress)
} label: {
Label("Connect to desktop", systemImage: "rectangle.connected.to.line.below")
}
.disabled(sessionAddress.isEmpty)
}
}
private func linkedDesktopsView() -> some View {
List {
Section("Desktop devices") {
ForEach(remoteCtrls, id: \.remoteCtrlId) { rc in
remoteCtrlView(rc)
}
.onDelete { indexSet in
if let i = indexSet.first, i < remoteCtrls.count {
alert = .unlinkDesktop(rc: remoteCtrls[i])
}
}
}
Section("Linked desktop options") {
Toggle("Verify connections", isOn: $confirmRemoteSessions)
Toggle("Discover via local network", isOn: $connectRemoteViaMulticast)
if connectRemoteViaMulticast {
Toggle("Connect automatically", isOn: $connectRemoteViaMulticastAuto)
}
}
}
.navigationTitle("Linked desktops")
}
private func remoteCtrlView(_ rc: RemoteCtrlInfo) -> some View {
Text(rc.deviceViewName)
}
private func setDeviceName(_ name: String) {
do {
try setLocalDeviceName(deviceName)
} catch let e {
errorAlert(e)
}
}
private func updateRemoteCtrls() {
do {
remoteCtrls = try listRemoteCtrls()
} catch let e {
errorAlert(e)
}
}
private func processDesktopQRCode(_ resp: Result<ScanResult, ScanError>) {
switch resp {
case let .success(r): connectDesktopAddress(r.string)
case let .failure(e): errorAlert(e)
}
}
private func findKnownDesktop() {
Task {
do {
try await findKnownRemoteCtrl()
await MainActor.run {
m.remoteCtrlSession = RemoteCtrlSession(
ctrlAppInfo: nil,
appVersion: "",
sessionState: .searching
)
showConnectScreen = true
}
} catch let e {
await MainActor.run {
errorAlert(e)
}
}
}
}
private func confirmKnownDesktop(_ rc: RemoteCtrlInfo) {
connectDesktop_ {
try await confirmRemoteCtrl(rc.remoteCtrlId)
}
}
private func connectDesktopAddress(_ addr: String) {
connectDesktop_ {
try await connectRemoteCtrl(desktopAddress: addr)
}
}
private func connectDesktop_(_ connect: @escaping () async throws -> (RemoteCtrlInfo?, CtrlAppInfo, String)) {
Task {
do {
let (rc_, ctrlAppInfo, v) = try await connect()
await MainActor.run {
sessionAddress = ""
m.remoteCtrlSession = RemoteCtrlSession(
ctrlAppInfo: ctrlAppInfo,
appVersion: v,
sessionState: .connecting(remoteCtrl_: rc_)
)
}
} catch let e {
await MainActor.run {
switch e as? ChatResponse {
case .chatCmdError(_, .errorRemoteCtrl(.badInvitation)): alert = .badInvitationError
case .chatCmdError(_, .error(.commandError)): alert = .badInvitationError
case let .chatCmdError(_, .errorRemoteCtrl(.badVersion(v))): alert = .badVersionError(version: v)
case .chatCmdError(_, .errorAgent(.RCP(.version))): alert = .badVersionError(version: nil)
case .chatCmdError(_, .errorAgent(.RCP(.ctrlAuth))): alert = .desktopDisconnectedError
default: errorAlert(e)
}
}
}
}
}
private func verifyDesktopSessionCode(_ sessCode: String) {
Task {
do {
let rc = try await verifyRemoteCtrlSession(sessCode)
await MainActor.run {
m.remoteCtrlSession = m.remoteCtrlSession?.updateState(.connected(remoteCtrl: rc, sessionCode: sessCode))
}
await MainActor.run {
updateRemoteCtrls()
}
} catch let error {
await MainActor.run {
errorAlert(error)
}
}
}
}
private func disconnectButton(_ label: LocalizedStringKey = "Disconnect") -> some View {
Button {
disconnectDesktop(.dismiss)
} label: {
Label(label, systemImage: "multiply")
}
}
private func disconnectDesktop(_ action: UserDisconnectAction? = nil) {
Task {
do {
try await stopRemoteCtrl()
await MainActor.run {
if case .connected = m.remoteCtrlSession?.sessionState {
switchToLocalSession()
} else {
m.remoteCtrlSession = nil
}
switch action {
case .back: dismiss()
case .dismiss: dismiss()
case .none: ()
}
}
} catch let e {
await MainActor.run {
errorAlert(e)
}
}
}
}
private func unlinkDesktop(_ rc: RemoteCtrlInfo) {
Task {
do {
try await deleteRemoteCtrl(rc.remoteCtrlId)
await MainActor.run {
remoteCtrls.removeAll(where: { $0.remoteCtrlId == rc.remoteCtrlId })
}
} catch let e {
await MainActor.run {
errorAlert(e)
}
}
}
}
private func errorAlert(_ error: Error) {
let a = getErrorAlert(error, "Error")
alert = .error(title: a.title, error: a.message)
}
}
#Preview {
ConnectDesktopView()
}

View File

@@ -51,9 +51,9 @@ struct AdvancedNetworkSettings: View {
}
.disabled(currentNetCfg == NetCfg.proxyDefaults)
timeoutSettingPicker("TCP connection timeout", selection: $netCfg.tcpConnectTimeout, values: [5_000000, 7_500000, 10_000000, 15_000000, 20_000000, 30_000000, 45_000000], label: secondsLabel)
timeoutSettingPicker("Protocol timeout", selection: $netCfg.tcpTimeout, values: [3_000000, 5_000000, 7_000000, 10_000000, 15_000000, 20_000000, 30_000000], label: secondsLabel)
timeoutSettingPicker("Protocol timeout per KB", selection: $netCfg.tcpTimeoutPerKb, values: [15_000, 30_000, 60_000, 90_000, 120_000], label: secondsLabel)
timeoutSettingPicker("TCP connection timeout", selection: $netCfg.tcpConnectTimeout, values: [7_500000, 10_000000, 15_000000, 20_000000, 30_000000, 45_000000], label: secondsLabel)
timeoutSettingPicker("Protocol timeout", selection: $netCfg.tcpTimeout, values: [5_000000, 7_000000, 10_000000, 15_000000, 20_000000, 30_000000], label: secondsLabel)
timeoutSettingPicker("Protocol timeout per KB", selection: $netCfg.tcpTimeoutPerKb, values: [15_000, 30_000, 45_000, 60_000, 90_000, 120_000], label: secondsLabel)
timeoutSettingPicker("PING interval", selection: $netCfg.smpPingInterval, values: [120_000000, 300_000000, 600_000000, 1200_000000, 2400_000000, 3600_000000], label: secondsLabel)
intSettingPicker("PING count", selection: $netCfg.smpPingCount, values: [1, 2, 3, 5, 8], label: "")
Toggle("Enable TCP keep-alive", isOn: $enableKeepAlive)

View File

@@ -14,9 +14,6 @@ struct NotificationsView: View {
@State private var notificationMode: NotificationsMode = ChatModel.shared.notificationMode
@State private var showAlert: NotificationAlert?
@State private var legacyDatabase = dbContainerGroupDefault.get() == .documents
// @AppStorage(DEFAULT_DEVELOPER_TOOLS) private var developerTools = false
// @AppStorage(GROUP_DEFAULT_NTF_ENABLE_LOCAL, store: groupDefaults) private var ntfEnableLocal = false
// @AppStorage(GROUP_DEFAULT_NTF_ENABLE_PERIODIC, store: groupDefaults) private var ntfEnablePeriodic = false
var body: some View {
List {
@@ -88,13 +85,6 @@ struct NotificationsView: View {
.padding(.top, 1)
}
}
// if developerTools {
// Section(String("Experimental")) {
// Toggle(String("Always enable local"), isOn: $ntfEnableLocal)
// Toggle(String("Always enable periodic"), isOn: $ntfEnablePeriodic)
// }
// }
}
.disabled(legacyDatabase)
}
@@ -119,7 +109,7 @@ struct NotificationsView: View {
private func ntfModeAlertTitle(_ mode: NotificationsMode) -> LocalizedStringKey {
switch mode {
case .off: return "Turn off notifications?"
case .off: return "Use only local notifications?"
case .periodic: return "Enable periodic notifications?"
case .instant: return "Enable instant notifications?"
}

View File

@@ -467,6 +467,7 @@ struct SimplexLockView: View {
switch a {
case .enableAuth:
SetAppPasscodeView {
m.contentViewAccessAuthenticated = true
laLockDelay = 30
prefPerformLA = true
showChangePassword = true
@@ -619,6 +620,7 @@ struct SimplexLockView: View {
authenticate(reason: NSLocalizedString("Enable SimpleX Lock", comment: "authentication reason")) { laResult in
switch laResult {
case .success:
m.contentViewAccessAuthenticated = true
prefPerformLA = true
laAlert = .laTurnedOnAlert
case .failed:

View File

@@ -21,7 +21,7 @@ struct ScanProtocolServer: View {
.font(.largeTitle)
.bold()
.padding(.vertical)
CodeScannerView(codeTypes: [.qr], completion: processQRCode)
CodeScannerView(codeTypes: [.qr], scanMode: .oncePerCode, completion: processQRCode)
.aspectRatio(1, contentMode: .fit)
.cornerRadius(12)
.padding(.top)

View File

@@ -53,6 +53,10 @@ let DEFAULT_WHATS_NEW_VERSION = "defaultWhatsNewVersion"
let DEFAULT_ONBOARDING_STAGE = "onboardingStage"
let DEFAULT_CUSTOM_DISAPPEARING_MESSAGE_TIME = "customDisappearingMessageTime"
let DEFAULT_SHOW_UNREAD_AND_FAVORITES = "showUnreadAndFavorites"
let DEFAULT_DEVICE_NAME_FOR_REMOTE_ACCESS = "deviceNameForRemoteAccess"
let DEFAULT_CONFIRM_REMOTE_SESSIONS = "confirmRemoteSessions"
let DEFAULT_CONNECT_REMOTE_VIA_MULTICAST = "connectRemoteViaMulticast"
let DEFAULT_CONNECT_REMOTE_VIA_MULTICAST_AUTO = "connectRemoteViaMulticastAuto"
let appDefaults: [String: Any] = [
DEFAULT_SHOW_LA_NOTICE: false,
@@ -85,7 +89,10 @@ let appDefaults: [String: Any] = [
DEFAULT_SHOW_MUTE_PROFILE_ALERT: true,
DEFAULT_ONBOARDING_STAGE: OnboardingStage.onboardingComplete.rawValue,
DEFAULT_CUSTOM_DISAPPEARING_MESSAGE_TIME: 300,
DEFAULT_SHOW_UNREAD_AND_FAVORITES: false
DEFAULT_SHOW_UNREAD_AND_FAVORITES: false,
DEFAULT_CONFIRM_REMOTE_SESSIONS: false,
DEFAULT_CONNECT_REMOTE_VIA_MULTICAST: true,
DEFAULT_CONNECT_REMOTE_VIA_MULTICAST_AUTO: true,
]
enum SimpleXLinkMode: String, Identifiable {
@@ -178,6 +185,12 @@ struct SettingsView: View {
} label: {
settingsRow("switch.2") { Text("Chat preferences") }
}
NavigationLink {
ConnectDesktopView(viaSettings: true)
} label: {
settingsRow("desktopcomputer") { Text("Use from desktop") }
}
}
.disabled(chatModel.chatRunning != true)
@@ -362,7 +375,9 @@ struct SettingsView: View {
func settingsRow<Content : View>(_ icon: String, color: Color = .secondary, content: @escaping () -> Content) -> some View {
ZStack(alignment: .leading) {
Image(systemName: icon).frame(maxWidth: 24, maxHeight: 24, alignment: .center).foregroundColor(color)
Image(systemName: icon).frame(maxWidth: 24, maxHeight: 24, alignment: .center)
.symbolRenderingMode(.monochrome)
.foregroundColor(color)
content().padding(.leading, indent)
}
}

View File

@@ -190,7 +190,8 @@ struct UserAddressView: View {
@ViewBuilder private func existingAddressView(_ userAddress: UserContactLink) -> some View {
Section {
MutableQRCode(uri: Binding.constant(simplexChatLink(userAddress.connReqContact)))
SimpleXLinkQRCode(uri: userAddress.connReqContact)
.id("simplex-contact-address-qrcode-\(userAddress.connReqContact)")
shareQRCodeButton(userAddress)
if MFMailComposeViewController.canSendMail() {
shareViaEmailButton(userAddress)

View File

@@ -120,8 +120,10 @@ struct UserProfile: View {
}
}
.sheet(isPresented: $showImagePicker) {
LibraryImagePicker(image: $chosenImage) {
didSelectItem in showImagePicker = false
LibraryImagePicker(image: $chosenImage) { _ in
await MainActor.run {
showImagePicker = false
}
}
}
.onChange(of: chosenImage) { image in

View File

@@ -18,5 +18,9 @@
<array>
<string>$(AppIdentifierPrefix)chat.simplex.app</string>
</array>
<key>com.apple.developer.networking.multicast</key>
<true/>
<key>com.apple.developer.device-information.user-assigned-device-name</key>
<true/>
</dict>
</plist>

View File

@@ -290,6 +290,14 @@
<target>(</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="(new)" xml:space="preserve">
<source>(new)</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="(this device v%@)" xml:space="preserve">
<source>(this device v%@)</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id=")" xml:space="preserve">
<source>)</source>
<target>)</target>
@@ -378,6 +386,12 @@
- и още!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="- optionally notify deleted contacts.&#10;- profile names with spaces.&#10;- and more!" xml:space="preserve">
<source>- optionally notify deleted contacts.
- profile names with spaces.
- and more!</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="- voice messages up to 5 minutes.&#10;- custom time to disappear.&#10;- editing history." xml:space="preserve">
<source>- voice messages up to 5 minutes.
- custom time to disappear.
@@ -858,6 +872,10 @@
<target>Назад</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Bad desktop address" xml:space="preserve">
<source>Bad desktop address</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Bad message ID" xml:space="preserve">
<source>Bad message ID</source>
<target>Лошо ID на съобщението</target>
@@ -868,6 +886,10 @@
<target>Лош хеш на съобщението</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Better groups" xml:space="preserve">
<source>Better groups</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Better messages" xml:space="preserve">
<source>Better messages</source>
<target>По-добри съобщения</target>
@@ -877,6 +899,10 @@
<source>Block</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Block group members" xml:space="preserve">
<source>Block group members</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Block member" xml:space="preserve">
<source>Block member</source>
<note>No comment provided by engineer.</note>
@@ -1146,11 +1172,19 @@
<target>Свързване</target>
<note>server test step</note>
</trans-unit>
<trans-unit id="Connect automatically" xml:space="preserve">
<source>Connect automatically</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connect incognito" xml:space="preserve">
<source>Connect incognito</source>
<target>Свързване инкогнито</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connect to desktop" xml:space="preserve">
<source>Connect to desktop</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connect to yourself?" xml:space="preserve">
<source>Connect to yourself?</source>
<note>No comment provided by engineer.</note>
@@ -1188,6 +1222,14 @@ This is your own one-time link!</source>
<source>Connect with %@</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connected desktop" xml:space="preserve">
<source>Connected desktop</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connected to desktop" xml:space="preserve">
<source>Connected to desktop</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connecting server…" xml:space="preserve">
<source>Connecting to server…</source>
<target>Свързване със сървъра…</target>
@@ -1198,6 +1240,10 @@ This is your own one-time link!</source>
<target>Свързване със сървър…(грешка: %@)</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connecting to desktop" xml:space="preserve">
<source>Connecting to desktop</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connection" xml:space="preserve">
<source>Connection</source>
<target>Връзка</target>
@@ -1218,6 +1264,10 @@ This is your own one-time link!</source>
<target>Заявката за връзка е изпратена!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connection terminated" xml:space="preserve">
<source>Connection terminated</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connection timeout" xml:space="preserve">
<source>Connection timeout</source>
<target>Времето на изчакване за установяване на връзката изтече</target>
@@ -1297,6 +1347,10 @@ This is your own one-time link!</source>
<target>Създай SimpleX адрес</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Create a group using a random profile." xml:space="preserve">
<source>Create a group using a random profile.</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Create an address to let people connect with you." xml:space="preserve">
<source>Create an address to let people connect with you.</source>
<target>Създайте адрес, за да позволите на хората да се свързват с вас.</target>
@@ -1701,6 +1755,18 @@ This cannot be undone!</source>
<target>Описание</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Desktop address" xml:space="preserve">
<source>Desktop address</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Desktop app version %@ is not compatible with this app." xml:space="preserve">
<source>Desktop app version %@ is not compatible with this app.</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Desktop devices" xml:space="preserve">
<source>Desktop devices</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Develop" xml:space="preserve">
<source>Develop</source>
<target>Разработване</target>
@@ -1791,11 +1857,19 @@ This cannot be undone!</source>
<target>Прекъсни връзката</target>
<note>server test step</note>
</trans-unit>
<trans-unit id="Disconnect desktop?" xml:space="preserve">
<source>Disconnect desktop?</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Discover and join groups" xml:space="preserve">
<source>Discover and join groups</source>
<target>Открийте и се присъединете към групи</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Discover via local network" xml:space="preserve">
<source>Discover via local network</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Do NOT use SimpleX for emergency calls." xml:space="preserve">
<source>Do NOT use SimpleX for emergency calls.</source>
<target>НЕ използвайте SimpleX за спешни повиквания.</target>
@@ -1966,6 +2040,14 @@ This cannot be undone!</source>
<target>Криптирано съобщение: неочаквана грешка</target>
<note>notification</note>
</trans-unit>
<trans-unit id="Encryption re-negotiation error" xml:space="preserve">
<source>Encryption re-negotiation error</source>
<note>message decrypt error item</note>
</trans-unit>
<trans-unit id="Encryption re-negotiation failed." xml:space="preserve">
<source>Encryption re-negotiation failed.</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Enter Passcode" xml:space="preserve">
<source>Enter Passcode</source>
<target>Въведете kодa за достъп</target>
@@ -1995,6 +2077,10 @@ This cannot be undone!</source>
<target>Въведи сървъра ръчно</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Enter this device name…" xml:space="preserve">
<source>Enter this device name…</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Enter welcome message…" xml:space="preserve">
<source>Enter welcome message…</source>
<target>Въведи съобщение при посрещане…</target>
@@ -2318,6 +2404,10 @@ This cannot be undone!</source>
<target>Бързо и без чакане, докато подателят е онлайн!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Faster joining and more reliable messages." xml:space="preserve">
<source>Faster joining and more reliable messages.</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Favorite" xml:space="preserve">
<source>Favorite</source>
<target>Любим</target>
@@ -2413,6 +2503,10 @@ This cannot be undone!</source>
<target>За конзолата</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Found desktop" xml:space="preserve">
<source>Found desktop</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="French interface" xml:space="preserve">
<source>French interface</source>
<target>Френски интерфейс</target>
@@ -2735,6 +2829,10 @@ This cannot be undone!</source>
<target>Инкогнито</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Incognito groups" xml:space="preserve">
<source>Incognito groups</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Incognito mode" xml:space="preserve">
<source>Incognito mode</source>
<target>Режим инкогнито</target>
@@ -2765,6 +2863,10 @@ This cannot be undone!</source>
<target>Несъвместима версия на базата данни</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Incompatible version" xml:space="preserve">
<source>Incompatible version</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Incorrect passcode" xml:space="preserve">
<source>Incorrect passcode</source>
<target>Неправилен kод за достъп</target>
@@ -2930,6 +3032,10 @@ This is your link for group %@!</source>
<target>Присъединяване към групата</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Keep the app open to use it from desktop" xml:space="preserve">
<source>Keep the app open to use it from desktop</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Keep your connections" xml:space="preserve">
<source>Keep your connections</source>
<target>Запазете връзките си</target>
@@ -2990,6 +3096,18 @@ This is your link for group %@!</source>
<target>Ограничения</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Link mobile and desktop apps! 🔗" xml:space="preserve">
<source>Link mobile and desktop apps! 🔗</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Linked desktop options" xml:space="preserve">
<source>Linked desktop options</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Linked desktops" xml:space="preserve">
<source>Linked desktops</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Live message!" xml:space="preserve">
<source>Live message!</source>
<target>Съобщение на живо!</target>
@@ -3339,6 +3457,10 @@ This is your link for group %@!</source>
<target>Няма получени или изпратени файлове</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Not compatible!" xml:space="preserve">
<source>Not compatible!</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Notifications" xml:space="preserve">
<source>Notifications</source>
<target>Известия</target>
@@ -3557,6 +3679,10 @@ This is your link for group %@!</source>
<target>Постави</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Paste desktop address" xml:space="preserve">
<source>Paste desktop address</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Paste image" xml:space="preserve">
<source>Paste image</source>
<target>Постави изображение</target>
@@ -4148,6 +4274,10 @@ This is your link for group %@!</source>
<target>Сканирай QR код</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Scan QR code from desktop" xml:space="preserve">
<source>Scan QR code from desktop</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Scan code" xml:space="preserve">
<source>Scan code</source>
<target>Сканирай код</target>
@@ -4368,6 +4498,10 @@ This is your link for group %@!</source>
<target>Сървъри</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Session code" xml:space="preserve">
<source>Session code</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Set 1 day" xml:space="preserve">
<source>Set 1 day</source>
<target>Задай 1 ден</target>
@@ -4864,6 +4998,10 @@ It can happen because of some bug or when the connection is compromised.</source
<target>Това действие не може да бъде отменено - вашият профил, контакти, съобщения и файлове ще бъдат безвъзвратно загубени.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="This device name" xml:space="preserve">
<source>This device name</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="This group has over %lld members, delivery receipts are not sent." xml:space="preserve">
<source>This group has over %lld members, delivery receipts are not sent.</source>
<target>Тази група има над %lld членове, потвърждения за доставка не се изпращат.</target>
@@ -4897,6 +5035,10 @@ It can happen because of some bug or when the connection is compromised.</source
<target>За да се свърже, вашият контакт може да сканира QR код или да използва линка в приложението.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="To hide unwanted messages." xml:space="preserve">
<source>To hide unwanted messages.</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="To make a new connection" xml:space="preserve">
<source>To make a new connection</source>
<target>За да направите нова връзка</target>
@@ -5053,6 +5195,14 @@ To connect, please ask your contact to create another connection link and check
За да се свържете, моля, помолете вашия контакт да създаде друг линк за връзка и проверете дали имате стабилна мрежова връзка.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Unlink" xml:space="preserve">
<source>Unlink</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Unlink desktop?" xml:space="preserve">
<source>Unlink desktop?</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Unlock" xml:space="preserve">
<source>Unlock</source>
<target>Отключи</target>
@@ -5143,6 +5293,10 @@ To connect, please ask your contact to create another connection link and check
<target>Използвай за нови връзки</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Use from desktop" xml:space="preserve">
<source>Use from desktop</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Use iOS call interface" xml:space="preserve">
<source>Use iOS call interface</source>
<target>Използвай интерфейса за повикване на iOS</target>
@@ -5173,11 +5327,23 @@ To connect, please ask your contact to create another connection link and check
<target>Използват се сървърите на SimpleX Chat.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Verify code with desktop" xml:space="preserve">
<source>Verify code with desktop</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Verify connection" xml:space="preserve">
<source>Verify connection</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Verify connection security" xml:space="preserve">
<source>Verify connection security</source>
<target>Потвръди сигурността на връзката</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Verify connections" xml:space="preserve">
<source>Verify connections</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Verify security code" xml:space="preserve">
<source>Verify security code</source>
<target>Потвръди кода за сигурност</target>
@@ -5188,6 +5354,10 @@ To connect, please ask your contact to create another connection link and check
<target>Чрез браузър</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Via secure quantum resistant protocol." xml:space="preserve">
<source>Via secure quantum resistant protocol.</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Video call" xml:space="preserve">
<source>Video call</source>
<target>Видео разговор</target>
@@ -5238,6 +5408,10 @@ To connect, please ask your contact to create another connection link and check
<target>Гласово съобщение…</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Waiting for desktop..." xml:space="preserve">
<source>Waiting for desktop...</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Waiting for file" xml:space="preserve">
<source>Waiting for file</source>
<target>Изчаква се получаването на файла</target>
@@ -5768,6 +5942,10 @@ SimpleX сървърите не могат да видят вашия профи
<target>аудио разговор (не е e2e криптиран)</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="author" xml:space="preserve">
<source>author</source>
<note>member role</note>
</trans-unit>
<trans-unit id="bad message ID" xml:space="preserve">
<source>bad message ID</source>
<target>лошо ID на съобщението</target>
@@ -6348,6 +6526,10 @@ SimpleX сървърите не могат да видят вашия профи
<target>актуализиран профил на групата</target>
<note>rcv group event chat item</note>
</trans-unit>
<trans-unit id="v%@" xml:space="preserve">
<source>v%@</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="v%@ (%@)" xml:space="preserve">
<source>v%@ (%@)</source>
<target>v%@ (%@)</target>
@@ -6485,6 +6667,10 @@ SimpleX сървърите не могат да видят вашия профи
<target>SimpleX използва Face ID за локалнa идентификация</target>
<note>Privacy - Face ID Usage Description</note>
</trans-unit>
<trans-unit id="NSLocalNetworkUsageDescription" xml:space="preserve">
<source>SimpleX uses local network access to allow using user chat profile via desktop app on the same network.</source>
<note>Privacy - Local Network Usage Description</note>
</trans-unit>
<trans-unit id="NSMicrophoneUsageDescription" xml:space="preserve">
<source>SimpleX needs microphone access for audio and video calls, and to record voice messages.</source>
<target>SimpleX се нуждае от достъп до микрофона за аудио и видео разговори и за запис на гласови съобщения.</target>

View File

@@ -4,6 +4,8 @@
"NSCameraUsageDescription" = "SimpleX needs camera access to scan QR codes to connect to other users and for video calls.";
/* Privacy - Face ID Usage Description */
"NSFaceIDUsageDescription" = "SimpleX uses Face ID for local authentication";
/* Privacy - Local Network Usage Description */
"NSLocalNetworkUsageDescription" = "SimpleX uses local network access to allow using user chat profile via desktop app on the same network.";
/* Privacy - Microphone Usage Description */
"NSMicrophoneUsageDescription" = "SimpleX needs microphone access for audio and video calls, and to record voice messages.";
/* Privacy - Photo Library Additions Usage Description */

View File

@@ -290,6 +290,14 @@
<target>(</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="(new)" xml:space="preserve">
<source>(new)</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="(this device v%@)" xml:space="preserve">
<source>(this device v%@)</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id=")" xml:space="preserve">
<source>)</source>
<target>)</target>
@@ -378,6 +386,12 @@
- a více!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="- optionally notify deleted contacts.&#10;- profile names with spaces.&#10;- and more!" xml:space="preserve">
<source>- optionally notify deleted contacts.
- profile names with spaces.
- and more!</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="- voice messages up to 5 minutes.&#10;- custom time to disappear.&#10;- editing history." xml:space="preserve">
<source>- voice messages up to 5 minutes.
- custom time to disappear.
@@ -858,6 +872,10 @@
<target>Zpět</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Bad desktop address" xml:space="preserve">
<source>Bad desktop address</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Bad message ID" xml:space="preserve">
<source>Bad message ID</source>
<target>Špatné ID zprávy</target>
@@ -868,6 +886,10 @@
<target>Špatný hash zprávy</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Better groups" xml:space="preserve">
<source>Better groups</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Better messages" xml:space="preserve">
<source>Better messages</source>
<target>Lepší zprávy</target>
@@ -877,6 +899,10 @@
<source>Block</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Block group members" xml:space="preserve">
<source>Block group members</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Block member" xml:space="preserve">
<source>Block member</source>
<note>No comment provided by engineer.</note>
@@ -1146,11 +1172,19 @@
<target>Připojit</target>
<note>server test step</note>
</trans-unit>
<trans-unit id="Connect automatically" xml:space="preserve">
<source>Connect automatically</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connect incognito" xml:space="preserve">
<source>Connect incognito</source>
<target>Spojit se inkognito</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connect to desktop" xml:space="preserve">
<source>Connect to desktop</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connect to yourself?" xml:space="preserve">
<source>Connect to yourself?</source>
<note>No comment provided by engineer.</note>
@@ -1188,6 +1222,14 @@ This is your own one-time link!</source>
<source>Connect with %@</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connected desktop" xml:space="preserve">
<source>Connected desktop</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connected to desktop" xml:space="preserve">
<source>Connected to desktop</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connecting server…" xml:space="preserve">
<source>Connecting to server…</source>
<target>Připojování k serveru…</target>
@@ -1198,6 +1240,10 @@ This is your own one-time link!</source>
<target>Připojování k serveru... (chyba: %@)</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connecting to desktop" xml:space="preserve">
<source>Connecting to desktop</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connection" xml:space="preserve">
<source>Connection</source>
<target>Připojení</target>
@@ -1218,6 +1264,10 @@ This is your own one-time link!</source>
<target>Požadavek na připojení byl odeslán!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connection terminated" xml:space="preserve">
<source>Connection terminated</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connection timeout" xml:space="preserve">
<source>Connection timeout</source>
<target>Časový limit připojení</target>
@@ -1297,6 +1347,10 @@ This is your own one-time link!</source>
<target>Vytvořit SimpleX adresu</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Create a group using a random profile." xml:space="preserve">
<source>Create a group using a random profile.</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Create an address to let people connect with you." xml:space="preserve">
<source>Create an address to let people connect with you.</source>
<target>Vytvořit adresu, aby se s vámi lidé mohli spojit.</target>
@@ -1701,6 +1755,18 @@ This cannot be undone!</source>
<target>Popis</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Desktop address" xml:space="preserve">
<source>Desktop address</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Desktop app version %@ is not compatible with this app." xml:space="preserve">
<source>Desktop app version %@ is not compatible with this app.</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Desktop devices" xml:space="preserve">
<source>Desktop devices</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Develop" xml:space="preserve">
<source>Develop</source>
<target>Vyvinout</target>
@@ -1791,11 +1857,19 @@ This cannot be undone!</source>
<target>Odpojit</target>
<note>server test step</note>
</trans-unit>
<trans-unit id="Disconnect desktop?" xml:space="preserve">
<source>Disconnect desktop?</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Discover and join groups" xml:space="preserve">
<source>Discover and join groups</source>
<target>Objevte a připojte skupiny</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Discover via local network" xml:space="preserve">
<source>Discover via local network</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Do NOT use SimpleX for emergency calls." xml:space="preserve">
<source>Do NOT use SimpleX for emergency calls.</source>
<target>NEpoužívejte SimpleX pro tísňová volání.</target>
@@ -1966,6 +2040,14 @@ This cannot be undone!</source>
<target>Šifrovaná zpráva: neočekávaná chyba</target>
<note>notification</note>
</trans-unit>
<trans-unit id="Encryption re-negotiation error" xml:space="preserve">
<source>Encryption re-negotiation error</source>
<note>message decrypt error item</note>
</trans-unit>
<trans-unit id="Encryption re-negotiation failed." xml:space="preserve">
<source>Encryption re-negotiation failed.</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Enter Passcode" xml:space="preserve">
<source>Enter Passcode</source>
<target>Zadat heslo</target>
@@ -1995,6 +2077,10 @@ This cannot be undone!</source>
<target>Zadejte server ručně</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Enter this device name…" xml:space="preserve">
<source>Enter this device name…</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Enter welcome message…" xml:space="preserve">
<source>Enter welcome message…</source>
<target>Zadat uvítací zprávu…</target>
@@ -2318,6 +2404,10 @@ This cannot be undone!</source>
<target>Rychle a bez čekání, než bude odesílatel online!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Faster joining and more reliable messages." xml:space="preserve">
<source>Faster joining and more reliable messages.</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Favorite" xml:space="preserve">
<source>Favorite</source>
<target>Oblíbené</target>
@@ -2413,6 +2503,10 @@ This cannot be undone!</source>
<target>Pro konzoli</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Found desktop" xml:space="preserve">
<source>Found desktop</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="French interface" xml:space="preserve">
<source>French interface</source>
<target>Francouzské rozhraní</target>
@@ -2735,6 +2829,10 @@ This cannot be undone!</source>
<target>Inkognito</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Incognito groups" xml:space="preserve">
<source>Incognito groups</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Incognito mode" xml:space="preserve">
<source>Incognito mode</source>
<target>Režim inkognito</target>
@@ -2765,6 +2863,10 @@ This cannot be undone!</source>
<target>Nekompatibilní verze databáze</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Incompatible version" xml:space="preserve">
<source>Incompatible version</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Incorrect passcode" xml:space="preserve">
<source>Incorrect passcode</source>
<target>Nesprávné heslo</target>
@@ -2930,6 +3032,10 @@ This is your link for group %@!</source>
<target>Připojování ke skupině</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Keep the app open to use it from desktop" xml:space="preserve">
<source>Keep the app open to use it from desktop</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Keep your connections" xml:space="preserve">
<source>Keep your connections</source>
<target>Zachovat vaše připojení</target>
@@ -2990,6 +3096,18 @@ This is your link for group %@!</source>
<target>Omezení</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Link mobile and desktop apps! 🔗" xml:space="preserve">
<source>Link mobile and desktop apps! 🔗</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Linked desktop options" xml:space="preserve">
<source>Linked desktop options</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Linked desktops" xml:space="preserve">
<source>Linked desktops</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Live message!" xml:space="preserve">
<source>Live message!</source>
<target>Živé zprávy!</target>
@@ -3339,6 +3457,10 @@ This is your link for group %@!</source>
<target>Žádné přijaté ani odeslané soubory</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Not compatible!" xml:space="preserve">
<source>Not compatible!</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Notifications" xml:space="preserve">
<source>Notifications</source>
<target>Oznámení</target>
@@ -3557,6 +3679,10 @@ This is your link for group %@!</source>
<target>Vložit</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Paste desktop address" xml:space="preserve">
<source>Paste desktop address</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Paste image" xml:space="preserve">
<source>Paste image</source>
<target>Vložit obrázek</target>
@@ -4148,6 +4274,10 @@ This is your link for group %@!</source>
<target>Skenovat QR kód</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Scan QR code from desktop" xml:space="preserve">
<source>Scan QR code from desktop</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Scan code" xml:space="preserve">
<source>Scan code</source>
<target>Skenovat kód</target>
@@ -4368,6 +4498,10 @@ This is your link for group %@!</source>
<target>Servery</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Session code" xml:space="preserve">
<source>Session code</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Set 1 day" xml:space="preserve">
<source>Set 1 day</source>
<target>Nastavit 1 den</target>
@@ -4864,6 +4998,10 @@ Může se to stát kvůli nějaké chybě, nebo pokud je spojení kompromitován
<target>Tuto akci nelze vzít zpět - váš profil, kontakty, zprávy a soubory budou nenávratně ztraceny.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="This device name" xml:space="preserve">
<source>This device name</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="This group has over %lld members, delivery receipts are not sent." xml:space="preserve">
<source>This group has over %lld members, delivery receipts are not sent.</source>
<target>Tato skupina má více než %lld členů, potvrzení o doručení nejsou odesílány.</target>
@@ -4897,6 +5035,10 @@ Může se to stát kvůli nějaké chybě, nebo pokud je spojení kompromitován
<target>Pro připojení může váš kontakt naskenovat QR kód, nebo použít odkaz v aplikaci.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="To hide unwanted messages." xml:space="preserve">
<source>To hide unwanted messages.</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="To make a new connection" xml:space="preserve">
<source>To make a new connection</source>
<target>Vytvoření nového připojení</target>
@@ -5053,6 +5195,14 @@ To connect, please ask your contact to create another connection link and check
Chcete-li se připojit, požádejte svůj kontakt o vytvoření dalšího odkazu na připojení a zkontrolujte, zda máte stabilní připojení k síti.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Unlink" xml:space="preserve">
<source>Unlink</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Unlink desktop?" xml:space="preserve">
<source>Unlink desktop?</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Unlock" xml:space="preserve">
<source>Unlock</source>
<target>Odemknout</target>
@@ -5143,6 +5293,10 @@ Chcete-li se připojit, požádejte svůj kontakt o vytvoření dalšího odkazu
<target>Použít pro nová připojení</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Use from desktop" xml:space="preserve">
<source>Use from desktop</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Use iOS call interface" xml:space="preserve">
<source>Use iOS call interface</source>
<target>Použít rozhraní volání iOS</target>
@@ -5173,11 +5327,23 @@ Chcete-li se připojit, požádejte svůj kontakt o vytvoření dalšího odkazu
<target>Používat servery SimpleX Chat.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Verify code with desktop" xml:space="preserve">
<source>Verify code with desktop</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Verify connection" xml:space="preserve">
<source>Verify connection</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Verify connection security" xml:space="preserve">
<source>Verify connection security</source>
<target>Ověření zabezpečení připojení</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Verify connections" xml:space="preserve">
<source>Verify connections</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Verify security code" xml:space="preserve">
<source>Verify security code</source>
<target>Ověření bezpečnostního kódu</target>
@@ -5188,6 +5354,10 @@ Chcete-li se připojit, požádejte svůj kontakt o vytvoření dalšího odkazu
<target>Prostřednictvím prohlížeče</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Via secure quantum resistant protocol." xml:space="preserve">
<source>Via secure quantum resistant protocol.</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Video call" xml:space="preserve">
<source>Video call</source>
<target>Videohovor</target>
@@ -5238,6 +5408,10 @@ Chcete-li se připojit, požádejte svůj kontakt o vytvoření dalšího odkazu
<target>Hlasová zpráva…</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Waiting for desktop..." xml:space="preserve">
<source>Waiting for desktop...</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Waiting for file" xml:space="preserve">
<source>Waiting for file</source>
<target>Čekání na soubor</target>
@@ -5768,6 +5942,10 @@ Servery SimpleX nevidí váš profil.</target>
<target>zvukový hovor (nešifrovaný e2e)</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="author" xml:space="preserve">
<source>author</source>
<note>member role</note>
</trans-unit>
<trans-unit id="bad message ID" xml:space="preserve">
<source>bad message ID</source>
<target>špatné ID zprávy</target>
@@ -6347,6 +6525,10 @@ Servery SimpleX nevidí váš profil.</target>
<target>aktualizoval profil skupiny</target>
<note>rcv group event chat item</note>
</trans-unit>
<trans-unit id="v%@" xml:space="preserve">
<source>v%@</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="v%@ (%@)" xml:space="preserve">
<source>v%@ (%@)</source>
<target>v%@ (%@)</target>
@@ -6484,6 +6666,10 @@ Servery SimpleX nevidí váš profil.</target>
<target>SimpleX používá Face ID pro místní ověřování</target>
<note>Privacy - Face ID Usage Description</note>
</trans-unit>
<trans-unit id="NSLocalNetworkUsageDescription" xml:space="preserve">
<source>SimpleX uses local network access to allow using user chat profile via desktop app on the same network.</source>
<note>Privacy - Local Network Usage Description</note>
</trans-unit>
<trans-unit id="NSMicrophoneUsageDescription" xml:space="preserve">
<source>SimpleX needs microphone access for audio and video calls, and to record voice messages.</source>
<target>SimpleX potřebuje přístup k mikrofonu pro audio a video hovory a pro nahrávání hlasových zpráv.</target>

View File

@@ -4,6 +4,8 @@
"NSCameraUsageDescription" = "SimpleX needs camera access to scan QR codes to connect to other users and for video calls.";
/* Privacy - Face ID Usage Description */
"NSFaceIDUsageDescription" = "SimpleX uses Face ID for local authentication";
/* Privacy - Local Network Usage Description */
"NSLocalNetworkUsageDescription" = "SimpleX uses local network access to allow using user chat profile via desktop app on the same network.";
/* Privacy - Microphone Usage Description */
"NSMicrophoneUsageDescription" = "SimpleX needs microphone access for audio and video calls, and to record voice messages.";
/* Privacy - Photo Library Additions Usage Description */

View File

@@ -89,11 +89,12 @@
</trans-unit>
<trans-unit id="%@ and %@" xml:space="preserve">
<source>%@ and %@</source>
<target>%@ und %@</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="%@ and %@ connected" xml:space="preserve">
<source>%@ and %@ connected</source>
<target>%@ und %@ wurden verbunden</target>
<target>%@ und %@ wurden mit Ihnen verbunden</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="%@ at %@:" xml:space="preserve">
@@ -103,6 +104,7 @@
</trans-unit>
<trans-unit id="%@ connected" xml:space="preserve">
<source>%@ connected</source>
<target>%@ wurde mit Ihnen verbunden</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="%@ is connected!" xml:space="preserve">
@@ -132,11 +134,12 @@
</trans-unit>
<trans-unit id="%@, %@ and %lld members" xml:space="preserve">
<source>%@, %@ and %lld members</source>
<target>%@, %@ und %lld Mitglieder</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="%@, %@ and %lld other members connected" xml:space="preserve">
<source>%@, %@ and %lld other members connected</source>
<target>%@, %@ und %lld weitere Mitglieder wurden verbunden</target>
<target>%@, %@ und %lld weitere Mitglieder wurden mit Ihnen verbunden</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="%@:" xml:space="preserve">
@@ -201,6 +204,7 @@
</trans-unit>
<trans-unit id="%lld group events" xml:space="preserve">
<source>%lld group events</source>
<target>%lld Gruppenereignisse</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="%lld members" xml:space="preserve">
@@ -210,14 +214,17 @@
</trans-unit>
<trans-unit id="%lld messages blocked" xml:space="preserve">
<source>%lld messages blocked</source>
<target>%lld Nachrichten blockiert</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="%lld messages marked deleted" xml:space="preserve">
<source>%lld messages marked deleted</source>
<target>%lld Nachrichten als gelöscht markiert</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="%lld messages moderated by %@" xml:space="preserve">
<source>%lld messages moderated by %@</source>
<target>%lld Nachrichten von %@ moderiert</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="%lld minutes" xml:space="preserve">
@@ -290,6 +297,16 @@
<target>(</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="(new)" xml:space="preserve">
<source>(new)</source>
<target>(Neu)</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="(this device v%@)" xml:space="preserve">
<source>(this device v%@)</source>
<target>(Dieses Gerät hat v%@)</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id=")" xml:space="preserve">
<source>)</source>
<target>)</target>
@@ -378,6 +395,15 @@
- und mehr!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="- optionally notify deleted contacts.&#10;- profile names with spaces.&#10;- and more!" xml:space="preserve">
<source>- optionally notify deleted contacts.
- profile names with spaces.
- and more!</source>
<target>- Optionale Benachrichtigung von gelöschten Kontakten.
- Profilnamen mit Leerzeichen.
- Und mehr!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="- voice messages up to 5 minutes.&#10;- custom time to disappear.&#10;- editing history." xml:space="preserve">
<source>- voice messages up to 5 minutes.
- custom time to disappear.
@@ -394,6 +420,7 @@
</trans-unit>
<trans-unit id="0 sec" xml:space="preserve">
<source>0 sec</source>
<target>0 sek</target>
<note>time to disappear</note>
</trans-unit>
<trans-unit id="0s" xml:space="preserve">
@@ -623,6 +650,7 @@
</trans-unit>
<trans-unit id="All new messages from %@ will be hidden!" xml:space="preserve">
<source>All new messages from %@ will be hidden!</source>
<target>Alle neuen Nachrichten von %@ werden verborgen!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="All your contacts will remain connected." xml:space="preserve">
@@ -732,10 +760,12 @@
</trans-unit>
<trans-unit id="Already connecting!" xml:space="preserve">
<source>Already connecting!</source>
<target>Bereits verbunden!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Already joining the group!" xml:space="preserve">
<source>Already joining the group!</source>
<target>Sie sind bereits Mitglied der Gruppe!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Always use relay" xml:space="preserve">
@@ -858,6 +888,11 @@
<target>Zurück</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Bad desktop address" xml:space="preserve">
<source>Bad desktop address</source>
<target>Falsche Desktop-Adresse</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Bad message ID" xml:space="preserve">
<source>Bad message ID</source>
<target>Falsche Nachrichten-ID</target>
@@ -868,6 +903,11 @@
<target>Ungültiger Nachrichten-Hash</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Better groups" xml:space="preserve">
<source>Better groups</source>
<target>Bessere Gruppen</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Better messages" xml:space="preserve">
<source>Better messages</source>
<target>Verbesserungen bei Nachrichten</target>
@@ -875,14 +915,22 @@
</trans-unit>
<trans-unit id="Block" xml:space="preserve">
<source>Block</source>
<target>Blockieren</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Block group members" xml:space="preserve">
<source>Block group members</source>
<target>Gruppenmitglieder blockieren</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Block member" xml:space="preserve">
<source>Block member</source>
<target>Mitglied blockieren</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Block member?" xml:space="preserve">
<source>Block member?</source>
<target>Mitglied blockieren?</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Both you and your contact can add message reactions." xml:space="preserve">
@@ -1146,27 +1194,43 @@
<target>Verbinden</target>
<note>server test step</note>
</trans-unit>
<trans-unit id="Connect automatically" xml:space="preserve">
<source>Connect automatically</source>
<target>Automatisch verbinden</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connect incognito" xml:space="preserve">
<source>Connect incognito</source>
<target>Inkognito verbinden</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connect to desktop" xml:space="preserve">
<source>Connect to desktop</source>
<target>Mit dem Desktop verbinden</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connect to yourself?" xml:space="preserve">
<source>Connect to yourself?</source>
<target>Mit Ihnen selbst verbinden?</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connect to yourself?&#10;This is your own SimpleX address!" xml:space="preserve">
<source>Connect to yourself?
This is your own SimpleX address!</source>
<target>Mit Ihnen selbst verbinden?
Das ist Ihre eigene SimpleX-Adresse!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connect to yourself?&#10;This is your own one-time link!" xml:space="preserve">
<source>Connect to yourself?
This is your own one-time link!</source>
<target>Mit Ihnen selbst verbinden?
Das ist Ihr eigener Einmal-Link!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connect via contact address" xml:space="preserve">
<source>Connect via contact address</source>
<target>Über die Kontakt-Adresse verbinden</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connect via link" xml:space="preserve">
@@ -1186,6 +1250,17 @@ This is your own one-time link!</source>
</trans-unit>
<trans-unit id="Connect with %@" xml:space="preserve">
<source>Connect with %@</source>
<target>Mit %@ verbinden</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connected desktop" xml:space="preserve">
<source>Connected desktop</source>
<target>Verbundener Desktop</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connected to desktop" xml:space="preserve">
<source>Connected to desktop</source>
<target>Mit dem Desktop verbunden</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connecting server…" xml:space="preserve">
@@ -1198,6 +1273,11 @@ This is your own one-time link!</source>
<target>Mit dem Server verbinden… (Fehler: %@)</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connecting to desktop" xml:space="preserve">
<source>Connecting to desktop</source>
<target>Mit dem Desktop verbinden</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connection" xml:space="preserve">
<source>Connection</source>
<target>Verbindung</target>
@@ -1218,6 +1298,11 @@ This is your own one-time link!</source>
<target>Verbindungsanfrage wurde gesendet!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connection terminated" xml:space="preserve">
<source>Connection terminated</source>
<target>Verbindung beendet</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connection timeout" xml:space="preserve">
<source>Connection timeout</source>
<target>Verbindungszeitüberschreitung</target>
@@ -1285,6 +1370,7 @@ This is your own one-time link!</source>
</trans-unit>
<trans-unit id="Correct name to %@?" xml:space="preserve">
<source>Correct name to %@?</source>
<target>Richtiger Name für %@?</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Create" xml:space="preserve">
@@ -1297,6 +1383,11 @@ This is your own one-time link!</source>
<target>SimpleX-Adresse erstellen</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Create a group using a random profile." xml:space="preserve">
<source>Create a group using a random profile.</source>
<target>Erstellen Sie eine Gruppe mit einem zufälligen Profil.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Create an address to let people connect with you." xml:space="preserve">
<source>Create an address to let people connect with you.</source>
<target>Erstellen Sie eine Adresse, damit sich Personen mit Ihnen verbinden können.</target>
@@ -1309,6 +1400,7 @@ This is your own one-time link!</source>
</trans-unit>
<trans-unit id="Create group" xml:space="preserve">
<source>Create group</source>
<target>Gruppe erstellen</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Create group link" xml:space="preserve">
@@ -1333,6 +1425,7 @@ This is your own one-time link!</source>
</trans-unit>
<trans-unit id="Create profile" xml:space="preserve">
<source>Create profile</source>
<target>Profil erstellen</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Create queue" xml:space="preserve">
@@ -1495,6 +1588,7 @@ This is your own one-time link!</source>
</trans-unit>
<trans-unit id="Delete %lld messages?" xml:space="preserve">
<source>Delete %lld messages?</source>
<target>%lld Nachrichten löschen?</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Delete Contact" xml:space="preserve">
@@ -1524,6 +1618,7 @@ This is your own one-time link!</source>
</trans-unit>
<trans-unit id="Delete and notify contact" xml:space="preserve">
<source>Delete and notify contact</source>
<target>Kontakt löschen und benachrichtigen</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Delete archive" xml:space="preserve">
@@ -1559,6 +1654,8 @@ This is your own one-time link!</source>
<trans-unit id="Delete contact?&#10;This cannot be undone!" xml:space="preserve">
<source>Delete contact?
This cannot be undone!</source>
<target>Kontakt löschen?
Das kann nicht rückgängig gemacht werden!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Delete database" xml:space="preserve">
@@ -1701,6 +1798,21 @@ This cannot be undone!</source>
<target>Beschreibung</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Desktop address" xml:space="preserve">
<source>Desktop address</source>
<target>Desktop-Adresse</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Desktop app version %@ is not compatible with this app." xml:space="preserve">
<source>Desktop app version %@ is not compatible with this app.</source>
<target>Desktop App-Version %@ ist mit dieser App nicht kompatibel.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Desktop devices" xml:space="preserve">
<source>Desktop devices</source>
<target>Desktop-Geräte</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Develop" xml:space="preserve">
<source>Develop</source>
<target>Entwicklung</target>
@@ -1791,11 +1903,21 @@ This cannot be undone!</source>
<target>Trennen</target>
<note>server test step</note>
</trans-unit>
<trans-unit id="Disconnect desktop?" xml:space="preserve">
<source>Disconnect desktop?</source>
<target>Desktop-Verbindung trennen?</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Discover and join groups" xml:space="preserve">
<source>Discover and join groups</source>
<target>Gruppen entdecken und ihnen beitreten</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Discover via local network" xml:space="preserve">
<source>Discover via local network</source>
<target>Lokales Netzwerk durchsuchen</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Do NOT use SimpleX for emergency calls." xml:space="preserve">
<source>Do NOT use SimpleX for emergency calls.</source>
<target>Nutzen Sie SimpleX nicht für Notrufe.</target>
@@ -1966,6 +2088,16 @@ This cannot be undone!</source>
<target>Verschlüsselte Nachricht: Unerwarteter Fehler</target>
<note>notification</note>
</trans-unit>
<trans-unit id="Encryption re-negotiation error" xml:space="preserve">
<source>Encryption re-negotiation error</source>
<target>Fehler bei der Neuverhandlung der Verschlüsselung</target>
<note>message decrypt error item</note>
</trans-unit>
<trans-unit id="Encryption re-negotiation failed." xml:space="preserve">
<source>Encryption re-negotiation failed.</source>
<target>Neuverhandlung der Verschlüsselung fehlgeschlagen.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Enter Passcode" xml:space="preserve">
<source>Enter Passcode</source>
<target>Zugangscode eingeben</target>
@@ -1978,6 +2110,7 @@ This cannot be undone!</source>
</trans-unit>
<trans-unit id="Enter group name…" xml:space="preserve">
<source>Enter group name…</source>
<target>Geben Sie den Gruppennamen ein…</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Enter passphrase…" xml:space="preserve">
@@ -1995,6 +2128,11 @@ This cannot be undone!</source>
<target>Geben Sie den Server manuell ein</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Enter this device name…" xml:space="preserve">
<source>Enter this device name…</source>
<target>Geben Sie diesen Gerätenamen ein…</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Enter welcome message…" xml:space="preserve">
<source>Enter welcome message…</source>
<target>Geben Sie eine Begrüßungsmeldung ein …</target>
@@ -2007,6 +2145,7 @@ This cannot be undone!</source>
</trans-unit>
<trans-unit id="Enter your name…" xml:space="preserve">
<source>Enter your name…</source>
<target>Geben Sie Ihren Namen ein…</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Error" xml:space="preserve">
@@ -2286,6 +2425,7 @@ This cannot be undone!</source>
</trans-unit>
<trans-unit id="Expand" xml:space="preserve">
<source>Expand</source>
<target>Erweitern</target>
<note>chat item action</note>
</trans-unit>
<trans-unit id="Export database" xml:space="preserve">
@@ -2318,6 +2458,11 @@ This cannot be undone!</source>
<target>Schnell und ohne warten auf den Absender, bis er online ist!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Faster joining and more reliable messages." xml:space="preserve">
<source>Faster joining and more reliable messages.</source>
<target>Schnellerer Gruppenbeitritt und zuverlässigere Nachrichtenzustellung.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Favorite" xml:space="preserve">
<source>Favorite</source>
<target>Favorit</target>
@@ -2413,6 +2558,11 @@ This cannot be undone!</source>
<target>Für Konsole</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Found desktop" xml:space="preserve">
<source>Found desktop</source>
<target>Gefundener Desktop</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="French interface" xml:space="preserve">
<source>French interface</source>
<target>Französische Bedienoberfläche</target>
@@ -2435,6 +2585,7 @@ This cannot be undone!</source>
</trans-unit>
<trans-unit id="Fully decentralized visible only to members." xml:space="preserve">
<source>Fully decentralized visible only to members.</source>
<target>Vollständig dezentralisiert nur für Mitglieder sichtbar.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Fully re-implemented - work in background!" xml:space="preserve">
@@ -2459,10 +2610,12 @@ This cannot be undone!</source>
</trans-unit>
<trans-unit id="Group already exists" xml:space="preserve">
<source>Group already exists</source>
<target>Die Gruppe besteht bereits</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Group already exists!" xml:space="preserve">
<source>Group already exists!</source>
<target>Die Gruppe besteht bereits!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Group display name" xml:space="preserve">
@@ -2735,6 +2888,11 @@ This cannot be undone!</source>
<target>Inkognito</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Incognito groups" xml:space="preserve">
<source>Incognito groups</source>
<target>Inkognito-Gruppen</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Incognito mode" xml:space="preserve">
<source>Incognito mode</source>
<target>Inkognito-Modus</target>
@@ -2765,6 +2923,11 @@ This cannot be undone!</source>
<target>Inkompatible Datenbank-Version</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Incompatible version" xml:space="preserve">
<source>Incompatible version</source>
<target>Inkompatible Version</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Incorrect passcode" xml:space="preserve">
<source>Incorrect passcode</source>
<target>Zugangscode ist falsch</target>
@@ -2814,6 +2977,7 @@ This cannot be undone!</source>
</trans-unit>
<trans-unit id="Invalid name!" xml:space="preserve">
<source>Invalid name!</source>
<target>Ungültiger Name!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Invalid server address!" xml:space="preserve">
@@ -2884,7 +3048,7 @@ This cannot be undone!</source>
</trans-unit>
<trans-unit id="It seems like you are already connected via this link. If it is not the case, there was an error (%@)." xml:space="preserve">
<source>It seems like you are already connected via this link. If it is not the case, there was an error (%@).</source>
<target>Es sieht so aus, dass Sie bereits über diesen Link verbunden sind. Wenn das nicht der Fall, gab es einen Fehler (%@).</target>
<target>Es sieht so aus, als ob Sie bereits über diesen Link verbunden sind. Wenn das nicht der Fall ist, gab es einen Fehler (%@).</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Italian interface" xml:space="preserve">
@@ -2909,6 +3073,7 @@ This cannot be undone!</source>
</trans-unit>
<trans-unit id="Join group?" xml:space="preserve">
<source>Join group?</source>
<target>Der Gruppe beitreten?</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Join incognito" xml:space="preserve">
@@ -2918,11 +3083,14 @@ This cannot be undone!</source>
</trans-unit>
<trans-unit id="Join with current profile" xml:space="preserve">
<source>Join with current profile</source>
<target>Mit dem aktuellen Profil beitreten</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Join your group?&#10;This is your link for group %@!" xml:space="preserve">
<source>Join your group?
This is your link for group %@!</source>
<target>Ihrer Gruppe beitreten?
Das ist Ihr Link für die Gruppe %@!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Joining group" xml:space="preserve">
@@ -2930,6 +3098,11 @@ This is your link for group %@!</source>
<target>Der Gruppe beitreten</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Keep the app open to use it from desktop" xml:space="preserve">
<source>Keep the app open to use it from desktop</source>
<target>Die App muss geöffnet bleiben, um sie vom Desktop aus nutzen zu können</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Keep your connections" xml:space="preserve">
<source>Keep your connections</source>
<target>Ihre Verbindungen beibehalten</target>
@@ -2990,6 +3163,21 @@ This is your link for group %@!</source>
<target>Einschränkungen</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Link mobile and desktop apps! 🔗" xml:space="preserve">
<source>Link mobile and desktop apps! 🔗</source>
<target>Verknüpfe Mobiltelefon- und Desktop-Apps! 🔗</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Linked desktop options" xml:space="preserve">
<source>Linked desktop options</source>
<target>Verknüpfte Desktop-Optionen</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Linked desktops" xml:space="preserve">
<source>Linked desktops</source>
<target>Verknüpfte Desktops</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Live message!" xml:space="preserve">
<source>Live message!</source>
<target>Live Nachricht!</target>
@@ -3142,6 +3330,7 @@ This is your link for group %@!</source>
</trans-unit>
<trans-unit id="Messages from %@ will be shown!" xml:space="preserve">
<source>Messages from %@ will be shown!</source>
<target>Die Nachrichten von %@ werden angezeigt!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Migrating database archive…" xml:space="preserve">
@@ -3339,6 +3528,11 @@ This is your link for group %@!</source>
<target>Keine empfangenen oder gesendeten Dateien</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Not compatible!" xml:space="preserve">
<source>Not compatible!</source>
<target>Nicht kompatibel!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Notifications" xml:space="preserve">
<source>Notifications</source>
<target>Benachrichtigungen</target>
@@ -3495,6 +3689,7 @@ This is your link for group %@!</source>
</trans-unit>
<trans-unit id="Open group" xml:space="preserve">
<source>Open group</source>
<target>Gruppe öffnen</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Open user profiles" xml:space="preserve">
@@ -3557,6 +3752,11 @@ This is your link for group %@!</source>
<target>Einfügen</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Paste desktop address" xml:space="preserve">
<source>Paste desktop address</source>
<target>Desktop-Adresse einfügen</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Paste image" xml:space="preserve">
<source>Paste image</source>
<target>Bild einfügen</target>
@@ -3704,10 +3904,12 @@ This is your link for group %@!</source>
</trans-unit>
<trans-unit id="Profile name" xml:space="preserve">
<source>Profile name</source>
<target>Profilname</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Profile name:" xml:space="preserve">
<source>Profile name:</source>
<target>Profilname:</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Profile password" xml:space="preserve">
@@ -3957,10 +4159,12 @@ This is your link for group %@!</source>
</trans-unit>
<trans-unit id="Repeat connection request?" xml:space="preserve">
<source>Repeat connection request?</source>
<target>Verbindungsanfrage wiederholen?</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Repeat join request?" xml:space="preserve">
<source>Repeat join request?</source>
<target>Verbindungsanfrage wiederholen?</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Reply" xml:space="preserve">
@@ -4148,6 +4352,11 @@ This is your link for group %@!</source>
<target>QR-Code scannen</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Scan QR code from desktop" xml:space="preserve">
<source>Scan QR code from desktop</source>
<target>Den QR-Code vom Desktop scannen</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Scan code" xml:space="preserve">
<source>Scan code</source>
<target>Code scannen</target>
@@ -4368,6 +4577,11 @@ This is your link for group %@!</source>
<target>Server</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Session code" xml:space="preserve">
<source>Session code</source>
<target>Sitzungscode</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Set 1 day" xml:space="preserve">
<source>Set 1 day</source>
<target>Einen Tag festlegen</target>
@@ -4680,6 +4894,7 @@ This is your link for group %@!</source>
</trans-unit>
<trans-unit id="Tap to Connect" xml:space="preserve">
<source>Tap to Connect</source>
<target>Zum Verbinden antippen</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Tap to activate profile." xml:space="preserve">
@@ -4864,6 +5079,11 @@ Dies kann passieren, wenn es einen Fehler gegeben hat oder die Verbindung kompro
<target>Diese Aktion kann nicht rückgängig gemacht werden! Ihr Profil und Ihre Kontakte, Nachrichten und Dateien gehen unwiderruflich verloren.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="This device name" xml:space="preserve">
<source>This device name</source>
<target>Dieser Gerätename</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="This group has over %lld members, delivery receipts are not sent." xml:space="preserve">
<source>This group has over %lld members, delivery receipts are not sent.</source>
<target>Es werden keine Empfangsbestätigungen gesendet, da diese Gruppe über %lld Mitglieder hat.</target>
@@ -4876,10 +5096,12 @@ Dies kann passieren, wenn es einen Fehler gegeben hat oder die Verbindung kompro
</trans-unit>
<trans-unit id="This is your own SimpleX address!" xml:space="preserve">
<source>This is your own SimpleX address!</source>
<target>Das ist Ihre eigene SimpleX-Adresse!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="This is your own one-time link!" xml:space="preserve">
<source>This is your own one-time link!</source>
<target>Das ist Ihr eigener Einmal-Link!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="This setting applies to messages in your current chat profile **%@**." xml:space="preserve">
@@ -4897,6 +5119,11 @@ Dies kann passieren, wenn es einen Fehler gegeben hat oder die Verbindung kompro
<target>Um eine Verbindung herzustellen, kann Ihr Kontakt den QR-Code scannen oder den Link in der App verwenden.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="To hide unwanted messages." xml:space="preserve">
<source>To hide unwanted messages.</source>
<target>Um unerwünschte Nachrichten zu verbergen.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="To make a new connection" xml:space="preserve">
<source>To make a new connection</source>
<target>Um eine Verbindung mit einem neuen Kontakt zu erstellen</target>
@@ -4926,7 +5153,7 @@ Sie werden aufgefordert, die Authentifizierung abzuschließen, bevor diese Funkt
</trans-unit>
<trans-unit id="To reveal your hidden profile, enter a full password into a search field in **Your chat profiles** page." xml:space="preserve">
<source>To reveal your hidden profile, enter a full password into a search field in **Your chat profiles** page.</source>
<target>Geben Sie ein vollständiges Passwort in das Suchfeld auf der Seite **Meine Chat-Profile** ein, um Ihr verborgenes Profil zu sehen.</target>
<target>Geben Sie ein vollständiges Passwort in das Suchfeld auf der Seite **Ihre Chat-Profile** ein, um Ihr verborgenes Profil zu sehen.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="To support instant push notifications the chat database has to be migrated." xml:space="preserve">
@@ -4981,14 +5208,17 @@ Sie werden aufgefordert, die Authentifizierung abzuschließen, bevor diese Funkt
</trans-unit>
<trans-unit id="Unblock" xml:space="preserve">
<source>Unblock</source>
<target>Freigeben</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Unblock member" xml:space="preserve">
<source>Unblock member</source>
<target>Mitglied freigeben</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Unblock member?" xml:space="preserve">
<source>Unblock member?</source>
<target>Mitglied freigeben?</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Unexpected error: %@" xml:space="preserve">
@@ -5053,6 +5283,16 @@ To connect, please ask your contact to create another connection link and check
Bitten Sie Ihren Kontakt darum einen weiteren Verbindungs-Link zu erzeugen, um sich neu verbinden zu können und stellen Sie sicher, dass Sie eine stabile Netzwerk-Verbindung haben.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Unlink" xml:space="preserve">
<source>Unlink</source>
<target>Entkoppeln</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Unlink desktop?" xml:space="preserve">
<source>Unlink desktop?</source>
<target>Desktop entkoppeln?</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Unlock" xml:space="preserve">
<source>Unlock</source>
<target>Entsperren</target>
@@ -5143,6 +5383,11 @@ Bitten Sie Ihren Kontakt darum einen weiteren Verbindungs-Link zu erzeugen, um s
<target>Für neue Verbindungen nutzen</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Use from desktop" xml:space="preserve">
<source>Use from desktop</source>
<target>Vom Desktop aus nutzen</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Use iOS call interface" xml:space="preserve">
<source>Use iOS call interface</source>
<target>iOS Anrufschnittstelle nutzen</target>
@@ -5173,11 +5418,26 @@ Bitten Sie Ihren Kontakt darum einen weiteren Verbindungs-Link zu erzeugen, um s
<target>Verwendung von SimpleX-Chat-Servern.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Verify code with desktop" xml:space="preserve">
<source>Verify code with desktop</source>
<target>Code mit dem Desktop überprüfen</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Verify connection" xml:space="preserve">
<source>Verify connection</source>
<target>Verbindung überprüfen</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Verify connection security" xml:space="preserve">
<source>Verify connection security</source>
<target>Sicherheit der Verbindung überprüfen</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Verify connections" xml:space="preserve">
<source>Verify connections</source>
<target>Verbindungen überprüfen</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Verify security code" xml:space="preserve">
<source>Verify security code</source>
<target>Sicherheitscode überprüfen</target>
@@ -5188,6 +5448,11 @@ Bitten Sie Ihren Kontakt darum einen weiteren Verbindungs-Link zu erzeugen, um s
<target>Über den Browser</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Via secure quantum resistant protocol." xml:space="preserve">
<source>Via secure quantum resistant protocol.</source>
<target>Über ein sicheres quantenbeständiges Protokoll.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Video call" xml:space="preserve">
<source>Video call</source>
<target>Videoanruf</target>
@@ -5238,6 +5503,11 @@ Bitten Sie Ihren Kontakt darum einen weiteren Verbindungs-Link zu erzeugen, um s
<target>Sprachnachrichten…</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Waiting for desktop..." xml:space="preserve">
<source>Waiting for desktop...</source>
<target>Es wird auf den Desktop gewartet...</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Waiting for file" xml:space="preserve">
<source>Waiting for file</source>
<target>Warte auf Datei</target>
@@ -5315,7 +5585,7 @@ Bitten Sie Ihren Kontakt darum einen weiteren Verbindungs-Link zu erzeugen, um s
</trans-unit>
<trans-unit id="You" xml:space="preserve">
<source>You</source>
<target>Meine Daten</target>
<target>Ihre Daten</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="You accepted connection" xml:space="preserve">
@@ -5340,31 +5610,39 @@ Bitten Sie Ihren Kontakt darum einen weiteren Verbindungs-Link zu erzeugen, um s
</trans-unit>
<trans-unit id="You are already connecting to %@." xml:space="preserve">
<source>You are already connecting to %@.</source>
<target>Sie sind bereits mit %@ verbunden.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="You are already connecting via this one-time link!" xml:space="preserve">
<source>You are already connecting via this one-time link!</source>
<target>Sie sind bereits über diesen Einmal-Link verbunden!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="You are already in group %@." xml:space="preserve">
<source>You are already in group %@.</source>
<target>Sie sind bereits Mitglied der Gruppe %@.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="You are already joining the group %@." xml:space="preserve">
<source>You are already joining the group %@.</source>
<target>Sie sind bereits Mitglied der Gruppe %@.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="You are already joining the group via this link!" xml:space="preserve">
<source>You are already joining the group via this link!</source>
<target>Sie sind über diesen Link bereits Mitglied der Gruppe!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="You are already joining the group via this link." xml:space="preserve">
<source>You are already joining the group via this link.</source>
<target>Sie sind über diesen Link bereits Mitglied der Gruppe.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="You are already joining the group!&#10;Repeat join request?" xml:space="preserve">
<source>You are already joining the group!
Repeat join request?</source>
<target>Sie sind bereits Mitglied dieser Gruppe!
Verbindungsanfrage wiederholen?</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="You are connected to the server used to receive messages from this contact." xml:space="preserve">
@@ -5464,11 +5742,14 @@ Repeat join request?</source>
</trans-unit>
<trans-unit id="You have already requested connection via this address!" xml:space="preserve">
<source>You have already requested connection via this address!</source>
<target>Sie haben über diese Adresse bereits eine Verbindung beantragt!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="You have already requested connection!&#10;Repeat connection request?" xml:space="preserve">
<source>You have already requested connection!
Repeat connection request?</source>
<target>Sie haben bereits ein Verbindungsanfrage beantragt!
Verbindungsanfrage wiederholen?</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="You have no chats" xml:space="preserve">
@@ -5523,6 +5804,7 @@ Repeat connection request?</source>
</trans-unit>
<trans-unit id="You will be connected when group link host's device is online, please wait or check later!" xml:space="preserve">
<source>You will be connected when group link host's device is online, please wait or check later!</source>
<target>Sie werden verbunden, sobald das Endgerät des Gruppenlink-Hosts online ist. Bitte warten oder schauen Sie später nochmal nach!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="You will be connected when your connection request is accepted, please wait or check later!" xml:space="preserve">
@@ -5542,6 +5824,7 @@ Repeat connection request?</source>
</trans-unit>
<trans-unit id="You will connect to all group members." xml:space="preserve">
<source>You will connect to all group members.</source>
<target>Sie werden mit allen Gruppenmitgliedern verbunden.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="You will still receive calls and notifications from muted profiles when they are active." xml:space="preserve">
@@ -5586,7 +5869,7 @@ Repeat connection request?</source>
</trans-unit>
<trans-unit id="Your SimpleX address" xml:space="preserve">
<source>Your SimpleX address</source>
<target>Meine SimpleX-Adresse</target>
<target>Ihre SimpleX-Adresse</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Your XFTP servers" xml:space="preserve">
@@ -5611,7 +5894,7 @@ Repeat connection request?</source>
</trans-unit>
<trans-unit id="Your chat profiles" xml:space="preserve">
<source>Your chat profiles</source>
<target>Meine Chat-Profile</target>
<target>Ihre Chat-Profile</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Your contact needs to be online for the connection to complete.&#10;You can cancel this connection and remove the contact (and try later with a new link)." xml:space="preserve">
@@ -5655,16 +5938,17 @@ Sie können es in den Einstellungen ändern.</target>
</trans-unit>
<trans-unit id="Your preferences" xml:space="preserve">
<source>Your preferences</source>
<target>Meine Präferenzen</target>
<target>Ihre Präferenzen</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Your privacy" xml:space="preserve">
<source>Your privacy</source>
<target>Meine Privatsphäre</target>
<target>Ihre Privatsphäre</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Your profile" xml:space="preserve">
<source>Your profile</source>
<target>Mein Profil</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Your profile **%@** will be shared." xml:space="preserve">
@@ -5701,7 +5985,7 @@ SimpleX-Server können Ihr Profil nicht einsehen.</target>
</trans-unit>
<trans-unit id="Your settings" xml:space="preserve">
<source>Your settings</source>
<target>Meine Einstellungen</target>
<target>Ihre Einstellungen</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="[Contribute](https://github.com/simplex-chat/simplex-chat#contribute)" xml:space="preserve">
@@ -5761,6 +6045,7 @@ SimpleX-Server können Ihr Profil nicht einsehen.</target>
</trans-unit>
<trans-unit id="and %lld other events" xml:space="preserve">
<source>and %lld other events</source>
<target>und %lld weitere Ereignisse</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="audio call (not e2e encrypted)" xml:space="preserve">
@@ -5768,6 +6053,11 @@ SimpleX-Server können Ihr Profil nicht einsehen.</target>
<target>Audioanruf (nicht E2E verschlüsselt)</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="author" xml:space="preserve">
<source>author</source>
<target>Autor</target>
<note>member role</note>
</trans-unit>
<trans-unit id="bad message ID" xml:space="preserve">
<source>bad message ID</source>
<target>Ungültige Nachrichten-ID</target>
@@ -5780,6 +6070,7 @@ SimpleX-Server können Ihr Profil nicht einsehen.</target>
</trans-unit>
<trans-unit id="blocked" xml:space="preserve">
<source>blocked</source>
<target>blockiert</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="bold" xml:space="preserve">
@@ -5954,6 +6245,7 @@ SimpleX-Server können Ihr Profil nicht einsehen.</target>
</trans-unit>
<trans-unit id="deleted contact" xml:space="preserve">
<source>deleted contact</source>
<target>Gelöschter Kontakt</target>
<note>rcv direct event chat item</note>
</trans-unit>
<trans-unit id="deleted group" xml:space="preserve">
@@ -6348,6 +6640,11 @@ SimpleX-Server können Ihr Profil nicht einsehen.</target>
<target>Aktualisiertes Gruppenprofil</target>
<note>rcv group event chat item</note>
</trans-unit>
<trans-unit id="v%@" xml:space="preserve">
<source>v%@</source>
<target>v%@</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="v%@ (%@)" xml:space="preserve">
<source>v%@ (%@)</source>
<target>v%@ (%@)</target>
@@ -6485,6 +6782,11 @@ SimpleX-Server können Ihr Profil nicht einsehen.</target>
<target>Face ID wird von SimpleX für die lokale Authentifizierung genutzt</target>
<note>Privacy - Face ID Usage Description</note>
</trans-unit>
<trans-unit id="NSLocalNetworkUsageDescription" xml:space="preserve">
<source>SimpleX uses local network access to allow using user chat profile via desktop app on the same network.</source>
<target>SimpleX nutzt den lokalen Netzwerkzugriff, um die Nutzung von Benutzer-Chatprofilen über eine Desktop-App im gleichen Netzwerk zu erlauben.</target>
<note>Privacy - Local Network Usage Description</note>
</trans-unit>
<trans-unit id="NSMicrophoneUsageDescription" xml:space="preserve">
<source>SimpleX needs microphone access for audio and video calls, and to record voice messages.</source>
<target>SimpleX benötigt Zugriff auf das Mikrofon, um Audio- und Videoanrufe und die Aufnahme von Sprachnachrichten zu ermöglichen.</target>

View File

@@ -4,6 +4,8 @@
"NSCameraUsageDescription" = "SimpleX needs camera access to scan QR codes to connect to other users and for video calls.";
/* Privacy - Face ID Usage Description */
"NSFaceIDUsageDescription" = "SimpleX uses Face ID for local authentication";
/* Privacy - Local Network Usage Description */
"NSLocalNetworkUsageDescription" = "SimpleX uses local network access to allow using user chat profile via desktop app on the same network.";
/* Privacy - Microphone Usage Description */
"NSMicrophoneUsageDescription" = "SimpleX needs microphone access for audio and video calls, and to record voice messages.";
/* Privacy - Photo Library Additions Usage Description */

View File

@@ -297,6 +297,16 @@
<target>(</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="(new)" xml:space="preserve">
<source>(new)</source>
<target>(new)</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="(this device v%@)" xml:space="preserve">
<source>(this device v%@)</source>
<target>(this device v%@)</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id=")" xml:space="preserve">
<source>)</source>
<target>)</target>
@@ -382,6 +392,15 @@
- and more!</source>
<target>- more stable message delivery.
- a bit better groups.
- and more!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="- optionally notify deleted contacts.&#10;- profile names with spaces.&#10;- and more!" xml:space="preserve">
<source>- optionally notify deleted contacts.
- profile names with spaces.
- and more!</source>
<target>- optionally notify deleted contacts.
- profile names with spaces.
- and more!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
@@ -869,6 +888,11 @@
<target>Back</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Bad desktop address" xml:space="preserve">
<source>Bad desktop address</source>
<target>Bad desktop address</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Bad message ID" xml:space="preserve">
<source>Bad message ID</source>
<target>Bad message ID</target>
@@ -879,6 +903,11 @@
<target>Bad message hash</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Better groups" xml:space="preserve">
<source>Better groups</source>
<target>Better groups</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Better messages" xml:space="preserve">
<source>Better messages</source>
<target>Better messages</target>
@@ -889,6 +918,11 @@
<target>Block</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Block group members" xml:space="preserve">
<source>Block group members</source>
<target>Block group members</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Block member" xml:space="preserve">
<source>Block member</source>
<target>Block member</target>
@@ -1160,11 +1194,21 @@
<target>Connect</target>
<note>server test step</note>
</trans-unit>
<trans-unit id="Connect automatically" xml:space="preserve">
<source>Connect automatically</source>
<target>Connect automatically</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connect incognito" xml:space="preserve">
<source>Connect incognito</source>
<target>Connect incognito</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connect to desktop" xml:space="preserve">
<source>Connect to desktop</source>
<target>Connect to desktop</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connect to yourself?" xml:space="preserve">
<source>Connect to yourself?</source>
<target>Connect to yourself?</target>
@@ -1209,6 +1253,16 @@ This is your own one-time link!</target>
<target>Connect with %@</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connected desktop" xml:space="preserve">
<source>Connected desktop</source>
<target>Connected desktop</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connected to desktop" xml:space="preserve">
<source>Connected to desktop</source>
<target>Connected to desktop</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connecting server…" xml:space="preserve">
<source>Connecting to server…</source>
<target>Connecting to server…</target>
@@ -1219,6 +1273,11 @@ This is your own one-time link!</target>
<target>Connecting to server… (error: %@)</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connecting to desktop" xml:space="preserve">
<source>Connecting to desktop</source>
<target>Connecting to desktop</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connection" xml:space="preserve">
<source>Connection</source>
<target>Connection</target>
@@ -1239,6 +1298,11 @@ This is your own one-time link!</target>
<target>Connection request sent!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connection terminated" xml:space="preserve">
<source>Connection terminated</source>
<target>Connection terminated</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connection timeout" xml:space="preserve">
<source>Connection timeout</source>
<target>Connection timeout</target>
@@ -1319,6 +1383,11 @@ This is your own one-time link!</target>
<target>Create SimpleX address</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Create a group using a random profile." xml:space="preserve">
<source>Create a group using a random profile.</source>
<target>Create a group using a random profile.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Create an address to let people connect with you." xml:space="preserve">
<source>Create an address to let people connect with you.</source>
<target>Create an address to let people connect with you.</target>
@@ -1729,6 +1798,21 @@ This cannot be undone!</target>
<target>Description</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Desktop address" xml:space="preserve">
<source>Desktop address</source>
<target>Desktop address</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Desktop app version %@ is not compatible with this app." xml:space="preserve">
<source>Desktop app version %@ is not compatible with this app.</source>
<target>Desktop app version %@ is not compatible with this app.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Desktop devices" xml:space="preserve">
<source>Desktop devices</source>
<target>Desktop devices</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Develop" xml:space="preserve">
<source>Develop</source>
<target>Develop</target>
@@ -1819,11 +1903,21 @@ This cannot be undone!</target>
<target>Disconnect</target>
<note>server test step</note>
</trans-unit>
<trans-unit id="Disconnect desktop?" xml:space="preserve">
<source>Disconnect desktop?</source>
<target>Disconnect desktop?</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Discover and join groups" xml:space="preserve">
<source>Discover and join groups</source>
<target>Discover and join groups</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Discover via local network" xml:space="preserve">
<source>Discover via local network</source>
<target>Discover via local network</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Do NOT use SimpleX for emergency calls." xml:space="preserve">
<source>Do NOT use SimpleX for emergency calls.</source>
<target>Do NOT use SimpleX for emergency calls.</target>
@@ -1994,6 +2088,16 @@ This cannot be undone!</target>
<target>Encrypted message: unexpected error</target>
<note>notification</note>
</trans-unit>
<trans-unit id="Encryption re-negotiation error" xml:space="preserve">
<source>Encryption re-negotiation error</source>
<target>Encryption re-negotiation error</target>
<note>message decrypt error item</note>
</trans-unit>
<trans-unit id="Encryption re-negotiation failed." xml:space="preserve">
<source>Encryption re-negotiation failed.</source>
<target>Encryption re-negotiation failed.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Enter Passcode" xml:space="preserve">
<source>Enter Passcode</source>
<target>Enter Passcode</target>
@@ -2024,6 +2128,11 @@ This cannot be undone!</target>
<target>Enter server manually</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Enter this device name…" xml:space="preserve">
<source>Enter this device name…</source>
<target>Enter this device name…</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Enter welcome message…" xml:space="preserve">
<source>Enter welcome message…</source>
<target>Enter welcome message…</target>
@@ -2349,6 +2458,11 @@ This cannot be undone!</target>
<target>Fast and no wait until the sender is online!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Faster joining and more reliable messages." xml:space="preserve">
<source>Faster joining and more reliable messages.</source>
<target>Faster joining and more reliable messages.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Favorite" xml:space="preserve">
<source>Favorite</source>
<target>Favorite</target>
@@ -2444,6 +2558,11 @@ This cannot be undone!</target>
<target>For console</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Found desktop" xml:space="preserve">
<source>Found desktop</source>
<target>Found desktop</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="French interface" xml:space="preserve">
<source>French interface</source>
<target>French interface</target>
@@ -2769,6 +2888,11 @@ This cannot be undone!</target>
<target>Incognito</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Incognito groups" xml:space="preserve">
<source>Incognito groups</source>
<target>Incognito groups</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Incognito mode" xml:space="preserve">
<source>Incognito mode</source>
<target>Incognito mode</target>
@@ -2799,6 +2923,11 @@ This cannot be undone!</target>
<target>Incompatible database version</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Incompatible version" xml:space="preserve">
<source>Incompatible version</source>
<target>Incompatible version</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Incorrect passcode" xml:space="preserve">
<source>Incorrect passcode</source>
<target>Incorrect passcode</target>
@@ -2969,6 +3098,11 @@ This is your link for group %@!</target>
<target>Joining group</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Keep the app open to use it from desktop" xml:space="preserve">
<source>Keep the app open to use it from desktop</source>
<target>Keep the app open to use it from desktop</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Keep your connections" xml:space="preserve">
<source>Keep your connections</source>
<target>Keep your connections</target>
@@ -3029,6 +3163,21 @@ This is your link for group %@!</target>
<target>Limitations</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Link mobile and desktop apps! 🔗" xml:space="preserve">
<source>Link mobile and desktop apps! 🔗</source>
<target>Link mobile and desktop apps! 🔗</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Linked desktop options" xml:space="preserve">
<source>Linked desktop options</source>
<target>Linked desktop options</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Linked desktops" xml:space="preserve">
<source>Linked desktops</source>
<target>Linked desktops</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Live message!" xml:space="preserve">
<source>Live message!</source>
<target>Live message!</target>
@@ -3379,6 +3528,11 @@ This is your link for group %@!</target>
<target>No received or sent files</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Not compatible!" xml:space="preserve">
<source>Not compatible!</source>
<target>Not compatible!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Notifications" xml:space="preserve">
<source>Notifications</source>
<target>Notifications</target>
@@ -3598,6 +3752,11 @@ This is your link for group %@!</target>
<target>Paste</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Paste desktop address" xml:space="preserve">
<source>Paste desktop address</source>
<target>Paste desktop address</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Paste image" xml:space="preserve">
<source>Paste image</source>
<target>Paste image</target>
@@ -4193,6 +4352,11 @@ This is your link for group %@!</target>
<target>Scan QR code</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Scan QR code from desktop" xml:space="preserve">
<source>Scan QR code from desktop</source>
<target>Scan QR code from desktop</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Scan code" xml:space="preserve">
<source>Scan code</source>
<target>Scan code</target>
@@ -4413,6 +4577,11 @@ This is your link for group %@!</target>
<target>Servers</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Session code" xml:space="preserve">
<source>Session code</source>
<target>Session code</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Set 1 day" xml:space="preserve">
<source>Set 1 day</source>
<target>Set 1 day</target>
@@ -4910,6 +5079,11 @@ It can happen because of some bug or when the connection is compromised.</target
<target>This action cannot be undone - your profile, contacts, messages and files will be irreversibly lost.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="This device name" xml:space="preserve">
<source>This device name</source>
<target>This device name</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="This group has over %lld members, delivery receipts are not sent." xml:space="preserve">
<source>This group has over %lld members, delivery receipts are not sent.</source>
<target>This group has over %lld members, delivery receipts are not sent.</target>
@@ -4945,6 +5119,11 @@ It can happen because of some bug or when the connection is compromised.</target
<target>To connect, your contact can scan QR code or use the link in the app.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="To hide unwanted messages." xml:space="preserve">
<source>To hide unwanted messages.</source>
<target>To hide unwanted messages.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="To make a new connection" xml:space="preserve">
<source>To make a new connection</source>
<target>To make a new connection</target>
@@ -5104,6 +5283,16 @@ To connect, please ask your contact to create another connection link and check
To connect, please ask your contact to create another connection link and check that you have a stable network connection.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Unlink" xml:space="preserve">
<source>Unlink</source>
<target>Unlink</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Unlink desktop?" xml:space="preserve">
<source>Unlink desktop?</source>
<target>Unlink desktop?</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Unlock" xml:space="preserve">
<source>Unlock</source>
<target>Unlock</target>
@@ -5194,6 +5383,11 @@ To connect, please ask your contact to create another connection link and check
<target>Use for new connections</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Use from desktop" xml:space="preserve">
<source>Use from desktop</source>
<target>Use from desktop</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Use iOS call interface" xml:space="preserve">
<source>Use iOS call interface</source>
<target>Use iOS call interface</target>
@@ -5224,11 +5418,26 @@ To connect, please ask your contact to create another connection link and check
<target>Using SimpleX Chat servers.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Verify code with desktop" xml:space="preserve">
<source>Verify code with desktop</source>
<target>Verify code with desktop</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Verify connection" xml:space="preserve">
<source>Verify connection</source>
<target>Verify connection</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Verify connection security" xml:space="preserve">
<source>Verify connection security</source>
<target>Verify connection security</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Verify connections" xml:space="preserve">
<source>Verify connections</source>
<target>Verify connections</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Verify security code" xml:space="preserve">
<source>Verify security code</source>
<target>Verify security code</target>
@@ -5239,6 +5448,11 @@ To connect, please ask your contact to create another connection link and check
<target>Via browser</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Via secure quantum resistant protocol." xml:space="preserve">
<source>Via secure quantum resistant protocol.</source>
<target>Via secure quantum resistant protocol.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Video call" xml:space="preserve">
<source>Video call</source>
<target>Video call</target>
@@ -5289,6 +5503,11 @@ To connect, please ask your contact to create another connection link and check
<target>Voice message…</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Waiting for desktop..." xml:space="preserve">
<source>Waiting for desktop...</source>
<target>Waiting for desktop...</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Waiting for file" xml:space="preserve">
<source>Waiting for file</source>
<target>Waiting for file</target>
@@ -5834,6 +6053,11 @@ SimpleX servers cannot see your profile.</target>
<target>audio call (not e2e encrypted)</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="author" xml:space="preserve">
<source>author</source>
<target>author</target>
<note>member role</note>
</trans-unit>
<trans-unit id="bad message ID" xml:space="preserve">
<source>bad message ID</source>
<target>bad message ID</target>
@@ -6416,6 +6640,11 @@ SimpleX servers cannot see your profile.</target>
<target>updated group profile</target>
<note>rcv group event chat item</note>
</trans-unit>
<trans-unit id="v%@" xml:space="preserve">
<source>v%@</source>
<target>v%@</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="v%@ (%@)" xml:space="preserve">
<source>v%@ (%@)</source>
<target>v%@ (%@)</target>
@@ -6553,6 +6782,11 @@ SimpleX servers cannot see your profile.</target>
<target>SimpleX uses Face ID for local authentication</target>
<note>Privacy - Face ID Usage Description</note>
</trans-unit>
<trans-unit id="NSLocalNetworkUsageDescription" xml:space="preserve">
<source>SimpleX uses local network access to allow using user chat profile via desktop app on the same network.</source>
<target>SimpleX uses local network access to allow using user chat profile via desktop app on the same network.</target>
<note>Privacy - Local Network Usage Description</note>
</trans-unit>
<trans-unit id="NSMicrophoneUsageDescription" xml:space="preserve">
<source>SimpleX needs microphone access for audio and video calls, and to record voice messages.</source>
<target>SimpleX needs microphone access for audio and video calls, and to record voice messages.</target>

View File

@@ -4,6 +4,8 @@
"NSCameraUsageDescription" = "SimpleX needs camera access to scan QR codes to connect to other users and for video calls.";
/* Privacy - Face ID Usage Description */
"NSFaceIDUsageDescription" = "SimpleX uses Face ID for local authentication";
/* Privacy - Local Network Usage Description */
"NSLocalNetworkUsageDescription" = "SimpleX uses local network access to allow using user chat profile via desktop app on the same network.";
/* Privacy - Microphone Usage Description */
"NSMicrophoneUsageDescription" = "SimpleX needs microphone access for audio and video calls, and to record voice messages.";
/* Privacy - Photo Library Additions Usage Description */

View File

@@ -290,6 +290,14 @@
<target>(</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="(new)" xml:space="preserve">
<source>(new)</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="(this device v%@)" xml:space="preserve">
<source>(this device v%@)</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id=")" xml:space="preserve">
<source>)</source>
<target>)</target>
@@ -378,6 +386,12 @@
- ¡y más!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="- optionally notify deleted contacts.&#10;- profile names with spaces.&#10;- and more!" xml:space="preserve">
<source>- optionally notify deleted contacts.
- profile names with spaces.
- and more!</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="- voice messages up to 5 minutes.&#10;- custom time to disappear.&#10;- editing history." xml:space="preserve">
<source>- voice messages up to 5 minutes.
- custom time to disappear.
@@ -858,6 +872,10 @@
<target>Volver</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Bad desktop address" xml:space="preserve">
<source>Bad desktop address</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Bad message ID" xml:space="preserve">
<source>Bad message ID</source>
<target>ID de mensaje incorrecto</target>
@@ -868,6 +886,10 @@
<target>Hash de mensaje incorrecto</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Better groups" xml:space="preserve">
<source>Better groups</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Better messages" xml:space="preserve">
<source>Better messages</source>
<target>Mensajes mejorados</target>
@@ -877,6 +899,10 @@
<source>Block</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Block group members" xml:space="preserve">
<source>Block group members</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Block member" xml:space="preserve">
<source>Block member</source>
<note>No comment provided by engineer.</note>
@@ -1146,11 +1172,19 @@
<target>Conectar</target>
<note>server test step</note>
</trans-unit>
<trans-unit id="Connect automatically" xml:space="preserve">
<source>Connect automatically</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connect incognito" xml:space="preserve">
<source>Connect incognito</source>
<target>Conectar incognito</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connect to desktop" xml:space="preserve">
<source>Connect to desktop</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connect to yourself?" xml:space="preserve">
<source>Connect to yourself?</source>
<note>No comment provided by engineer.</note>
@@ -1188,6 +1222,14 @@ This is your own one-time link!</source>
<source>Connect with %@</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connected desktop" xml:space="preserve">
<source>Connected desktop</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connected to desktop" xml:space="preserve">
<source>Connected to desktop</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connecting server…" xml:space="preserve">
<source>Connecting to server…</source>
<target>Conectando con el servidor…</target>
@@ -1198,6 +1240,10 @@ This is your own one-time link!</source>
<target>Conectando con el servidor... (error: %@)</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connecting to desktop" xml:space="preserve">
<source>Connecting to desktop</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connection" xml:space="preserve">
<source>Connection</source>
<target>Conexión</target>
@@ -1218,6 +1264,10 @@ This is your own one-time link!</source>
<target>¡Solicitud de conexión enviada!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connection terminated" xml:space="preserve">
<source>Connection terminated</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connection timeout" xml:space="preserve">
<source>Connection timeout</source>
<target>Tiempo de conexión expirado</target>
@@ -1297,6 +1347,10 @@ This is your own one-time link!</source>
<target>Crear tu dirección SimpleX</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Create a group using a random profile." xml:space="preserve">
<source>Create a group using a random profile.</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Create an address to let people connect with you." xml:space="preserve">
<source>Create an address to let people connect with you.</source>
<target>Crea una dirección para que otras personas puedan conectar contigo.</target>
@@ -1701,6 +1755,18 @@ This cannot be undone!</source>
<target>Descripción</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Desktop address" xml:space="preserve">
<source>Desktop address</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Desktop app version %@ is not compatible with this app." xml:space="preserve">
<source>Desktop app version %@ is not compatible with this app.</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Desktop devices" xml:space="preserve">
<source>Desktop devices</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Develop" xml:space="preserve">
<source>Develop</source>
<target>Desarrollo</target>
@@ -1791,11 +1857,19 @@ This cannot be undone!</source>
<target>Desconectar</target>
<note>server test step</note>
</trans-unit>
<trans-unit id="Disconnect desktop?" xml:space="preserve">
<source>Disconnect desktop?</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Discover and join groups" xml:space="preserve">
<source>Discover and join groups</source>
<target>Descubre y únete a grupos</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Discover via local network" xml:space="preserve">
<source>Discover via local network</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Do NOT use SimpleX for emergency calls." xml:space="preserve">
<source>Do NOT use SimpleX for emergency calls.</source>
<target>NO uses SimpleX para llamadas de emergencia.</target>
@@ -1966,6 +2040,14 @@ This cannot be undone!</source>
<target>Mensaje cifrado: error inesperado</target>
<note>notification</note>
</trans-unit>
<trans-unit id="Encryption re-negotiation error" xml:space="preserve">
<source>Encryption re-negotiation error</source>
<note>message decrypt error item</note>
</trans-unit>
<trans-unit id="Encryption re-negotiation failed." xml:space="preserve">
<source>Encryption re-negotiation failed.</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Enter Passcode" xml:space="preserve">
<source>Enter Passcode</source>
<target>Introduce Código</target>
@@ -1995,6 +2077,10 @@ This cannot be undone!</source>
<target>Introduce el servidor manualmente</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Enter this device name…" xml:space="preserve">
<source>Enter this device name…</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Enter welcome message…" xml:space="preserve">
<source>Enter welcome message…</source>
<target>Introduce mensaje de bienvenida…</target>
@@ -2318,6 +2404,10 @@ This cannot be undone!</source>
<target>¡Rápido y sin necesidad de esperar a que el remitente esté en línea!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Faster joining and more reliable messages." xml:space="preserve">
<source>Faster joining and more reliable messages.</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Favorite" xml:space="preserve">
<source>Favorite</source>
<target>Favoritos</target>
@@ -2413,6 +2503,10 @@ This cannot be undone!</source>
<target>Para consola</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Found desktop" xml:space="preserve">
<source>Found desktop</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="French interface" xml:space="preserve">
<source>French interface</source>
<target>Interfaz en francés</target>
@@ -2735,6 +2829,10 @@ This cannot be undone!</source>
<target>Incógnito</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Incognito groups" xml:space="preserve">
<source>Incognito groups</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Incognito mode" xml:space="preserve">
<source>Incognito mode</source>
<target>Modo incógnito</target>
@@ -2765,6 +2863,10 @@ This cannot be undone!</source>
<target>Versión de base de datos incompatible</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Incompatible version" xml:space="preserve">
<source>Incompatible version</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Incorrect passcode" xml:space="preserve">
<source>Incorrect passcode</source>
<target>Código de acceso incorrecto</target>
@@ -2930,6 +3032,10 @@ This is your link for group %@!</source>
<target>Entrando al grupo</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Keep the app open to use it from desktop" xml:space="preserve">
<source>Keep the app open to use it from desktop</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Keep your connections" xml:space="preserve">
<source>Keep your connections</source>
<target>Conserva tus conexiones</target>
@@ -2990,6 +3096,18 @@ This is your link for group %@!</source>
<target>Limitaciones</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Link mobile and desktop apps! 🔗" xml:space="preserve">
<source>Link mobile and desktop apps! 🔗</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Linked desktop options" xml:space="preserve">
<source>Linked desktop options</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Linked desktops" xml:space="preserve">
<source>Linked desktops</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Live message!" xml:space="preserve">
<source>Live message!</source>
<target>¡Mensaje en vivo!</target>
@@ -3339,6 +3457,10 @@ This is your link for group %@!</source>
<target>Sin archivos recibidos o enviados</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Not compatible!" xml:space="preserve">
<source>Not compatible!</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Notifications" xml:space="preserve">
<source>Notifications</source>
<target>Notificaciones</target>
@@ -3557,6 +3679,10 @@ This is your link for group %@!</source>
<target>Pegar</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Paste desktop address" xml:space="preserve">
<source>Paste desktop address</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Paste image" xml:space="preserve">
<source>Paste image</source>
<target>Pegar imagen</target>
@@ -4148,6 +4274,10 @@ This is your link for group %@!</source>
<target>Escanear código QR</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Scan QR code from desktop" xml:space="preserve">
<source>Scan QR code from desktop</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Scan code" xml:space="preserve">
<source>Scan code</source>
<target>Escanear código</target>
@@ -4368,6 +4498,10 @@ This is your link for group %@!</source>
<target>Servidores</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Session code" xml:space="preserve">
<source>Session code</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Set 1 day" xml:space="preserve">
<source>Set 1 day</source>
<target>Establecer 1 día</target>
@@ -4864,6 +4998,10 @@ Puede ocurrir por algún bug o cuando la conexión está comprometida.</target>
<target>Esta acción no se puede deshacer. Tu perfil, contactos, mensajes y archivos se perderán irreversiblemente.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="This device name" xml:space="preserve">
<source>This device name</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="This group has over %lld members, delivery receipts are not sent." xml:space="preserve">
<source>This group has over %lld members, delivery receipts are not sent.</source>
<target>Este grupo tiene más de %lld miembros, no se enviarán confirmaciones de entrega.</target>
@@ -4897,6 +5035,10 @@ Puede ocurrir por algún bug o cuando la conexión está comprometida.</target>
<target>Para conectarse, tu contacto puede escanear el código QR o usar el enlace en la aplicación.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="To hide unwanted messages." xml:space="preserve">
<source>To hide unwanted messages.</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="To make a new connection" xml:space="preserve">
<source>To make a new connection</source>
<target>Para hacer una conexión nueva</target>
@@ -5054,6 +5196,14 @@ que este enlace ya se haya usado, podría ser un error. Por favor, notifícalo.
Para conectarte, pide a tu contacto que cree otro enlace de conexión y comprueba que tienes buena conexión de red.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Unlink" xml:space="preserve">
<source>Unlink</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Unlink desktop?" xml:space="preserve">
<source>Unlink desktop?</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Unlock" xml:space="preserve">
<source>Unlock</source>
<target>Desbloquear</target>
@@ -5144,6 +5294,10 @@ Para conectarte, pide a tu contacto que cree otro enlace de conexión y comprueb
<target>Usar para conexiones nuevas</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Use from desktop" xml:space="preserve">
<source>Use from desktop</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Use iOS call interface" xml:space="preserve">
<source>Use iOS call interface</source>
<target>Usar interfaz de llamada de iOS</target>
@@ -5174,11 +5328,23 @@ Para conectarte, pide a tu contacto que cree otro enlace de conexión y comprueb
<target>Usar servidores SimpleX Chat.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Verify code with desktop" xml:space="preserve">
<source>Verify code with desktop</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Verify connection" xml:space="preserve">
<source>Verify connection</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Verify connection security" xml:space="preserve">
<source>Verify connection security</source>
<target>Comprobar la seguridad de la conexión</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Verify connections" xml:space="preserve">
<source>Verify connections</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Verify security code" xml:space="preserve">
<source>Verify security code</source>
<target>Comprobar código de seguridad</target>
@@ -5189,6 +5355,10 @@ Para conectarte, pide a tu contacto que cree otro enlace de conexión y comprueb
<target>Mediante navegador</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Via secure quantum resistant protocol." xml:space="preserve">
<source>Via secure quantum resistant protocol.</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Video call" xml:space="preserve">
<source>Video call</source>
<target>Videollamada</target>
@@ -5239,6 +5409,10 @@ Para conectarte, pide a tu contacto que cree otro enlace de conexión y comprueb
<target>Mensaje de voz…</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Waiting for desktop..." xml:space="preserve">
<source>Waiting for desktop...</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Waiting for file" xml:space="preserve">
<source>Waiting for file</source>
<target>Esperando archivo</target>
@@ -5769,6 +5943,10 @@ Los servidores de SimpleX no pueden ver tu perfil.</target>
<target>llamada (sin cifrar)</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="author" xml:space="preserve">
<source>author</source>
<note>member role</note>
</trans-unit>
<trans-unit id="bad message ID" xml:space="preserve">
<source>bad message ID</source>
<target>ID de mensaje erróneo</target>
@@ -6349,6 +6527,10 @@ Los servidores de SimpleX no pueden ver tu perfil.</target>
<target>ha actualizado el perfil del grupo</target>
<note>rcv group event chat item</note>
</trans-unit>
<trans-unit id="v%@" xml:space="preserve">
<source>v%@</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="v%@ (%@)" xml:space="preserve">
<source>v%@ (%@)</source>
<target>v%@ (%@)</target>
@@ -6486,6 +6668,10 @@ Los servidores de SimpleX no pueden ver tu perfil.</target>
<target>SimpleX usa reconocimiento facial para la autenticación local</target>
<note>Privacy - Face ID Usage Description</note>
</trans-unit>
<trans-unit id="NSLocalNetworkUsageDescription" xml:space="preserve">
<source>SimpleX uses local network access to allow using user chat profile via desktop app on the same network.</source>
<note>Privacy - Local Network Usage Description</note>
</trans-unit>
<trans-unit id="NSMicrophoneUsageDescription" xml:space="preserve">
<source>SimpleX needs microphone access for audio and video calls, and to record voice messages.</source>
<target>SimpleX necesita acceso al micrófono para las llamadas de audio, vídeo y para grabar mensajes de voz.</target>

View File

@@ -4,6 +4,8 @@
"NSCameraUsageDescription" = "SimpleX needs camera access to scan QR codes to connect to other users and for video calls.";
/* Privacy - Face ID Usage Description */
"NSFaceIDUsageDescription" = "SimpleX uses Face ID for local authentication";
/* Privacy - Local Network Usage Description */
"NSLocalNetworkUsageDescription" = "SimpleX uses local network access to allow using user chat profile via desktop app on the same network.";
/* Privacy - Microphone Usage Description */
"NSMicrophoneUsageDescription" = "SimpleX needs microphone access for audio and video calls, and to record voice messages.";
/* Privacy - Photo Library Additions Usage Description */

View File

@@ -290,6 +290,14 @@
<target>(</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="(new)" xml:space="preserve">
<source>(new)</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="(this device v%@)" xml:space="preserve">
<source>(this device v%@)</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id=")" xml:space="preserve">
<source>)</source>
<target>)</target>
@@ -375,6 +383,12 @@
- ja paljon muuta!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="- optionally notify deleted contacts.&#10;- profile names with spaces.&#10;- and more!" xml:space="preserve">
<source>- optionally notify deleted contacts.
- profile names with spaces.
- and more!</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="- voice messages up to 5 minutes.&#10;- custom time to disappear.&#10;- editing history." xml:space="preserve">
<source>- voice messages up to 5 minutes.
- custom time to disappear.
@@ -854,6 +868,10 @@
<target>Takaisin</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Bad desktop address" xml:space="preserve">
<source>Bad desktop address</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Bad message ID" xml:space="preserve">
<source>Bad message ID</source>
<target>Virheellinen viestin tunniste</target>
@@ -864,6 +882,10 @@
<target>Virheellinen viestin tarkiste</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Better groups" xml:space="preserve">
<source>Better groups</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Better messages" xml:space="preserve">
<source>Better messages</source>
<target>Parempia viestejä</target>
@@ -873,6 +895,10 @@
<source>Block</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Block group members" xml:space="preserve">
<source>Block group members</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Block member" xml:space="preserve">
<source>Block member</source>
<note>No comment provided by engineer.</note>
@@ -1141,11 +1167,19 @@
<target>Yhdistä</target>
<note>server test step</note>
</trans-unit>
<trans-unit id="Connect automatically" xml:space="preserve">
<source>Connect automatically</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connect incognito" xml:space="preserve">
<source>Connect incognito</source>
<target>Yhdistä Incognito</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connect to desktop" xml:space="preserve">
<source>Connect to desktop</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connect to yourself?" xml:space="preserve">
<source>Connect to yourself?</source>
<note>No comment provided by engineer.</note>
@@ -1183,6 +1217,14 @@ This is your own one-time link!</source>
<source>Connect with %@</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connected desktop" xml:space="preserve">
<source>Connected desktop</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connected to desktop" xml:space="preserve">
<source>Connected to desktop</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connecting server…" xml:space="preserve">
<source>Connecting to server…</source>
<target>Yhteyden muodostaminen palvelimeen…</target>
@@ -1193,6 +1235,10 @@ This is your own one-time link!</source>
<target>Yhteyden muodostaminen palvelimeen... (virhe: %@)</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connecting to desktop" xml:space="preserve">
<source>Connecting to desktop</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connection" xml:space="preserve">
<source>Connection</source>
<target>Yhteys</target>
@@ -1213,6 +1259,10 @@ This is your own one-time link!</source>
<target>Yhteyspyyntö lähetetty!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connection terminated" xml:space="preserve">
<source>Connection terminated</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connection timeout" xml:space="preserve">
<source>Connection timeout</source>
<target>Yhteyden aikakatkaisu</target>
@@ -1292,6 +1342,10 @@ This is your own one-time link!</source>
<target>Luo SimpleX-osoite</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Create a group using a random profile." xml:space="preserve">
<source>Create a group using a random profile.</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Create an address to let people connect with you." xml:space="preserve">
<source>Create an address to let people connect with you.</source>
<target>Luo osoite, jolla ihmiset voivat ottaa sinuun yhteyttä.</target>
@@ -1696,6 +1750,18 @@ This cannot be undone!</source>
<target>Kuvaus</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Desktop address" xml:space="preserve">
<source>Desktop address</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Desktop app version %@ is not compatible with this app." xml:space="preserve">
<source>Desktop app version %@ is not compatible with this app.</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Desktop devices" xml:space="preserve">
<source>Desktop devices</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Develop" xml:space="preserve">
<source>Develop</source>
<target>Kehitä</target>
@@ -1786,11 +1852,19 @@ This cannot be undone!</source>
<target>Katkaise</target>
<note>server test step</note>
</trans-unit>
<trans-unit id="Disconnect desktop?" xml:space="preserve">
<source>Disconnect desktop?</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Discover and join groups" xml:space="preserve">
<source>Discover and join groups</source>
<target>Löydä ryhmiä ja liity niihin</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Discover via local network" xml:space="preserve">
<source>Discover via local network</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Do NOT use SimpleX for emergency calls." xml:space="preserve">
<source>Do NOT use SimpleX for emergency calls.</source>
<target>Älä käytä SimpleX-sovellusta hätäpuheluihin.</target>
@@ -1960,6 +2034,14 @@ This cannot be undone!</source>
<target>Salattu viesti: odottamaton virhe</target>
<note>notification</note>
</trans-unit>
<trans-unit id="Encryption re-negotiation error" xml:space="preserve">
<source>Encryption re-negotiation error</source>
<note>message decrypt error item</note>
</trans-unit>
<trans-unit id="Encryption re-negotiation failed." xml:space="preserve">
<source>Encryption re-negotiation failed.</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Enter Passcode" xml:space="preserve">
<source>Enter Passcode</source>
<target>Syötä pääsykoodi</target>
@@ -1989,6 +2071,10 @@ This cannot be undone!</source>
<target>Syötä palvelin manuaalisesti</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Enter this device name…" xml:space="preserve">
<source>Enter this device name…</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Enter welcome message…" xml:space="preserve">
<source>Enter welcome message…</source>
<target>Kirjoita tervetuloviesti…</target>
@@ -2310,6 +2396,10 @@ This cannot be undone!</source>
<target>Nopea ja ei odotusta, kunnes lähettäjä on online-tilassa!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Faster joining and more reliable messages." xml:space="preserve">
<source>Faster joining and more reliable messages.</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Favorite" xml:space="preserve">
<source>Favorite</source>
<target>Suosikki</target>
@@ -2405,6 +2495,10 @@ This cannot be undone!</source>
<target>Konsoliin</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Found desktop" xml:space="preserve">
<source>Found desktop</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="French interface" xml:space="preserve">
<source>French interface</source>
<target>Ranskalainen käyttöliittymä</target>
@@ -2727,6 +2821,10 @@ This cannot be undone!</source>
<target>Incognito</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Incognito groups" xml:space="preserve">
<source>Incognito groups</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Incognito mode" xml:space="preserve">
<source>Incognito mode</source>
<target>Incognito-tila</target>
@@ -2757,6 +2855,10 @@ This cannot be undone!</source>
<target>Yhteensopimaton tietokantaversio</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Incompatible version" xml:space="preserve">
<source>Incompatible version</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Incorrect passcode" xml:space="preserve">
<source>Incorrect passcode</source>
<target>Väärä pääsykoodi</target>
@@ -2922,6 +3024,10 @@ This is your link for group %@!</source>
<target>Liittyy ryhmään</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Keep the app open to use it from desktop" xml:space="preserve">
<source>Keep the app open to use it from desktop</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Keep your connections" xml:space="preserve">
<source>Keep your connections</source>
<target>Pidä kontaktisi</target>
@@ -2982,6 +3088,18 @@ This is your link for group %@!</source>
<target>Rajoitukset</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Link mobile and desktop apps! 🔗" xml:space="preserve">
<source>Link mobile and desktop apps! 🔗</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Linked desktop options" xml:space="preserve">
<source>Linked desktop options</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Linked desktops" xml:space="preserve">
<source>Linked desktops</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Live message!" xml:space="preserve">
<source>Live message!</source>
<target>Live-viesti!</target>
@@ -3330,6 +3448,10 @@ This is your link for group %@!</source>
<target>Ei vastaanotettuja tai lähetettyjä tiedostoja</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Not compatible!" xml:space="preserve">
<source>Not compatible!</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Notifications" xml:space="preserve">
<source>Notifications</source>
<target>Ilmoitukset</target>
@@ -3547,6 +3669,10 @@ This is your link for group %@!</source>
<target>Liitä</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Paste desktop address" xml:space="preserve">
<source>Paste desktop address</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Paste image" xml:space="preserve">
<source>Paste image</source>
<target>Liitä kuva</target>
@@ -4138,6 +4264,10 @@ This is your link for group %@!</source>
<target>Skannaa QR-koodi</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Scan QR code from desktop" xml:space="preserve">
<source>Scan QR code from desktop</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Scan code" xml:space="preserve">
<source>Scan code</source>
<target>Skannaa koodi</target>
@@ -4357,6 +4487,10 @@ This is your link for group %@!</source>
<target>Palvelimet</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Session code" xml:space="preserve">
<source>Session code</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Set 1 day" xml:space="preserve">
<source>Set 1 day</source>
<target>Aseta 1 päivä</target>
@@ -4852,6 +4986,10 @@ Tämä voi johtua jostain virheestä tai siitä, että yhteys on vaarantunut.</t
<target>Tätä toimintoa ei voi kumota - profiilisi, kontaktisi, viestisi ja tiedostosi poistuvat peruuttamattomasti.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="This device name" xml:space="preserve">
<source>This device name</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="This group has over %lld members, delivery receipts are not sent." xml:space="preserve">
<source>This group has over %lld members, delivery receipts are not sent.</source>
<target>Tässä ryhmässä on yli %lld jäsentä, lähetyskuittauksia ei lähetetä.</target>
@@ -4885,6 +5023,10 @@ Tämä voi johtua jostain virheestä tai siitä, että yhteys on vaarantunut.</t
<target>Kontaktisi voi muodostaa yhteyden skannaamalla QR-koodin tai käyttämällä sovelluksessa olevaa linkkiä.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="To hide unwanted messages." xml:space="preserve">
<source>To hide unwanted messages.</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="To make a new connection" xml:space="preserve">
<source>To make a new connection</source>
<target>Uuden yhteyden luominen</target>
@@ -5040,6 +5182,14 @@ To connect, please ask your contact to create another connection link and check
Jos haluat muodostaa yhteyden, pyydä kontaktiasi luomaan toinen yhteyslinkki ja tarkista, että verkkoyhteytesi on vakaa.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Unlink" xml:space="preserve">
<source>Unlink</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Unlink desktop?" xml:space="preserve">
<source>Unlink desktop?</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Unlock" xml:space="preserve">
<source>Unlock</source>
<target>Avaa</target>
@@ -5130,6 +5280,10 @@ Jos haluat muodostaa yhteyden, pyydä kontaktiasi luomaan toinen yhteyslinkki ja
<target>Käytä uusiin yhteyksiin</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Use from desktop" xml:space="preserve">
<source>Use from desktop</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Use iOS call interface" xml:space="preserve">
<source>Use iOS call interface</source>
<target>Käytä iOS:n puhelujen käyttöliittymää</target>
@@ -5160,11 +5314,23 @@ Jos haluat muodostaa yhteyden, pyydä kontaktiasi luomaan toinen yhteyslinkki ja
<target>Käyttää SimpleX Chat -palvelimia.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Verify code with desktop" xml:space="preserve">
<source>Verify code with desktop</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Verify connection" xml:space="preserve">
<source>Verify connection</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Verify connection security" xml:space="preserve">
<source>Verify connection security</source>
<target>Tarkista yhteyden suojaus</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Verify connections" xml:space="preserve">
<source>Verify connections</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Verify security code" xml:space="preserve">
<source>Verify security code</source>
<target>Tarkista turvakoodi</target>
@@ -5175,6 +5341,10 @@ Jos haluat muodostaa yhteyden, pyydä kontaktiasi luomaan toinen yhteyslinkki ja
<target>Selaimella</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Via secure quantum resistant protocol." xml:space="preserve">
<source>Via secure quantum resistant protocol.</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Video call" xml:space="preserve">
<source>Video call</source>
<target>Videopuhelu</target>
@@ -5225,6 +5395,10 @@ Jos haluat muodostaa yhteyden, pyydä kontaktiasi luomaan toinen yhteyslinkki ja
<target>Ääniviesti…</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Waiting for desktop..." xml:space="preserve">
<source>Waiting for desktop...</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Waiting for file" xml:space="preserve">
<source>Waiting for file</source>
<target>Odottaa tiedostoa</target>
@@ -5755,6 +5929,10 @@ SimpleX-palvelimet eivät näe profiiliasi.</target>
<target>äänipuhelu (ei e2e-salattu)</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="author" xml:space="preserve">
<source>author</source>
<note>member role</note>
</trans-unit>
<trans-unit id="bad message ID" xml:space="preserve">
<source>bad message ID</source>
<target>virheellinen viestin tunniste</target>
@@ -6333,6 +6511,10 @@ SimpleX-palvelimet eivät näe profiiliasi.</target>
<target>päivitetty ryhmäprofiili</target>
<note>rcv group event chat item</note>
</trans-unit>
<trans-unit id="v%@" xml:space="preserve">
<source>v%@</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="v%@ (%@)" xml:space="preserve">
<source>v%@ (%@)</source>
<target>v%@ (%@)</target>
@@ -6470,6 +6652,10 @@ SimpleX-palvelimet eivät näe profiiliasi.</target>
<target>SimpleX käyttää Face ID:tä paikalliseen todennukseen</target>
<note>Privacy - Face ID Usage Description</note>
</trans-unit>
<trans-unit id="NSLocalNetworkUsageDescription" xml:space="preserve">
<source>SimpleX uses local network access to allow using user chat profile via desktop app on the same network.</source>
<note>Privacy - Local Network Usage Description</note>
</trans-unit>
<trans-unit id="NSMicrophoneUsageDescription" xml:space="preserve">
<source>SimpleX needs microphone access for audio and video calls, and to record voice messages.</source>
<target>SimpleX tarvitsee mikrofonia ääni- ja videopuheluita ja ääniviestien tallentamista varten.</target>

View File

@@ -4,6 +4,8 @@
"NSCameraUsageDescription" = "SimpleX needs camera access to scan QR codes to connect to other users and for video calls.";
/* Privacy - Face ID Usage Description */
"NSFaceIDUsageDescription" = "SimpleX uses Face ID for local authentication";
/* Privacy - Local Network Usage Description */
"NSLocalNetworkUsageDescription" = "SimpleX uses local network access to allow using user chat profile via desktop app on the same network.";
/* Privacy - Microphone Usage Description */
"NSMicrophoneUsageDescription" = "SimpleX needs microphone access for audio and video calls, and to record voice messages.";
/* Privacy - Photo Library Additions Usage Description */

View File

@@ -89,6 +89,7 @@
</trans-unit>
<trans-unit id="%@ and %@" xml:space="preserve">
<source>%@ and %@</source>
<target>%@ et %@</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="%@ and %@ connected" xml:space="preserve">
@@ -103,6 +104,7 @@
</trans-unit>
<trans-unit id="%@ connected" xml:space="preserve">
<source>%@ connected</source>
<target>%@ connecté(e)</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="%@ is connected!" xml:space="preserve">
@@ -132,6 +134,7 @@
</trans-unit>
<trans-unit id="%@, %@ and %lld members" xml:space="preserve">
<source>%@, %@ and %lld members</source>
<target>%@, %@ et %lld membres</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="%@, %@ and %lld other members connected" xml:space="preserve">
@@ -201,6 +204,7 @@
</trans-unit>
<trans-unit id="%lld group events" xml:space="preserve">
<source>%lld group events</source>
<target>%lld événements de groupe</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="%lld members" xml:space="preserve">
@@ -210,14 +214,17 @@
</trans-unit>
<trans-unit id="%lld messages blocked" xml:space="preserve">
<source>%lld messages blocked</source>
<target>%lld messages bloqués</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="%lld messages marked deleted" xml:space="preserve">
<source>%lld messages marked deleted</source>
<target>%lld messages marqués comme supprimés</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="%lld messages moderated by %@" xml:space="preserve">
<source>%lld messages moderated by %@</source>
<target>%lld messages modérés par %@</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="%lld minutes" xml:space="preserve">
@@ -290,6 +297,16 @@
<target>(</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="(new)" xml:space="preserve">
<source>(new)</source>
<target>(nouveau)</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="(this device v%@)" xml:space="preserve">
<source>(this device v%@)</source>
<target>(cet appareil v%@)</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id=")" xml:space="preserve">
<source>)</source>
<target>)</target>
@@ -378,6 +395,15 @@
- et bien d'autres choses encore !</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="- optionally notify deleted contacts.&#10;- profile names with spaces.&#10;- and more!" xml:space="preserve">
<source>- optionally notify deleted contacts.
- profile names with spaces.
- and more!</source>
<target>- option pour notifier les contacts supprimés.
- noms de profil avec espaces.
- et plus encore !</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="- voice messages up to 5 minutes.&#10;- custom time to disappear.&#10;- editing history." xml:space="preserve">
<source>- voice messages up to 5 minutes.
- custom time to disappear.
@@ -394,6 +420,7 @@
</trans-unit>
<trans-unit id="0 sec" xml:space="preserve">
<source>0 sec</source>
<target>0 sec</target>
<note>time to disappear</note>
</trans-unit>
<trans-unit id="0s" xml:space="preserve">
@@ -623,6 +650,7 @@
</trans-unit>
<trans-unit id="All new messages from %@ will be hidden!" xml:space="preserve">
<source>All new messages from %@ will be hidden!</source>
<target>Tous les nouveaux messages de %@ seront cachés !</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="All your contacts will remain connected." xml:space="preserve">
@@ -732,10 +760,12 @@
</trans-unit>
<trans-unit id="Already connecting!" xml:space="preserve">
<source>Already connecting!</source>
<target>Déjà en connexion !</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Already joining the group!" xml:space="preserve">
<source>Already joining the group!</source>
<target>Groupe déjà rejoint !</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Always use relay" xml:space="preserve">
@@ -858,6 +888,11 @@
<target>Retour</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Bad desktop address" xml:space="preserve">
<source>Bad desktop address</source>
<target>Mauvaise adresse de bureau</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Bad message ID" xml:space="preserve">
<source>Bad message ID</source>
<target>Mauvais ID de message</target>
@@ -868,6 +903,11 @@
<target>Mauvais hash de message</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Better groups" xml:space="preserve">
<source>Better groups</source>
<target>Des groupes plus performants</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Better messages" xml:space="preserve">
<source>Better messages</source>
<target>Meilleurs messages</target>
@@ -875,14 +915,22 @@
</trans-unit>
<trans-unit id="Block" xml:space="preserve">
<source>Block</source>
<target>Bloquer</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Block group members" xml:space="preserve">
<source>Block group members</source>
<target>Bloquer des membres d'un groupe</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Block member" xml:space="preserve">
<source>Block member</source>
<target>Bloquer ce membre</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Block member?" xml:space="preserve">
<source>Block member?</source>
<target>Bloquer ce membre ?</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Both you and your contact can add message reactions." xml:space="preserve">
@@ -1146,27 +1194,43 @@
<target>Se connecter</target>
<note>server test step</note>
</trans-unit>
<trans-unit id="Connect automatically" xml:space="preserve">
<source>Connect automatically</source>
<target>Connexion automatique</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connect incognito" xml:space="preserve">
<source>Connect incognito</source>
<target>Se connecter incognito</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connect to desktop" xml:space="preserve">
<source>Connect to desktop</source>
<target>Se connecter au bureau</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connect to yourself?" xml:space="preserve">
<source>Connect to yourself?</source>
<target>Se connecter à soi-même ?</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connect to yourself?&#10;This is your own SimpleX address!" xml:space="preserve">
<source>Connect to yourself?
This is your own SimpleX address!</source>
<target>Se connecter à soi-même ?
C'est votre propre adresse SimpleX !</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connect to yourself?&#10;This is your own one-time link!" xml:space="preserve">
<source>Connect to yourself?
This is your own one-time link!</source>
<target>Se connecter à soi-même ?
Il s'agit de votre propre lien unique !</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connect via contact address" xml:space="preserve">
<source>Connect via contact address</source>
<target>Se connecter via l'adresse de contact</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connect via link" xml:space="preserve">
@@ -1186,6 +1250,17 @@ This is your own one-time link!</source>
</trans-unit>
<trans-unit id="Connect with %@" xml:space="preserve">
<source>Connect with %@</source>
<target>Se connecter avec %@</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connected desktop" xml:space="preserve">
<source>Connected desktop</source>
<target>Bureau connecté</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connected to desktop" xml:space="preserve">
<source>Connected to desktop</source>
<target>Connecté au bureau</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connecting server…" xml:space="preserve">
@@ -1198,6 +1273,11 @@ This is your own one-time link!</source>
<target>Connexion au serveur… (erreur : %@)</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connecting to desktop" xml:space="preserve">
<source>Connecting to desktop</source>
<target>Connexion au bureau</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connection" xml:space="preserve">
<source>Connection</source>
<target>Connexion</target>
@@ -1218,6 +1298,11 @@ This is your own one-time link!</source>
<target>Demande de connexion envoyée !</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connection terminated" xml:space="preserve">
<source>Connection terminated</source>
<target>Connexion terminée</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connection timeout" xml:space="preserve">
<source>Connection timeout</source>
<target>Délai de connexion</target>
@@ -1285,6 +1370,7 @@ This is your own one-time link!</source>
</trans-unit>
<trans-unit id="Correct name to %@?" xml:space="preserve">
<source>Correct name to %@?</source>
<target>Corriger le nom pour %@ ?</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Create" xml:space="preserve">
@@ -1297,6 +1383,11 @@ This is your own one-time link!</source>
<target>Créer une adresse SimpleX</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Create a group using a random profile." xml:space="preserve">
<source>Create a group using a random profile.</source>
<target>Création de groupes via un profil aléatoire.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Create an address to let people connect with you." xml:space="preserve">
<source>Create an address to let people connect with you.</source>
<target>Créez une adresse pour permettre aux gens de vous contacter.</target>
@@ -1309,6 +1400,7 @@ This is your own one-time link!</source>
</trans-unit>
<trans-unit id="Create group" xml:space="preserve">
<source>Create group</source>
<target>Créer un groupe</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Create group link" xml:space="preserve">
@@ -1333,6 +1425,7 @@ This is your own one-time link!</source>
</trans-unit>
<trans-unit id="Create profile" xml:space="preserve">
<source>Create profile</source>
<target>Créer le profil</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Create queue" xml:space="preserve">
@@ -1495,6 +1588,7 @@ This is your own one-time link!</source>
</trans-unit>
<trans-unit id="Delete %lld messages?" xml:space="preserve">
<source>Delete %lld messages?</source>
<target>Supprimer %lld messages ?</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Delete Contact" xml:space="preserve">
@@ -1524,6 +1618,7 @@ This is your own one-time link!</source>
</trans-unit>
<trans-unit id="Delete and notify contact" xml:space="preserve">
<source>Delete and notify contact</source>
<target>Supprimer et en informer le contact</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Delete archive" xml:space="preserve">
@@ -1559,6 +1654,8 @@ This is your own one-time link!</source>
<trans-unit id="Delete contact?&#10;This cannot be undone!" xml:space="preserve">
<source>Delete contact?
This cannot be undone!</source>
<target>Supprimer le contact ?
Cette opération ne peut être annulée !</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Delete database" xml:space="preserve">
@@ -1701,6 +1798,21 @@ This cannot be undone!</source>
<target>Description</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Desktop address" xml:space="preserve">
<source>Desktop address</source>
<target>Adresse de bureau</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Desktop app version %@ is not compatible with this app." xml:space="preserve">
<source>Desktop app version %@ is not compatible with this app.</source>
<target>La version de l'application de bureau %@ n'est pas compatible avec cette application.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Desktop devices" xml:space="preserve">
<source>Desktop devices</source>
<target>Appareils de bureau</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Develop" xml:space="preserve">
<source>Develop</source>
<target>Développer</target>
@@ -1791,11 +1903,21 @@ This cannot be undone!</source>
<target>Se déconnecter</target>
<note>server test step</note>
</trans-unit>
<trans-unit id="Disconnect desktop?" xml:space="preserve">
<source>Disconnect desktop?</source>
<target>Déconnecter le bureau ?</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Discover and join groups" xml:space="preserve">
<source>Discover and join groups</source>
<target>Découvrir et rejoindre des groupes</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Discover via local network" xml:space="preserve">
<source>Discover via local network</source>
<target>Rechercher sur le réseau</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Do NOT use SimpleX for emergency calls." xml:space="preserve">
<source>Do NOT use SimpleX for emergency calls.</source>
<target>N'utilisez PAS SimpleX pour les appels d'urgence.</target>
@@ -1966,6 +2088,16 @@ This cannot be undone!</source>
<target>Message chiffrée: erreur inattendue</target>
<note>notification</note>
</trans-unit>
<trans-unit id="Encryption re-negotiation error" xml:space="preserve">
<source>Encryption re-negotiation error</source>
<target>Erreur lors de la renégociation du chiffrement</target>
<note>message decrypt error item</note>
</trans-unit>
<trans-unit id="Encryption re-negotiation failed." xml:space="preserve">
<source>Encryption re-negotiation failed.</source>
<target>La renégociation du chiffrement a échoué.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Enter Passcode" xml:space="preserve">
<source>Enter Passcode</source>
<target>Entrer le code d'accès</target>
@@ -1978,6 +2110,7 @@ This cannot be undone!</source>
</trans-unit>
<trans-unit id="Enter group name…" xml:space="preserve">
<source>Enter group name…</source>
<target>Entrer un nom de groupe…</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Enter passphrase…" xml:space="preserve">
@@ -1995,6 +2128,11 @@ This cannot be undone!</source>
<target>Entrer un serveur manuellement</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Enter this device name…" xml:space="preserve">
<source>Enter this device name…</source>
<target>Entrez le nom de l'appareil…</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Enter welcome message…" xml:space="preserve">
<source>Enter welcome message…</source>
<target>Entrez un message de bienvenue…</target>
@@ -2007,6 +2145,7 @@ This cannot be undone!</source>
</trans-unit>
<trans-unit id="Enter your name…" xml:space="preserve">
<source>Enter your name…</source>
<target>Entrez votre nom…</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Error" xml:space="preserve">
@@ -2286,6 +2425,7 @@ This cannot be undone!</source>
</trans-unit>
<trans-unit id="Expand" xml:space="preserve">
<source>Expand</source>
<target>Développer</target>
<note>chat item action</note>
</trans-unit>
<trans-unit id="Export database" xml:space="preserve">
@@ -2318,6 +2458,11 @@ This cannot be undone!</source>
<target>Rapide et ne nécessitant pas d'attendre que l'expéditeur soit en ligne !</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Faster joining and more reliable messages." xml:space="preserve">
<source>Faster joining and more reliable messages.</source>
<target>Connexion plus rapide et messages plus fiables.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Favorite" xml:space="preserve">
<source>Favorite</source>
<target>Favoris</target>
@@ -2413,6 +2558,11 @@ This cannot be undone!</source>
<target>Pour la console</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Found desktop" xml:space="preserve">
<source>Found desktop</source>
<target>Bureau trouvé</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="French interface" xml:space="preserve">
<source>French interface</source>
<target>Interface en français</target>
@@ -2435,6 +2585,7 @@ This cannot be undone!</source>
</trans-unit>
<trans-unit id="Fully decentralized visible only to members." xml:space="preserve">
<source>Fully decentralized visible only to members.</source>
<target>Entièrement décentralisé visible que par ses membres.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Fully re-implemented - work in background!" xml:space="preserve">
@@ -2459,10 +2610,12 @@ This cannot be undone!</source>
</trans-unit>
<trans-unit id="Group already exists" xml:space="preserve">
<source>Group already exists</source>
<target>Le groupe existe déjà</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Group already exists!" xml:space="preserve">
<source>Group already exists!</source>
<target>Ce groupe existe déjà !</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Group display name" xml:space="preserve">
@@ -2735,6 +2888,11 @@ This cannot be undone!</source>
<target>Incognito</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Incognito groups" xml:space="preserve">
<source>Incognito groups</source>
<target>Groupes incognito</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Incognito mode" xml:space="preserve">
<source>Incognito mode</source>
<target>Mode Incognito</target>
@@ -2765,6 +2923,11 @@ This cannot be undone!</source>
<target>Version de la base de données incompatible</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Incompatible version" xml:space="preserve">
<source>Incompatible version</source>
<target>Version incompatible</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Incorrect passcode" xml:space="preserve">
<source>Incorrect passcode</source>
<target>Code d'accès erroné</target>
@@ -2814,6 +2977,7 @@ This cannot be undone!</source>
</trans-unit>
<trans-unit id="Invalid name!" xml:space="preserve">
<source>Invalid name!</source>
<target>Nom invalide !</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Invalid server address!" xml:space="preserve">
@@ -2909,6 +3073,7 @@ This cannot be undone!</source>
</trans-unit>
<trans-unit id="Join group?" xml:space="preserve">
<source>Join group?</source>
<target>Rejoindre le groupe ?</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Join incognito" xml:space="preserve">
@@ -2918,11 +3083,14 @@ This cannot be undone!</source>
</trans-unit>
<trans-unit id="Join with current profile" xml:space="preserve">
<source>Join with current profile</source>
<target>Rejoindre avec le profil actuel</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Join your group?&#10;This is your link for group %@!" xml:space="preserve">
<source>Join your group?
This is your link for group %@!</source>
<target>Rejoindre votre groupe ?
Voici votre lien pour le groupe %@ !</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Joining group" xml:space="preserve">
@@ -2930,6 +3098,11 @@ This is your link for group %@!</source>
<target>Entrain de rejoindre le groupe</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Keep the app open to use it from desktop" xml:space="preserve">
<source>Keep the app open to use it from desktop</source>
<target>Garder l'application ouverte pour l'utiliser depuis le bureau</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Keep your connections" xml:space="preserve">
<source>Keep your connections</source>
<target>Conserver vos connexions</target>
@@ -2990,6 +3163,21 @@ This is your link for group %@!</source>
<target>Limitations</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Link mobile and desktop apps! 🔗" xml:space="preserve">
<source>Link mobile and desktop apps! 🔗</source>
<target>Liez vos applications mobiles et de bureau ! 🔗</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Linked desktop options" xml:space="preserve">
<source>Linked desktop options</source>
<target>Options de bureau lié</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Linked desktops" xml:space="preserve">
<source>Linked desktops</source>
<target>Bureaux liés</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Live message!" xml:space="preserve">
<source>Live message!</source>
<target>Message dynamique !</target>
@@ -3142,6 +3330,7 @@ This is your link for group %@!</source>
</trans-unit>
<trans-unit id="Messages from %@ will be shown!" xml:space="preserve">
<source>Messages from %@ will be shown!</source>
<target>Les messages de %@ seront affichés !</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Migrating database archive…" xml:space="preserve">
@@ -3339,6 +3528,11 @@ This is your link for group %@!</source>
<target>Aucun fichier reçu ou envoyé</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Not compatible!" xml:space="preserve">
<source>Not compatible!</source>
<target>Non compatible !</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Notifications" xml:space="preserve">
<source>Notifications</source>
<target>Notifications</target>
@@ -3495,6 +3689,7 @@ This is your link for group %@!</source>
</trans-unit>
<trans-unit id="Open group" xml:space="preserve">
<source>Open group</source>
<target>Ouvrir le groupe</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Open user profiles" xml:space="preserve">
@@ -3557,6 +3752,11 @@ This is your link for group %@!</source>
<target>Coller</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Paste desktop address" xml:space="preserve">
<source>Paste desktop address</source>
<target>Coller l'adresse du bureau</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Paste image" xml:space="preserve">
<source>Paste image</source>
<target>Coller l'image</target>
@@ -3704,10 +3904,12 @@ This is your link for group %@!</source>
</trans-unit>
<trans-unit id="Profile name" xml:space="preserve">
<source>Profile name</source>
<target>Nom du profil</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Profile name:" xml:space="preserve">
<source>Profile name:</source>
<target>Nom du profil :</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Profile password" xml:space="preserve">
@@ -3957,10 +4159,12 @@ This is your link for group %@!</source>
</trans-unit>
<trans-unit id="Repeat connection request?" xml:space="preserve">
<source>Repeat connection request?</source>
<target>Répéter la demande de connexion ?</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Repeat join request?" xml:space="preserve">
<source>Repeat join request?</source>
<target>Répéter la requête d'adhésion ?</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Reply" xml:space="preserve">
@@ -4148,6 +4352,11 @@ This is your link for group %@!</source>
<target>Scanner un code QR</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Scan QR code from desktop" xml:space="preserve">
<source>Scan QR code from desktop</source>
<target>Scanner le code QR du bureau</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Scan code" xml:space="preserve">
<source>Scan code</source>
<target>Scanner le code</target>
@@ -4368,6 +4577,11 @@ This is your link for group %@!</source>
<target>Serveurs</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Session code" xml:space="preserve">
<source>Session code</source>
<target>Code de session</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Set 1 day" xml:space="preserve">
<source>Set 1 day</source>
<target>Définir 1 jour</target>
@@ -4680,6 +4894,7 @@ This is your link for group %@!</source>
</trans-unit>
<trans-unit id="Tap to Connect" xml:space="preserve">
<source>Tap to Connect</source>
<target>Tapez pour vous connecter</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Tap to activate profile." xml:space="preserve">
@@ -4864,6 +5079,11 @@ Cela peut se produire en raison d'un bug ou lorsque la connexion est compromise.
<target>Cette action ne peut être annulée - votre profil, vos contacts, vos messages et vos fichiers seront irréversiblement perdus.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="This device name" xml:space="preserve">
<source>This device name</source>
<target>Ce nom d'appareil</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="This group has over %lld members, delivery receipts are not sent." xml:space="preserve">
<source>This group has over %lld members, delivery receipts are not sent.</source>
<target>Ce groupe compte plus de %lld membres, les accusés de réception ne sont pas envoyés.</target>
@@ -4876,10 +5096,12 @@ Cela peut se produire en raison d'un bug ou lorsque la connexion est compromise.
</trans-unit>
<trans-unit id="This is your own SimpleX address!" xml:space="preserve">
<source>This is your own SimpleX address!</source>
<target>Voici votre propre adresse SimpleX !</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="This is your own one-time link!" xml:space="preserve">
<source>This is your own one-time link!</source>
<target>Voici votre propre lien unique !</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="This setting applies to messages in your current chat profile **%@**." xml:space="preserve">
@@ -4897,6 +5119,11 @@ Cela peut se produire en raison d'un bug ou lorsque la connexion est compromise.
<target>Pour se connecter, votre contact peut scanner le code QR ou utiliser le lien dans l'application.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="To hide unwanted messages." xml:space="preserve">
<source>To hide unwanted messages.</source>
<target>Pour cacher les messages indésirables.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="To make a new connection" xml:space="preserve">
<source>To make a new connection</source>
<target>Pour établir une nouvelle connexion</target>
@@ -4981,14 +5208,17 @@ Vous serez invité à confirmer l'authentification avant que cette fonction ne s
</trans-unit>
<trans-unit id="Unblock" xml:space="preserve">
<source>Unblock</source>
<target>Débloquer</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Unblock member" xml:space="preserve">
<source>Unblock member</source>
<target>Débloquer ce membre</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Unblock member?" xml:space="preserve">
<source>Unblock member?</source>
<target>Débloquer ce membre ?</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Unexpected error: %@" xml:space="preserve">
@@ -5053,6 +5283,16 @@ To connect, please ask your contact to create another connection link and check
Pour vous connecter, veuillez demander à votre contact de créer un autre lien de connexion et vérifiez que vous disposez d'une connexion réseau stable.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Unlink" xml:space="preserve">
<source>Unlink</source>
<target>Délier</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Unlink desktop?" xml:space="preserve">
<source>Unlink desktop?</source>
<target>Délier le bureau ?</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Unlock" xml:space="preserve">
<source>Unlock</source>
<target>Déverrouiller</target>
@@ -5143,6 +5383,11 @@ Pour vous connecter, veuillez demander à votre contact de créer un autre lien
<target>Utiliser pour les nouvelles connexions</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Use from desktop" xml:space="preserve">
<source>Use from desktop</source>
<target>Utilisation depuis le bureau</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Use iOS call interface" xml:space="preserve">
<source>Use iOS call interface</source>
<target>Utiliser l'interface d'appel d'iOS</target>
@@ -5173,11 +5418,26 @@ Pour vous connecter, veuillez demander à votre contact de créer un autre lien
<target>Utilisation des serveurs SimpleX Chat.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Verify code with desktop" xml:space="preserve">
<source>Verify code with desktop</source>
<target>Vérifier le code avec le bureau</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Verify connection" xml:space="preserve">
<source>Verify connection</source>
<target>Vérifier la connexion</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Verify connection security" xml:space="preserve">
<source>Verify connection security</source>
<target>Vérifier la sécurité de la connexion</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Verify connections" xml:space="preserve">
<source>Verify connections</source>
<target>Vérifier les connexions</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Verify security code" xml:space="preserve">
<source>Verify security code</source>
<target>Vérifier le code de sécurité</target>
@@ -5188,6 +5448,11 @@ Pour vous connecter, veuillez demander à votre contact de créer un autre lien
<target>Via navigateur</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Via secure quantum resistant protocol." xml:space="preserve">
<source>Via secure quantum resistant protocol.</source>
<target>Via un protocole sécurisé de cryptographie post-quantique.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Video call" xml:space="preserve">
<source>Video call</source>
<target>Appel vidéo</target>
@@ -5238,6 +5503,11 @@ Pour vous connecter, veuillez demander à votre contact de créer un autre lien
<target>Message vocal…</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Waiting for desktop..." xml:space="preserve">
<source>Waiting for desktop...</source>
<target>En attente du bureau...</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Waiting for file" xml:space="preserve">
<source>Waiting for file</source>
<target>En attente du fichier</target>
@@ -5340,31 +5610,39 @@ Pour vous connecter, veuillez demander à votre contact de créer un autre lien
</trans-unit>
<trans-unit id="You are already connecting to %@." xml:space="preserve">
<source>You are already connecting to %@.</source>
<target>Vous êtes déjà en train de vous connecter à %@.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="You are already connecting via this one-time link!" xml:space="preserve">
<source>You are already connecting via this one-time link!</source>
<target>Vous êtes déjà connecté(e) via ce lien unique !</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="You are already in group %@." xml:space="preserve">
<source>You are already in group %@.</source>
<target>Vous êtes déjà dans le groupe %@.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="You are already joining the group %@." xml:space="preserve">
<source>You are already joining the group %@.</source>
<target>Vous êtes déjà en train de rejoindre le groupe %@.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="You are already joining the group via this link!" xml:space="preserve">
<source>You are already joining the group via this link!</source>
<target>Vous êtes déjà en train de rejoindre le groupe via ce lien !</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="You are already joining the group via this link." xml:space="preserve">
<source>You are already joining the group via this link.</source>
<target>Vous êtes déjà en train de rejoindre le groupe via ce lien.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="You are already joining the group!&#10;Repeat join request?" xml:space="preserve">
<source>You are already joining the group!
Repeat join request?</source>
<target>Vous êtes déjà membre de ce groupe !
Répéter la demande d'adhésion ?</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="You are connected to the server used to receive messages from this contact." xml:space="preserve">
@@ -5464,11 +5742,14 @@ Repeat join request?</source>
</trans-unit>
<trans-unit id="You have already requested connection via this address!" xml:space="preserve">
<source>You have already requested connection via this address!</source>
<target>Vous avez déjà demandé une connexion via cette adresse !</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="You have already requested connection!&#10;Repeat connection request?" xml:space="preserve">
<source>You have already requested connection!
Repeat connection request?</source>
<target>Vous avez déjà demandé une connexion !
Répéter la demande de connexion ?</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="You have no chats" xml:space="preserve">
@@ -5523,6 +5804,7 @@ Repeat connection request?</source>
</trans-unit>
<trans-unit id="You will be connected when group link host's device is online, please wait or check later!" xml:space="preserve">
<source>You will be connected when group link host's device is online, please wait or check later!</source>
<target>Vous serez connecté(e) lorsque l'appareil de l'hôte du lien de groupe sera en ligne, veuillez patienter ou vérifier plus tard !</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="You will be connected when your connection request is accepted, please wait or check later!" xml:space="preserve">
@@ -5542,6 +5824,7 @@ Repeat connection request?</source>
</trans-unit>
<trans-unit id="You will connect to all group members." xml:space="preserve">
<source>You will connect to all group members.</source>
<target>Vous vous connecterez à tous les membres du groupe.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="You will still receive calls and notifications from muted profiles when they are active." xml:space="preserve">
@@ -5665,6 +5948,7 @@ Vous pouvez modifier ce choix dans les Paramètres.</target>
</trans-unit>
<trans-unit id="Your profile" xml:space="preserve">
<source>Your profile</source>
<target>Votre profil</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Your profile **%@** will be shared." xml:space="preserve">
@@ -5761,6 +6045,7 @@ Les serveurs SimpleX ne peuvent pas voir votre profil.</target>
</trans-unit>
<trans-unit id="and %lld other events" xml:space="preserve">
<source>and %lld other events</source>
<target>et %lld autres événements</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="audio call (not e2e encrypted)" xml:space="preserve">
@@ -5768,6 +6053,11 @@ Les serveurs SimpleX ne peuvent pas voir votre profil.</target>
<target>appel audio (sans chiffrement)</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="author" xml:space="preserve">
<source>author</source>
<target>auteur</target>
<note>member role</note>
</trans-unit>
<trans-unit id="bad message ID" xml:space="preserve">
<source>bad message ID</source>
<target>ID de message incorrecte</target>
@@ -5780,6 +6070,7 @@ Les serveurs SimpleX ne peuvent pas voir votre profil.</target>
</trans-unit>
<trans-unit id="blocked" xml:space="preserve">
<source>blocked</source>
<target>blocké</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="bold" xml:space="preserve">
@@ -5954,6 +6245,7 @@ Les serveurs SimpleX ne peuvent pas voir votre profil.</target>
</trans-unit>
<trans-unit id="deleted contact" xml:space="preserve">
<source>deleted contact</source>
<target>contact supprimé</target>
<note>rcv direct event chat item</note>
</trans-unit>
<trans-unit id="deleted group" xml:space="preserve">
@@ -6348,6 +6640,11 @@ Les serveurs SimpleX ne peuvent pas voir votre profil.</target>
<target>mise à jour du profil de groupe</target>
<note>rcv group event chat item</note>
</trans-unit>
<trans-unit id="v%@" xml:space="preserve">
<source>v%@</source>
<target>v%@</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="v%@ (%@)" xml:space="preserve">
<source>v%@ (%@)</source>
<target>v%@ (%@)</target>
@@ -6485,6 +6782,11 @@ Les serveurs SimpleX ne peuvent pas voir votre profil.</target>
<target>SimpleGroup not found!X utilise Face ID pour l'authentification locale</target>
<note>Privacy - Face ID Usage Description</note>
</trans-unit>
<trans-unit id="NSLocalNetworkUsageDescription" xml:space="preserve">
<source>SimpleX uses local network access to allow using user chat profile via desktop app on the same network.</source>
<target>SimpleX utilise un accès au réseau local pour permettre l'utilisation du profil de chat de l'utilisateur via l'application de bureau au sein de ce même réseau.</target>
<note>Privacy - Local Network Usage Description</note>
</trans-unit>
<trans-unit id="NSMicrophoneUsageDescription" xml:space="preserve">
<source>SimpleX needs microphone access for audio and video calls, and to record voice messages.</source>
<target>SimpleX a besoin d'un accès au microphone pour les appels audio et vidéo ainsi que pour enregistrer des messages vocaux.</target>

View File

@@ -4,6 +4,8 @@
"NSCameraUsageDescription" = "SimpleX needs camera access to scan QR codes to connect to other users and for video calls.";
/* Privacy - Face ID Usage Description */
"NSFaceIDUsageDescription" = "SimpleX uses Face ID for local authentication";
/* Privacy - Local Network Usage Description */
"NSLocalNetworkUsageDescription" = "SimpleX uses local network access to allow using user chat profile via desktop app on the same network.";
/* Privacy - Microphone Usage Description */
"NSMicrophoneUsageDescription" = "SimpleX needs microphone access for audio and video calls, and to record voice messages.";
/* Privacy - Photo Library Additions Usage Description */

View File

@@ -89,6 +89,7 @@
</trans-unit>
<trans-unit id="%@ and %@" xml:space="preserve">
<source>%@ and %@</source>
<target>%@ e %@</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="%@ and %@ connected" xml:space="preserve">
@@ -103,6 +104,7 @@
</trans-unit>
<trans-unit id="%@ connected" xml:space="preserve">
<source>%@ connected</source>
<target>%@ si è connesso/a</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="%@ is connected!" xml:space="preserve">
@@ -132,6 +134,7 @@
</trans-unit>
<trans-unit id="%@, %@ and %lld members" xml:space="preserve">
<source>%@, %@ and %lld members</source>
<target>%@, %@ e %lld membri</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="%@, %@ and %lld other members connected" xml:space="preserve">
@@ -201,6 +204,7 @@
</trans-unit>
<trans-unit id="%lld group events" xml:space="preserve">
<source>%lld group events</source>
<target>%lld eventi del gruppo</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="%lld members" xml:space="preserve">
@@ -210,14 +214,17 @@
</trans-unit>
<trans-unit id="%lld messages blocked" xml:space="preserve">
<source>%lld messages blocked</source>
<target>%lld messaggi bloccati</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="%lld messages marked deleted" xml:space="preserve">
<source>%lld messages marked deleted</source>
<target>%lld messaggi contrassegnati eliminati</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="%lld messages moderated by %@" xml:space="preserve">
<source>%lld messages moderated by %@</source>
<target>%lld messaggi moderati da %@</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="%lld minutes" xml:space="preserve">
@@ -290,6 +297,16 @@
<target>(</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="(new)" xml:space="preserve">
<source>(new)</source>
<target>(nuovo)</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="(this device v%@)" xml:space="preserve">
<source>(this device v%@)</source>
<target>(questo dispositivo v%@)</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id=")" xml:space="preserve">
<source>)</source>
<target>)</target>
@@ -378,6 +395,15 @@
- e altro ancora!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="- optionally notify deleted contacts.&#10;- profile names with spaces.&#10;- and more!" xml:space="preserve">
<source>- optionally notify deleted contacts.
- profile names with spaces.
- and more!</source>
<target>- avvisa facoltativamente i contatti eliminati.
- nomi del profilo con spazi.
- e molto altro!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="- voice messages up to 5 minutes.&#10;- custom time to disappear.&#10;- editing history." xml:space="preserve">
<source>- voice messages up to 5 minutes.
- custom time to disappear.
@@ -394,6 +420,7 @@
</trans-unit>
<trans-unit id="0 sec" xml:space="preserve">
<source>0 sec</source>
<target>0 sec</target>
<note>time to disappear</note>
</trans-unit>
<trans-unit id="0s" xml:space="preserve">
@@ -623,6 +650,7 @@
</trans-unit>
<trans-unit id="All new messages from %@ will be hidden!" xml:space="preserve">
<source>All new messages from %@ will be hidden!</source>
<target>Tutti i nuovi messaggi da %@ verrranno nascosti!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="All your contacts will remain connected." xml:space="preserve">
@@ -732,10 +760,12 @@
</trans-unit>
<trans-unit id="Already connecting!" xml:space="preserve">
<source>Already connecting!</source>
<target>Già in connessione!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Already joining the group!" xml:space="preserve">
<source>Already joining the group!</source>
<target>Già in ingresso nel gruppo!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Always use relay" xml:space="preserve">
@@ -858,6 +888,11 @@
<target>Indietro</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Bad desktop address" xml:space="preserve">
<source>Bad desktop address</source>
<target>Indirizzo desktop errato</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Bad message ID" xml:space="preserve">
<source>Bad message ID</source>
<target>ID del messaggio errato</target>
@@ -868,6 +903,11 @@
<target>Hash del messaggio errato</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Better groups" xml:space="preserve">
<source>Better groups</source>
<target>Gruppi migliorati</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Better messages" xml:space="preserve">
<source>Better messages</source>
<target>Messaggi migliorati</target>
@@ -875,14 +915,22 @@
</trans-unit>
<trans-unit id="Block" xml:space="preserve">
<source>Block</source>
<target>Blocca</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Block group members" xml:space="preserve">
<source>Block group members</source>
<target>Blocca i membri dei gruppi</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Block member" xml:space="preserve">
<source>Block member</source>
<target>Blocca membro</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Block member?" xml:space="preserve">
<source>Block member?</source>
<target>Bloccare il membro?</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Both you and your contact can add message reactions." xml:space="preserve">
@@ -1146,27 +1194,42 @@
<target>Connetti</target>
<note>server test step</note>
</trans-unit>
<trans-unit id="Connect automatically" xml:space="preserve">
<source>Connect automatically</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connect incognito" xml:space="preserve">
<source>Connect incognito</source>
<target>Connetti in incognito</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connect to desktop" xml:space="preserve">
<source>Connect to desktop</source>
<target>Connetti al desktop</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connect to yourself?" xml:space="preserve">
<source>Connect to yourself?</source>
<target>Connettersi a te stesso?</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connect to yourself?&#10;This is your own SimpleX address!" xml:space="preserve">
<source>Connect to yourself?
This is your own SimpleX address!</source>
<target>Connettersi a te stesso?
Questo è il tuo indirizzo SimpleX!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connect to yourself?&#10;This is your own one-time link!" xml:space="preserve">
<source>Connect to yourself?
This is your own one-time link!</source>
<target>Connettersi a te stesso?
Questo è il tuo link una tantum!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connect via contact address" xml:space="preserve">
<source>Connect via contact address</source>
<target>Connettere via indirizzo del contatto</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connect via link" xml:space="preserve">
@@ -1186,6 +1249,17 @@ This is your own one-time link!</source>
</trans-unit>
<trans-unit id="Connect with %@" xml:space="preserve">
<source>Connect with %@</source>
<target>Connettersi con %@</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connected desktop" xml:space="preserve">
<source>Connected desktop</source>
<target>Desktop connesso</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connected to desktop" xml:space="preserve">
<source>Connected to desktop</source>
<target>Connesso al desktop</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connecting server…" xml:space="preserve">
@@ -1198,6 +1272,11 @@ This is your own one-time link!</source>
<target>Connessione al server… (errore: %@)</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connecting to desktop" xml:space="preserve">
<source>Connecting to desktop</source>
<target>Connessione al desktop</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connection" xml:space="preserve">
<source>Connection</source>
<target>Connessione</target>
@@ -1218,6 +1297,11 @@ This is your own one-time link!</source>
<target>Richiesta di connessione inviata!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connection terminated" xml:space="preserve">
<source>Connection terminated</source>
<target>Connessione terminata</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connection timeout" xml:space="preserve">
<source>Connection timeout</source>
<target>Connessione scaduta</target>
@@ -1285,6 +1369,7 @@ This is your own one-time link!</source>
</trans-unit>
<trans-unit id="Correct name to %@?" xml:space="preserve">
<source>Correct name to %@?</source>
<target>Correggere il nome a %@?</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Create" xml:space="preserve">
@@ -1297,6 +1382,11 @@ This is your own one-time link!</source>
<target>Crea indirizzo SimpleX</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Create a group using a random profile." xml:space="preserve">
<source>Create a group using a random profile.</source>
<target>Crea un gruppo usando un profilo casuale.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Create an address to let people connect with you." xml:space="preserve">
<source>Create an address to let people connect with you.</source>
<target>Crea un indirizzo per consentire alle persone di connettersi con te.</target>
@@ -1309,6 +1399,7 @@ This is your own one-time link!</source>
</trans-unit>
<trans-unit id="Create group" xml:space="preserve">
<source>Create group</source>
<target>Crea gruppo</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Create group link" xml:space="preserve">
@@ -1333,6 +1424,7 @@ This is your own one-time link!</source>
</trans-unit>
<trans-unit id="Create profile" xml:space="preserve">
<source>Create profile</source>
<target>Crea profilo</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Create queue" xml:space="preserve">
@@ -1495,6 +1587,7 @@ This is your own one-time link!</source>
</trans-unit>
<trans-unit id="Delete %lld messages?" xml:space="preserve">
<source>Delete %lld messages?</source>
<target>Eliminare %lld messaggi?</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Delete Contact" xml:space="preserve">
@@ -1524,6 +1617,7 @@ This is your own one-time link!</source>
</trans-unit>
<trans-unit id="Delete and notify contact" xml:space="preserve">
<source>Delete and notify contact</source>
<target>Elimina e avvisa il contatto</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Delete archive" xml:space="preserve">
@@ -1559,6 +1653,8 @@ This is your own one-time link!</source>
<trans-unit id="Delete contact?&#10;This cannot be undone!" xml:space="preserve">
<source>Delete contact?
This cannot be undone!</source>
<target>Eliminare il contatto?
Non è reversibile!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Delete database" xml:space="preserve">
@@ -1701,6 +1797,21 @@ This cannot be undone!</source>
<target>Descrizione</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Desktop address" xml:space="preserve">
<source>Desktop address</source>
<target>Indirizzo desktop</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Desktop app version %@ is not compatible with this app." xml:space="preserve">
<source>Desktop app version %@ is not compatible with this app.</source>
<target>La versione dell'app desktop %@ non è compatibile con questa app.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Desktop devices" xml:space="preserve">
<source>Desktop devices</source>
<target>Dispositivi desktop</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Develop" xml:space="preserve">
<source>Develop</source>
<target>Sviluppa</target>
@@ -1791,11 +1902,20 @@ This cannot be undone!</source>
<target>Disconnetti</target>
<note>server test step</note>
</trans-unit>
<trans-unit id="Disconnect desktop?" xml:space="preserve">
<source>Disconnect desktop?</source>
<target>Disconnettere il desktop?</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Discover and join groups" xml:space="preserve">
<source>Discover and join groups</source>
<target>Scopri ed unisciti ai gruppi</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Discover via local network" xml:space="preserve">
<source>Discover via local network</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Do NOT use SimpleX for emergency calls." xml:space="preserve">
<source>Do NOT use SimpleX for emergency calls.</source>
<target>NON usare SimpleX per chiamate di emergenza.</target>
@@ -1966,6 +2086,16 @@ This cannot be undone!</source>
<target>Messaggio crittografato: errore imprevisto</target>
<note>notification</note>
</trans-unit>
<trans-unit id="Encryption re-negotiation error" xml:space="preserve">
<source>Encryption re-negotiation error</source>
<target>Errore di rinegoziazione crittografia</target>
<note>message decrypt error item</note>
</trans-unit>
<trans-unit id="Encryption re-negotiation failed." xml:space="preserve">
<source>Encryption re-negotiation failed.</source>
<target>Rinegoziazione crittografia fallita.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Enter Passcode" xml:space="preserve">
<source>Enter Passcode</source>
<target>Inserisci il codice di accesso</target>
@@ -1978,6 +2108,7 @@ This cannot be undone!</source>
</trans-unit>
<trans-unit id="Enter group name…" xml:space="preserve">
<source>Enter group name…</source>
<target>Inserisci il nome del gruppo…</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Enter passphrase…" xml:space="preserve">
@@ -1995,6 +2126,11 @@ This cannot be undone!</source>
<target>Inserisci il server a mano</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Enter this device name…" xml:space="preserve">
<source>Enter this device name…</source>
<target>Inserisci il nome di questo dispositivo…</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Enter welcome message…" xml:space="preserve">
<source>Enter welcome message…</source>
<target>Inserisci il messaggio di benvenuto…</target>
@@ -2007,6 +2143,7 @@ This cannot be undone!</source>
</trans-unit>
<trans-unit id="Enter your name…" xml:space="preserve">
<source>Enter your name…</source>
<target>Inserisci il tuo nome…</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Error" xml:space="preserve">
@@ -2286,6 +2423,7 @@ This cannot be undone!</source>
</trans-unit>
<trans-unit id="Expand" xml:space="preserve">
<source>Expand</source>
<target>Espandi</target>
<note>chat item action</note>
</trans-unit>
<trans-unit id="Export database" xml:space="preserve">
@@ -2318,6 +2456,11 @@ This cannot be undone!</source>
<target>Veloce e senza aspettare che il mittente sia in linea!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Faster joining and more reliable messages." xml:space="preserve">
<source>Faster joining and more reliable messages.</source>
<target>Ingresso più veloce e messaggi più affidabili.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Favorite" xml:space="preserve">
<source>Favorite</source>
<target>Preferito</target>
@@ -2413,6 +2556,10 @@ This cannot be undone!</source>
<target>Per console</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Found desktop" xml:space="preserve">
<source>Found desktop</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="French interface" xml:space="preserve">
<source>French interface</source>
<target>Interfaccia francese</target>
@@ -2435,6 +2582,7 @@ This cannot be undone!</source>
</trans-unit>
<trans-unit id="Fully decentralized visible only to members." xml:space="preserve">
<source>Fully decentralized visible only to members.</source>
<target>Completamente decentralizzato: visibile solo ai membri.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Fully re-implemented - work in background!" xml:space="preserve">
@@ -2459,10 +2607,12 @@ This cannot be undone!</source>
</trans-unit>
<trans-unit id="Group already exists" xml:space="preserve">
<source>Group already exists</source>
<target>Il gruppo esiste già</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Group already exists!" xml:space="preserve">
<source>Group already exists!</source>
<target>Il gruppo esiste già!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Group display name" xml:space="preserve">
@@ -2735,6 +2885,11 @@ This cannot be undone!</source>
<target>Incognito</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Incognito groups" xml:space="preserve">
<source>Incognito groups</source>
<target>Gruppi in incognito</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Incognito mode" xml:space="preserve">
<source>Incognito mode</source>
<target>Modalità incognito</target>
@@ -2765,6 +2920,11 @@ This cannot be undone!</source>
<target>Versione del database incompatibile</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Incompatible version" xml:space="preserve">
<source>Incompatible version</source>
<target>Versione incompatibile</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Incorrect passcode" xml:space="preserve">
<source>Incorrect passcode</source>
<target>Codice di accesso errato</target>
@@ -2814,6 +2974,7 @@ This cannot be undone!</source>
</trans-unit>
<trans-unit id="Invalid name!" xml:space="preserve">
<source>Invalid name!</source>
<target>Nome non valido!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Invalid server address!" xml:space="preserve">
@@ -2909,6 +3070,7 @@ This cannot be undone!</source>
</trans-unit>
<trans-unit id="Join group?" xml:space="preserve">
<source>Join group?</source>
<target>Entrare nel gruppo?</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Join incognito" xml:space="preserve">
@@ -2918,11 +3080,14 @@ This cannot be undone!</source>
</trans-unit>
<trans-unit id="Join with current profile" xml:space="preserve">
<source>Join with current profile</source>
<target>Entra con il profilo attuale</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Join your group?&#10;This is your link for group %@!" xml:space="preserve">
<source>Join your group?
This is your link for group %@!</source>
<target>Entrare nel tuo gruppo?
Questo è il tuo link per il gruppo %@!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Joining group" xml:space="preserve">
@@ -2930,6 +3095,11 @@ This is your link for group %@!</source>
<target>Ingresso nel gruppo</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Keep the app open to use it from desktop" xml:space="preserve">
<source>Keep the app open to use it from desktop</source>
<target>Tieni aperta l'app per usarla dal desktop</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Keep your connections" xml:space="preserve">
<source>Keep your connections</source>
<target>Mantieni le tue connessioni</target>
@@ -2990,6 +3160,21 @@ This is your link for group %@!</source>
<target>Limitazioni</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Link mobile and desktop apps! 🔗" xml:space="preserve">
<source>Link mobile and desktop apps! 🔗</source>
<target>Collega le app mobile e desktop! 🔗</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Linked desktop options" xml:space="preserve">
<source>Linked desktop options</source>
<target>Opzioni del desktop collegato</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Linked desktops" xml:space="preserve">
<source>Linked desktops</source>
<target>Desktop collegati</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Live message!" xml:space="preserve">
<source>Live message!</source>
<target>Messaggio in diretta!</target>
@@ -3142,6 +3327,7 @@ This is your link for group %@!</source>
</trans-unit>
<trans-unit id="Messages from %@ will be shown!" xml:space="preserve">
<source>Messages from %@ will be shown!</source>
<target>I messaggi da %@ verranno mostrati!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Migrating database archive…" xml:space="preserve">
@@ -3339,6 +3525,10 @@ This is your link for group %@!</source>
<target>Nessun file ricevuto o inviato</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Not compatible!" xml:space="preserve">
<source>Not compatible!</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Notifications" xml:space="preserve">
<source>Notifications</source>
<target>Notifiche</target>
@@ -3495,6 +3685,7 @@ This is your link for group %@!</source>
</trans-unit>
<trans-unit id="Open group" xml:space="preserve">
<source>Open group</source>
<target>Apri gruppo</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Open user profiles" xml:space="preserve">
@@ -3557,6 +3748,11 @@ This is your link for group %@!</source>
<target>Incolla</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Paste desktop address" xml:space="preserve">
<source>Paste desktop address</source>
<target>Incolla l'indirizzo desktop</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Paste image" xml:space="preserve">
<source>Paste image</source>
<target>Incolla immagine</target>
@@ -3704,10 +3900,12 @@ This is your link for group %@!</source>
</trans-unit>
<trans-unit id="Profile name" xml:space="preserve">
<source>Profile name</source>
<target>Nome del profilo</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Profile name:" xml:space="preserve">
<source>Profile name:</source>
<target>Nome del profilo:</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Profile password" xml:space="preserve">
@@ -3957,10 +4155,12 @@ This is your link for group %@!</source>
</trans-unit>
<trans-unit id="Repeat connection request?" xml:space="preserve">
<source>Repeat connection request?</source>
<target>Ripetere la richiesta di connessione?</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Repeat join request?" xml:space="preserve">
<source>Repeat join request?</source>
<target>Ripetere la richiesta di ingresso?</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Reply" xml:space="preserve">
@@ -4148,6 +4348,11 @@ This is your link for group %@!</source>
<target>Scansiona codice QR</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Scan QR code from desktop" xml:space="preserve">
<source>Scan QR code from desktop</source>
<target>Scansiona codice QR dal desktop</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Scan code" xml:space="preserve">
<source>Scan code</source>
<target>Scansiona codice</target>
@@ -4368,6 +4573,11 @@ This is your link for group %@!</source>
<target>Server</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Session code" xml:space="preserve">
<source>Session code</source>
<target>Codice di sessione</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Set 1 day" xml:space="preserve">
<source>Set 1 day</source>
<target>Imposta 1 giorno</target>
@@ -4680,6 +4890,7 @@ This is your link for group %@!</source>
</trans-unit>
<trans-unit id="Tap to Connect" xml:space="preserve">
<source>Tap to Connect</source>
<target>Tocca per connettere</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Tap to activate profile." xml:space="preserve">
@@ -4864,6 +5075,11 @@ Può accadere a causa di qualche bug o quando la connessione è compromessa.</ta
<target>Questa azione non può essere annullata: il tuo profilo, i contatti, i messaggi e i file andranno persi in modo irreversibile.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="This device name" xml:space="preserve">
<source>This device name</source>
<target>Il nome di questo dispositivo</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="This group has over %lld members, delivery receipts are not sent." xml:space="preserve">
<source>This group has over %lld members, delivery receipts are not sent.</source>
<target>Questo gruppo ha più di %lld membri, le ricevute di consegna non vengono inviate.</target>
@@ -4876,10 +5092,12 @@ Può accadere a causa di qualche bug o quando la connessione è compromessa.</ta
</trans-unit>
<trans-unit id="This is your own SimpleX address!" xml:space="preserve">
<source>This is your own SimpleX address!</source>
<target>Questo è il tuo indirizzo SimpleX!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="This is your own one-time link!" xml:space="preserve">
<source>This is your own one-time link!</source>
<target>Questo è il tuo link una tantum!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="This setting applies to messages in your current chat profile **%@**." xml:space="preserve">
@@ -4897,6 +5115,11 @@ Può accadere a causa di qualche bug o quando la connessione è compromessa.</ta
<target>Per connettervi, il tuo contatto può scansionare il codice QR o usare il link nell'app.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="To hide unwanted messages." xml:space="preserve">
<source>To hide unwanted messages.</source>
<target>Per nascondere messaggi indesiderati.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="To make a new connection" xml:space="preserve">
<source>To make a new connection</source>
<target>Per creare una nuova connessione</target>
@@ -4981,14 +5204,17 @@ Ti verrà chiesto di completare l'autenticazione prima di attivare questa funzio
</trans-unit>
<trans-unit id="Unblock" xml:space="preserve">
<source>Unblock</source>
<target>Sblocca</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Unblock member" xml:space="preserve">
<source>Unblock member</source>
<target>Sblocca membro</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Unblock member?" xml:space="preserve">
<source>Unblock member?</source>
<target>Sbloccare il membro?</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Unexpected error: %@" xml:space="preserve">
@@ -5053,6 +5279,16 @@ To connect, please ask your contact to create another connection link and check
Per connetterti, chiedi al tuo contatto di creare un altro link di connessione e controlla di avere una connessione di rete stabile.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Unlink" xml:space="preserve">
<source>Unlink</source>
<target>Scollega</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Unlink desktop?" xml:space="preserve">
<source>Unlink desktop?</source>
<target>Scollegare il desktop?</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Unlock" xml:space="preserve">
<source>Unlock</source>
<target>Sblocca</target>
@@ -5143,6 +5379,11 @@ Per connetterti, chiedi al tuo contatto di creare un altro link di connessione e
<target>Usa per connessioni nuove</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Use from desktop" xml:space="preserve">
<source>Use from desktop</source>
<target>Usa dal desktop</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Use iOS call interface" xml:space="preserve">
<source>Use iOS call interface</source>
<target>Usa interfaccia di chiamata iOS</target>
@@ -5173,11 +5414,26 @@ Per connetterti, chiedi al tuo contatto di creare un altro link di connessione e
<target>Utilizzo dei server SimpleX Chat.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Verify code with desktop" xml:space="preserve">
<source>Verify code with desktop</source>
<target>Verifica il codice con il desktop</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Verify connection" xml:space="preserve">
<source>Verify connection</source>
<target>Verifica la connessione</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Verify connection security" xml:space="preserve">
<source>Verify connection security</source>
<target>Verifica la sicurezza della connessione</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Verify connections" xml:space="preserve">
<source>Verify connections</source>
<target>Verifica le connessioni</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Verify security code" xml:space="preserve">
<source>Verify security code</source>
<target>Verifica codice di sicurezza</target>
@@ -5188,6 +5444,11 @@ Per connetterti, chiedi al tuo contatto di creare un altro link di connessione e
<target>Via browser</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Via secure quantum resistant protocol." xml:space="preserve">
<source>Via secure quantum resistant protocol.</source>
<target>Tramite protocollo sicuro resistente alla quantistica.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Video call" xml:space="preserve">
<source>Video call</source>
<target>Videochiamata</target>
@@ -5238,6 +5499,10 @@ Per connetterti, chiedi al tuo contatto di creare un altro link di connessione e
<target>Messaggio vocale…</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Waiting for desktop..." xml:space="preserve">
<source>Waiting for desktop...</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Waiting for file" xml:space="preserve">
<source>Waiting for file</source>
<target>In attesa del file</target>
@@ -5340,31 +5605,39 @@ Per connetterti, chiedi al tuo contatto di creare un altro link di connessione e
</trans-unit>
<trans-unit id="You are already connecting to %@." xml:space="preserve">
<source>You are already connecting to %@.</source>
<target>Ti stai già connettendo a %@.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="You are already connecting via this one-time link!" xml:space="preserve">
<source>You are already connecting via this one-time link!</source>
<target>Ti stai già connettendo tramite questo link una tantum!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="You are already in group %@." xml:space="preserve">
<source>You are already in group %@.</source>
<target>Sei già nel gruppo %@.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="You are already joining the group %@." xml:space="preserve">
<source>You are already joining the group %@.</source>
<target>Stai già entrando nel gruppo %@.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="You are already joining the group via this link!" xml:space="preserve">
<source>You are already joining the group via this link!</source>
<target>Stai già entrando nel gruppo tramite questo link!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="You are already joining the group via this link." xml:space="preserve">
<source>You are already joining the group via this link.</source>
<target>Stai già entrando nel gruppo tramite questo link.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="You are already joining the group!&#10;Repeat join request?" xml:space="preserve">
<source>You are already joining the group!
Repeat join request?</source>
<target>Stai già entrando nel gruppo!
Ripetere la richiesta di ingresso?</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="You are connected to the server used to receive messages from this contact." xml:space="preserve">
@@ -5464,11 +5737,14 @@ Repeat join request?</source>
</trans-unit>
<trans-unit id="You have already requested connection via this address!" xml:space="preserve">
<source>You have already requested connection via this address!</source>
<target>Hai già richiesto la connessione tramite questo indirizzo!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="You have already requested connection!&#10;Repeat connection request?" xml:space="preserve">
<source>You have already requested connection!
Repeat connection request?</source>
<target>Hai già richiesto la connessione!
Ripetere la richiesta di connessione?</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="You have no chats" xml:space="preserve">
@@ -5523,6 +5799,7 @@ Repeat connection request?</source>
</trans-unit>
<trans-unit id="You will be connected when group link host's device is online, please wait or check later!" xml:space="preserve">
<source>You will be connected when group link host's device is online, please wait or check later!</source>
<target>Verrai connesso/a quando il dispositivo dell'host del gruppo sarà in linea, attendi o controlla più tardi!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="You will be connected when your connection request is accepted, please wait or check later!" xml:space="preserve">
@@ -5542,6 +5819,7 @@ Repeat connection request?</source>
</trans-unit>
<trans-unit id="You will connect to all group members." xml:space="preserve">
<source>You will connect to all group members.</source>
<target>Ti connetterai a tutti i membri del gruppo.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="You will still receive calls and notifications from muted profiles when they are active." xml:space="preserve">
@@ -5665,6 +5943,7 @@ Puoi modificarlo nelle impostazioni.</target>
</trans-unit>
<trans-unit id="Your profile" xml:space="preserve">
<source>Your profile</source>
<target>Il tuo profilo</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Your profile **%@** will be shared." xml:space="preserve">
@@ -5761,6 +6040,7 @@ I server di SimpleX non possono vedere il tuo profilo.</target>
</trans-unit>
<trans-unit id="and %lld other events" xml:space="preserve">
<source>and %lld other events</source>
<target>e altri %lld eventi</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="audio call (not e2e encrypted)" xml:space="preserve">
@@ -5768,6 +6048,10 @@ I server di SimpleX non possono vedere il tuo profilo.</target>
<target>chiamata audio (non crittografata e2e)</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="author" xml:space="preserve">
<source>author</source>
<note>member role</note>
</trans-unit>
<trans-unit id="bad message ID" xml:space="preserve">
<source>bad message ID</source>
<target>ID messaggio errato</target>
@@ -5780,6 +6064,7 @@ I server di SimpleX non possono vedere il tuo profilo.</target>
</trans-unit>
<trans-unit id="blocked" xml:space="preserve">
<source>blocked</source>
<target>bloccato</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="bold" xml:space="preserve">
@@ -5814,7 +6099,7 @@ I server di SimpleX non possono vedere il tuo profilo.</target>
</trans-unit>
<trans-unit id="changed role of %@ to %@" xml:space="preserve">
<source>changed role of %1$@ to %2$@</source>
<target>cambiato il ruolo di %1$@ in %2$@</target>
<target>ha cambiato il ruolo di %1$@ in %2$@</target>
<note>rcv group event chat item</note>
</trans-unit>
<trans-unit id="changed your role to %@" xml:space="preserve">
@@ -5954,6 +6239,7 @@ I server di SimpleX non possono vedere il tuo profilo.</target>
</trans-unit>
<trans-unit id="deleted contact" xml:space="preserve">
<source>deleted contact</source>
<target>contatto eliminato</target>
<note>rcv direct event chat item</note>
</trans-unit>
<trans-unit id="deleted group" xml:space="preserve">
@@ -6348,6 +6634,11 @@ I server di SimpleX non possono vedere il tuo profilo.</target>
<target>profilo del gruppo aggiornato</target>
<note>rcv group event chat item</note>
</trans-unit>
<trans-unit id="v%@" xml:space="preserve">
<source>v%@</source>
<target>v%@</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="v%@ (%@)" xml:space="preserve">
<source>v%@ (%@)</source>
<target>v%@ (%@)</target>
@@ -6485,6 +6776,11 @@ I server di SimpleX non possono vedere il tuo profilo.</target>
<target>SimpleX usa Face ID per l'autenticazione locale</target>
<note>Privacy - Face ID Usage Description</note>
</trans-unit>
<trans-unit id="NSLocalNetworkUsageDescription" xml:space="preserve">
<source>SimpleX uses local network access to allow using user chat profile via desktop app on the same network.</source>
<target>SimpleX usa l'accesso alla rete locale per consentire di usare il profilo di chat tramite l'app desktop sulla stessa rete.</target>
<note>Privacy - Local Network Usage Description</note>
</trans-unit>
<trans-unit id="NSMicrophoneUsageDescription" xml:space="preserve">
<source>SimpleX needs microphone access for audio and video calls, and to record voice messages.</source>
<target>SimpleX ha bisogno dell'accesso al microfono per le chiamate audio e video e per registrare messaggi vocali.</target>

View File

@@ -4,6 +4,8 @@
"NSCameraUsageDescription" = "SimpleX needs camera access to scan QR codes to connect to other users and for video calls.";
/* Privacy - Face ID Usage Description */
"NSFaceIDUsageDescription" = "SimpleX uses Face ID for local authentication";
/* Privacy - Local Network Usage Description */
"NSLocalNetworkUsageDescription" = "SimpleX uses local network access to allow using user chat profile via desktop app on the same network.";
/* Privacy - Microphone Usage Description */
"NSMicrophoneUsageDescription" = "SimpleX needs microphone access for audio and video calls, and to record voice messages.";
/* Privacy - Photo Library Additions Usage Description */

View File

@@ -290,6 +290,14 @@
<target>(</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="(new)" xml:space="preserve">
<source>(new)</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="(this device v%@)" xml:space="preserve">
<source>(this device v%@)</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id=")" xml:space="preserve">
<source>)</source>
<target>)</target>
@@ -375,6 +383,12 @@
- などなど!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="- optionally notify deleted contacts.&#10;- profile names with spaces.&#10;- and more!" xml:space="preserve">
<source>- optionally notify deleted contacts.
- profile names with spaces.
- and more!</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="- voice messages up to 5 minutes.&#10;- custom time to disappear.&#10;- editing history." xml:space="preserve">
<source>- voice messages up to 5 minutes.
- custom time to disappear.
@@ -855,6 +869,10 @@
<target>戻る</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Bad desktop address" xml:space="preserve">
<source>Bad desktop address</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Bad message ID" xml:space="preserve">
<source>Bad message ID</source>
<target>メッセージ ID が正しくありません</target>
@@ -865,6 +883,10 @@
<target>メッセージのハッシュ値問題</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Better groups" xml:space="preserve">
<source>Better groups</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Better messages" xml:space="preserve">
<source>Better messages</source>
<target>より良いメッセージ</target>
@@ -874,6 +896,10 @@
<source>Block</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Block group members" xml:space="preserve">
<source>Block group members</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Block member" xml:space="preserve">
<source>Block member</source>
<note>No comment provided by engineer.</note>
@@ -1143,11 +1169,19 @@
<target>接続</target>
<note>server test step</note>
</trans-unit>
<trans-unit id="Connect automatically" xml:space="preserve">
<source>Connect automatically</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connect incognito" xml:space="preserve">
<source>Connect incognito</source>
<target>シークレットモードで接続</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connect to desktop" xml:space="preserve">
<source>Connect to desktop</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connect to yourself?" xml:space="preserve">
<source>Connect to yourself?</source>
<note>No comment provided by engineer.</note>
@@ -1185,6 +1219,14 @@ This is your own one-time link!</source>
<source>Connect with %@</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connected desktop" xml:space="preserve">
<source>Connected desktop</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connected to desktop" xml:space="preserve">
<source>Connected to desktop</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connecting server…" xml:space="preserve">
<source>Connecting to server…</source>
<target>サーバーに接続中…</target>
@@ -1195,6 +1237,10 @@ This is your own one-time link!</source>
<target>サーバーに接続中… (エラー: %@)</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connecting to desktop" xml:space="preserve">
<source>Connecting to desktop</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connection" xml:space="preserve">
<source>Connection</source>
<target>接続</target>
@@ -1215,6 +1261,10 @@ This is your own one-time link!</source>
<target>接続リクエストを送信しました!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connection terminated" xml:space="preserve">
<source>Connection terminated</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connection timeout" xml:space="preserve">
<source>Connection timeout</source>
<target>接続タイムアウト</target>
@@ -1294,6 +1344,10 @@ This is your own one-time link!</source>
<target>SimpleXアドレスの作成</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Create a group using a random profile." xml:space="preserve">
<source>Create a group using a random profile.</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Create an address to let people connect with you." xml:space="preserve">
<source>Create an address to let people connect with you.</source>
<target>人とつながるためのアドレスを作成する。</target>
@@ -1698,6 +1752,18 @@ This cannot be undone!</source>
<target>説明</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Desktop address" xml:space="preserve">
<source>Desktop address</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Desktop app version %@ is not compatible with this app." xml:space="preserve">
<source>Desktop app version %@ is not compatible with this app.</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Desktop devices" xml:space="preserve">
<source>Desktop devices</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Develop" xml:space="preserve">
<source>Develop</source>
<target>開発</target>
@@ -1788,11 +1854,19 @@ This cannot be undone!</source>
<target>切断</target>
<note>server test step</note>
</trans-unit>
<trans-unit id="Disconnect desktop?" xml:space="preserve">
<source>Disconnect desktop?</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Discover and join groups" xml:space="preserve">
<source>Discover and join groups</source>
<target>グループを見つけて参加する</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Discover via local network" xml:space="preserve">
<source>Discover via local network</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Do NOT use SimpleX for emergency calls." xml:space="preserve">
<source>Do NOT use SimpleX for emergency calls.</source>
<target>緊急通報にSimpleXを使用しないでください。</target>
@@ -1963,6 +2037,14 @@ This cannot be undone!</source>
<target>暗号化されたメッセージ : 予期しないエラー</target>
<note>notification</note>
</trans-unit>
<trans-unit id="Encryption re-negotiation error" xml:space="preserve">
<source>Encryption re-negotiation error</source>
<note>message decrypt error item</note>
</trans-unit>
<trans-unit id="Encryption re-negotiation failed." xml:space="preserve">
<source>Encryption re-negotiation failed.</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Enter Passcode" xml:space="preserve">
<source>Enter Passcode</source>
<target>パスコードを入力</target>
@@ -1992,6 +2074,10 @@ This cannot be undone!</source>
<target>サーバを手動で入力</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Enter this device name…" xml:space="preserve">
<source>Enter this device name…</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Enter welcome message…" xml:space="preserve">
<source>Enter welcome message…</source>
<target>ウェルカムメッセージを入力してください…</target>
@@ -2313,6 +2399,10 @@ This cannot be undone!</source>
<target>送信者がオンラインになるまでの待ち時間がなく、速い!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Faster joining and more reliable messages." xml:space="preserve">
<source>Faster joining and more reliable messages.</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Favorite" xml:space="preserve">
<source>Favorite</source>
<target>お気に入り</target>
@@ -2408,6 +2498,10 @@ This cannot be undone!</source>
<target>コンソール</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Found desktop" xml:space="preserve">
<source>Found desktop</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="French interface" xml:space="preserve">
<source>French interface</source>
<target>フランス語UI</target>
@@ -2730,6 +2824,10 @@ This cannot be undone!</source>
<target>シークレットモード</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Incognito groups" xml:space="preserve">
<source>Incognito groups</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Incognito mode" xml:space="preserve">
<source>Incognito mode</source>
<target>シークレットモード</target>
@@ -2760,6 +2858,10 @@ This cannot be undone!</source>
<target>データベースのバージョンと互換性がない</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Incompatible version" xml:space="preserve">
<source>Incompatible version</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Incorrect passcode" xml:space="preserve">
<source>Incorrect passcode</source>
<target>パスコードが正しくありません</target>
@@ -2925,6 +3027,10 @@ This is your link for group %@!</source>
<target>グループに参加</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Keep the app open to use it from desktop" xml:space="preserve">
<source>Keep the app open to use it from desktop</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Keep your connections" xml:space="preserve">
<source>Keep your connections</source>
<target>接続を維持</target>
@@ -2985,6 +3091,18 @@ This is your link for group %@!</source>
<target>制限事項</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Link mobile and desktop apps! 🔗" xml:space="preserve">
<source>Link mobile and desktop apps! 🔗</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Linked desktop options" xml:space="preserve">
<source>Linked desktop options</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Linked desktops" xml:space="preserve">
<source>Linked desktops</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Live message!" xml:space="preserve">
<source>Live message!</source>
<target>ライブメッセージ!</target>
@@ -3333,6 +3451,10 @@ This is your link for group %@!</source>
<target>送受信済みのファイルがありません</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Not compatible!" xml:space="preserve">
<source>Not compatible!</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Notifications" xml:space="preserve">
<source>Notifications</source>
<target>通知</target>
@@ -3551,6 +3673,10 @@ This is your link for group %@!</source>
<target>貼り付け</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Paste desktop address" xml:space="preserve">
<source>Paste desktop address</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Paste image" xml:space="preserve">
<source>Paste image</source>
<target>画像の貼り付け</target>
@@ -4141,6 +4267,10 @@ This is your link for group %@!</source>
<target>QRコードを読み込む</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Scan QR code from desktop" xml:space="preserve">
<source>Scan QR code from desktop</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Scan code" xml:space="preserve">
<source>Scan code</source>
<target>コードを読み込む</target>
@@ -4353,6 +4483,10 @@ This is your link for group %@!</source>
<target>サーバ</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Session code" xml:space="preserve">
<source>Session code</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Set 1 day" xml:space="preserve">
<source>Set 1 day</source>
<target>1日に設定</target>
@@ -4849,6 +4983,10 @@ It can happen because of some bug or when the connection is compromised.</source
<target>あなたのプロフィール、連絡先、メッセージ、ファイルが完全削除されます (※元に戻せません※)。</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="This device name" xml:space="preserve">
<source>This device name</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="This group has over %lld members, delivery receipts are not sent." xml:space="preserve">
<source>This group has over %lld members, delivery receipts are not sent.</source>
<note>No comment provided by engineer.</note>
@@ -4881,6 +5019,10 @@ It can happen because of some bug or when the connection is compromised.</source
<target>接続するにはQRコードを読み込むか、アプリ内のリンクを使用する必要があります。</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="To hide unwanted messages." xml:space="preserve">
<source>To hide unwanted messages.</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="To make a new connection" xml:space="preserve">
<source>To make a new connection</source>
<target>新規に接続する場合</target>
@@ -5036,6 +5178,14 @@ To connect, please ask your contact to create another connection link and check
接続するには、連絡先に別の接続リンクを作成するよう依頼し、ネットワーク接続が安定していることを確認してください。</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Unlink" xml:space="preserve">
<source>Unlink</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Unlink desktop?" xml:space="preserve">
<source>Unlink desktop?</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Unlock" xml:space="preserve">
<source>Unlock</source>
<target>ロック解除</target>
@@ -5126,6 +5276,10 @@ To connect, please ask your contact to create another connection link and check
<target>新しい接続に使う</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Use from desktop" xml:space="preserve">
<source>Use from desktop</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Use iOS call interface" xml:space="preserve">
<source>Use iOS call interface</source>
<target>iOS通話インターフェースを使用する</target>
@@ -5156,11 +5310,23 @@ To connect, please ask your contact to create another connection link and check
<target>SimpleX チャット サーバーを使用する。</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Verify code with desktop" xml:space="preserve">
<source>Verify code with desktop</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Verify connection" xml:space="preserve">
<source>Verify connection</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Verify connection security" xml:space="preserve">
<source>Verify connection security</source>
<target>接続のセキュリティを確認</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Verify connections" xml:space="preserve">
<source>Verify connections</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Verify security code" xml:space="preserve">
<source>Verify security code</source>
<target>セキュリティコードを確認</target>
@@ -5171,6 +5337,10 @@ To connect, please ask your contact to create another connection link and check
<target>ブラウザ経由</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Via secure quantum resistant protocol." xml:space="preserve">
<source>Via secure quantum resistant protocol.</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Video call" xml:space="preserve">
<source>Video call</source>
<target>ビデオ通話</target>
@@ -5221,6 +5391,10 @@ To connect, please ask your contact to create another connection link and check
<target>音声メッセージ…</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Waiting for desktop..." xml:space="preserve">
<source>Waiting for desktop...</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Waiting for file" xml:space="preserve">
<source>Waiting for file</source>
<target>ファイル待ち</target>
@@ -5751,6 +5925,10 @@ SimpleX サーバーはあなたのプロファイルを参照できません。
<target>音声通話 (エンドツーエンド暗号化なし)</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="author" xml:space="preserve">
<source>author</source>
<note>member role</note>
</trans-unit>
<trans-unit id="bad message ID" xml:space="preserve">
<source>bad message ID</source>
<target>メッセージ ID が正しくありません</target>
@@ -6329,6 +6507,10 @@ SimpleX サーバーはあなたのプロファイルを参照できません。
<target>グループプロフィールを更新しました</target>
<note>rcv group event chat item</note>
</trans-unit>
<trans-unit id="v%@" xml:space="preserve">
<source>v%@</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="v%@ (%@)" xml:space="preserve">
<source>v%@ (%@)</source>
<target>v%@ (%@)</target>
@@ -6466,6 +6648,10 @@ SimpleX サーバーはあなたのプロファイルを参照できません。
<target>SimpleX はローカル認証に Face ID を使用します</target>
<note>Privacy - Face ID Usage Description</note>
</trans-unit>
<trans-unit id="NSLocalNetworkUsageDescription" xml:space="preserve">
<source>SimpleX uses local network access to allow using user chat profile via desktop app on the same network.</source>
<note>Privacy - Local Network Usage Description</note>
</trans-unit>
<trans-unit id="NSMicrophoneUsageDescription" xml:space="preserve">
<source>SimpleX needs microphone access for audio and video calls, and to record voice messages.</source>
<target>SimpleX では、音声通話やビデオ通話、および音声メッセージの録音のためにマイクへのアクセスが必要です。</target>

View File

@@ -4,6 +4,8 @@
"NSCameraUsageDescription" = "SimpleX needs camera access to scan QR codes to connect to other users and for video calls.";
/* Privacy - Face ID Usage Description */
"NSFaceIDUsageDescription" = "SimpleX uses Face ID for local authentication";
/* Privacy - Local Network Usage Description */
"NSLocalNetworkUsageDescription" = "SimpleX uses local network access to allow using user chat profile via desktop app on the same network.";
/* Privacy - Microphone Usage Description */
"NSMicrophoneUsageDescription" = "SimpleX needs microphone access for audio and video calls, and to record voice messages.";
/* Privacy - Photo Library Additions Usage Description */

View File

@@ -89,6 +89,7 @@
</trans-unit>
<trans-unit id="%@ and %@" xml:space="preserve">
<source>%@ and %@</source>
<target>%@ en %@</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="%@ and %@ connected" xml:space="preserve">
@@ -103,6 +104,7 @@
</trans-unit>
<trans-unit id="%@ connected" xml:space="preserve">
<source>%@ connected</source>
<target>%@ verbonden</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="%@ is connected!" xml:space="preserve">
@@ -132,6 +134,7 @@
</trans-unit>
<trans-unit id="%@, %@ and %lld members" xml:space="preserve">
<source>%@, %@ and %lld members</source>
<target>%@, %@ en %lld leden</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="%@, %@ and %lld other members connected" xml:space="preserve">
@@ -201,6 +204,7 @@
</trans-unit>
<trans-unit id="%lld group events" xml:space="preserve">
<source>%lld group events</source>
<target>%lld groep gebeurtenissen</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="%lld members" xml:space="preserve">
@@ -210,14 +214,17 @@
</trans-unit>
<trans-unit id="%lld messages blocked" xml:space="preserve">
<source>%lld messages blocked</source>
<target>%lld berichten geblokkeerd</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="%lld messages marked deleted" xml:space="preserve">
<source>%lld messages marked deleted</source>
<target>%lld berichten gemarkeerd als verwijderd</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="%lld messages moderated by %@" xml:space="preserve">
<source>%lld messages moderated by %@</source>
<target>%lld berichten gemodereerd door %@</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="%lld minutes" xml:space="preserve">
@@ -290,6 +297,16 @@
<target>(</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="(new)" xml:space="preserve">
<source>(new)</source>
<target>(nieuw)</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="(this device v%@)" xml:space="preserve">
<source>(this device v%@)</source>
<target>(dit apparaat v%@)</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id=")" xml:space="preserve">
<source>)</source>
<target>)</target>
@@ -375,6 +392,15 @@
- and more!</source>
<target>- stabielere berichtbezorging.
- een beetje betere groepen.
- en meer!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="- optionally notify deleted contacts.&#10;- profile names with spaces.&#10;- and more!" xml:space="preserve">
<source>- optionally notify deleted contacts.
- profile names with spaces.
- and more!</source>
<target>- optioneel verwijderde contacten op de hoogte stellen.
- profielnamen met spaties.
- en meer!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
@@ -394,6 +420,7 @@
</trans-unit>
<trans-unit id="0 sec" xml:space="preserve">
<source>0 sec</source>
<target>0 sec</target>
<note>time to disappear</note>
</trans-unit>
<trans-unit id="0s" xml:space="preserve">
@@ -623,6 +650,7 @@
</trans-unit>
<trans-unit id="All new messages from %@ will be hidden!" xml:space="preserve">
<source>All new messages from %@ will be hidden!</source>
<target>Alle nieuwe berichten van %@ worden verborgen!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="All your contacts will remain connected." xml:space="preserve">
@@ -732,10 +760,12 @@
</trans-unit>
<trans-unit id="Already connecting!" xml:space="preserve">
<source>Already connecting!</source>
<target>Al bezig met verbinden!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Already joining the group!" xml:space="preserve">
<source>Already joining the group!</source>
<target>Al lid van de groep!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Always use relay" xml:space="preserve">
@@ -858,6 +888,11 @@
<target>Terug</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Bad desktop address" xml:space="preserve">
<source>Bad desktop address</source>
<target>Onjuist desktopadres</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Bad message ID" xml:space="preserve">
<source>Bad message ID</source>
<target>Onjuiste bericht-ID</target>
@@ -868,6 +903,11 @@
<target>Onjuiste bericht hash</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Better groups" xml:space="preserve">
<source>Better groups</source>
<target>Betere groepen</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Better messages" xml:space="preserve">
<source>Better messages</source>
<target>Betere berichten</target>
@@ -875,14 +915,22 @@
</trans-unit>
<trans-unit id="Block" xml:space="preserve">
<source>Block</source>
<target>Blokkeren</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Block group members" xml:space="preserve">
<source>Block group members</source>
<target>Groepsleden blokkeren</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Block member" xml:space="preserve">
<source>Block member</source>
<target>Lid blokkeren</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Block member?" xml:space="preserve">
<source>Block member?</source>
<target>Lid blokkeren?</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Both you and your contact can add message reactions." xml:space="preserve">
@@ -977,7 +1025,7 @@
</trans-unit>
<trans-unit id="Change member role?" xml:space="preserve">
<source>Change member role?</source>
<target>Rol van gebruiker wijzigen?</target>
<target>Rol van lid wijzigen?</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Change passcode" xml:space="preserve">
@@ -1146,27 +1194,43 @@
<target>Verbind</target>
<note>server test step</note>
</trans-unit>
<trans-unit id="Connect automatically" xml:space="preserve">
<source>Connect automatically</source>
<target>Automatisch verbinden</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connect incognito" xml:space="preserve">
<source>Connect incognito</source>
<target>Verbind incognito</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connect to desktop" xml:space="preserve">
<source>Connect to desktop</source>
<target>Verbinden met desktop</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connect to yourself?" xml:space="preserve">
<source>Connect to yourself?</source>
<target>Verbinding maken met jezelf?</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connect to yourself?&#10;This is your own SimpleX address!" xml:space="preserve">
<source>Connect to yourself?
This is your own SimpleX address!</source>
<target>Verbinding maken met jezelf?
Dit is uw eigen SimpleX adres!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connect to yourself?&#10;This is your own one-time link!" xml:space="preserve">
<source>Connect to yourself?
This is your own one-time link!</source>
<target>Verbinding maken met jezelf?
Dit is uw eigen eenmalige link!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connect via contact address" xml:space="preserve">
<source>Connect via contact address</source>
<target>Verbinding maken via contactadres</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connect via link" xml:space="preserve">
@@ -1186,6 +1250,17 @@ This is your own one-time link!</source>
</trans-unit>
<trans-unit id="Connect with %@" xml:space="preserve">
<source>Connect with %@</source>
<target>Verbonden met %@</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connected desktop" xml:space="preserve">
<source>Connected desktop</source>
<target>Verbonden desktop</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connected to desktop" xml:space="preserve">
<source>Connected to desktop</source>
<target>Verbonden met desktop</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connecting server…" xml:space="preserve">
@@ -1198,6 +1273,11 @@ This is your own one-time link!</source>
<target>Verbinden met server... (fout: %@)</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connecting to desktop" xml:space="preserve">
<source>Connecting to desktop</source>
<target>Verbinding maken met desktop</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connection" xml:space="preserve">
<source>Connection</source>
<target>Verbinding</target>
@@ -1218,6 +1298,11 @@ This is your own one-time link!</source>
<target>Verbindingsverzoek verzonden!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connection terminated" xml:space="preserve">
<source>Connection terminated</source>
<target>Verbinding beëindigd</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connection timeout" xml:space="preserve">
<source>Connection timeout</source>
<target>Timeout verbinding</target>
@@ -1285,6 +1370,7 @@ This is your own one-time link!</source>
</trans-unit>
<trans-unit id="Correct name to %@?" xml:space="preserve">
<source>Correct name to %@?</source>
<target>Juiste naam voor %@?</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Create" xml:space="preserve">
@@ -1297,6 +1383,11 @@ This is your own one-time link!</source>
<target>Maak een SimpleX adres aan</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Create a group using a random profile." xml:space="preserve">
<source>Create a group using a random profile.</source>
<target>Maak een groep met een willekeurig profiel.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Create an address to let people connect with you." xml:space="preserve">
<source>Create an address to let people connect with you.</source>
<target>Maak een adres aan zodat mensen contact met je kunnen opnemen.</target>
@@ -1309,6 +1400,7 @@ This is your own one-time link!</source>
</trans-unit>
<trans-unit id="Create group" xml:space="preserve">
<source>Create group</source>
<target>Groep aanmaken</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Create group link" xml:space="preserve">
@@ -1333,6 +1425,7 @@ This is your own one-time link!</source>
</trans-unit>
<trans-unit id="Create profile" xml:space="preserve">
<source>Create profile</source>
<target>Maak een profiel aan</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Create queue" xml:space="preserve">
@@ -1495,6 +1588,7 @@ This is your own one-time link!</source>
</trans-unit>
<trans-unit id="Delete %lld messages?" xml:space="preserve">
<source>Delete %lld messages?</source>
<target>%lld berichten verwijderen?</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Delete Contact" xml:space="preserve">
@@ -1524,6 +1618,7 @@ This is your own one-time link!</source>
</trans-unit>
<trans-unit id="Delete and notify contact" xml:space="preserve">
<source>Delete and notify contact</source>
<target>Contact verwijderen en op de hoogte stellen</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Delete archive" xml:space="preserve">
@@ -1559,6 +1654,8 @@ This is your own one-time link!</source>
<trans-unit id="Delete contact?&#10;This cannot be undone!" xml:space="preserve">
<source>Delete contact?
This cannot be undone!</source>
<target>Verwijder contact?
Dit kan niet ongedaan gemaakt worden!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Delete database" xml:space="preserve">
@@ -1701,6 +1798,21 @@ This cannot be undone!</source>
<target>Beschrijving</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Desktop address" xml:space="preserve">
<source>Desktop address</source>
<target>Desktop adres</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Desktop app version %@ is not compatible with this app." xml:space="preserve">
<source>Desktop app version %@ is not compatible with this app.</source>
<target>Desktop-app-versie %@ is niet compatibel met deze app.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Desktop devices" xml:space="preserve">
<source>Desktop devices</source>
<target>Desktop apparaten</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Develop" xml:space="preserve">
<source>Develop</source>
<target>Ontwikkelen</target>
@@ -1791,11 +1903,21 @@ This cannot be undone!</source>
<target>verbinding verbreken</target>
<note>server test step</note>
</trans-unit>
<trans-unit id="Disconnect desktop?" xml:space="preserve">
<source>Disconnect desktop?</source>
<target>Desktop loskoppelen?</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Discover and join groups" xml:space="preserve">
<source>Discover and join groups</source>
<target>Ontdek en sluit je aan bij groepen</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Discover via local network" xml:space="preserve">
<source>Discover via local network</source>
<target>Ontdek via het lokale netwerk</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Do NOT use SimpleX for emergency calls." xml:space="preserve">
<source>Do NOT use SimpleX for emergency calls.</source>
<target>Gebruik SimpleX NIET voor noodoproepen.</target>
@@ -1966,6 +2088,16 @@ This cannot be undone!</source>
<target>Versleuteld bericht: onverwachte fout</target>
<note>notification</note>
</trans-unit>
<trans-unit id="Encryption re-negotiation error" xml:space="preserve">
<source>Encryption re-negotiation error</source>
<target>Fout bij heronderhandeling van codering</target>
<note>message decrypt error item</note>
</trans-unit>
<trans-unit id="Encryption re-negotiation failed." xml:space="preserve">
<source>Encryption re-negotiation failed.</source>
<target>Opnieuw onderhandelen over de codering is mislukt.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Enter Passcode" xml:space="preserve">
<source>Enter Passcode</source>
<target>Voer toegangscode in</target>
@@ -1978,6 +2110,7 @@ This cannot be undone!</source>
</trans-unit>
<trans-unit id="Enter group name…" xml:space="preserve">
<source>Enter group name…</source>
<target>Groep naam invoeren…</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Enter passphrase…" xml:space="preserve">
@@ -1995,6 +2128,11 @@ This cannot be undone!</source>
<target>Voer de server handmatig in</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Enter this device name…" xml:space="preserve">
<source>Enter this device name…</source>
<target>Voer deze apparaatnaam in…</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Enter welcome message…" xml:space="preserve">
<source>Enter welcome message…</source>
<target>Welkomst bericht invoeren…</target>
@@ -2007,6 +2145,7 @@ This cannot be undone!</source>
</trans-unit>
<trans-unit id="Enter your name…" xml:space="preserve">
<source>Enter your name…</source>
<target>Vul uw naam in…</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Error" xml:space="preserve">
@@ -2031,7 +2170,7 @@ This cannot be undone!</source>
</trans-unit>
<trans-unit id="Error adding member(s)" xml:space="preserve">
<source>Error adding member(s)</source>
<target>Fout bij het toevoegen van gebruiker(s)</target>
<target>Fout bij het toevoegen van leden</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Error changing address" xml:space="preserve">
@@ -2161,7 +2300,7 @@ This cannot be undone!</source>
</trans-unit>
<trans-unit id="Error removing member" xml:space="preserve">
<source>Error removing member</source>
<target>Fout bij verwijderen van gebruiker</target>
<target>Fout bij verwijderen van lid</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Error saving %@ servers" xml:space="preserve">
@@ -2286,6 +2425,7 @@ This cannot be undone!</source>
</trans-unit>
<trans-unit id="Expand" xml:space="preserve">
<source>Expand</source>
<target>Uitbreiden</target>
<note>chat item action</note>
</trans-unit>
<trans-unit id="Export database" xml:space="preserve">
@@ -2318,6 +2458,11 @@ This cannot be undone!</source>
<target>Snel en niet wachten tot de afzender online is!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Faster joining and more reliable messages." xml:space="preserve">
<source>Faster joining and more reliable messages.</source>
<target>Snellere deelname en betrouwbaardere berichten.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Favorite" xml:space="preserve">
<source>Favorite</source>
<target>Favoriet</target>
@@ -2413,6 +2558,11 @@ This cannot be undone!</source>
<target>Voor console</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Found desktop" xml:space="preserve">
<source>Found desktop</source>
<target>Desktop gevonden</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="French interface" xml:space="preserve">
<source>French interface</source>
<target>Franse interface</target>
@@ -2435,6 +2585,7 @@ This cannot be undone!</source>
</trans-unit>
<trans-unit id="Fully decentralized visible only to members." xml:space="preserve">
<source>Fully decentralized visible only to members.</source>
<target>Volledig gedecentraliseerd alleen zichtbaar voor leden.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Fully re-implemented - work in background!" xml:space="preserve">
@@ -2459,10 +2610,12 @@ This cannot be undone!</source>
</trans-unit>
<trans-unit id="Group already exists" xml:space="preserve">
<source>Group already exists</source>
<target>Groep bestaat al</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Group already exists!" xml:space="preserve">
<source>Group already exists!</source>
<target>Groep bestaat al!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Group display name" xml:space="preserve">
@@ -2735,6 +2888,11 @@ This cannot be undone!</source>
<target>Incognito</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Incognito groups" xml:space="preserve">
<source>Incognito groups</source>
<target>Incognitogroepen</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Incognito mode" xml:space="preserve">
<source>Incognito mode</source>
<target>Incognito modus</target>
@@ -2765,6 +2923,11 @@ This cannot be undone!</source>
<target>Incompatibele database versie</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Incompatible version" xml:space="preserve">
<source>Incompatible version</source>
<target>Incompatibele versie</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Incorrect passcode" xml:space="preserve">
<source>Incorrect passcode</source>
<target>Onjuiste toegangscode</target>
@@ -2814,6 +2977,7 @@ This cannot be undone!</source>
</trans-unit>
<trans-unit id="Invalid name!" xml:space="preserve">
<source>Invalid name!</source>
<target>Ongeldige naam!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Invalid server address!" xml:space="preserve">
@@ -2909,6 +3073,7 @@ This cannot be undone!</source>
</trans-unit>
<trans-unit id="Join group?" xml:space="preserve">
<source>Join group?</source>
<target>Deelnemen aan groep?</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Join incognito" xml:space="preserve">
@@ -2918,11 +3083,14 @@ This cannot be undone!</source>
</trans-unit>
<trans-unit id="Join with current profile" xml:space="preserve">
<source>Join with current profile</source>
<target>Word lid met huidig profiel</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Join your group?&#10;This is your link for group %@!" xml:space="preserve">
<source>Join your group?
This is your link for group %@!</source>
<target>Sluit u aan bij uw groep?
Dit is jouw link voor groep %@!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Joining group" xml:space="preserve">
@@ -2930,6 +3098,11 @@ This is your link for group %@!</source>
<target>Deel nemen aan groep</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Keep the app open to use it from desktop" xml:space="preserve">
<source>Keep the app open to use it from desktop</source>
<target>Houd de app geopend om deze vanaf de desktop te gebruiken</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Keep your connections" xml:space="preserve">
<source>Keep your connections</source>
<target>Behoud uw verbindingen</target>
@@ -2990,6 +3163,21 @@ This is your link for group %@!</source>
<target>Beperkingen</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Link mobile and desktop apps! 🔗" xml:space="preserve">
<source>Link mobile and desktop apps! 🔗</source>
<target>Koppel mobiele en desktop-apps! 🔗</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Linked desktop options" xml:space="preserve">
<source>Linked desktop options</source>
<target>Gekoppelde desktop opties</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Linked desktops" xml:space="preserve">
<source>Linked desktops</source>
<target>Gelinkte desktops</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Live message!" xml:space="preserve">
<source>Live message!</source>
<target>Live bericht!</target>
@@ -3077,22 +3265,22 @@ This is your link for group %@!</source>
</trans-unit>
<trans-unit id="Member" xml:space="preserve">
<source>Member</source>
<target>Gebruiker</target>
<target>Lid</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Member role will be changed to &quot;%@&quot;. All group members will be notified." xml:space="preserve">
<source>Member role will be changed to "%@". All group members will be notified.</source>
<target>De rol van gebruiker wordt gewijzigd in "%@". Alle groepsleden worden op de hoogte gebracht.</target>
<target>De rol van lid wordt gewijzigd in "%@". Alle groepsleden worden op de hoogte gebracht.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Member role will be changed to &quot;%@&quot;. The member will receive a new invitation." xml:space="preserve">
<source>Member role will be changed to "%@". The member will receive a new invitation.</source>
<target>De rol van gebruiker wordt gewijzigd in "%@". Het lid ontvangt een nieuwe uitnodiging.</target>
<target>De rol van lid wordt gewijzigd in "%@". Het lid ontvangt een nieuwe uitnodiging.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Member will be removed from group - this cannot be undone!" xml:space="preserve">
<source>Member will be removed from group - this cannot be undone!</source>
<target>Gebruiker wordt uit de groep verwijderd, dit kan niet ongedaan worden gemaakt!</target>
<target>Lid wordt uit de groep verwijderd, dit kan niet ongedaan worden gemaakt!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Message delivery error" xml:space="preserve">
@@ -3142,6 +3330,7 @@ This is your link for group %@!</source>
</trans-unit>
<trans-unit id="Messages from %@ will be shown!" xml:space="preserve">
<source>Messages from %@ will be shown!</source>
<target>Berichten van %@ worden getoond!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Migrating database archive…" xml:space="preserve">
@@ -3339,6 +3528,11 @@ This is your link for group %@!</source>
<target>Geen ontvangen of verzonden bestanden</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Not compatible!" xml:space="preserve">
<source>Not compatible!</source>
<target>Niet compatibel!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Notifications" xml:space="preserve">
<source>Notifications</source>
<target>Meldingen</target>
@@ -3415,7 +3609,7 @@ This is your link for group %@!</source>
</trans-unit>
<trans-unit id="Only group owners can enable files and media." xml:space="preserve">
<source>Only group owners can enable files and media.</source>
<target>Alleen groepseigenaren kunnen bestanden en media inschakelen.</target>
<target>Alleen groep eigenaren kunnen bestanden en media inschakelen.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Only group owners can enable voice messages." xml:space="preserve">
@@ -3495,6 +3689,7 @@ This is your link for group %@!</source>
</trans-unit>
<trans-unit id="Open group" xml:space="preserve">
<source>Open group</source>
<target>Open groep</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Open user profiles" xml:space="preserve">
@@ -3557,6 +3752,11 @@ This is your link for group %@!</source>
<target>Plakken</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Paste desktop address" xml:space="preserve">
<source>Paste desktop address</source>
<target>Desktopadres plakken</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Paste image" xml:space="preserve">
<source>Paste image</source>
<target>Afbeelding plakken</target>
@@ -3704,10 +3904,12 @@ This is your link for group %@!</source>
</trans-unit>
<trans-unit id="Profile name" xml:space="preserve">
<source>Profile name</source>
<target>Profielnaam</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Profile name:" xml:space="preserve">
<source>Profile name:</source>
<target>Profielnaam:</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Profile password" xml:space="preserve">
@@ -3927,12 +4129,12 @@ This is your link for group %@!</source>
</trans-unit>
<trans-unit id="Remove member" xml:space="preserve">
<source>Remove member</source>
<target>Gebruiker verwijderen</target>
<target>Lid verwijderen</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Remove member?" xml:space="preserve">
<source>Remove member?</source>
<target>Gebruiker verwijderen?</target>
<target>Lid verwijderen?</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Remove passphrase from keychain?" xml:space="preserve">
@@ -3957,10 +4159,12 @@ This is your link for group %@!</source>
</trans-unit>
<trans-unit id="Repeat connection request?" xml:space="preserve">
<source>Repeat connection request?</source>
<target>Verbindingsverzoek herhalen?</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Repeat join request?" xml:space="preserve">
<source>Repeat join request?</source>
<target>Deelnameverzoek herhalen?</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Reply" xml:space="preserve">
@@ -4075,7 +4279,7 @@ This is your link for group %@!</source>
</trans-unit>
<trans-unit id="Save and notify group members" xml:space="preserve">
<source>Save and notify group members</source>
<target>Opslaan en Groep leden melden</target>
<target>Opslaan en groep leden melden</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Save and update group profile" xml:space="preserve">
@@ -4148,6 +4352,11 @@ This is your link for group %@!</source>
<target>Scan QR-code</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Scan QR code from desktop" xml:space="preserve">
<source>Scan QR code from desktop</source>
<target>Scan QR-code vanaf uw desktop</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Scan code" xml:space="preserve">
<source>Scan code</source>
<target>Code scannen</target>
@@ -4368,6 +4577,11 @@ This is your link for group %@!</source>
<target>Servers</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Session code" xml:space="preserve">
<source>Session code</source>
<target>Sessie code</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Set 1 day" xml:space="preserve">
<source>Set 1 day</source>
<target>Stel 1 dag in</target>
@@ -4680,6 +4894,7 @@ This is your link for group %@!</source>
</trans-unit>
<trans-unit id="Tap to Connect" xml:space="preserve">
<source>Tap to Connect</source>
<target>Tik om verbinding te maken</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Tap to activate profile." xml:space="preserve">
@@ -4689,12 +4904,12 @@ This is your link for group %@!</source>
</trans-unit>
<trans-unit id="Tap to join" xml:space="preserve">
<source>Tap to join</source>
<target>Tik om mee te doen</target>
<target>Tik om lid te worden</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Tap to join incognito" xml:space="preserve">
<source>Tap to join incognito</source>
<target>Tik om incognito deel te nemen</target>
<target>Tik om incognito lid te worden</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Tap to start a new chat" xml:space="preserve">
@@ -4864,6 +5079,11 @@ Het kan gebeuren vanwege een bug of wanneer de verbinding is aangetast.</target>
<target>Deze actie kan niet ongedaan worden gemaakt. Uw profiel, contacten, berichten en bestanden gaan onomkeerbaar verloren.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="This device name" xml:space="preserve">
<source>This device name</source>
<target>Deze apparaatnaam</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="This group has over %lld members, delivery receipts are not sent." xml:space="preserve">
<source>This group has over %lld members, delivery receipts are not sent.</source>
<target>Deze groep heeft meer dan %lld -leden, ontvangstbevestigingen worden niet verzonden.</target>
@@ -4876,10 +5096,12 @@ Het kan gebeuren vanwege een bug of wanneer de verbinding is aangetast.</target>
</trans-unit>
<trans-unit id="This is your own SimpleX address!" xml:space="preserve">
<source>This is your own SimpleX address!</source>
<target>Dit is uw eigen SimpleX adres!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="This is your own one-time link!" xml:space="preserve">
<source>This is your own one-time link!</source>
<target>Dit is uw eigen eenmalige link!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="This setting applies to messages in your current chat profile **%@**." xml:space="preserve">
@@ -4897,6 +5119,11 @@ Het kan gebeuren vanwege een bug of wanneer de verbinding is aangetast.</target>
<target>Om verbinding te maken, kan uw contact de QR-code scannen of de link in de app gebruiken.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="To hide unwanted messages." xml:space="preserve">
<source>To hide unwanted messages.</source>
<target>Om ongewenste berichten te verbergen.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="To make a new connection" xml:space="preserve">
<source>To make a new connection</source>
<target>Om een nieuwe verbinding te maken</target>
@@ -4981,14 +5208,17 @@ U wordt gevraagd de authenticatie te voltooien voordat deze functie wordt ingesc
</trans-unit>
<trans-unit id="Unblock" xml:space="preserve">
<source>Unblock</source>
<target>Deblokkeren</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Unblock member" xml:space="preserve">
<source>Unblock member</source>
<target>Lid deblokkeren</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Unblock member?" xml:space="preserve">
<source>Unblock member?</source>
<target>Lid deblokkeren?</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Unexpected error: %@" xml:space="preserve">
@@ -5053,6 +5283,16 @@ To connect, please ask your contact to create another connection link and check
Om verbinding te maken, vraagt u uw contact om een andere verbinding link te maken en te controleren of u een stabiele netwerkverbinding heeft.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Unlink" xml:space="preserve">
<source>Unlink</source>
<target>Ontkoppelen</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Unlink desktop?" xml:space="preserve">
<source>Unlink desktop?</source>
<target>Desktop ontkoppelen?</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Unlock" xml:space="preserve">
<source>Unlock</source>
<target>Ontgrendelen</target>
@@ -5143,6 +5383,11 @@ Om verbinding te maken, vraagt u uw contact om een andere verbinding link te mak
<target>Gebruik voor nieuwe verbindingen</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Use from desktop" xml:space="preserve">
<source>Use from desktop</source>
<target>Gebruik vanaf desktop</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Use iOS call interface" xml:space="preserve">
<source>Use iOS call interface</source>
<target>De iOS-oproepinterface gebruiken</target>
@@ -5173,11 +5418,26 @@ Om verbinding te maken, vraagt u uw contact om een andere verbinding link te mak
<target>SimpleX Chat servers gebruiken.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Verify code with desktop" xml:space="preserve">
<source>Verify code with desktop</source>
<target>Code verifiëren met desktop</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Verify connection" xml:space="preserve">
<source>Verify connection</source>
<target>Controleer de verbinding</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Verify connection security" xml:space="preserve">
<source>Verify connection security</source>
<target>Controleer de verbindingsbeveiliging</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Verify connections" xml:space="preserve">
<source>Verify connections</source>
<target>Controleer verbindingen</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Verify security code" xml:space="preserve">
<source>Verify security code</source>
<target>Controleer de beveiligingscode</target>
@@ -5188,6 +5448,11 @@ Om verbinding te maken, vraagt u uw contact om een andere verbinding link te mak
<target>Via browser</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Via secure quantum resistant protocol." xml:space="preserve">
<source>Via secure quantum resistant protocol.</source>
<target>Via een beveiligd kwantumbestendig protocol.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Video call" xml:space="preserve">
<source>Video call</source>
<target>video oproep</target>
@@ -5238,6 +5503,11 @@ Om verbinding te maken, vraagt u uw contact om een andere verbinding link te mak
<target>Spraakbericht…</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Waiting for desktop..." xml:space="preserve">
<source>Waiting for desktop...</source>
<target>Wachten op desktop...</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Waiting for file" xml:space="preserve">
<source>Waiting for file</source>
<target>Wachten op bestand</target>
@@ -5340,31 +5610,39 @@ Om verbinding te maken, vraagt u uw contact om een andere verbinding link te mak
</trans-unit>
<trans-unit id="You are already connecting to %@." xml:space="preserve">
<source>You are already connecting to %@.</source>
<target>U maakt al verbinding met %@.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="You are already connecting via this one-time link!" xml:space="preserve">
<source>You are already connecting via this one-time link!</source>
<target>Je maakt al verbinding via deze eenmalige link!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="You are already in group %@." xml:space="preserve">
<source>You are already in group %@.</source>
<target>Je zit al in groep %@.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="You are already joining the group %@." xml:space="preserve">
<source>You are already joining the group %@.</source>
<target>Je bent al lid van de groep %@.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="You are already joining the group via this link!" xml:space="preserve">
<source>You are already joining the group via this link!</source>
<target>Je wordt al lid van de groep via deze link!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="You are already joining the group via this link." xml:space="preserve">
<source>You are already joining the group via this link.</source>
<target>Je wordt al lid van de groep via deze link.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="You are already joining the group!&#10;Repeat join request?" xml:space="preserve">
<source>You are already joining the group!
Repeat join request?</source>
<target>Je sluit je al aan bij de groep!
Deelnameverzoek herhalen?</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="You are connected to the server used to receive messages from this contact." xml:space="preserve">
@@ -5464,11 +5742,14 @@ Repeat join request?</source>
</trans-unit>
<trans-unit id="You have already requested connection via this address!" xml:space="preserve">
<source>You have already requested connection via this address!</source>
<target>U heeft al een verbinding aangevraagd via dit adres!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="You have already requested connection!&#10;Repeat connection request?" xml:space="preserve">
<source>You have already requested connection!
Repeat connection request?</source>
<target>Je hebt al verbinding aangevraagd!
Verbindingsverzoek herhalen?</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="You have no chats" xml:space="preserve">
@@ -5523,6 +5804,7 @@ Repeat connection request?</source>
</trans-unit>
<trans-unit id="You will be connected when group link host's device is online, please wait or check later!" xml:space="preserve">
<source>You will be connected when group link host's device is online, please wait or check later!</source>
<target>U wordt verbonden wanneer het apparaat van de groep link host online is. Wacht even of controleer het later opnieuw!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="You will be connected when your connection request is accepted, please wait or check later!" xml:space="preserve">
@@ -5542,6 +5824,7 @@ Repeat connection request?</source>
</trans-unit>
<trans-unit id="You will connect to all group members." xml:space="preserve">
<source>You will connect to all group members.</source>
<target>Je maakt verbinding met alle leden.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="You will still receive calls and notifications from muted profiles when they are active." xml:space="preserve">
@@ -5665,6 +5948,7 @@ U kunt dit wijzigen in Instellingen.</target>
</trans-unit>
<trans-unit id="Your profile" xml:space="preserve">
<source>Your profile</source>
<target>Jouw profiel</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Your profile **%@** will be shared." xml:space="preserve">
@@ -5761,6 +6045,7 @@ SimpleX servers kunnen uw profiel niet zien.</target>
</trans-unit>
<trans-unit id="and %lld other events" xml:space="preserve">
<source>and %lld other events</source>
<target>en %lld andere gebeurtenissen</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="audio call (not e2e encrypted)" xml:space="preserve">
@@ -5768,6 +6053,11 @@ SimpleX servers kunnen uw profiel niet zien.</target>
<target>audio oproep (niet e2e versleuteld)</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="author" xml:space="preserve">
<source>author</source>
<target>auteur</target>
<note>member role</note>
</trans-unit>
<trans-unit id="bad message ID" xml:space="preserve">
<source>bad message ID</source>
<target>Onjuiste bericht-ID</target>
@@ -5780,6 +6070,7 @@ SimpleX servers kunnen uw profiel niet zien.</target>
</trans-unit>
<trans-unit id="blocked" xml:space="preserve">
<source>blocked</source>
<target>geblokkeerd</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="bold" xml:space="preserve">
@@ -5954,6 +6245,7 @@ SimpleX servers kunnen uw profiel niet zien.</target>
</trans-unit>
<trans-unit id="deleted contact" xml:space="preserve">
<source>deleted contact</source>
<target>verwijderd contact</target>
<note>rcv direct event chat item</note>
</trans-unit>
<trans-unit id="deleted group" xml:space="preserve">
@@ -6168,7 +6460,7 @@ SimpleX servers kunnen uw profiel niet zien.</target>
</trans-unit>
<trans-unit id="member" xml:space="preserve">
<source>member</source>
<target>gebruiker</target>
<target>lid</target>
<note>member role</note>
</trans-unit>
<trans-unit id="member connected" xml:space="preserve">
@@ -6348,6 +6640,11 @@ SimpleX servers kunnen uw profiel niet zien.</target>
<target>bijgewerkt groep profiel</target>
<note>rcv group event chat item</note>
</trans-unit>
<trans-unit id="v%@" xml:space="preserve">
<source>v%@</source>
<target>v%@</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="v%@ (%@)" xml:space="preserve">
<source>v%@ (%@)</source>
<target>v%@ (%@)</target>
@@ -6485,6 +6782,11 @@ SimpleX servers kunnen uw profiel niet zien.</target>
<target>SimpleX gebruikt Face-ID voor lokale authenticatie</target>
<note>Privacy - Face ID Usage Description</note>
</trans-unit>
<trans-unit id="NSLocalNetworkUsageDescription" xml:space="preserve">
<source>SimpleX uses local network access to allow using user chat profile via desktop app on the same network.</source>
<target>SimpleX maakt gebruik van lokale netwerktoegang om het gebruik van een gebruikerschatprofiel via de desktop-app op hetzelfde netwerk mogelijk te maken.</target>
<note>Privacy - Local Network Usage Description</note>
</trans-unit>
<trans-unit id="NSMicrophoneUsageDescription" xml:space="preserve">
<source>SimpleX needs microphone access for audio and video calls, and to record voice messages.</source>
<target>SimpleX heeft microfoon toegang nodig voor audio en video oproepen en om spraak berichten op te nemen.</target>

View File

@@ -4,6 +4,8 @@
"NSCameraUsageDescription" = "SimpleX needs camera access to scan QR codes to connect to other users and for video calls.";
/* Privacy - Face ID Usage Description */
"NSFaceIDUsageDescription" = "SimpleX uses Face ID for local authentication";
/* Privacy - Local Network Usage Description */
"NSLocalNetworkUsageDescription" = "SimpleX uses local network access to allow using user chat profile via desktop app on the same network.";
/* Privacy - Microphone Usage Description */
"NSMicrophoneUsageDescription" = "SimpleX needs microphone access for audio and video calls, and to record voice messages.";
/* Privacy - Photo Library Additions Usage Description */

View File

@@ -89,6 +89,7 @@
</trans-unit>
<trans-unit id="%@ and %@" xml:space="preserve">
<source>%@ and %@</source>
<target>%@ i %@</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="%@ and %@ connected" xml:space="preserve">
@@ -103,6 +104,7 @@
</trans-unit>
<trans-unit id="%@ connected" xml:space="preserve">
<source>%@ connected</source>
<target>%@ połączony</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="%@ is connected!" xml:space="preserve">
@@ -132,6 +134,7 @@
</trans-unit>
<trans-unit id="%@, %@ and %lld members" xml:space="preserve">
<source>%@, %@ and %lld members</source>
<target>%@, %@ i %lld członków</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="%@, %@ and %lld other members connected" xml:space="preserve">
@@ -201,6 +204,7 @@
</trans-unit>
<trans-unit id="%lld group events" xml:space="preserve">
<source>%lld group events</source>
<target>%lld wydarzeń grupy</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="%lld members" xml:space="preserve">
@@ -210,14 +214,17 @@
</trans-unit>
<trans-unit id="%lld messages blocked" xml:space="preserve">
<source>%lld messages blocked</source>
<target>%lld wiadomości zablokowanych</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="%lld messages marked deleted" xml:space="preserve">
<source>%lld messages marked deleted</source>
<target>%lld wiadomości oznaczonych do usunięcia</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="%lld messages moderated by %@" xml:space="preserve">
<source>%lld messages moderated by %@</source>
<target>%lld wiadomości zmoderowanych przez %@</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="%lld minutes" xml:space="preserve">
@@ -290,6 +297,16 @@
<target>(</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="(new)" xml:space="preserve">
<source>(new)</source>
<target>(nowy)</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="(this device v%@)" xml:space="preserve">
<source>(this device v%@)</source>
<target>(to urządzenie v%@)</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id=")" xml:space="preserve">
<source>)</source>
<target>)</target>
@@ -378,6 +395,15 @@
- i więcej!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="- optionally notify deleted contacts.&#10;- profile names with spaces.&#10;- and more!" xml:space="preserve">
<source>- optionally notify deleted contacts.
- profile names with spaces.
- and more!</source>
<target>- opcjonalnie powiadamiaj usunięte kontakty.
- nazwy profili ze spacją.
- i wiele więcej!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="- voice messages up to 5 minutes.&#10;- custom time to disappear.&#10;- editing history." xml:space="preserve">
<source>- voice messages up to 5 minutes.
- custom time to disappear.
@@ -394,6 +420,7 @@
</trans-unit>
<trans-unit id="0 sec" xml:space="preserve">
<source>0 sec</source>
<target>0 sek</target>
<note>time to disappear</note>
</trans-unit>
<trans-unit id="0s" xml:space="preserve">
@@ -623,6 +650,7 @@
</trans-unit>
<trans-unit id="All new messages from %@ will be hidden!" xml:space="preserve">
<source>All new messages from %@ will be hidden!</source>
<target>Wszystkie nowe wiadomości z %@ zostaną ukryte!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="All your contacts will remain connected." xml:space="preserve">
@@ -732,10 +760,12 @@
</trans-unit>
<trans-unit id="Already connecting!" xml:space="preserve">
<source>Already connecting!</source>
<target>Już połączony!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Already joining the group!" xml:space="preserve">
<source>Already joining the group!</source>
<target>Już dołączono do grupy!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Always use relay" xml:space="preserve">
@@ -858,6 +888,11 @@
<target>Wstecz</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Bad desktop address" xml:space="preserve">
<source>Bad desktop address</source>
<target>Zły adres komputera</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Bad message ID" xml:space="preserve">
<source>Bad message ID</source>
<target>Zły identyfikator wiadomości</target>
@@ -868,6 +903,11 @@
<target>Zły hash wiadomości</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Better groups" xml:space="preserve">
<source>Better groups</source>
<target>Lepsze grupy</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Better messages" xml:space="preserve">
<source>Better messages</source>
<target>Lepsze wiadomości</target>
@@ -875,14 +915,22 @@
</trans-unit>
<trans-unit id="Block" xml:space="preserve">
<source>Block</source>
<target>Zablokuj</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Block group members" xml:space="preserve">
<source>Block group members</source>
<target>Blokuj członków grupy</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Block member" xml:space="preserve">
<source>Block member</source>
<target>Zablokuj członka</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Block member?" xml:space="preserve">
<source>Block member?</source>
<target>Zablokować członka?</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Both you and your contact can add message reactions." xml:space="preserve">
@@ -1146,27 +1194,43 @@
<target>Połącz</target>
<note>server test step</note>
</trans-unit>
<trans-unit id="Connect automatically" xml:space="preserve">
<source>Connect automatically</source>
<target>Łącz automatycznie</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connect incognito" xml:space="preserve">
<source>Connect incognito</source>
<target>Połącz incognito</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connect to desktop" xml:space="preserve">
<source>Connect to desktop</source>
<target>Połącz do komputera</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connect to yourself?" xml:space="preserve">
<source>Connect to yourself?</source>
<target>Połączyć się ze sobą?</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connect to yourself?&#10;This is your own SimpleX address!" xml:space="preserve">
<source>Connect to yourself?
This is your own SimpleX address!</source>
<target>Połączyć się ze sobą?
To jest twój własny adres SimpleX!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connect to yourself?&#10;This is your own one-time link!" xml:space="preserve">
<source>Connect to yourself?
This is your own one-time link!</source>
<target>Połączyć się ze sobą?
To jest twój jednorazowy link!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connect via contact address" xml:space="preserve">
<source>Connect via contact address</source>
<target>Połącz przez adres kontaktowy</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connect via link" xml:space="preserve">
@@ -1186,6 +1250,17 @@ This is your own one-time link!</source>
</trans-unit>
<trans-unit id="Connect with %@" xml:space="preserve">
<source>Connect with %@</source>
<target>Połącz z %@</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connected desktop" xml:space="preserve">
<source>Connected desktop</source>
<target>Połączony komputer</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connected to desktop" xml:space="preserve">
<source>Connected to desktop</source>
<target>Połączony do komputera</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connecting server…" xml:space="preserve">
@@ -1198,6 +1273,11 @@ This is your own one-time link!</source>
<target>Łączenie z serwerem... (błąd: %@)</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connecting to desktop" xml:space="preserve">
<source>Connecting to desktop</source>
<target>Łączenie z komputerem</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connection" xml:space="preserve">
<source>Connection</source>
<target>Połączenie</target>
@@ -1218,6 +1298,11 @@ This is your own one-time link!</source>
<target>Prośba o połączenie wysłana!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connection terminated" xml:space="preserve">
<source>Connection terminated</source>
<target>Połączenie zakończone</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connection timeout" xml:space="preserve">
<source>Connection timeout</source>
<target>Czas połączenia minął</target>
@@ -1285,6 +1370,7 @@ This is your own one-time link!</source>
</trans-unit>
<trans-unit id="Correct name to %@?" xml:space="preserve">
<source>Correct name to %@?</source>
<target>Poprawić imię na %@?</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Create" xml:space="preserve">
@@ -1297,6 +1383,11 @@ This is your own one-time link!</source>
<target>Utwórz adres SimpleX</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Create a group using a random profile." xml:space="preserve">
<source>Create a group using a random profile.</source>
<target>Utwórz grupę używając losowego profilu.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Create an address to let people connect with you." xml:space="preserve">
<source>Create an address to let people connect with you.</source>
<target>Utwórz adres, aby ludzie mogli się z Tobą połączyć.</target>
@@ -1309,6 +1400,7 @@ This is your own one-time link!</source>
</trans-unit>
<trans-unit id="Create group" xml:space="preserve">
<source>Create group</source>
<target>Utwórz grupę</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Create group link" xml:space="preserve">
@@ -1333,6 +1425,7 @@ This is your own one-time link!</source>
</trans-unit>
<trans-unit id="Create profile" xml:space="preserve">
<source>Create profile</source>
<target>Utwórz profil</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Create queue" xml:space="preserve">
@@ -1495,6 +1588,7 @@ This is your own one-time link!</source>
</trans-unit>
<trans-unit id="Delete %lld messages?" xml:space="preserve">
<source>Delete %lld messages?</source>
<target>Usunąć %lld wiadomości?</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Delete Contact" xml:space="preserve">
@@ -1524,6 +1618,7 @@ This is your own one-time link!</source>
</trans-unit>
<trans-unit id="Delete and notify contact" xml:space="preserve">
<source>Delete and notify contact</source>
<target>Usuń i powiadom kontakt</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Delete archive" xml:space="preserve">
@@ -1559,6 +1654,8 @@ This is your own one-time link!</source>
<trans-unit id="Delete contact?&#10;This cannot be undone!" xml:space="preserve">
<source>Delete contact?
This cannot be undone!</source>
<target>Usunąć kontakt?
To nie może być cofnięte!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Delete database" xml:space="preserve">
@@ -1701,6 +1798,21 @@ This cannot be undone!</source>
<target>Opis</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Desktop address" xml:space="preserve">
<source>Desktop address</source>
<target>Adres komputera</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Desktop app version %@ is not compatible with this app." xml:space="preserve">
<source>Desktop app version %@ is not compatible with this app.</source>
<target>Wersja aplikacji komputerowej %@ nie jest kompatybilna z tą aplikacją.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Desktop devices" xml:space="preserve">
<source>Desktop devices</source>
<target>Urządzenia komputerowe</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Develop" xml:space="preserve">
<source>Develop</source>
<target>Deweloperskie</target>
@@ -1791,11 +1903,21 @@ This cannot be undone!</source>
<target>Rozłącz</target>
<note>server test step</note>
</trans-unit>
<trans-unit id="Disconnect desktop?" xml:space="preserve">
<source>Disconnect desktop?</source>
<target>Rozłączyć komputer?</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Discover and join groups" xml:space="preserve">
<source>Discover and join groups</source>
<target>Odkrywaj i dołączaj do grup</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Discover via local network" xml:space="preserve">
<source>Discover via local network</source>
<target>Odkryj przez sieć lokalną</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Do NOT use SimpleX for emergency calls." xml:space="preserve">
<source>Do NOT use SimpleX for emergency calls.</source>
<target>NIE używaj SimpleX do połączeń alarmowych.</target>
@@ -1966,6 +2088,16 @@ This cannot be undone!</source>
<target>Zaszyfrowana wiadomość: nieoczekiwany błąd</target>
<note>notification</note>
</trans-unit>
<trans-unit id="Encryption re-negotiation error" xml:space="preserve">
<source>Encryption re-negotiation error</source>
<target>Błąd renegocjacji szyfrowania</target>
<note>message decrypt error item</note>
</trans-unit>
<trans-unit id="Encryption re-negotiation failed." xml:space="preserve">
<source>Encryption re-negotiation failed.</source>
<target>Renegocjacja szyfrowania nie powiodła się.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Enter Passcode" xml:space="preserve">
<source>Enter Passcode</source>
<target>Wprowadź Pin</target>
@@ -1978,6 +2110,7 @@ This cannot be undone!</source>
</trans-unit>
<trans-unit id="Enter group name…" xml:space="preserve">
<source>Enter group name…</source>
<target>Wpisz nazwę grupy…</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Enter passphrase…" xml:space="preserve">
@@ -1995,6 +2128,11 @@ This cannot be undone!</source>
<target>Wprowadź serwer ręcznie</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Enter this device name…" xml:space="preserve">
<source>Enter this device name…</source>
<target>Podaj nazwę urządzenia…</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Enter welcome message…" xml:space="preserve">
<source>Enter welcome message…</source>
<target>Wpisz wiadomość powitalną…</target>
@@ -2007,6 +2145,7 @@ This cannot be undone!</source>
</trans-unit>
<trans-unit id="Enter your name…" xml:space="preserve">
<source>Enter your name…</source>
<target>Wpisz swoją nazwę…</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Error" xml:space="preserve">
@@ -2286,6 +2425,7 @@ This cannot be undone!</source>
</trans-unit>
<trans-unit id="Expand" xml:space="preserve">
<source>Expand</source>
<target>Rozszerz</target>
<note>chat item action</note>
</trans-unit>
<trans-unit id="Export database" xml:space="preserve">
@@ -2318,6 +2458,11 @@ This cannot be undone!</source>
<target>Szybko i bez czekania aż nadawca będzie online!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Faster joining and more reliable messages." xml:space="preserve">
<source>Faster joining and more reliable messages.</source>
<target>Szybsze dołączenie i bardziej niezawodne wiadomości.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Favorite" xml:space="preserve">
<source>Favorite</source>
<target>Ulubione</target>
@@ -2413,6 +2558,11 @@ This cannot be undone!</source>
<target>Dla konsoli</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Found desktop" xml:space="preserve">
<source>Found desktop</source>
<target>Znaleziono komputer</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="French interface" xml:space="preserve">
<source>French interface</source>
<target>Francuski interfejs</target>
@@ -2435,6 +2585,7 @@ This cannot be undone!</source>
</trans-unit>
<trans-unit id="Fully decentralized visible only to members." xml:space="preserve">
<source>Fully decentralized visible only to members.</source>
<target>W pełni zdecentralizowana widoczna tylko dla członków.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Fully re-implemented - work in background!" xml:space="preserve">
@@ -2459,10 +2610,12 @@ This cannot be undone!</source>
</trans-unit>
<trans-unit id="Group already exists" xml:space="preserve">
<source>Group already exists</source>
<target>Grupa już istnieje</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Group already exists!" xml:space="preserve">
<source>Group already exists!</source>
<target>Grupa już istnieje!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Group display name" xml:space="preserve">
@@ -2735,6 +2888,11 @@ This cannot be undone!</source>
<target>Incognito</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Incognito groups" xml:space="preserve">
<source>Incognito groups</source>
<target>Grupy incognito</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Incognito mode" xml:space="preserve">
<source>Incognito mode</source>
<target>Tryb incognito</target>
@@ -2765,6 +2923,11 @@ This cannot be undone!</source>
<target>Niekompatybilna wersja bazy danych</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Incompatible version" xml:space="preserve">
<source>Incompatible version</source>
<target>Niekompatybilna wersja</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Incorrect passcode" xml:space="preserve">
<source>Incorrect passcode</source>
<target>Nieprawidłowy pin</target>
@@ -2814,6 +2977,7 @@ This cannot be undone!</source>
</trans-unit>
<trans-unit id="Invalid name!" xml:space="preserve">
<source>Invalid name!</source>
<target>Nieprawidłowa nazwa!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Invalid server address!" xml:space="preserve">
@@ -2909,6 +3073,7 @@ This cannot be undone!</source>
</trans-unit>
<trans-unit id="Join group?" xml:space="preserve">
<source>Join group?</source>
<target>Dołączyć do grupy?</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Join incognito" xml:space="preserve">
@@ -2918,11 +3083,14 @@ This cannot be undone!</source>
</trans-unit>
<trans-unit id="Join with current profile" xml:space="preserve">
<source>Join with current profile</source>
<target>Dołącz z obecnym profilem</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Join your group?&#10;This is your link for group %@!" xml:space="preserve">
<source>Join your group?
This is your link for group %@!</source>
<target>Dołączyć do twojej grupy?
To jest twój link do grupy %@!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Joining group" xml:space="preserve">
@@ -2930,6 +3098,11 @@ This is your link for group %@!</source>
<target>Dołączanie do grupy</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Keep the app open to use it from desktop" xml:space="preserve">
<source>Keep the app open to use it from desktop</source>
<target>Zostaw aplikację otwartą i używaj ją z komputera</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Keep your connections" xml:space="preserve">
<source>Keep your connections</source>
<target>Zachowaj swoje połączenia</target>
@@ -2990,6 +3163,21 @@ This is your link for group %@!</source>
<target>Ograniczenia</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Link mobile and desktop apps! 🔗" xml:space="preserve">
<source>Link mobile and desktop apps! 🔗</source>
<target>Połącz mobile i komputerowe aplikacje! 🔗</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Linked desktop options" xml:space="preserve">
<source>Linked desktop options</source>
<target>Połączone opcje komputera</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Linked desktops" xml:space="preserve">
<source>Linked desktops</source>
<target>Połączone komputery</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Live message!" xml:space="preserve">
<source>Live message!</source>
<target>Wiadomość na żywo!</target>
@@ -3142,6 +3330,7 @@ This is your link for group %@!</source>
</trans-unit>
<trans-unit id="Messages from %@ will be shown!" xml:space="preserve">
<source>Messages from %@ will be shown!</source>
<target>Wiadomości od %@ zostaną pokazane!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Migrating database archive…" xml:space="preserve">
@@ -3339,6 +3528,11 @@ This is your link for group %@!</source>
<target>Brak odebranych lub wysłanych plików</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Not compatible!" xml:space="preserve">
<source>Not compatible!</source>
<target>Nie kompatybilny!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Notifications" xml:space="preserve">
<source>Notifications</source>
<target>Powiadomienia</target>
@@ -3495,6 +3689,7 @@ This is your link for group %@!</source>
</trans-unit>
<trans-unit id="Open group" xml:space="preserve">
<source>Open group</source>
<target>Grupa otwarta</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Open user profiles" xml:space="preserve">
@@ -3557,6 +3752,11 @@ This is your link for group %@!</source>
<target>Wklej</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Paste desktop address" xml:space="preserve">
<source>Paste desktop address</source>
<target>Wklej adres komputera</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Paste image" xml:space="preserve">
<source>Paste image</source>
<target>Wklej obraz</target>
@@ -3704,10 +3904,12 @@ This is your link for group %@!</source>
</trans-unit>
<trans-unit id="Profile name" xml:space="preserve">
<source>Profile name</source>
<target>Nazwa profilu</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Profile name:" xml:space="preserve">
<source>Profile name:</source>
<target>Nazwa profilu:</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Profile password" xml:space="preserve">
@@ -3957,10 +4159,12 @@ This is your link for group %@!</source>
</trans-unit>
<trans-unit id="Repeat connection request?" xml:space="preserve">
<source>Repeat connection request?</source>
<target>Powtórzyć prośbę połączenia?</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Repeat join request?" xml:space="preserve">
<source>Repeat join request?</source>
<target>Powtórzyć prośbę dołączenia?</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Reply" xml:space="preserve">
@@ -4148,6 +4352,11 @@ This is your link for group %@!</source>
<target>Zeskanuj kod QR</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Scan QR code from desktop" xml:space="preserve">
<source>Scan QR code from desktop</source>
<target>Zeskanuj kod QR z komputera</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Scan code" xml:space="preserve">
<source>Scan code</source>
<target>Zeskanuj kod</target>
@@ -4368,6 +4577,11 @@ This is your link for group %@!</source>
<target>Serwery</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Session code" xml:space="preserve">
<source>Session code</source>
<target>Kod sesji</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Set 1 day" xml:space="preserve">
<source>Set 1 day</source>
<target>Ustaw 1 dzień</target>
@@ -4680,6 +4894,7 @@ This is your link for group %@!</source>
</trans-unit>
<trans-unit id="Tap to Connect" xml:space="preserve">
<source>Tap to Connect</source>
<target>Dotknij aby połączyć</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Tap to activate profile." xml:space="preserve">
@@ -4864,6 +5079,11 @@ Może się to zdarzyć z powodu jakiegoś błędu lub gdy połączenie jest skom
<target>Tego działania nie można cofnąć - Twój profil, kontakty, wiadomości i pliki zostaną nieodwracalnie utracone.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="This device name" xml:space="preserve">
<source>This device name</source>
<target>Nazwa tego urządzenia</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="This group has over %lld members, delivery receipts are not sent." xml:space="preserve">
<source>This group has over %lld members, delivery receipts are not sent.</source>
<target>Ta grupa ma ponad %lld członków, potwierdzenia dostawy nie są wysyłane.</target>
@@ -4876,10 +5096,12 @@ Może się to zdarzyć z powodu jakiegoś błędu lub gdy połączenie jest skom
</trans-unit>
<trans-unit id="This is your own SimpleX address!" xml:space="preserve">
<source>This is your own SimpleX address!</source>
<target>To jest twój własny adres SimpleX!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="This is your own one-time link!" xml:space="preserve">
<source>This is your own one-time link!</source>
<target>To jest twój jednorazowy link!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="This setting applies to messages in your current chat profile **%@**." xml:space="preserve">
@@ -4897,6 +5119,11 @@ Może się to zdarzyć z powodu jakiegoś błędu lub gdy połączenie jest skom
<target>Aby się połączyć, Twój kontakt może zeskanować kod QR lub skorzystać z linku w aplikacji.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="To hide unwanted messages." xml:space="preserve">
<source>To hide unwanted messages.</source>
<target>Aby ukryć niechciane wiadomości.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="To make a new connection" xml:space="preserve">
<source>To make a new connection</source>
<target>Aby nawiązać nowe połączenie</target>
@@ -4981,14 +5208,17 @@ Przed włączeniem tej funkcji zostanie wyświetlony monit uwierzytelniania.</ta
</trans-unit>
<trans-unit id="Unblock" xml:space="preserve">
<source>Unblock</source>
<target>Odblokuj</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Unblock member" xml:space="preserve">
<source>Unblock member</source>
<target>Odblokuj członka</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Unblock member?" xml:space="preserve">
<source>Unblock member?</source>
<target>Odblokować członka?</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Unexpected error: %@" xml:space="preserve">
@@ -5053,6 +5283,16 @@ To connect, please ask your contact to create another connection link and check
Aby się połączyć, poproś Twój kontakt o utworzenie kolejnego linku połączenia i sprawdź, czy masz stabilne połączenie z siecią.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Unlink" xml:space="preserve">
<source>Unlink</source>
<target>Odłącz</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Unlink desktop?" xml:space="preserve">
<source>Unlink desktop?</source>
<target>Odłączyć komputer?</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Unlock" xml:space="preserve">
<source>Unlock</source>
<target>Odblokuj</target>
@@ -5143,6 +5383,11 @@ Aby się połączyć, poproś Twój kontakt o utworzenie kolejnego linku połąc
<target>Użyj dla nowych połączeń</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Use from desktop" xml:space="preserve">
<source>Use from desktop</source>
<target>Użyj z komputera</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Use iOS call interface" xml:space="preserve">
<source>Use iOS call interface</source>
<target>Użyj interfejsu połączeń iOS</target>
@@ -5173,11 +5418,26 @@ Aby się połączyć, poproś Twój kontakt o utworzenie kolejnego linku połąc
<target>Używanie serwerów SimpleX Chat.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Verify code with desktop" xml:space="preserve">
<source>Verify code with desktop</source>
<target>Zweryfikuj kod z komputera</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Verify connection" xml:space="preserve">
<source>Verify connection</source>
<target>Zweryfikuj połączenie</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Verify connection security" xml:space="preserve">
<source>Verify connection security</source>
<target>Weryfikuj bezpieczeństwo połączenia</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Verify connections" xml:space="preserve">
<source>Verify connections</source>
<target>Zweryfikuj połączenia</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Verify security code" xml:space="preserve">
<source>Verify security code</source>
<target>Weryfikuj kod bezpieczeństwa</target>
@@ -5188,6 +5448,11 @@ Aby się połączyć, poproś Twój kontakt o utworzenie kolejnego linku połąc
<target>Przez przeglądarkę</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Via secure quantum resistant protocol." xml:space="preserve">
<source>Via secure quantum resistant protocol.</source>
<target>Dzięki bezpiecznemu protokołowi odpornego kwantowo.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Video call" xml:space="preserve">
<source>Video call</source>
<target>Połączenie wideo</target>
@@ -5238,6 +5503,11 @@ Aby się połączyć, poproś Twój kontakt o utworzenie kolejnego linku połąc
<target>Wiadomość głosowa…</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Waiting for desktop..." xml:space="preserve">
<source>Waiting for desktop...</source>
<target>Oczekiwanie na komputer...</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Waiting for file" xml:space="preserve">
<source>Waiting for file</source>
<target>Oczekiwanie na plik</target>
@@ -5340,31 +5610,39 @@ Aby się połączyć, poproś Twój kontakt o utworzenie kolejnego linku połąc
</trans-unit>
<trans-unit id="You are already connecting to %@." xml:space="preserve">
<source>You are already connecting to %@.</source>
<target>Już się łączysz z %@.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="You are already connecting via this one-time link!" xml:space="preserve">
<source>You are already connecting via this one-time link!</source>
<target>Już jesteś połączony z tym jednorazowym linkiem!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="You are already in group %@." xml:space="preserve">
<source>You are already in group %@.</source>
<target>Już jesteś w grupie %@.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="You are already joining the group %@." xml:space="preserve">
<source>You are already joining the group %@.</source>
<target>Już dołączasz do grupy %@.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="You are already joining the group via this link!" xml:space="preserve">
<source>You are already joining the group via this link!</source>
<target>Już dołączasz do grupy przez ten link!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="You are already joining the group via this link." xml:space="preserve">
<source>You are already joining the group via this link.</source>
<target>Już dołączasz do grupy przez ten link.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="You are already joining the group!&#10;Repeat join request?" xml:space="preserve">
<source>You are already joining the group!
Repeat join request?</source>
<target>Już dołączasz do grupy!
Powtórzyć prośbę dołączenia?</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="You are connected to the server used to receive messages from this contact." xml:space="preserve">
@@ -5464,11 +5742,14 @@ Repeat join request?</source>
</trans-unit>
<trans-unit id="You have already requested connection via this address!" xml:space="preserve">
<source>You have already requested connection via this address!</source>
<target>Już prosiłeś o połączenie na ten adres!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="You have already requested connection!&#10;Repeat connection request?" xml:space="preserve">
<source>You have already requested connection!
Repeat connection request?</source>
<target>Już prosiłeś o połączenie!
Powtórzyć prośbę połączenia?</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="You have no chats" xml:space="preserve">
@@ -5523,6 +5804,7 @@ Repeat connection request?</source>
</trans-unit>
<trans-unit id="You will be connected when group link host's device is online, please wait or check later!" xml:space="preserve">
<source>You will be connected when group link host's device is online, please wait or check later!</source>
<target>Zostaniesz połączony, gdy urządzenie hosta grupy będzie online, proszę czekać lub sprawdzić później!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="You will be connected when your connection request is accepted, please wait or check later!" xml:space="preserve">
@@ -5542,6 +5824,7 @@ Repeat connection request?</source>
</trans-unit>
<trans-unit id="You will connect to all group members." xml:space="preserve">
<source>You will connect to all group members.</source>
<target>Zostaniesz połączony ze wszystkimi członkami grupy.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="You will still receive calls and notifications from muted profiles when they are active." xml:space="preserve">
@@ -5665,6 +5948,7 @@ Możesz to zmienić w Ustawieniach.</target>
</trans-unit>
<trans-unit id="Your profile" xml:space="preserve">
<source>Your profile</source>
<target>Twój profil</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Your profile **%@** will be shared." xml:space="preserve">
@@ -5761,6 +6045,7 @@ Serwery SimpleX nie mogą zobaczyć Twojego profilu.</target>
</trans-unit>
<trans-unit id="and %lld other events" xml:space="preserve">
<source>and %lld other events</source>
<target>i %lld innych wydarzeń</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="audio call (not e2e encrypted)" xml:space="preserve">
@@ -5768,6 +6053,11 @@ Serwery SimpleX nie mogą zobaczyć Twojego profilu.</target>
<target>połączenie audio (nie szyfrowane e2e)</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="author" xml:space="preserve">
<source>author</source>
<target>autor</target>
<note>member role</note>
</trans-unit>
<trans-unit id="bad message ID" xml:space="preserve">
<source>bad message ID</source>
<target>zły identyfikator wiadomości</target>
@@ -5780,6 +6070,7 @@ Serwery SimpleX nie mogą zobaczyć Twojego profilu.</target>
</trans-unit>
<trans-unit id="blocked" xml:space="preserve">
<source>blocked</source>
<target>zablokowany</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="bold" xml:space="preserve">
@@ -5954,6 +6245,7 @@ Serwery SimpleX nie mogą zobaczyć Twojego profilu.</target>
</trans-unit>
<trans-unit id="deleted contact" xml:space="preserve">
<source>deleted contact</source>
<target>usunięto kontakt</target>
<note>rcv direct event chat item</note>
</trans-unit>
<trans-unit id="deleted group" xml:space="preserve">
@@ -6348,6 +6640,11 @@ Serwery SimpleX nie mogą zobaczyć Twojego profilu.</target>
<target>zaktualizowano profil grupy</target>
<note>rcv group event chat item</note>
</trans-unit>
<trans-unit id="v%@" xml:space="preserve">
<source>v%@</source>
<target>v%@</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="v%@ (%@)" xml:space="preserve">
<source>v%@ (%@)</source>
<target>v%@ (%@)</target>
@@ -6485,6 +6782,11 @@ Serwery SimpleX nie mogą zobaczyć Twojego profilu.</target>
<target>SimpleX używa Face ID do lokalnego uwierzytelniania</target>
<note>Privacy - Face ID Usage Description</note>
</trans-unit>
<trans-unit id="NSLocalNetworkUsageDescription" xml:space="preserve">
<source>SimpleX uses local network access to allow using user chat profile via desktop app on the same network.</source>
<target>SimpleX używa sieci lokalnej aby pozwolić na dostęp profilom czatu użytkownika przez aplikację komputerową na tej samej sieci.</target>
<note>Privacy - Local Network Usage Description</note>
</trans-unit>
<trans-unit id="NSMicrophoneUsageDescription" xml:space="preserve">
<source>SimpleX needs microphone access for audio and video calls, and to record voice messages.</source>
<target>SimpleX potrzebuje dostępu do mikrofonu, w celu połączeń audio i wideo oraz nagrywania wiadomości głosowych.</target>

View File

@@ -4,6 +4,8 @@
"NSCameraUsageDescription" = "SimpleX needs camera access to scan QR codes to connect to other users and for video calls.";
/* Privacy - Face ID Usage Description */
"NSFaceIDUsageDescription" = "SimpleX uses Face ID for local authentication";
/* Privacy - Local Network Usage Description */
"NSLocalNetworkUsageDescription" = "SimpleX uses local network access to allow using user chat profile via desktop app on the same network.";
/* Privacy - Microphone Usage Description */
"NSMicrophoneUsageDescription" = "SimpleX needs microphone access for audio and video calls, and to record voice messages.";
/* Privacy - Photo Library Additions Usage Description */

View File

@@ -89,6 +89,7 @@
</trans-unit>
<trans-unit id="%@ and %@" xml:space="preserve">
<source>%@ and %@</source>
<target>%@ и %@</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="%@ and %@ connected" xml:space="preserve">
@@ -103,6 +104,7 @@
</trans-unit>
<trans-unit id="%@ connected" xml:space="preserve">
<source>%@ connected</source>
<target>%@ соединен(а)</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="%@ is connected!" xml:space="preserve">
@@ -132,6 +134,7 @@
</trans-unit>
<trans-unit id="%@, %@ and %lld members" xml:space="preserve">
<source>%@, %@ and %lld members</source>
<target>%@, %@ и %lld членов группы</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="%@, %@ and %lld other members connected" xml:space="preserve">
@@ -201,6 +204,7 @@
</trans-unit>
<trans-unit id="%lld group events" xml:space="preserve">
<source>%lld group events</source>
<target>%lld событий</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="%lld members" xml:space="preserve">
@@ -210,14 +214,17 @@
</trans-unit>
<trans-unit id="%lld messages blocked" xml:space="preserve">
<source>%lld messages blocked</source>
<target>%lld сообщений заблокировано</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="%lld messages marked deleted" xml:space="preserve">
<source>%lld messages marked deleted</source>
<target>%lld сообщений помечено удалёнными</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="%lld messages moderated by %@" xml:space="preserve">
<source>%lld messages moderated by %@</source>
<target>%lld сообщений модерировано членом %@</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="%lld minutes" xml:space="preserve">
@@ -290,6 +297,16 @@
<target>(</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="(new)" xml:space="preserve">
<source>(new)</source>
<target>(новое)</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="(this device v%@)" xml:space="preserve">
<source>(this device v%@)</source>
<target>(это устройство v%@)</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id=")" xml:space="preserve">
<source>)</source>
<target>)</target>
@@ -375,6 +392,15 @@
- and more!</source>
<target>- более стабильная доставка сообщений.
- немного улучшенные группы.
- и прочее!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="- optionally notify deleted contacts.&#10;- profile names with spaces.&#10;- and more!" xml:space="preserve">
<source>- optionally notify deleted contacts.
- profile names with spaces.
- and more!</source>
<target>- опционально уведомляйте удалённые контакты.
- имена профилей с пробелами.
- и прочее!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
@@ -394,6 +420,7 @@
</trans-unit>
<trans-unit id="0 sec" xml:space="preserve">
<source>0 sec</source>
<target>0 сек</target>
<note>time to disappear</note>
</trans-unit>
<trans-unit id="0s" xml:space="preserve">
@@ -623,6 +650,7 @@
</trans-unit>
<trans-unit id="All new messages from %@ will be hidden!" xml:space="preserve">
<source>All new messages from %@ will be hidden!</source>
<target>Все новые сообщения от %@ будут скрыты!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="All your contacts will remain connected." xml:space="preserve">
@@ -732,10 +760,12 @@
</trans-unit>
<trans-unit id="Already connecting!" xml:space="preserve">
<source>Already connecting!</source>
<target>Уже соединяется!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Already joining the group!" xml:space="preserve">
<source>Already joining the group!</source>
<target>Вступление в группу уже начато!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Always use relay" xml:space="preserve">
@@ -858,6 +888,11 @@
<target>Назад</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Bad desktop address" xml:space="preserve">
<source>Bad desktop address</source>
<target>Неверный адрес компьютера</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Bad message ID" xml:space="preserve">
<source>Bad message ID</source>
<target>Ошибка ID сообщения</target>
@@ -868,6 +903,11 @@
<target>Ошибка хэш сообщения</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Better groups" xml:space="preserve">
<source>Better groups</source>
<target>Улучшенные группы</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Better messages" xml:space="preserve">
<source>Better messages</source>
<target>Улучшенные сообщения</target>
@@ -875,14 +915,22 @@
</trans-unit>
<trans-unit id="Block" xml:space="preserve">
<source>Block</source>
<target>Заблокировать</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Block group members" xml:space="preserve">
<source>Block group members</source>
<target>Блокируйте членов группы</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Block member" xml:space="preserve">
<source>Block member</source>
<target>Заблокировать члена группы</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Block member?" xml:space="preserve">
<source>Block member?</source>
<target>Заблокировать члена группы?</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Both you and your contact can add message reactions." xml:space="preserve">
@@ -1146,27 +1194,43 @@
<target>Соединиться</target>
<note>server test step</note>
</trans-unit>
<trans-unit id="Connect automatically" xml:space="preserve">
<source>Connect automatically</source>
<target>Соединяться автоматически</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connect incognito" xml:space="preserve">
<source>Connect incognito</source>
<target>Соединиться Инкогнито</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connect to desktop" xml:space="preserve">
<source>Connect to desktop</source>
<target>Подключиться к компьютеру</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connect to yourself?" xml:space="preserve">
<source>Connect to yourself?</source>
<target>Соединиться с самим собой?</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connect to yourself?&#10;This is your own SimpleX address!" xml:space="preserve">
<source>Connect to yourself?
This is your own SimpleX address!</source>
<target>Соединиться с самим собой?
Это ваш собственный адрес SimpleX!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connect to yourself?&#10;This is your own one-time link!" xml:space="preserve">
<source>Connect to yourself?
This is your own one-time link!</source>
<target>Соединиться с самим собой?
Это ваша собственная одноразовая ссылка!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connect via contact address" xml:space="preserve">
<source>Connect via contact address</source>
<target>Соединиться через адрес</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connect via link" xml:space="preserve">
@@ -1186,6 +1250,17 @@ This is your own one-time link!</source>
</trans-unit>
<trans-unit id="Connect with %@" xml:space="preserve">
<source>Connect with %@</source>
<target>Соединиться с %@</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connected desktop" xml:space="preserve">
<source>Connected desktop</source>
<target>Подключенный компьютер</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connected to desktop" xml:space="preserve">
<source>Connected to desktop</source>
<target>Компьютер подключен</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connecting server…" xml:space="preserve">
@@ -1198,6 +1273,11 @@ This is your own one-time link!</source>
<target>Устанавливается соединение с сервером… (ошибка: %@)</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connecting to desktop" xml:space="preserve">
<source>Connecting to desktop</source>
<target>Подключение к компьютеру</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connection" xml:space="preserve">
<source>Connection</source>
<target>Соединение</target>
@@ -1218,6 +1298,11 @@ This is your own one-time link!</source>
<target>Запрос на соединение отправлен!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connection terminated" xml:space="preserve">
<source>Connection terminated</source>
<target>Подключение прервано</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connection timeout" xml:space="preserve">
<source>Connection timeout</source>
<target>Превышено время соединения</target>
@@ -1285,6 +1370,7 @@ This is your own one-time link!</source>
</trans-unit>
<trans-unit id="Correct name to %@?" xml:space="preserve">
<source>Correct name to %@?</source>
<target>Исправить имя на %@?</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Create" xml:space="preserve">
@@ -1297,6 +1383,11 @@ This is your own one-time link!</source>
<target>Создать адрес SimpleX</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Create a group using a random profile." xml:space="preserve">
<source>Create a group using a random profile.</source>
<target>Создайте группу, используя случайный профиль.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Create an address to let people connect with you." xml:space="preserve">
<source>Create an address to let people connect with you.</source>
<target>Создайте адрес, чтобы можно было соединиться с вами.</target>
@@ -1309,6 +1400,7 @@ This is your own one-time link!</source>
</trans-unit>
<trans-unit id="Create group" xml:space="preserve">
<source>Create group</source>
<target>Создать группу</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Create group link" xml:space="preserve">
@@ -1333,6 +1425,7 @@ This is your own one-time link!</source>
</trans-unit>
<trans-unit id="Create profile" xml:space="preserve">
<source>Create profile</source>
<target>Создать профиль</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Create queue" xml:space="preserve">
@@ -1495,6 +1588,7 @@ This is your own one-time link!</source>
</trans-unit>
<trans-unit id="Delete %lld messages?" xml:space="preserve">
<source>Delete %lld messages?</source>
<target>Удалить %lld сообщений?</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Delete Contact" xml:space="preserve">
@@ -1524,6 +1618,7 @@ This is your own one-time link!</source>
</trans-unit>
<trans-unit id="Delete and notify contact" xml:space="preserve">
<source>Delete and notify contact</source>
<target>Удалить и уведомить контакт</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Delete archive" xml:space="preserve">
@@ -1559,6 +1654,8 @@ This is your own one-time link!</source>
<trans-unit id="Delete contact?&#10;This cannot be undone!" xml:space="preserve">
<source>Delete contact?
This cannot be undone!</source>
<target>Удалить контакт?
Это не может быть отменено!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Delete database" xml:space="preserve">
@@ -1701,6 +1798,21 @@ This cannot be undone!</source>
<target>Описание</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Desktop address" xml:space="preserve">
<source>Desktop address</source>
<target>Адрес компьютера</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Desktop app version %@ is not compatible with this app." xml:space="preserve">
<source>Desktop app version %@ is not compatible with this app.</source>
<target>Версия настольного приложения %@ несовместима с этим приложением.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Desktop devices" xml:space="preserve">
<source>Desktop devices</source>
<target>Компьютеры</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Develop" xml:space="preserve">
<source>Develop</source>
<target>Для разработчиков</target>
@@ -1791,11 +1903,21 @@ This cannot be undone!</source>
<target>Разрыв соединения</target>
<note>server test step</note>
</trans-unit>
<trans-unit id="Disconnect desktop?" xml:space="preserve">
<source>Disconnect desktop?</source>
<target>Отключить компьютер?</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Discover and join groups" xml:space="preserve">
<source>Discover and join groups</source>
<target>Найдите и вступите в группы</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Discover via local network" xml:space="preserve">
<source>Discover via local network</source>
<target>Обнаружение по локальной сети</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Do NOT use SimpleX for emergency calls." xml:space="preserve">
<source>Do NOT use SimpleX for emergency calls.</source>
<target>Не используйте SimpleX для экстренных звонков.</target>
@@ -1966,6 +2088,16 @@ This cannot be undone!</source>
<target>Зашифрованное сообщение: неожиданная ошибка</target>
<note>notification</note>
</trans-unit>
<trans-unit id="Encryption re-negotiation error" xml:space="preserve">
<source>Encryption re-negotiation error</source>
<target>Ошибка нового соглашения о шифровании</target>
<note>message decrypt error item</note>
</trans-unit>
<trans-unit id="Encryption re-negotiation failed." xml:space="preserve">
<source>Encryption re-negotiation failed.</source>
<target>Ошибка нового соглашения о шифровании.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Enter Passcode" xml:space="preserve">
<source>Enter Passcode</source>
<target>Введите Код</target>
@@ -1978,6 +2110,7 @@ This cannot be undone!</source>
</trans-unit>
<trans-unit id="Enter group name…" xml:space="preserve">
<source>Enter group name…</source>
<target>Введите имя группы…</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Enter passphrase…" xml:space="preserve">
@@ -1995,6 +2128,11 @@ This cannot be undone!</source>
<target>Ввести сервер вручную</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Enter this device name…" xml:space="preserve">
<source>Enter this device name…</source>
<target>Введите имя этого устройства…</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Enter welcome message…" xml:space="preserve">
<source>Enter welcome message…</source>
<target>Введите приветственное сообщение…</target>
@@ -2007,6 +2145,7 @@ This cannot be undone!</source>
</trans-unit>
<trans-unit id="Enter your name…" xml:space="preserve">
<source>Enter your name…</source>
<target>Введите ваше имя…</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Error" xml:space="preserve">
@@ -2066,6 +2205,7 @@ This cannot be undone!</source>
</trans-unit>
<trans-unit id="Error creating member contact" xml:space="preserve">
<source>Error creating member contact</source>
<target>Ошибка создания контакта с членом группы</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Error creating profile!" xml:space="preserve">
@@ -2200,6 +2340,7 @@ This cannot be undone!</source>
</trans-unit>
<trans-unit id="Error sending member contact invitation" xml:space="preserve">
<source>Error sending member contact invitation</source>
<target>Ошибка отправки приглашения члену группы</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Error sending message" xml:space="preserve">
@@ -2284,6 +2425,7 @@ This cannot be undone!</source>
</trans-unit>
<trans-unit id="Expand" xml:space="preserve">
<source>Expand</source>
<target>Раскрыть</target>
<note>chat item action</note>
</trans-unit>
<trans-unit id="Export database" xml:space="preserve">
@@ -2316,6 +2458,11 @@ This cannot be undone!</source>
<target>Быстрые и не нужно ждать, когда отправитель онлайн!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Faster joining and more reliable messages." xml:space="preserve">
<source>Faster joining and more reliable messages.</source>
<target>Быстрое вступление и надежная доставка сообщений.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Favorite" xml:space="preserve">
<source>Favorite</source>
<target>Избранный</target>
@@ -2411,6 +2558,11 @@ This cannot be undone!</source>
<target>Для консоли</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Found desktop" xml:space="preserve">
<source>Found desktop</source>
<target>Компьютер найден</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="French interface" xml:space="preserve">
<source>French interface</source>
<target>Французский интерфейс</target>
@@ -2433,6 +2585,7 @@ This cannot be undone!</source>
</trans-unit>
<trans-unit id="Fully decentralized visible only to members." xml:space="preserve">
<source>Fully decentralized visible only to members.</source>
<target>Группа полностью децентрализована она видна только членам.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Fully re-implemented - work in background!" xml:space="preserve">
@@ -2457,10 +2610,12 @@ This cannot be undone!</source>
</trans-unit>
<trans-unit id="Group already exists" xml:space="preserve">
<source>Group already exists</source>
<target>Группа уже существует</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Group already exists!" xml:space="preserve">
<source>Group already exists!</source>
<target>Группа уже существует!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Group display name" xml:space="preserve">
@@ -2733,6 +2888,11 @@ This cannot be undone!</source>
<target>Инкогнито</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Incognito groups" xml:space="preserve">
<source>Incognito groups</source>
<target>Инкогнито группы</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Incognito mode" xml:space="preserve">
<source>Incognito mode</source>
<target>Режим Инкогнито</target>
@@ -2763,6 +2923,11 @@ This cannot be undone!</source>
<target>Несовместимая версия базы данных</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Incompatible version" xml:space="preserve">
<source>Incompatible version</source>
<target>Несовместимая версия</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Incorrect passcode" xml:space="preserve">
<source>Incorrect passcode</source>
<target>Неправильный код</target>
@@ -2812,6 +2977,7 @@ This cannot be undone!</source>
</trans-unit>
<trans-unit id="Invalid name!" xml:space="preserve">
<source>Invalid name!</source>
<target>Неверное имя!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Invalid server address!" xml:space="preserve">
@@ -2907,6 +3073,7 @@ This cannot be undone!</source>
</trans-unit>
<trans-unit id="Join group?" xml:space="preserve">
<source>Join group?</source>
<target>Вступить в группу?</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Join incognito" xml:space="preserve">
@@ -2916,11 +3083,14 @@ This cannot be undone!</source>
</trans-unit>
<trans-unit id="Join with current profile" xml:space="preserve">
<source>Join with current profile</source>
<target>Вступить с активным профилем</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Join your group?&#10;This is your link for group %@!" xml:space="preserve">
<source>Join your group?
This is your link for group %@!</source>
<target>Вступить в вашу группу?
Это ваша ссылка на группу %@!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Joining group" xml:space="preserve">
@@ -2928,6 +3098,11 @@ This is your link for group %@!</source>
<target>Вступление в группу</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Keep the app open to use it from desktop" xml:space="preserve">
<source>Keep the app open to use it from desktop</source>
<target>Оставьте приложение открытым, чтобы использовать его с компьютера</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Keep your connections" xml:space="preserve">
<source>Keep your connections</source>
<target>Сохраните Ваши соединения</target>
@@ -2988,6 +3163,21 @@ This is your link for group %@!</source>
<target>Ограничения</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Link mobile and desktop apps! 🔗" xml:space="preserve">
<source>Link mobile and desktop apps! 🔗</source>
<target>Свяжите мобильное и настольное приложения! 🔗</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Linked desktop options" xml:space="preserve">
<source>Linked desktop options</source>
<target>Опции связанных компьютеров</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Linked desktops" xml:space="preserve">
<source>Linked desktops</source>
<target>Связанные компьютеры</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Live message!" xml:space="preserve">
<source>Live message!</source>
<target>Живое сообщение!</target>
@@ -3140,6 +3330,7 @@ This is your link for group %@!</source>
</trans-unit>
<trans-unit id="Messages from %@ will be shown!" xml:space="preserve">
<source>Messages from %@ will be shown!</source>
<target>Сообщения от %@ будут показаны!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Migrating database archive…" xml:space="preserve">
@@ -3337,6 +3528,11 @@ This is your link for group %@!</source>
<target>Нет полученных или отправленных файлов</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Not compatible!" xml:space="preserve">
<source>Not compatible!</source>
<target>Несовместимая версия!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Notifications" xml:space="preserve">
<source>Notifications</source>
<target>Уведомления</target>
@@ -3473,6 +3669,7 @@ This is your link for group %@!</source>
</trans-unit>
<trans-unit id="Open" xml:space="preserve">
<source>Open</source>
<target>Открыть</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Open Settings" xml:space="preserve">
@@ -3492,6 +3689,7 @@ This is your link for group %@!</source>
</trans-unit>
<trans-unit id="Open group" xml:space="preserve">
<source>Open group</source>
<target>Открыть группу</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Open user profiles" xml:space="preserve">
@@ -3554,6 +3752,11 @@ This is your link for group %@!</source>
<target>Вставить</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Paste desktop address" xml:space="preserve">
<source>Paste desktop address</source>
<target>Вставить адрес компьютера</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Paste image" xml:space="preserve">
<source>Paste image</source>
<target>Вставить изображение</target>
@@ -3701,10 +3904,12 @@ This is your link for group %@!</source>
</trans-unit>
<trans-unit id="Profile name" xml:space="preserve">
<source>Profile name</source>
<target>Имя профиля</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Profile name:" xml:space="preserve">
<source>Profile name:</source>
<target>Имя профиля:</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Profile password" xml:space="preserve">
@@ -3954,10 +4159,12 @@ This is your link for group %@!</source>
</trans-unit>
<trans-unit id="Repeat connection request?" xml:space="preserve">
<source>Repeat connection request?</source>
<target>Повторить запрос на соединение?</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Repeat join request?" xml:space="preserve">
<source>Repeat join request?</source>
<target>Повторить запрос на вступление?</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Reply" xml:space="preserve">
@@ -4145,6 +4352,11 @@ This is your link for group %@!</source>
<target>Сканировать QR код</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Scan QR code from desktop" xml:space="preserve">
<source>Scan QR code from desktop</source>
<target>Сканировать QR код с компьютера</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Scan code" xml:space="preserve">
<source>Scan code</source>
<target>Сканировать код</target>
@@ -4227,6 +4439,7 @@ This is your link for group %@!</source>
</trans-unit>
<trans-unit id="Send direct message to connect" xml:space="preserve">
<source>Send direct message to connect</source>
<target>Отправьте сообщение чтобы соединиться</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Send disappearing message" xml:space="preserve">
@@ -4364,6 +4577,11 @@ This is your link for group %@!</source>
<target>Серверы</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Session code" xml:space="preserve">
<source>Session code</source>
<target>Код сессии</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Set 1 day" xml:space="preserve">
<source>Set 1 day</source>
<target>Установить 1 день</target>
@@ -4676,6 +4894,7 @@ This is your link for group %@!</source>
</trans-unit>
<trans-unit id="Tap to Connect" xml:space="preserve">
<source>Tap to Connect</source>
<target>Нажмите чтобы соединиться</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Tap to activate profile." xml:space="preserve">
@@ -4860,6 +5079,11 @@ It can happen because of some bug or when the connection is compromised.</source
<target>Это действие нельзя отменить — Ваш профиль, контакты, сообщения и файлы будут безвозвратно утеряны.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="This device name" xml:space="preserve">
<source>This device name</source>
<target>Имя этого устройства</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="This group has over %lld members, delivery receipts are not sent." xml:space="preserve">
<source>This group has over %lld members, delivery receipts are not sent.</source>
<target>В группе более %lld членов, отчёты о доставке выключены.</target>
@@ -4872,10 +5096,12 @@ It can happen because of some bug or when the connection is compromised.</source
</trans-unit>
<trans-unit id="This is your own SimpleX address!" xml:space="preserve">
<source>This is your own SimpleX address!</source>
<target>Это ваш собственный адрес SimpleX!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="This is your own one-time link!" xml:space="preserve">
<source>This is your own one-time link!</source>
<target>Это ваша собственная одноразовая ссылка!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="This setting applies to messages in your current chat profile **%@**." xml:space="preserve">
@@ -4893,6 +5119,11 @@ It can happen because of some bug or when the connection is compromised.</source
<target>Чтобы соединиться с Вами, Ваш контакт может отсканировать QR-код или использовать ссылку в приложении.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="To hide unwanted messages." xml:space="preserve">
<source>To hide unwanted messages.</source>
<target>Чтобы скрыть нежелательные сообщения.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="To make a new connection" xml:space="preserve">
<source>To make a new connection</source>
<target>Чтобы соединиться</target>
@@ -4977,14 +5208,17 @@ You will be prompted to complete authentication before this feature is enabled.<
</trans-unit>
<trans-unit id="Unblock" xml:space="preserve">
<source>Unblock</source>
<target>Разблокировать</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Unblock member" xml:space="preserve">
<source>Unblock member</source>
<target>Разблокировать члена группы</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Unblock member?" xml:space="preserve">
<source>Unblock member?</source>
<target>Разблокировать члена группы?</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Unexpected error: %@" xml:space="preserve">
@@ -5049,6 +5283,16 @@ To connect, please ask your contact to create another connection link and check
Чтобы установить соединение, попросите Ваш контакт создать еще одну ссылку и проверьте Ваше соединение с сетью.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Unlink" xml:space="preserve">
<source>Unlink</source>
<target>Забыть</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Unlink desktop?" xml:space="preserve">
<source>Unlink desktop?</source>
<target>Забыть компьютер?</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Unlock" xml:space="preserve">
<source>Unlock</source>
<target>Разблокировать</target>
@@ -5139,6 +5383,11 @@ To connect, please ask your contact to create another connection link and check
<target>Использовать для новых соединений</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Use from desktop" xml:space="preserve">
<source>Use from desktop</source>
<target>Использовать с компьютера</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Use iOS call interface" xml:space="preserve">
<source>Use iOS call interface</source>
<target>Использовать интерфейс iOS для звонков</target>
@@ -5169,11 +5418,26 @@ To connect, please ask your contact to create another connection link and check
<target>Используются серверы, предоставленные SimpleX Chat.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Verify code with desktop" xml:space="preserve">
<source>Verify code with desktop</source>
<target>Сверьте код с компьютером</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Verify connection" xml:space="preserve">
<source>Verify connection</source>
<target>Проверить соединение</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Verify connection security" xml:space="preserve">
<source>Verify connection security</source>
<target>Проверить безопасность соединения</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Verify connections" xml:space="preserve">
<source>Verify connections</source>
<target>Проверять соединения</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Verify security code" xml:space="preserve">
<source>Verify security code</source>
<target>Подтвердить код безопасности</target>
@@ -5184,6 +5448,11 @@ To connect, please ask your contact to create another connection link and check
<target>В браузере</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Via secure quantum resistant protocol." xml:space="preserve">
<source>Via secure quantum resistant protocol.</source>
<target>Через безопасный квантово-устойчивый протокол.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Video call" xml:space="preserve">
<source>Video call</source>
<target>Видеозвонок</target>
@@ -5234,6 +5503,11 @@ To connect, please ask your contact to create another connection link and check
<target>Голосовое сообщение…</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Waiting for desktop..." xml:space="preserve">
<source>Waiting for desktop...</source>
<target>Ожидается подключение компьютера...</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Waiting for file" xml:space="preserve">
<source>Waiting for file</source>
<target>Ожидается прием файла</target>
@@ -5336,31 +5610,39 @@ To connect, please ask your contact to create another connection link and check
</trans-unit>
<trans-unit id="You are already connecting to %@." xml:space="preserve">
<source>You are already connecting to %@.</source>
<target>Вы уже соединяетесь с %@.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="You are already connecting via this one-time link!" xml:space="preserve">
<source>You are already connecting via this one-time link!</source>
<target>Вы уже соединяетесь по этой одноразовой ссылке!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="You are already in group %@." xml:space="preserve">
<source>You are already in group %@.</source>
<target>Вы уже состоите в группе %@.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="You are already joining the group %@." xml:space="preserve">
<source>You are already joining the group %@.</source>
<target>Вы уже вступаете в группу %@.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="You are already joining the group via this link!" xml:space="preserve">
<source>You are already joining the group via this link!</source>
<target>Вы уже вступаете в группу по этой ссылке!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="You are already joining the group via this link." xml:space="preserve">
<source>You are already joining the group via this link.</source>
<target>Вы уже вступаете в группу по этой ссылке.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="You are already joining the group!&#10;Repeat join request?" xml:space="preserve">
<source>You are already joining the group!
Repeat join request?</source>
<target>Вы уже вступаете в группу!
Повторить запрос на вступление?</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="You are connected to the server used to receive messages from this contact." xml:space="preserve">
@@ -5460,11 +5742,14 @@ Repeat join request?</source>
</trans-unit>
<trans-unit id="You have already requested connection via this address!" xml:space="preserve">
<source>You have already requested connection via this address!</source>
<target>Вы уже запросили соединение через этот адрес!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="You have already requested connection!&#10;Repeat connection request?" xml:space="preserve">
<source>You have already requested connection!
Repeat connection request?</source>
<target>Вы уже запросили соединение!
Повторить запрос?</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="You have no chats" xml:space="preserve">
@@ -5519,6 +5804,7 @@ Repeat connection request?</source>
</trans-unit>
<trans-unit id="You will be connected when group link host's device is online, please wait or check later!" xml:space="preserve">
<source>You will be connected when group link host's device is online, please wait or check later!</source>
<target>Соединение будет установлено, когда владелец ссылки группы будет онлайн. Пожалуйста, подождите или проверьте позже!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="You will be connected when your connection request is accepted, please wait or check later!" xml:space="preserve">
@@ -5538,6 +5824,7 @@ Repeat connection request?</source>
</trans-unit>
<trans-unit id="You will connect to all group members." xml:space="preserve">
<source>You will connect to all group members.</source>
<target>Вы соединитесь со всеми членами группы.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="You will still receive calls and notifications from muted profiles when they are active." xml:space="preserve">
@@ -5661,6 +5948,7 @@ You can change it in Settings.</source>
</trans-unit>
<trans-unit id="Your profile" xml:space="preserve">
<source>Your profile</source>
<target>Ваш профиль</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Your profile **%@** will be shared." xml:space="preserve">
@@ -5757,6 +6045,7 @@ SimpleX серверы не могут получить доступ к Ваше
</trans-unit>
<trans-unit id="and %lld other events" xml:space="preserve">
<source>and %lld other events</source>
<target>и %lld других событий</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="audio call (not e2e encrypted)" xml:space="preserve">
@@ -5764,6 +6053,11 @@ SimpleX серверы не могут получить доступ к Ваше
<target>аудиозвонок (не e2e зашифрованный)</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="author" xml:space="preserve">
<source>author</source>
<target>автор</target>
<note>member role</note>
</trans-unit>
<trans-unit id="bad message ID" xml:space="preserve">
<source>bad message ID</source>
<target>ошибка ID сообщения</target>
@@ -5776,6 +6070,7 @@ SimpleX серверы не могут получить доступ к Ваше
</trans-unit>
<trans-unit id="blocked" xml:space="preserve">
<source>blocked</source>
<target>заблокировано</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="bold" xml:space="preserve">
@@ -5850,6 +6145,7 @@ SimpleX серверы не могут получить доступ к Ваше
</trans-unit>
<trans-unit id="connected directly" xml:space="preserve">
<source>connected directly</source>
<target>соединен(а) напрямую</target>
<note>rcv group event chat item</note>
</trans-unit>
<trans-unit id="connecting" xml:space="preserve">
@@ -5949,6 +6245,7 @@ SimpleX серверы не могут получить доступ к Ваше
</trans-unit>
<trans-unit id="deleted contact" xml:space="preserve">
<source>deleted contact</source>
<target>удалил(а) контакт</target>
<note>rcv direct event chat item</note>
</trans-unit>
<trans-unit id="deleted group" xml:space="preserve">
@@ -6315,6 +6612,7 @@ SimpleX серверы не могут получить доступ к Ваше
</trans-unit>
<trans-unit id="send direct message" xml:space="preserve">
<source>send direct message</source>
<target>отправьте сообщение</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="starting…" xml:space="preserve">
@@ -6342,6 +6640,11 @@ SimpleX серверы не могут получить доступ к Ваше
<target>обновил(а) профиль группы</target>
<note>rcv group event chat item</note>
</trans-unit>
<trans-unit id="v%@" xml:space="preserve">
<source>v%@</source>
<target>v%@</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="v%@ (%@)" xml:space="preserve">
<source>v%@ (%@)</source>
<target>v%@ (%@)</target>
@@ -6479,6 +6782,11 @@ SimpleX серверы не могут получить доступ к Ваше
<target>SimpleX использует Face ID для аутентификации</target>
<note>Privacy - Face ID Usage Description</note>
</trans-unit>
<trans-unit id="NSLocalNetworkUsageDescription" xml:space="preserve">
<source>SimpleX uses local network access to allow using user chat profile via desktop app on the same network.</source>
<target>SimpleX использует доступ к локальной сети, чтобы разрешить использование профиля чата через компьютер в той же сети.</target>
<note>Privacy - Local Network Usage Description</note>
</trans-unit>
<trans-unit id="NSMicrophoneUsageDescription" xml:space="preserve">
<source>SimpleX needs microphone access for audio and video calls, and to record voice messages.</source>
<target>SimpleX использует микрофон для аудио и видео звонков, и для записи голосовых сообщений.</target>

View File

@@ -4,6 +4,8 @@
"NSCameraUsageDescription" = "SimpleX needs camera access to scan QR codes to connect to other users and for video calls.";
/* Privacy - Face ID Usage Description */
"NSFaceIDUsageDescription" = "SimpleX uses Face ID for local authentication";
/* Privacy - Local Network Usage Description */
"NSLocalNetworkUsageDescription" = "SimpleX uses local network access to allow using user chat profile via desktop app on the same network.";
/* Privacy - Microphone Usage Description */
"NSMicrophoneUsageDescription" = "SimpleX needs microphone access for audio and video calls, and to record voice messages.";
/* Privacy - Photo Library Additions Usage Description */

View File

@@ -284,6 +284,14 @@
<target>(</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="(new)" xml:space="preserve">
<source>(new)</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="(this device v%@)" xml:space="preserve">
<source>(this device v%@)</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id=")" xml:space="preserve">
<source>)</source>
<target>)</target>
@@ -369,6 +377,12 @@
- และอื่น ๆ!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="- optionally notify deleted contacts.&#10;- profile names with spaces.&#10;- and more!" xml:space="preserve">
<source>- optionally notify deleted contacts.
- profile names with spaces.
- and more!</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="- voice messages up to 5 minutes.&#10;- custom time to disappear.&#10;- editing history." xml:space="preserve">
<source>- voice messages up to 5 minutes.
- custom time to disappear.
@@ -846,6 +860,10 @@
<target>กลับ</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Bad desktop address" xml:space="preserve">
<source>Bad desktop address</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Bad message ID" xml:space="preserve">
<source>Bad message ID</source>
<target>ID ข้อความที่ไม่ดี</target>
@@ -856,6 +874,10 @@
<target>แฮชข้อความไม่ดี</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Better groups" xml:space="preserve">
<source>Better groups</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Better messages" xml:space="preserve">
<source>Better messages</source>
<target>ข้อความที่ดีขึ้น</target>
@@ -865,6 +887,10 @@
<source>Block</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Block group members" xml:space="preserve">
<source>Block group members</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Block member" xml:space="preserve">
<source>Block member</source>
<note>No comment provided by engineer.</note>
@@ -1133,10 +1159,18 @@
<target>เชื่อมต่อ</target>
<note>server test step</note>
</trans-unit>
<trans-unit id="Connect automatically" xml:space="preserve">
<source>Connect automatically</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connect incognito" xml:space="preserve">
<source>Connect incognito</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connect to desktop" xml:space="preserve">
<source>Connect to desktop</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connect to yourself?" xml:space="preserve">
<source>Connect to yourself?</source>
<note>No comment provided by engineer.</note>
@@ -1173,6 +1207,14 @@ This is your own one-time link!</source>
<source>Connect with %@</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connected desktop" xml:space="preserve">
<source>Connected desktop</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connected to desktop" xml:space="preserve">
<source>Connected to desktop</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connecting server…" xml:space="preserve">
<source>Connecting to server…</source>
<target>กำลังเชื่อมต่อกับเซิร์ฟเวอร์…</target>
@@ -1183,6 +1225,10 @@ This is your own one-time link!</source>
<target>กำลังเชื่อมต่อกับเซิร์ฟเวอร์... (ข้อผิดพลาด: %@)</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connecting to desktop" xml:space="preserve">
<source>Connecting to desktop</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connection" xml:space="preserve">
<source>Connection</source>
<target>การเชื่อมต่อ</target>
@@ -1203,6 +1249,10 @@ This is your own one-time link!</source>
<target>ส่งคําขอเชื่อมต่อแล้ว!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connection terminated" xml:space="preserve">
<source>Connection terminated</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connection timeout" xml:space="preserve">
<source>Connection timeout</source>
<target>หมดเวลาการเชื่อมต่อ</target>
@@ -1282,6 +1332,10 @@ This is your own one-time link!</source>
<target>สร้างที่อยู่ SimpleX</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Create a group using a random profile." xml:space="preserve">
<source>Create a group using a random profile.</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Create an address to let people connect with you." xml:space="preserve">
<source>Create an address to let people connect with you.</source>
<target>สร้างที่อยู่เพื่อให้ผู้อื่นเชื่อมต่อกับคุณ</target>
@@ -1684,6 +1738,18 @@ This cannot be undone!</source>
<target>คำอธิบาย</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Desktop address" xml:space="preserve">
<source>Desktop address</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Desktop app version %@ is not compatible with this app." xml:space="preserve">
<source>Desktop app version %@ is not compatible with this app.</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Desktop devices" xml:space="preserve">
<source>Desktop devices</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Develop" xml:space="preserve">
<source>Develop</source>
<target>พัฒนา</target>
@@ -1774,10 +1840,18 @@ This cannot be undone!</source>
<target>ตัดการเชื่อมต่อ</target>
<note>server test step</note>
</trans-unit>
<trans-unit id="Disconnect desktop?" xml:space="preserve">
<source>Disconnect desktop?</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Discover and join groups" xml:space="preserve">
<source>Discover and join groups</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Discover via local network" xml:space="preserve">
<source>Discover via local network</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Do NOT use SimpleX for emergency calls." xml:space="preserve">
<source>Do NOT use SimpleX for emergency calls.</source>
<target>อย่าใช้ SimpleX สําหรับการโทรฉุกเฉิน</target>
@@ -1946,6 +2020,14 @@ This cannot be undone!</source>
<target>ข้อความที่ encrypt: ข้อผิดพลาดที่ไม่คาดคิด</target>
<note>notification</note>
</trans-unit>
<trans-unit id="Encryption re-negotiation error" xml:space="preserve">
<source>Encryption re-negotiation error</source>
<note>message decrypt error item</note>
</trans-unit>
<trans-unit id="Encryption re-negotiation failed." xml:space="preserve">
<source>Encryption re-negotiation failed.</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Enter Passcode" xml:space="preserve">
<source>Enter Passcode</source>
<target>ใส่รหัสผ่าน</target>
@@ -1975,6 +2057,10 @@ This cannot be undone!</source>
<target>ใส่เซิร์ฟเวอร์ด้วยตนเอง</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Enter this device name…" xml:space="preserve">
<source>Enter this device name…</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Enter welcome message…" xml:space="preserve">
<source>Enter welcome message…</source>
<target>ใส่ข้อความต้อนรับ…</target>
@@ -2295,6 +2381,10 @@ This cannot be undone!</source>
<target>รวดเร็วและไม่ต้องรอจนกว่าผู้ส่งจะออนไลน์!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Faster joining and more reliable messages." xml:space="preserve">
<source>Faster joining and more reliable messages.</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Favorite" xml:space="preserve">
<source>Favorite</source>
<target>ที่ชอบ</target>
@@ -2390,6 +2480,10 @@ This cannot be undone!</source>
<target>สำหรับคอนโซล</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Found desktop" xml:space="preserve">
<source>Found desktop</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="French interface" xml:space="preserve">
<source>French interface</source>
<target>อินเทอร์เฟซภาษาฝรั่งเศส</target>
@@ -2712,6 +2806,10 @@ This cannot be undone!</source>
<target>ไม่ระบุตัวตน</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Incognito groups" xml:space="preserve">
<source>Incognito groups</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Incognito mode" xml:space="preserve">
<source>Incognito mode</source>
<target>โหมดไม่ระบุตัวตน</target>
@@ -2741,6 +2839,10 @@ This cannot be undone!</source>
<target>เวอร์ชันฐานข้อมูลที่เข้ากันไม่ได้</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Incompatible version" xml:space="preserve">
<source>Incompatible version</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Incorrect passcode" xml:space="preserve">
<source>Incorrect passcode</source>
<target>รหัสผ่านไม่ถูกต้อง</target>
@@ -2905,6 +3007,10 @@ This is your link for group %@!</source>
<target>กำลังจะเข้าร่วมกลุ่ม</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Keep the app open to use it from desktop" xml:space="preserve">
<source>Keep the app open to use it from desktop</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Keep your connections" xml:space="preserve">
<source>Keep your connections</source>
<target>รักษาการเชื่อมต่อของคุณ</target>
@@ -2965,6 +3071,18 @@ This is your link for group %@!</source>
<target>ข้อจำกัด</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Link mobile and desktop apps! 🔗" xml:space="preserve">
<source>Link mobile and desktop apps! 🔗</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Linked desktop options" xml:space="preserve">
<source>Linked desktop options</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Linked desktops" xml:space="preserve">
<source>Linked desktops</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Live message!" xml:space="preserve">
<source>Live message!</source>
<target>ข้อความสด!</target>
@@ -3311,6 +3429,10 @@ This is your link for group %@!</source>
<target>ไม่มีไฟล์ที่ได้รับหรือส่ง</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Not compatible!" xml:space="preserve">
<source>Not compatible!</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Notifications" xml:space="preserve">
<source>Notifications</source>
<target>การแจ้งเตือน</target>
@@ -3528,6 +3650,10 @@ This is your link for group %@!</source>
<target>แปะ</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Paste desktop address" xml:space="preserve">
<source>Paste desktop address</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Paste image" xml:space="preserve">
<source>Paste image</source>
<target>แปะภาพ</target>
@@ -4116,6 +4242,10 @@ This is your link for group %@!</source>
<target>สแกนคิวอาร์โค้ด</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Scan QR code from desktop" xml:space="preserve">
<source>Scan QR code from desktop</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Scan code" xml:space="preserve">
<source>Scan code</source>
<target>สแกนรหัส</target>
@@ -4333,6 +4463,10 @@ This is your link for group %@!</source>
<target>เซิร์ฟเวอร์</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Session code" xml:space="preserve">
<source>Session code</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Set 1 day" xml:space="preserve">
<source>Set 1 day</source>
<target>ตั้ง 1 วัน</target>
@@ -4826,6 +4960,10 @@ It can happen because of some bug or when the connection is compromised.</source
<target>การดำเนินการนี้ไม่สามารถยกเลิกได้ - โปรไฟล์ ผู้ติดต่อ ข้อความ และไฟล์ของคุณจะสูญหายไปอย่างถาวร</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="This device name" xml:space="preserve">
<source>This device name</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="This group has over %lld members, delivery receipts are not sent." xml:space="preserve">
<source>This group has over %lld members, delivery receipts are not sent.</source>
<note>No comment provided by engineer.</note>
@@ -4858,6 +4996,10 @@ It can happen because of some bug or when the connection is compromised.</source
<target>เพื่อการเชื่อมต่อ ผู้ติดต่อของคุณสามารถสแกนคิวอาร์โค้ดหรือใช้ลิงก์ในแอป</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="To hide unwanted messages." xml:space="preserve">
<source>To hide unwanted messages.</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="To make a new connection" xml:space="preserve">
<source>To make a new connection</source>
<target>เพื่อสร้างการเชื่อมต่อใหม่</target>
@@ -5013,6 +5155,14 @@ To connect, please ask your contact to create another connection link and check
ในการเชื่อมต่อ โปรดขอให้ผู้ติดต่อของคุณสร้างลิงก์การเชื่อมต่ออื่น และตรวจสอบว่าคุณมีการเชื่อมต่อเครือข่ายที่เสถียร</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Unlink" xml:space="preserve">
<source>Unlink</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Unlink desktop?" xml:space="preserve">
<source>Unlink desktop?</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Unlock" xml:space="preserve">
<source>Unlock</source>
<target>ปลดล็อค</target>
@@ -5102,6 +5252,10 @@ To connect, please ask your contact to create another connection link and check
<target>ใช้สำหรับการเชื่อมต่อใหม่</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Use from desktop" xml:space="preserve">
<source>Use from desktop</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Use iOS call interface" xml:space="preserve">
<source>Use iOS call interface</source>
<target>ใช้อินเทอร์เฟซการโทร iOS</target>
@@ -5131,11 +5285,23 @@ To connect, please ask your contact to create another connection link and check
<target>กำลังใช้เซิร์ฟเวอร์ SimpleX Chat อยู่</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Verify code with desktop" xml:space="preserve">
<source>Verify code with desktop</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Verify connection" xml:space="preserve">
<source>Verify connection</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Verify connection security" xml:space="preserve">
<source>Verify connection security</source>
<target>ตรวจสอบความปลอดภัยในการเชื่อมต่อ</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Verify connections" xml:space="preserve">
<source>Verify connections</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Verify security code" xml:space="preserve">
<source>Verify security code</source>
<target>ตรวจสอบรหัสความปลอดภัย</target>
@@ -5146,6 +5312,10 @@ To connect, please ask your contact to create another connection link and check
<target>ผ่านเบราว์เซอร์</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Via secure quantum resistant protocol." xml:space="preserve">
<source>Via secure quantum resistant protocol.</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Video call" xml:space="preserve">
<source>Video call</source>
<target>การสนทนาทางวิดีโอ</target>
@@ -5196,6 +5366,10 @@ To connect, please ask your contact to create another connection link and check
<target>ข้อความเสียง…</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Waiting for desktop..." xml:space="preserve">
<source>Waiting for desktop...</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Waiting for file" xml:space="preserve">
<source>Waiting for file</source>
<target>กำลังรอไฟล์</target>
@@ -5724,6 +5898,10 @@ SimpleX servers cannot see your profile.</source>
<target>การโทรด้วยเสียง (ไม่ได้ encrypt จากต้นจนจบ)</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="author" xml:space="preserve">
<source>author</source>
<note>member role</note>
</trans-unit>
<trans-unit id="bad message ID" xml:space="preserve">
<source>bad message ID</source>
<target>ID ข้อความที่ไม่ดี</target>
@@ -6300,6 +6478,10 @@ SimpleX servers cannot see your profile.</source>
<target>อัปเดตโปรไฟล์กลุ่มแล้ว</target>
<note>rcv group event chat item</note>
</trans-unit>
<trans-unit id="v%@" xml:space="preserve">
<source>v%@</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="v%@ (%@)" xml:space="preserve">
<source>v%@ (%@)</source>
<target>v%@ (%@)</target>
@@ -6437,6 +6619,10 @@ SimpleX servers cannot see your profile.</source>
<target>SimpleX ใช้ Face ID สำหรับการรับรองความถูกต้องในเครื่อง</target>
<note>Privacy - Face ID Usage Description</note>
</trans-unit>
<trans-unit id="NSLocalNetworkUsageDescription" xml:space="preserve">
<source>SimpleX uses local network access to allow using user chat profile via desktop app on the same network.</source>
<note>Privacy - Local Network Usage Description</note>
</trans-unit>
<trans-unit id="NSMicrophoneUsageDescription" xml:space="preserve">
<source>SimpleX needs microphone access for audio and video calls, and to record voice messages.</source>
<target>SimpleX ต้องการการเข้าถึงไมโครโฟนสำหรับการโทรด้วยเสียงและวิดีโอ และเพื่อบันทึกข้อความเสียง</target>

View File

@@ -4,6 +4,8 @@
"NSCameraUsageDescription" = "SimpleX needs camera access to scan QR codes to connect to other users and for video calls.";
/* Privacy - Face ID Usage Description */
"NSFaceIDUsageDescription" = "SimpleX uses Face ID for local authentication";
/* Privacy - Local Network Usage Description */
"NSLocalNetworkUsageDescription" = "SimpleX uses local network access to allow using user chat profile via desktop app on the same network.";
/* Privacy - Microphone Usage Description */
"NSMicrophoneUsageDescription" = "SimpleX needs microphone access for audio and video calls, and to record voice messages.";
/* Privacy - Photo Library Additions Usage Description */

View File

@@ -289,6 +289,14 @@
<target>(</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="(new)" xml:space="preserve">
<source>(new)</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="(this device v%@)" xml:space="preserve">
<source>(this device v%@)</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id=")" xml:space="preserve">
<source>)</source>
<target>)</target>
@@ -374,6 +382,12 @@
- і багато іншого!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="- optionally notify deleted contacts.&#10;- profile names with spaces.&#10;- and more!" xml:space="preserve">
<source>- optionally notify deleted contacts.
- profile names with spaces.
- and more!</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="- voice messages up to 5 minutes.&#10;- custom time to disappear.&#10;- editing history." xml:space="preserve">
<source>- voice messages up to 5 minutes.
- custom time to disappear.
@@ -853,6 +867,10 @@
<target>Назад</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Bad desktop address" xml:space="preserve">
<source>Bad desktop address</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Bad message ID" xml:space="preserve">
<source>Bad message ID</source>
<target>Неправильний ідентифікатор повідомлення</target>
@@ -863,6 +881,10 @@
<target>Поганий хеш повідомлення</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Better groups" xml:space="preserve">
<source>Better groups</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Better messages" xml:space="preserve">
<source>Better messages</source>
<target>Кращі повідомлення</target>
@@ -872,6 +894,10 @@
<source>Block</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Block group members" xml:space="preserve">
<source>Block group members</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Block member" xml:space="preserve">
<source>Block member</source>
<note>No comment provided by engineer.</note>
@@ -1140,11 +1166,19 @@
<target>Підключіться</target>
<note>server test step</note>
</trans-unit>
<trans-unit id="Connect automatically" xml:space="preserve">
<source>Connect automatically</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connect incognito" xml:space="preserve">
<source>Connect incognito</source>
<target>Підключайтеся інкогніто</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connect to desktop" xml:space="preserve">
<source>Connect to desktop</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connect to yourself?" xml:space="preserve">
<source>Connect to yourself?</source>
<note>No comment provided by engineer.</note>
@@ -1182,6 +1216,14 @@ This is your own one-time link!</source>
<source>Connect with %@</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connected desktop" xml:space="preserve">
<source>Connected desktop</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connected to desktop" xml:space="preserve">
<source>Connected to desktop</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connecting server…" xml:space="preserve">
<source>Connecting to server…</source>
<target>Підключення до сервера…</target>
@@ -1192,6 +1234,10 @@ This is your own one-time link!</source>
<target>Підключення до сервера... (помилка: %@)</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connecting to desktop" xml:space="preserve">
<source>Connecting to desktop</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connection" xml:space="preserve">
<source>Connection</source>
<target>Підключення</target>
@@ -1212,6 +1258,10 @@ This is your own one-time link!</source>
<target>Запит на підключення відправлено!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connection terminated" xml:space="preserve">
<source>Connection terminated</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connection timeout" xml:space="preserve">
<source>Connection timeout</source>
<target>Тайм-аут з'єднання</target>
@@ -1291,6 +1341,10 @@ This is your own one-time link!</source>
<target>Створіть адресу SimpleX</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Create a group using a random profile." xml:space="preserve">
<source>Create a group using a random profile.</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Create an address to let people connect with you." xml:space="preserve">
<source>Create an address to let people connect with you.</source>
<target>Створіть адресу, щоб люди могли з вами зв'язатися.</target>
@@ -1694,6 +1748,18 @@ This cannot be undone!</source>
<target>Опис</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Desktop address" xml:space="preserve">
<source>Desktop address</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Desktop app version %@ is not compatible with this app." xml:space="preserve">
<source>Desktop app version %@ is not compatible with this app.</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Desktop devices" xml:space="preserve">
<source>Desktop devices</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Develop" xml:space="preserve">
<source>Develop</source>
<target>Розробник</target>
@@ -1784,10 +1850,18 @@ This cannot be undone!</source>
<target>Від'єднати</target>
<note>server test step</note>
</trans-unit>
<trans-unit id="Disconnect desktop?" xml:space="preserve">
<source>Disconnect desktop?</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Discover and join groups" xml:space="preserve">
<source>Discover and join groups</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Discover via local network" xml:space="preserve">
<source>Discover via local network</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Do NOT use SimpleX for emergency calls." xml:space="preserve">
<source>Do NOT use SimpleX for emergency calls.</source>
<target>НЕ використовуйте SimpleX для екстрених викликів.</target>
@@ -1956,6 +2030,14 @@ This cannot be undone!</source>
<target>Зашифроване повідомлення: несподівана помилка</target>
<note>notification</note>
</trans-unit>
<trans-unit id="Encryption re-negotiation error" xml:space="preserve">
<source>Encryption re-negotiation error</source>
<note>message decrypt error item</note>
</trans-unit>
<trans-unit id="Encryption re-negotiation failed." xml:space="preserve">
<source>Encryption re-negotiation failed.</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Enter Passcode" xml:space="preserve">
<source>Enter Passcode</source>
<target>Введіть пароль</target>
@@ -1985,6 +2067,10 @@ This cannot be undone!</source>
<target>Увійдіть на сервер вручну</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Enter this device name…" xml:space="preserve">
<source>Enter this device name…</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Enter welcome message…" xml:space="preserve">
<source>Enter welcome message…</source>
<target>Введіть вітальне повідомлення…</target>
@@ -2305,6 +2391,10 @@ This cannot be undone!</source>
<target>Швидко і без очікування, поки відправник буде онлайн!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Faster joining and more reliable messages." xml:space="preserve">
<source>Faster joining and more reliable messages.</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Favorite" xml:space="preserve">
<source>Favorite</source>
<target>Улюблений</target>
@@ -2400,6 +2490,10 @@ This cannot be undone!</source>
<target>Для консолі</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Found desktop" xml:space="preserve">
<source>Found desktop</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="French interface" xml:space="preserve">
<source>French interface</source>
<target>Французький інтерфейс</target>
@@ -2722,6 +2816,10 @@ This cannot be undone!</source>
<target>Інкогніто</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Incognito groups" xml:space="preserve">
<source>Incognito groups</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Incognito mode" xml:space="preserve">
<source>Incognito mode</source>
<target>Режим інкогніто</target>
@@ -2752,6 +2850,10 @@ This cannot be undone!</source>
<target>Несумісна версія бази даних</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Incompatible version" xml:space="preserve">
<source>Incompatible version</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Incorrect passcode" xml:space="preserve">
<source>Incorrect passcode</source>
<target>Неправильний пароль</target>
@@ -2917,6 +3019,10 @@ This is your link for group %@!</source>
<target>Приєднання до групи</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Keep the app open to use it from desktop" xml:space="preserve">
<source>Keep the app open to use it from desktop</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Keep your connections" xml:space="preserve">
<source>Keep your connections</source>
<target>Зберігайте свої зв'язки</target>
@@ -2977,6 +3083,18 @@ This is your link for group %@!</source>
<target>Обмеження</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Link mobile and desktop apps! 🔗" xml:space="preserve">
<source>Link mobile and desktop apps! 🔗</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Linked desktop options" xml:space="preserve">
<source>Linked desktop options</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Linked desktops" xml:space="preserve">
<source>Linked desktops</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Live message!" xml:space="preserve">
<source>Live message!</source>
<target>Живе повідомлення!</target>
@@ -3325,6 +3443,10 @@ This is your link for group %@!</source>
<target>Немає отриманих або відправлених файлів</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Not compatible!" xml:space="preserve">
<source>Not compatible!</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Notifications" xml:space="preserve">
<source>Notifications</source>
<target>Сповіщення</target>
@@ -3542,6 +3664,10 @@ This is your link for group %@!</source>
<target>Вставити</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Paste desktop address" xml:space="preserve">
<source>Paste desktop address</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Paste image" xml:space="preserve">
<source>Paste image</source>
<target>Вставити зображення</target>
@@ -4133,6 +4259,10 @@ This is your link for group %@!</source>
<target>Відскануйте QR-код</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Scan QR code from desktop" xml:space="preserve">
<source>Scan QR code from desktop</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Scan code" xml:space="preserve">
<source>Scan code</source>
<target>Сканувати код</target>
@@ -4352,6 +4482,10 @@ This is your link for group %@!</source>
<target>Сервери</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Session code" xml:space="preserve">
<source>Session code</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Set 1 day" xml:space="preserve">
<source>Set 1 day</source>
<target>Встановити 1 день</target>
@@ -4847,6 +4981,10 @@ It can happen because of some bug or when the connection is compromised.</source
<target>Цю дію неможливо скасувати - ваш профіль, контакти, повідомлення та файли будуть безповоротно втрачені.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="This device name" xml:space="preserve">
<source>This device name</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="This group has over %lld members, delivery receipts are not sent." xml:space="preserve">
<source>This group has over %lld members, delivery receipts are not sent.</source>
<target>У цій групі більше %lld учасників, підтвердження доставки не надсилаються.</target>
@@ -4880,6 +5018,10 @@ It can happen because of some bug or when the connection is compromised.</source
<target>Щоб підключитися, ваш контакт може відсканувати QR-код або скористатися посиланням у додатку.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="To hide unwanted messages." xml:space="preserve">
<source>To hide unwanted messages.</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="To make a new connection" xml:space="preserve">
<source>To make a new connection</source>
<target>Щоб створити нове з'єднання</target>
@@ -5035,6 +5177,14 @@ To connect, please ask your contact to create another connection link and check
Щоб підключитися, попросіть вашого контакта створити інше посилання і перевірте, чи маєте ви стабільне з'єднання з мережею.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Unlink" xml:space="preserve">
<source>Unlink</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Unlink desktop?" xml:space="preserve">
<source>Unlink desktop?</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Unlock" xml:space="preserve">
<source>Unlock</source>
<target>Розблокувати</target>
@@ -5125,6 +5275,10 @@ To connect, please ask your contact to create another connection link and check
<target>Використовуйте для нових з'єднань</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Use from desktop" xml:space="preserve">
<source>Use from desktop</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Use iOS call interface" xml:space="preserve">
<source>Use iOS call interface</source>
<target>Використовуйте інтерфейс виклику iOS</target>
@@ -5155,11 +5309,23 @@ To connect, please ask your contact to create another connection link and check
<target>Використання серверів SimpleX Chat.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Verify code with desktop" xml:space="preserve">
<source>Verify code with desktop</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Verify connection" xml:space="preserve">
<source>Verify connection</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Verify connection security" xml:space="preserve">
<source>Verify connection security</source>
<target>Перевірте безпеку з'єднання</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Verify connections" xml:space="preserve">
<source>Verify connections</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Verify security code" xml:space="preserve">
<source>Verify security code</source>
<target>Підтвердіть код безпеки</target>
@@ -5170,6 +5336,10 @@ To connect, please ask your contact to create another connection link and check
<target>Через браузер</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Via secure quantum resistant protocol." xml:space="preserve">
<source>Via secure quantum resistant protocol.</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Video call" xml:space="preserve">
<source>Video call</source>
<target>Відеодзвінок</target>
@@ -5220,6 +5390,10 @@ To connect, please ask your contact to create another connection link and check
<target>Голосове повідомлення…</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Waiting for desktop..." xml:space="preserve">
<source>Waiting for desktop...</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Waiting for file" xml:space="preserve">
<source>Waiting for file</source>
<target>Очікування файлу</target>
@@ -5750,6 +5924,10 @@ SimpleX servers cannot see your profile.</source>
<target>аудіовиклик (без шифрування e2e)</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="author" xml:space="preserve">
<source>author</source>
<note>member role</note>
</trans-unit>
<trans-unit id="bad message ID" xml:space="preserve">
<source>bad message ID</source>
<target>невірний ідентифікатор повідомлення</target>
@@ -6328,6 +6506,10 @@ SimpleX servers cannot see your profile.</source>
<target>оновлений профіль групи</target>
<note>rcv group event chat item</note>
</trans-unit>
<trans-unit id="v%@" xml:space="preserve">
<source>v%@</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="v%@ (%@)" xml:space="preserve">
<source>v%@ (%@)</source>
<target>v%@ (%@)</target>
@@ -6465,6 +6647,10 @@ SimpleX servers cannot see your profile.</source>
<target>SimpleX використовує Face ID для локальної автентифікації</target>
<note>Privacy - Face ID Usage Description</note>
</trans-unit>
<trans-unit id="NSLocalNetworkUsageDescription" xml:space="preserve">
<source>SimpleX uses local network access to allow using user chat profile via desktop app on the same network.</source>
<note>Privacy - Local Network Usage Description</note>
</trans-unit>
<trans-unit id="NSMicrophoneUsageDescription" xml:space="preserve">
<source>SimpleX needs microphone access for audio and video calls, and to record voice messages.</source>
<target>SimpleX потребує доступу до мікрофона для аудіо та відео дзвінків, а також для запису голосових повідомлень.</target>

View File

@@ -4,6 +4,8 @@
"NSCameraUsageDescription" = "SimpleX needs camera access to scan QR codes to connect to other users and for video calls.";
/* Privacy - Face ID Usage Description */
"NSFaceIDUsageDescription" = "SimpleX uses Face ID for local authentication";
/* Privacy - Local Network Usage Description */
"NSLocalNetworkUsageDescription" = "SimpleX uses local network access to allow using user chat profile via desktop app on the same network.";
/* Privacy - Microphone Usage Description */
"NSMicrophoneUsageDescription" = "SimpleX needs microphone access for audio and video calls, and to record voice messages.";
/* Privacy - Photo Library Additions Usage Description */

View File

@@ -290,6 +290,14 @@
<target>(</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="(new)" xml:space="preserve">
<source>(new)</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="(this device v%@)" xml:space="preserve">
<source>(this device v%@)</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id=")" xml:space="preserve">
<source>)</source>
<target>)</target>
@@ -378,6 +386,12 @@
- 以及更多!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="- optionally notify deleted contacts.&#10;- profile names with spaces.&#10;- and more!" xml:space="preserve">
<source>- optionally notify deleted contacts.
- profile names with spaces.
- and more!</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="- voice messages up to 5 minutes.&#10;- custom time to disappear.&#10;- editing history." xml:space="preserve">
<source>- voice messages up to 5 minutes.
- custom time to disappear.
@@ -858,6 +872,10 @@
<target>返回</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Bad desktop address" xml:space="preserve">
<source>Bad desktop address</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Bad message ID" xml:space="preserve">
<source>Bad message ID</source>
<target>错误消息 ID</target>
@@ -868,6 +886,10 @@
<target>错误消息散列</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Better groups" xml:space="preserve">
<source>Better groups</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Better messages" xml:space="preserve">
<source>Better messages</source>
<target>更好的消息</target>
@@ -877,6 +899,10 @@
<source>Block</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Block group members" xml:space="preserve">
<source>Block group members</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Block member" xml:space="preserve">
<source>Block member</source>
<note>No comment provided by engineer.</note>
@@ -1146,11 +1172,19 @@
<target>连接</target>
<note>server test step</note>
</trans-unit>
<trans-unit id="Connect automatically" xml:space="preserve">
<source>Connect automatically</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connect incognito" xml:space="preserve">
<source>Connect incognito</source>
<target>在隐身状态下连接</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connect to desktop" xml:space="preserve">
<source>Connect to desktop</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connect to yourself?" xml:space="preserve">
<source>Connect to yourself?</source>
<note>No comment provided by engineer.</note>
@@ -1188,6 +1222,14 @@ This is your own one-time link!</source>
<source>Connect with %@</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connected desktop" xml:space="preserve">
<source>Connected desktop</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connected to desktop" xml:space="preserve">
<source>Connected to desktop</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connecting server…" xml:space="preserve">
<source>Connecting to server…</source>
<target>连接服务器中……</target>
@@ -1198,6 +1240,10 @@ This is your own one-time link!</source>
<target>连接服务器中……(错误:%@</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connecting to desktop" xml:space="preserve">
<source>Connecting to desktop</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connection" xml:space="preserve">
<source>Connection</source>
<target>连接</target>
@@ -1218,6 +1264,10 @@ This is your own one-time link!</source>
<target>已发送连接请求!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connection terminated" xml:space="preserve">
<source>Connection terminated</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connection timeout" xml:space="preserve">
<source>Connection timeout</source>
<target>连接超时</target>
@@ -1297,6 +1347,10 @@ This is your own one-time link!</source>
<target>创建 SimpleX 地址</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Create a group using a random profile." xml:space="preserve">
<source>Create a group using a random profile.</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Create an address to let people connect with you." xml:space="preserve">
<source>Create an address to let people connect with you.</source>
<target>创建一个地址,让人们与您联系。</target>
@@ -1701,6 +1755,18 @@ This cannot be undone!</source>
<target>描述</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Desktop address" xml:space="preserve">
<source>Desktop address</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Desktop app version %@ is not compatible with this app." xml:space="preserve">
<source>Desktop app version %@ is not compatible with this app.</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Desktop devices" xml:space="preserve">
<source>Desktop devices</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Develop" xml:space="preserve">
<source>Develop</source>
<target>开发</target>
@@ -1791,11 +1857,19 @@ This cannot be undone!</source>
<target>断开连接</target>
<note>server test step</note>
</trans-unit>
<trans-unit id="Disconnect desktop?" xml:space="preserve">
<source>Disconnect desktop?</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Discover and join groups" xml:space="preserve">
<source>Discover and join groups</source>
<target>发现和加入群组</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Discover via local network" xml:space="preserve">
<source>Discover via local network</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Do NOT use SimpleX for emergency calls." xml:space="preserve">
<source>Do NOT use SimpleX for emergency calls.</source>
<target>请勿使用 SimpleX 进行紧急通话。</target>
@@ -1966,6 +2040,14 @@ This cannot be undone!</source>
<target>加密消息:意外错误</target>
<note>notification</note>
</trans-unit>
<trans-unit id="Encryption re-negotiation error" xml:space="preserve">
<source>Encryption re-negotiation error</source>
<note>message decrypt error item</note>
</trans-unit>
<trans-unit id="Encryption re-negotiation failed." xml:space="preserve">
<source>Encryption re-negotiation failed.</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Enter Passcode" xml:space="preserve">
<source>Enter Passcode</source>
<target>输入密码</target>
@@ -1995,6 +2077,10 @@ This cannot be undone!</source>
<target>手动输入服务器</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Enter this device name…" xml:space="preserve">
<source>Enter this device name…</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Enter welcome message…" xml:space="preserve">
<source>Enter welcome message…</source>
<target>输入欢迎消息……</target>
@@ -2318,6 +2404,10 @@ This cannot be undone!</source>
<target>快速且无需等待发件人在线!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Faster joining and more reliable messages." xml:space="preserve">
<source>Faster joining and more reliable messages.</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Favorite" xml:space="preserve">
<source>Favorite</source>
<target>最喜欢</target>
@@ -2413,6 +2503,10 @@ This cannot be undone!</source>
<target>用于控制台</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Found desktop" xml:space="preserve">
<source>Found desktop</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="French interface" xml:space="preserve">
<source>French interface</source>
<target>法语界面</target>
@@ -2735,6 +2829,10 @@ This cannot be undone!</source>
<target>隐身聊天</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Incognito groups" xml:space="preserve">
<source>Incognito groups</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Incognito mode" xml:space="preserve">
<source>Incognito mode</source>
<target>隐身模式</target>
@@ -2765,6 +2863,10 @@ This cannot be undone!</source>
<target>数据库版本不兼容</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Incompatible version" xml:space="preserve">
<source>Incompatible version</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Incorrect passcode" xml:space="preserve">
<source>Incorrect passcode</source>
<target>密码错误</target>
@@ -2930,6 +3032,10 @@ This is your link for group %@!</source>
<target>加入群组中</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Keep the app open to use it from desktop" xml:space="preserve">
<source>Keep the app open to use it from desktop</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Keep your connections" xml:space="preserve">
<source>Keep your connections</source>
<target>保持连接</target>
@@ -2990,6 +3096,18 @@ This is your link for group %@!</source>
<target>限制</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Link mobile and desktop apps! 🔗" xml:space="preserve">
<source>Link mobile and desktop apps! 🔗</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Linked desktop options" xml:space="preserve">
<source>Linked desktop options</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Linked desktops" xml:space="preserve">
<source>Linked desktops</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Live message!" xml:space="preserve">
<source>Live message!</source>
<target>实时消息!</target>
@@ -3339,6 +3457,10 @@ This is your link for group %@!</source>
<target>未收到或发送文件</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Not compatible!" xml:space="preserve">
<source>Not compatible!</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Notifications" xml:space="preserve">
<source>Notifications</source>
<target>通知</target>
@@ -3557,6 +3679,10 @@ This is your link for group %@!</source>
<target>粘贴</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Paste desktop address" xml:space="preserve">
<source>Paste desktop address</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Paste image" xml:space="preserve">
<source>Paste image</source>
<target>粘贴图片</target>
@@ -4148,6 +4274,10 @@ This is your link for group %@!</source>
<target>扫描二维码</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Scan QR code from desktop" xml:space="preserve">
<source>Scan QR code from desktop</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Scan code" xml:space="preserve">
<source>Scan code</source>
<target>扫码</target>
@@ -4368,6 +4498,10 @@ This is your link for group %@!</source>
<target>服务器</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Session code" xml:space="preserve">
<source>Session code</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Set 1 day" xml:space="preserve">
<source>Set 1 day</source>
<target>设定1天</target>
@@ -4864,6 +4998,10 @@ It can happen because of some bug or when the connection is compromised.</source
<target>此操作无法撤消——您的个人资料、联系人、消息和文件将不可撤回地丢失。</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="This device name" xml:space="preserve">
<source>This device name</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="This group has over %lld members, delivery receipts are not sent." xml:space="preserve">
<source>This group has over %lld members, delivery receipts are not sent.</source>
<target>该组有超过 %lld 个成员,不发送送货单。</target>
@@ -4897,6 +5035,10 @@ It can happen because of some bug or when the connection is compromised.</source
<target>您的联系人可以扫描二维码或使用应用程序中的链接来建立连接。</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="To hide unwanted messages." xml:space="preserve">
<source>To hide unwanted messages.</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="To make a new connection" xml:space="preserve">
<source>To make a new connection</source>
<target>建立新连接</target>
@@ -5053,6 +5195,14 @@ To connect, please ask your contact to create another connection link and check
如果要连接,请让您的联系人创建另一个连接链接,并检查您的网络连接是否稳定。</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Unlink" xml:space="preserve">
<source>Unlink</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Unlink desktop?" xml:space="preserve">
<source>Unlink desktop?</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Unlock" xml:space="preserve">
<source>Unlock</source>
<target>解锁</target>
@@ -5143,6 +5293,10 @@ To connect, please ask your contact to create another connection link and check
<target>用于新连接</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Use from desktop" xml:space="preserve">
<source>Use from desktop</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Use iOS call interface" xml:space="preserve">
<source>Use iOS call interface</source>
<target>使用 iOS 通话界面</target>
@@ -5173,11 +5327,23 @@ To connect, please ask your contact to create another connection link and check
<target>使用 SimpleX Chat 服务器。</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Verify code with desktop" xml:space="preserve">
<source>Verify code with desktop</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Verify connection" xml:space="preserve">
<source>Verify connection</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Verify connection security" xml:space="preserve">
<source>Verify connection security</source>
<target>验证连接安全</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Verify connections" xml:space="preserve">
<source>Verify connections</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Verify security code" xml:space="preserve">
<source>Verify security code</source>
<target>验证安全码</target>
@@ -5188,6 +5354,10 @@ To connect, please ask your contact to create another connection link and check
<target>通过浏览器</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Via secure quantum resistant protocol." xml:space="preserve">
<source>Via secure quantum resistant protocol.</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Video call" xml:space="preserve">
<source>Video call</source>
<target>视频通话</target>
@@ -5238,6 +5408,10 @@ To connect, please ask your contact to create another connection link and check
<target>语音消息……</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Waiting for desktop..." xml:space="preserve">
<source>Waiting for desktop...</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Waiting for file" xml:space="preserve">
<source>Waiting for file</source>
<target>等待文件中</target>
@@ -5768,6 +5942,10 @@ SimpleX 服务器无法看到您的资料。</target>
<target>语音通话(非端到端加密)</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="author" xml:space="preserve">
<source>author</source>
<note>member role</note>
</trans-unit>
<trans-unit id="bad message ID" xml:space="preserve">
<source>bad message ID</source>
<target>错误消息 ID</target>
@@ -6348,6 +6526,10 @@ SimpleX 服务器无法看到您的资料。</target>
<target>已更新的群组资料</target>
<note>rcv group event chat item</note>
</trans-unit>
<trans-unit id="v%@" xml:space="preserve">
<source>v%@</source>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="v%@ (%@)" xml:space="preserve">
<source>v%@ (%@)</source>
<target>v%@ (%@)</target>
@@ -6485,6 +6667,10 @@ SimpleX 服务器无法看到您的资料。</target>
<target>SimpleX 使用Face ID进行本地身份验证</target>
<note>Privacy - Face ID Usage Description</note>
</trans-unit>
<trans-unit id="NSLocalNetworkUsageDescription" xml:space="preserve">
<source>SimpleX uses local network access to allow using user chat profile via desktop app on the same network.</source>
<note>Privacy - Local Network Usage Description</note>
</trans-unit>
<trans-unit id="NSMicrophoneUsageDescription" xml:space="preserve">
<source>SimpleX needs microphone access for audio and video calls, and to record voice messages.</source>
<target>SimpleX 需要麦克风访问权限才能进行音频和视频通话,以及录制语音消息。</target>

View File

@@ -4,6 +4,8 @@
"NSCameraUsageDescription" = "SimpleX needs camera access to scan QR codes to connect to other users and for video calls.";
/* Privacy - Face ID Usage Description */
"NSFaceIDUsageDescription" = "SimpleX uses Face ID for local authentication";
/* Privacy - Local Network Usage Description */
"NSLocalNetworkUsageDescription" = "SimpleX uses local network access to allow using user chat profile via desktop app on the same network.";
/* Privacy - Microphone Usage Description */
"NSMicrophoneUsageDescription" = "SimpleX needs microphone access for audio and video calls, and to record voice messages.";
/* Privacy - Photo Library Additions Usage Description */

View File

@@ -0,0 +1,64 @@
//
// ConcurrentQueue.swift
// SimpleX NSE
//
// Created by Evgeny on 08/12/2023.
// Copyright © 2023 SimpleX Chat. All rights reserved.
//
import Foundation
struct DequeueElement<T> {
var elementId: UUID?
var task: Task<T?, Never>
}
class ConcurrentQueue<T> {
private var queue: [T] = []
private var queueLock = DispatchQueue(label: "chat.simplex.app.SimpleX-NSE.concurrent-queue.lock.\(UUID())")
private var continuations = [(elementId: UUID, continuation: CheckedContinuation<T?, Never>)]()
func enqueue(_ el: T) {
resumeContinuation(el) { self.queue.append(el) }
}
func frontEnqueue(_ el: T) {
resumeContinuation(el) { self.queue.insert(el, at: 0) }
}
private func resumeContinuation(_ el: T, add: @escaping () -> Void) {
queueLock.sync {
if let (_, cont) = continuations.first {
continuations.remove(at: 0)
cont.resume(returning: el)
} else {
add()
}
}
}
func dequeue() -> DequeueElement<T> {
queueLock.sync {
if queue.isEmpty {
let elementId = UUID()
let task = Task {
await withCheckedContinuation { cont in
continuations.append((elementId, cont))
}
}
return DequeueElement(elementId: elementId, task: task)
} else {
let el = queue.remove(at: 0)
return DequeueElement(task: Task { el })
}
}
}
func cancelDequeue(_ elementId: UUID) {
queueLock.sync {
let cancelled = continuations.filter { $0.elementId == elementId }
continuations.removeAll { $0.elementId == elementId }
cancelled.forEach { $0.continuation.resume(returning: nil) }
}
}
}

View File

@@ -14,91 +14,233 @@ import SimpleXChat
let logger = Logger()
let suspendingDelay: UInt64 = 2_000_000_000
let appSuspendingDelay: UInt64 = 2_500_000_000
typealias NtfStream = AsyncStream<NSENotification>
typealias SuspendSchedule = (delay: TimeInterval, timeout: Int)
let nseSuspendSchedule: SuspendSchedule = (2, 4)
let fastNSESuspendSchedule: SuspendSchedule = (1, 1)
typealias NtfStream = ConcurrentQueue<NSENotification>
// Notifications are delivered via concurrent queues, as they are all received from chat controller in a single loop that
// writes to ConcurrentQueue and when notification is processed, the instance of Notification service extension reads from the queue.
// One queue per connection (entity) is used.
// The concurrent queues allow read cancellation, to ensure that notifications are not lost in case the current thread completes
// before expected notification is read (multiple notifications can be expected, because one notification can be delivered for several messages).
actor PendingNtfs {
static let shared = PendingNtfs()
private var ntfStreams: [String: NtfStream] = [:]
private var ntfConts: [String: NtfStream.Continuation] = [:]
func createStream(_ id: String) {
logger.debug("PendingNtfs.createStream: \(id, privacy: .public)")
if ntfStreams.index(forKey: id) == nil {
ntfStreams[id] = AsyncStream { cont in
ntfConts[id] = cont
logger.debug("PendingNtfs.createStream: store continuation")
}
func createStream(_ id: String) async {
logger.debug("NotificationService PendingNtfs.createStream: \(id)")
if ntfStreams[id] == nil {
ntfStreams[id] = ConcurrentQueue()
logger.debug("NotificationService PendingNtfs.createStream: created ConcurrentQueue")
}
}
func readStream(_ id: String, for nse: NotificationService, msgCount: Int = 1, showNotifications: Bool) async {
logger.debug("PendingNtfs.readStream: \(id, privacy: .public) \(msgCount, privacy: .public)")
func readStream(_ id: String, for nse: NotificationService, ntfInfo: NtfMessages) async {
logger.debug("NotificationService PendingNtfs.readStream: \(id) \(ntfInfo.ntfMessages.count)")
if !ntfInfo.user.showNotifications {
nse.setBestAttemptNtf(.empty)
}
if let s = ntfStreams[id] {
logger.debug("PendingNtfs.readStream: has stream")
var rcvCount = max(1, msgCount)
for await ntf in s {
nse.setBestAttemptNtf(showNotifications ? ntf : .empty)
rcvCount -= 1
if rcvCount == 0 || ntf.categoryIdentifier == ntfCategoryCallInvitation { break }
logger.debug("NotificationService PendingNtfs.readStream: has stream")
var expected = Set(ntfInfo.ntfMessages.map { $0.msgId })
logger.debug("NotificationService PendingNtfs.readStream: expecting: \(expected)")
var readCancelled = false
var dequeued: DequeueElement<NSENotification>?
nse.cancelRead = {
readCancelled = true
if let elementId = dequeued?.elementId {
s.cancelDequeue(elementId)
}
}
logger.debug("PendingNtfs.readStream: exiting")
while !readCancelled {
dequeued = s.dequeue()
if let ntf = await dequeued?.task.value {
if readCancelled {
logger.debug("NotificationService PendingNtfs.readStream: read cancelled, put ntf to queue front")
s.frontEnqueue(ntf)
break
} else if case let .msgInfo(info) = ntf {
let found = expected.remove(info.msgId)
if found != nil {
logger.debug("NotificationService PendingNtfs.readStream: msgInfo, last: \(expected.isEmpty)")
if expected.isEmpty { break }
} else if let msgTs = ntfInfo.msgTs, info.msgTs > msgTs {
logger.debug("NotificationService PendingNtfs.readStream: unexpected msgInfo")
s.frontEnqueue(ntf)
break
}
} else if ntfInfo.user.showNotifications {
logger.debug("NotificationService PendingNtfs.readStream: setting best attempt")
nse.setBestAttemptNtf(ntf)
if ntf.isCallInvitation { break }
}
} else {
break
}
}
nse.cancelRead = nil
logger.debug("NotificationService PendingNtfs.readStream: exiting")
}
}
func writeStream(_ id: String, _ ntf: NSENotification) {
logger.debug("PendingNtfs.writeStream: \(id, privacy: .public)")
if let cont = ntfConts[id] {
logger.debug("PendingNtfs.writeStream: writing ntf")
cont.yield(ntf)
func writeStream(_ id: String, _ ntf: NSENotification) async {
logger.debug("NotificationService PendingNtfs.writeStream: \(id)")
if let s = ntfStreams[id] {
logger.debug("NotificationService PendingNtfs.writeStream: writing ntf")
s.enqueue(ntf)
}
}
}
// The current implementation assumes concurrent notification delivery and uses semaphores
// to process only one notification per connection (entity) at a time.
class NtfStreamSemaphores {
static let shared = NtfStreamSemaphores()
private static let queue = DispatchQueue(label: "chat.simplex.app.SimpleX-NSE.notification-semaphores.lock")
private var semaphores: [String: DispatchSemaphore] = [:]
func waitForStream(_ id: String) {
streamSemaphore(id, value: 0)?.wait()
}
func signalStreamReady(_ id: String) {
streamSemaphore(id, value: 1)?.signal()
}
// this function returns nil if semaphore is just created, so passed value shoud be coordinated with the desired end value of the semaphore
private func streamSemaphore(_ id: String, value: Int) -> DispatchSemaphore? {
NtfStreamSemaphores.queue.sync {
if let s = semaphores[id] {
return s
} else {
semaphores[id] = DispatchSemaphore(value: value)
return nil
}
}
}
}
enum NSENotification {
case nse(notification: UNMutableNotificationContent)
case callkit(invitation: RcvCallInvitation)
case nse(UNMutableNotificationContent)
case callkit(RcvCallInvitation)
case empty
case msgInfo(NtfMsgInfo)
var categoryIdentifier: String? {
var isCallInvitation: Bool {
switch self {
case let .nse(ntf): return ntf.categoryIdentifier
case .callkit: return ntfCategoryCallInvitation
case .empty: return nil
case let .nse(ntf): ntf.categoryIdentifier == ntfCategoryCallInvitation
case .callkit: true
case .empty: false
case .msgInfo: false
}
}
}
// Once the last thread in the process completes processing chat controller is suspended, and the database is closed, to avoid
// background crashes and contention for database with the application (both UI and background fetch triggered either on schedule
// or when background notification is received.
class NSEThreads {
static let shared = NSEThreads()
private static let queue = DispatchQueue(label: "chat.simplex.app.SimpleX-NSE.notification-threads.lock")
private var allThreads: Set<UUID> = []
private var activeThreads: Set<UUID> = []
func newThread() -> UUID {
NSEThreads.queue.sync {
let (_, t) = allThreads.insert(UUID())
return t
}
}
func startThread(_ t: UUID) {
NSEThreads.queue.sync {
if allThreads.contains(t) {
_ = activeThreads.insert(t)
} else {
logger.warning("NotificationService startThread: thread \(t) was removed before it started")
}
}
}
func endThread(_ t: UUID) -> Bool {
NSEThreads.queue.sync {
let tActive = activeThreads.remove(t)
let t = allThreads.remove(t)
if tActive != nil && activeThreads.isEmpty {
return true
}
if t != nil && allThreads.isEmpty {
NSEChatState.shared.set(.suspended)
}
return false
}
}
var noThreads: Bool {
allThreads.isEmpty
}
}
// Notification service extension creates a new instance of the class and calls didReceive for each notification.
// Each didReceive is called in its own thread, but multiple calls can be made in one process, and, empirically, there is never
// more than one process of notification service extension exists at a time.
// Soon after notification service delivers the last notification it is either suspended or terminated.
class NotificationService: UNNotificationServiceExtension {
var contentHandler: ((UNNotificationContent) -> Void)?
var bestAttemptNtf: NSENotification?
var badgeCount: Int = 0
// thread is added to allThreads here - if thread did not start chat,
// chat does not need to be suspended but NSE state still needs to be set to "suspended".
var threadId: UUID? = NSEThreads.shared.newThread()
var receiveEntityId: String?
var cancelRead: (() -> Void)?
var appSubscriber: AppSubscriber?
var returnedSuspension = false
override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {
logger.debug("DEBUGGING: NotificationService.didReceive")
if let ntf = request.content.mutableCopy() as? UNMutableNotificationContent {
setBestAttemptNtf(ntf)
}
let ntf = if let ntf_ = request.content.mutableCopy() as? UNMutableNotificationContent { ntf_ } else { UNMutableNotificationContent() }
setBestAttemptNtf(ntf)
self.contentHandler = contentHandler
registerGroupDefaults()
let appState = appStateGroupDefault.get()
logger.debug("NotificationService: app is \(appState.rawValue)")
switch appState {
case .stopped:
setBadgeCount()
setBestAttemptNtf(createAppStoppedNtf())
deliverBestAttemptNtf()
case .suspended:
logger.debug("NotificationService: app is suspended")
setBadgeCount()
receiveNtfMessages(request, contentHandler)
case .suspending:
logger.debug("NotificationService: app is suspending")
setBadgeCount()
Task {
var state = appState
for _ in 1...5 {
_ = try await Task.sleep(nanoseconds: suspendingDelay)
state = appStateGroupDefault.get()
if state == .suspended || state != .suspending { break }
let state: AppState = await withCheckedContinuation { cont in
appSubscriber = appStateSubscriber { s in
if s == .suspended { appSuspension(s) }
}
DispatchQueue.global().asyncAfter(deadline: .now() + Double(appSuspendTimeout) + 1) {
logger.debug("NotificationService: appSuspension timeout")
appSuspension(appStateGroupDefault.get())
}
@Sendable
func appSuspension(_ s: AppState) {
if !self.returnedSuspension {
self.returnedSuspension = true
self.appSubscriber = nil // this disposes of appStateSubscriber
cont.resume(returning: s)
}
}
}
logger.debug("NotificationService: app state is \(state.rawValue, privacy: .public)")
logger.debug("NotificationService: app state is now \(state.rawValue)")
if state.inactive {
receiveNtfMessages(request, contentHandler)
} else {
@@ -106,7 +248,6 @@ class NotificationService: UNNotificationServiceExtension {
}
}
default:
logger.debug("NotificationService: app state is \(appState.rawValue, privacy: .public)")
deliverBestAttemptNtf()
}
}
@@ -121,27 +262,35 @@ class NotificationService: UNNotificationServiceExtension {
if let ntfData = userInfo["notificationData"] as? [AnyHashable : Any],
let nonce = ntfData["nonce"] as? String,
let encNtfInfo = ntfData["message"] as? String,
let dbStatus = startChat() {
// check it here again
appStateGroupDefault.get().inactive {
// thread is added to activeThreads tracking set here - if thread started chat it needs to be suspended
if let t = threadId { NSEThreads.shared.startThread(t) }
let dbStatus = startChat()
if case .ok = dbStatus,
let ntfMsgInfo = apiGetNtfMessage(nonce: nonce, encNtfInfo: encNtfInfo) {
logger.debug("NotificationService: receiveNtfMessages: apiGetNtfMessage \(String(describing: ntfMsgInfo), privacy: .public)")
if let connEntity = ntfMsgInfo.connEntity {
let ntfInfo = apiGetNtfMessage(nonce: nonce, encNtfInfo: encNtfInfo) {
logger.debug("NotificationService: receiveNtfMessages: apiGetNtfMessage \(String(describing: ntfInfo.ntfMessages.count))")
if let connEntity = ntfInfo.connEntity_ {
setBestAttemptNtf(
ntfMsgInfo.ntfsEnabled
? .nse(notification: createConnectionEventNtf(ntfMsgInfo.user, connEntity))
ntfInfo.ntfsEnabled
? .nse(createConnectionEventNtf(ntfInfo.user, connEntity))
: .empty
)
if let id = connEntity.id {
Task {
logger.debug("NotificationService: receiveNtfMessages: in Task, connEntity id \(id, privacy: .public)")
await PendingNtfs.shared.createStream(id)
await PendingNtfs.shared.readStream(id, for: self, msgCount: ntfMsgInfo.ntfMessages.count, showNotifications: ntfMsgInfo.user.showNotifications)
deliverBestAttemptNtf()
receiveEntityId = id
NtfStreamSemaphores.shared.waitForStream(id)
if receiveEntityId != nil {
Task {
logger.debug("NotificationService: receiveNtfMessages: in Task, connEntity id \(id)")
await PendingNtfs.shared.createStream(id)
await PendingNtfs.shared.readStream(id, for: self, ntfInfo: ntfInfo)
deliverBestAttemptNtf()
}
}
return
}
}
return
} else {
} else if let dbStatus = dbStatus {
setBestAttemptNtf(createErrorNtf(dbStatus))
}
}
@@ -150,7 +299,7 @@ class NotificationService: UNNotificationServiceExtension {
override func serviceExtensionTimeWillExpire() {
logger.debug("DEBUGGING: NotificationService.serviceExtensionTimeWillExpire")
deliverBestAttemptNtf()
deliverBestAttemptNtf(urgent: true)
}
func setBadgeCount() {
@@ -159,91 +308,301 @@ class NotificationService: UNNotificationServiceExtension {
}
func setBestAttemptNtf(_ ntf: UNMutableNotificationContent) {
setBestAttemptNtf(.nse(notification: ntf))
setBestAttemptNtf(.nse(ntf))
}
func setBestAttemptNtf(_ ntf: NSENotification) {
logger.debug("NotificationService.setBestAttemptNtf")
if case let .nse(notification) = ntf {
notification.badge = badgeCount as NSNumber
bestAttemptNtf = .nse(notification: notification)
bestAttemptNtf = .nse(notification)
} else {
bestAttemptNtf = ntf
}
}
private func deliverBestAttemptNtf() {
private func deliverBestAttemptNtf(urgent: Bool = false) {
logger.debug("NotificationService.deliverBestAttemptNtf")
if let cancel = cancelRead {
cancelRead = nil
cancel()
}
if let id = receiveEntityId {
receiveEntityId = nil
NtfStreamSemaphores.shared.signalStreamReady(id)
}
let suspend: Bool
if let t = threadId {
threadId = nil
suspend = NSEThreads.shared.endThread(t) && NSEThreads.shared.noThreads
} else {
suspend = false
}
deliverCallkitOrNotification(urgent: urgent, suspend: suspend)
}
private func deliverCallkitOrNotification(urgent: Bool, suspend: Bool = false) {
if case .callkit = bestAttemptNtf {
logger.debug("NotificationService.deliverCallkitOrNotification: will suspend, callkit")
if urgent {
// suspending NSE even though there may be other notifications
// to allow the app to process callkit call
suspendChat(0)
deliverNotification()
} else {
// suspending NSE with delay and delivering after the suspension
// because pushkit notification must be processed without delay
// to avoid app termination
DispatchQueue.global().asyncAfter(deadline: .now() + fastNSESuspendSchedule.delay) {
suspendChat(fastNSESuspendSchedule.timeout)
DispatchQueue.global().asyncAfter(deadline: .now() + Double(fastNSESuspendSchedule.timeout)) {
self.deliverNotification()
}
}
}
} else {
if suspend {
logger.debug("NotificationService.deliverCallkitOrNotification: will suspend")
if urgent {
suspendChat(0)
} else {
// suspension is delayed to allow chat core finalise any processing
// (e.g., send delivery receipts)
DispatchQueue.global().asyncAfter(deadline: .now() + nseSuspendSchedule.delay) {
if NSEThreads.shared.noThreads {
suspendChat(nseSuspendSchedule.timeout)
}
}
}
}
deliverNotification()
}
}
private func deliverNotification() {
if let handler = contentHandler, let ntf = bestAttemptNtf {
contentHandler = nil
bestAttemptNtf = nil
let deliver: (UNMutableNotificationContent?) -> Void = { ntf in
let useNtf = if let ntf = ntf {
appStateGroupDefault.get().running ? UNMutableNotificationContent() : ntf
} else {
UNMutableNotificationContent()
}
handler(useNtf)
}
switch ntf {
case let .nse(content): handler(content)
case let .nse(content): deliver(content)
case let .callkit(invitation):
logger.debug("NotificationService reportNewIncomingVoIPPushPayload for \(invitation.contact.id)")
CXProvider.reportNewIncomingVoIPPushPayload([
"displayName": invitation.contact.displayName,
"contactId": invitation.contact.id,
"media": invitation.callType.media.rawValue
]) { error in
if error == nil {
handler(UNMutableNotificationContent())
} else {
logger.debug("reportNewIncomingVoIPPushPayload success to CallController for \(invitation.contact.id)")
handler(createCallInvitationNtf(invitation))
}
logger.debug("reportNewIncomingVoIPPushPayload result: \(error)")
deliver(error == nil ? nil : createCallInvitationNtf(invitation))
}
case .empty: handler(UNMutableNotificationContent())
case .empty: deliver(nil) // used to mute notifications that did not unsubscribe yet
case .msgInfo: deliver(nil) // unreachable, the best attempt is never set to msgInfo
}
bestAttemptNtf = nil
}
}
}
var chatStarted = false
var networkConfig: NetCfg = getNetCfg()
var xftpConfig: XFTPFileConfig? = getXFTPCfg()
// nseStateGroupDefault must not be used in NSE directly, only via this singleton
class NSEChatState {
static let shared = NSEChatState()
private var value_ = NSEState.created
var value: NSEState {
value_
}
func set(_ state: NSEState) {
nseStateGroupDefault.set(state)
sendNSEState(state)
value_ = state
}
init() {
// This is always set to .created state, as in case previous start of NSE crashed in .active state, it is stored correctly.
// Otherwise the app will be activating slower
set(.created)
}
}
var appSubscriber: AppSubscriber = appStateSubscriber { state in
logger.debug("NotificationService: appSubscriber")
if state.running && NSEChatState.shared.value.canSuspend {
logger.debug("NotificationService: appSubscriber app state \(state.rawValue), suspending")
suspendChat(fastNSESuspendSchedule.timeout)
}
}
func appStateSubscriber(onState: @escaping (AppState) -> Void) -> AppSubscriber {
appMessageSubscriber { msg in
if case let .state(state) = msg {
logger.debug("NotificationService: appStateSubscriber \(state.rawValue)")
onState(state)
}
}
}
var receiverStarted = false
let startLock = DispatchSemaphore(value: 1)
let suspendLock = DispatchSemaphore(value: 1)
var networkConfig: NetCfg = getNetCfg()
let xftpConfig: XFTPFileConfig? = getXFTPCfg()
// startChat uses semaphore startLock to ensure that only one didReceive thread can start chat controller
// Subsequent calls to didReceive will be waiting on semaphore and won't start chat again, as it will be .active
func startChat() -> DBMigrationResult? {
hs_init(0, nil)
if chatStarted { return .ok }
let (_, dbStatus) = chatMigrateInit(confirmMigrations: defaultMigrationConfirmation())
logger.debug("NotificationService: startChat")
// only skip creating if there is chat controller
if case .active = NSEChatState.shared.value, hasChatCtrl() { return .ok }
startLock.wait()
defer { startLock.signal() }
if hasChatCtrl() {
return switch NSEChatState.shared.value {
case .created: doStartChat()
case .starting: .ok // it should never get to this branch, as it would be waiting for start on startLock
case .active: .ok
case .suspending: activateChat()
case .suspended: activateChat()
}
} else {
// Ignore state in preference if there is no chat controller.
// State in preference may have failed to update e.g. because of a crash.
NSEChatState.shared.set(.created)
return doStartChat()
}
}
func doStartChat() -> DBMigrationResult? {
logger.debug("NotificationService: doStartChat")
haskell_init_nse()
let (_, dbStatus) = chatMigrateInit(confirmMigrations: defaultMigrationConfirmation(), backgroundMode: true)
logger.debug("NotificationService: doStartChat \(String(describing: dbStatus))")
if dbStatus != .ok {
resetChatCtrl()
NSEChatState.shared.set(.created)
return dbStatus
}
let state = NSEChatState.shared.value
NSEChatState.shared.set(.starting)
if let user = apiGetActiveUser() {
logger.debug("active user \(String(describing: user))")
logger.debug("NotificationService active user \(String(describing: user))")
do {
try setNetworkConfig(networkConfig)
try apiSetTempFolder(tempFolder: getTempFilesDirectory().path)
try apiSetFilesFolder(filesFolder: getAppFilesDirectory().path)
try setXFTPConfig(xftpConfig)
try apiSetEncryptLocalFiles(privacyEncryptLocalFilesGroupDefault.get())
let justStarted = try apiStartChat()
chatStarted = true
if justStarted {
chatLastStartGroupDefault.set(Date.now)
Task { await receiveMessages() }
// prevent suspension while starting chat
suspendLock.wait()
defer { suspendLock.signal() }
if NSEChatState.shared.value == .starting {
updateNetCfg()
let justStarted = try apiStartChat()
NSEChatState.shared.set(.active)
if justStarted {
chatLastStartGroupDefault.set(Date.now)
Task {
if !receiverStarted {
receiverStarted = true
await receiveMessages()
}
}
}
return .ok
}
return .ok
} catch {
logger.error("NotificationService startChat error: \(responseError(error), privacy: .public)")
logger.error("NotificationService startChat error: \(responseError(error))")
}
} else {
logger.debug("no active user")
logger.debug("NotificationService: no active user")
}
if NSEChatState.shared.value == .starting { NSEChatState.shared.set(state) }
return nil
}
func activateChat() -> DBMigrationResult? {
logger.debug("NotificationService: activateChat")
let state = NSEChatState.shared.value
NSEChatState.shared.set(.active)
if apiActivateChat() {
logger.debug("NotificationService: activateChat: after apiActivateChat")
return .ok
} else {
NSEChatState.shared.set(state)
return nil
}
}
// suspendChat uses semaphore suspendLock to ensure that only one suspension can happen.
func suspendChat(_ timeout: Int) {
logger.debug("NotificationService: suspendChat")
let state = NSEChatState.shared.value
if !state.canSuspend {
logger.error("NotificationService suspendChat called, current state: \(state.rawValue)")
} else if hasChatCtrl() {
// only suspend if we have chat controller to avoid crashes when suspension is
// attempted when chat controller was not created
suspendLock.wait()
defer { suspendLock.signal() }
NSEChatState.shared.set(.suspending)
if apiSuspendChat(timeoutMicroseconds: timeout * 1000000) {
logger.debug("NotificationService: suspendChat: after apiSuspendChat")
DispatchQueue.global().asyncAfter(deadline: .now() + Double(timeout) + 1, execute: chatSuspended)
} else {
NSEChatState.shared.set(state)
}
}
}
func chatSuspended() {
logger.debug("NotificationService chatSuspended")
if case .suspending = NSEChatState.shared.value {
NSEChatState.shared.set(.suspended)
chatCloseStore()
logger.debug("NotificationService chatSuspended: suspended")
}
}
// A single loop is used per Notification service extension process to receive and process all messages depending on the NSE state
// If the extension is not active yet, or suspended/suspending, or the app is running, the notifications will no be received.
func receiveMessages() async {
logger.debug("NotificationService receiveMessages")
while true {
updateNetCfg()
switch NSEChatState.shared.value {
// it should never get to "created" and "starting" branches, as NSE state is set to .active before the loop start
case .created: await delayWhenInactive()
case .starting: await delayWhenInactive()
case .active: await receiveMsg()
case .suspending: await receiveMsg()
case .suspended: await delayWhenInactive()
}
}
func receiveMsg() async {
if let msg = await chatRecvMsg() {
logger.debug("NotificationService receiveMsg: message")
if let (id, ntf) = await receivedMsgNtf(msg) {
logger.debug("NotificationService receiveMsg: notification")
await PendingNtfs.shared.createStream(id)
await PendingNtfs.shared.writeStream(id, ntf)
}
}
}
func delayWhenInactive() async {
logger.debug("NotificationService delayWhenInactive")
_ = try? await Task.sleep(nanoseconds: 1000_000000)
}
}
func chatRecvMsg() async -> ChatResponse? {
@@ -257,14 +616,14 @@ private let isInChina = SKStorefront().countryCode == "CHN"
private func useCallKit() -> Bool { !isInChina && callKitEnabledGroupDefault.get() }
func receivedMsgNtf(_ res: ChatResponse) async -> (String, NSENotification)? {
logger.debug("NotificationService processReceivedMsg: \(res.responseType)")
logger.debug("NotificationService receivedMsgNtf: \(res.responseType)")
switch res {
case let .contactConnected(user, contact, _):
return (contact.id, .nse(notification: createContactConnectedNtf(user, contact)))
return (contact.id, .nse(createContactConnectedNtf(user, contact)))
// case let .contactConnecting(contact):
// TODO profile update
case let .receivedContactRequest(user, contactRequest):
return (UserContact(contactRequest: contactRequest).id, .nse(notification: createContactRequestNtf(user, contactRequest)))
return (UserContact(contactRequest: contactRequest).id, .nse(createContactRequestNtf(user, contactRequest)))
case let .newChatItem(user, aChatItem):
let cInfo = aChatItem.chatInfo
var cItem = aChatItem.chatItem
@@ -274,7 +633,7 @@ func receivedMsgNtf(_ res: ChatResponse) async -> (String, NSENotification)? {
if let file = cItem.autoReceiveFile() {
cItem = autoReceiveFile(file, encrypted: cItem.encryptLocalFile) ?? cItem
}
let ntf: NSENotification = cInfo.ntfsEnabled ? .nse(notification: createMessageReceivedNtf(user, cInfo, cItem)) : .empty
let ntf: NSENotification = cInfo.ntfsEnabled ? .nse(createMessageReceivedNtf(user, cInfo, cItem)) : .empty
return cItem.showNotification ? (aChatItem.chatId, ntf) : nil
case let .rcvFileSndCancelled(_, aChatItem, _):
cleanupFile(aChatItem)
@@ -292,10 +651,18 @@ func receivedMsgNtf(_ res: ChatResponse) async -> (String, NSENotification)? {
// Do not post it without CallKit support, iOS will stop launching the app without showing CallKit
return (
invitation.contact.id,
useCallKit() ? .callkit(invitation: invitation) : .nse(notification: createCallInvitationNtf(invitation))
useCallKit() ? .callkit(invitation) : .nse(createCallInvitationNtf(invitation))
)
case let .ntfMessage(_, connEntity, ntfMessage):
return if let id = connEntity.id { (id, .msgInfo(ntfMessage)) } else { nil }
case .chatSuspended:
chatSuspended()
return nil
case let .chatError(_, err):
logger.error("NotificationService receivedMsgNtf error: \(String(describing: err))")
return nil
default:
logger.debug("NotificationService processReceivedMsg ignored event: \(res.responseType)")
logger.debug("NotificationService receivedMsgNtf ignored event: \(res.responseType)")
return nil
}
}
@@ -308,17 +675,22 @@ func updateNetCfg() {
try setNetworkConfig(networkConfig)
networkConfig = newNetConfig
} catch {
logger.error("NotificationService apply changed network config error: \(responseError(error), privacy: .public)")
logger.error("NotificationService apply changed network config error: \(responseError(error))")
}
}
}
func apiGetActiveUser() -> User? {
let r = sendSimpleXCmd(.showActiveUser)
logger.debug("apiGetActiveUser sendSimpleXCmd response: \(String(describing: r))")
logger.debug("apiGetActiveUser sendSimpleXCmd response: \(r.responseType)")
switch r {
case let .activeUser(user): return user
case .chatCmdError(_, .error(.noActiveUser)): return nil
case .chatCmdError(_, .error(.noActiveUser)):
logger.debug("apiGetActiveUser sendSimpleXCmd no active user")
return nil
case let .chatCmdError(_, err):
logger.debug("apiGetActiveUser sendSimpleXCmd error: \(String(describing: err))")
return nil
default:
logger.error("NotificationService apiGetActiveUser unexpected response: \(String(describing: r))")
return nil
@@ -326,7 +698,7 @@ func apiGetActiveUser() -> User? {
}
func apiStartChat() throws -> Bool {
let r = sendSimpleXCmd(.startChat(subscribe: false, expire: false, xftp: false))
let r = sendSimpleXCmd(.startChat(mainApp: false))
switch r {
case .chatStarted: return true
case .chatRunning: return false
@@ -334,6 +706,21 @@ func apiStartChat() throws -> Bool {
}
}
func apiActivateChat() -> Bool {
chatReopenStore()
let r = sendSimpleXCmd(.apiActivateChat(restoreChat: false))
if case .cmdOk = r { return true }
logger.error("NotificationService apiActivateChat error: \(String(describing: r))")
return false
}
func apiSuspendChat(timeoutMicroseconds: Int) -> Bool {
let r = sendSimpleXCmd(.apiSuspendChat(timeoutMicroseconds: timeoutMicroseconds))
if case .cmdOk = r { return true }
logger.error("NotificationService apiSuspendChat error: \(String(describing: r))")
return false
}
func apiSetTempFolder(tempFolder: String) throws {
let r = sendSimpleXCmd(.setTempFolder(tempFolder: tempFolder))
if case .cmdOk = r { return }
@@ -364,12 +751,13 @@ func apiGetNtfMessage(nonce: String, encNtfInfo: String) -> NtfMessages? {
return nil
}
let r = sendSimpleXCmd(.apiGetNtfMessage(nonce: nonce, encNtfInfo: encNtfInfo))
if case let .ntfMessages(user, connEntity, msgTs, ntfMessages) = r, let user = user {
return NtfMessages(user: user, connEntity: connEntity, msgTs: msgTs, ntfMessages: ntfMessages)
if case let .ntfMessages(user, connEntity_, msgTs, ntfMessages) = r, let user = user {
logger.debug("apiGetNtfMessage response ntfMessages: \(ntfMessages.count)")
return NtfMessages(user: user, connEntity_: connEntity_, msgTs: msgTs, ntfMessages: ntfMessages)
} else if case let .chatCmdError(_, error) = r {
logger.debug("apiGetNtfMessage error response: \(String.init(describing: error))")
} else {
logger.debug("apiGetNtfMessage ignored response: \(r.responseType, privacy: .public) \(String.init(describing: r), privacy: .private)")
logger.debug("apiGetNtfMessage ignored response: \(r.responseType) \(String.init(describing: r))")
}
return nil
}
@@ -405,11 +793,11 @@ func setNetworkConfig(_ cfg: NetCfg) throws {
struct NtfMessages {
var user: User
var connEntity: ConnectionEntity?
var connEntity_: ConnectionEntity?
var msgTs: Date?
var ntfMessages: [NtfMsgInfo]
var ntfsEnabled: Bool {
user.showNotifications && (connEntity?.ntfsEnabled ?? false)
user.showNotifications && (connEntity_?.ntfsEnabled ?? false)
}
}

View File

@@ -30,6 +30,11 @@
5C116CDC27AABE0400E66D01 /* ContactRequestView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C116CDB27AABE0400E66D01 /* ContactRequestView.swift */; };
5C13730B28156D2700F43030 /* ContactConnectionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C13730A28156D2700F43030 /* ContactConnectionView.swift */; };
5C1A4C1E27A715B700EAD5AD /* ChatItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C1A4C1D27A715B700EAD5AD /* ChatItemView.swift */; };
5C245F232B4EAA5E001CC39F /* libgmpxx.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5C245F1E2B4EAA5E001CC39F /* libgmpxx.a */; };
5C245F242B4EAA5E001CC39F /* libHSsimplex-chat-5.4.3.0-BrNBQIZf2Ju9TtaZoeJyIH-ghc9.6.3.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5C245F1F2B4EAA5E001CC39F /* libHSsimplex-chat-5.4.3.0-BrNBQIZf2Ju9TtaZoeJyIH-ghc9.6.3.a */; };
5C245F252B4EAA5E001CC39F /* libgmp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5C245F202B4EAA5E001CC39F /* libgmp.a */; };
5C245F262B4EAA5E001CC39F /* libHSsimplex-chat-5.4.3.0-BrNBQIZf2Ju9TtaZoeJyIH.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5C245F212B4EAA5E001CC39F /* libHSsimplex-chat-5.4.3.0-BrNBQIZf2Ju9TtaZoeJyIH.a */; };
5C245F272B4EAA5E001CC39F /* libffi.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5C245F222B4EAA5E001CC39F /* libffi.a */; };
5C2E260727A2941F00F70299 /* SimpleXAPI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C2E260627A2941F00F70299 /* SimpleXAPI.swift */; };
5C2E260B27A30CFA00F70299 /* ChatListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C2E260A27A30CFA00F70299 /* ChatListView.swift */; };
5C2E260F27A30FDC00F70299 /* ChatView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C2E260E27A30FDC00F70299 /* ChatView.swift */; };
@@ -39,6 +44,7 @@
5C36027327F47AD5009F19D9 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C36027227F47AD5009F19D9 /* AppDelegate.swift */; };
5C3A88CE27DF50170060F1C2 /* DetermineWidth.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C3A88CD27DF50170060F1C2 /* DetermineWidth.swift */; };
5C3A88D127DF57800060F1C2 /* FramedItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C3A88D027DF57800060F1C2 /* FramedItemView.swift */; };
5C3CCFCC2AE6BD3100C3F0C3 /* ConnectDesktopView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C3CCFCB2AE6BD3100C3F0C3 /* ConnectDesktopView.swift */; };
5C3F1D562842B68D00EC8A82 /* IntegrityErrorItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C3F1D552842B68D00EC8A82 /* IntegrityErrorItemView.swift */; };
5C3F1D58284363C400EC8A82 /* PrivacySettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C3F1D57284363C400EC8A82 /* PrivacySettings.swift */; };
5C4B3B0A285FB130003915F2 /* DatabaseView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C4B3B09285FB130003915F2 /* DatabaseView.swift */; };
@@ -117,6 +123,8 @@
5CCB939C297EFCB100399E78 /* NavStackCompat.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CCB939B297EFCB100399E78 /* NavStackCompat.swift */; };
5CCD403427A5F6DF00368C90 /* AddContactView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CCD403327A5F6DF00368C90 /* AddContactView.swift */; };
5CCD403727A5F9A200368C90 /* ScanToConnectView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CCD403627A5F9A200368C90 /* ScanToConnectView.swift */; };
5CD67B8F2B0E858A00C510B1 /* hs_init.h in Headers */ = {isa = PBXBuildFile; fileRef = 5CD67B8D2B0E858A00C510B1 /* hs_init.h */; settings = {ATTRIBUTES = (Public, ); }; };
5CD67B902B0E858A00C510B1 /* hs_init.c in Sources */ = {isa = PBXBuildFile; fileRef = 5CD67B8E2B0E858A00C510B1 /* hs_init.c */; };
5CDCAD482818589900503DA2 /* NotificationService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CDCAD472818589900503DA2 /* NotificationService.swift */; };
5CE2BA702845308900EC33A6 /* SimpleXChat.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5CE2BA682845308900EC33A6 /* SimpleXChat.framework */; };
5CE2BA712845308900EC33A6 /* SimpleXChat.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 5CE2BA682845308900EC33A6 /* SimpleXChat.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
@@ -142,11 +150,9 @@
5CEACCED27DEA495000BD591 /* MsgContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CEACCEC27DEA495000BD591 /* MsgContentView.swift */; };
5CEBD7462A5C0A8F00665FE2 /* KeyboardPadding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CEBD7452A5C0A8F00665FE2 /* KeyboardPadding.swift */; };
5CEBD7482A5F115D00665FE2 /* SetDeliveryReceiptsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CEBD7472A5F115D00665FE2 /* SetDeliveryReceiptsView.swift */; };
5CF4DF772AFF8D4E007893ED /* libffi.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5CF4DF722AFF8D4D007893ED /* libffi.a */; };
5CF4DF782AFF8D4E007893ED /* libHSsimplex-chat-5.4.0.3-EnhmkSQK6HvJ11g1uZERg8-ghc9.6.3.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5CF4DF732AFF8D4D007893ED /* libHSsimplex-chat-5.4.0.3-EnhmkSQK6HvJ11g1uZERg8-ghc9.6.3.a */; };
5CF4DF792AFF8D4E007893ED /* libgmpxx.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5CF4DF742AFF8D4D007893ED /* libgmpxx.a */; };
5CF4DF7A2AFF8D4E007893ED /* libgmp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5CF4DF752AFF8D4E007893ED /* libgmp.a */; };
5CF4DF7B2AFF8D4E007893ED /* libHSsimplex-chat-5.4.0.3-EnhmkSQK6HvJ11g1uZERg8.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5CF4DF762AFF8D4E007893ED /* libHSsimplex-chat-5.4.0.3-EnhmkSQK6HvJ11g1uZERg8.a */; };
5CF9371E2B23429500E1D781 /* ConcurrentQueue.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CF9371D2B23429500E1D781 /* ConcurrentQueue.swift */; };
5CF937202B24DE8C00E1D781 /* SharedFileSubscriber.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CF9371F2B24DE8C00E1D781 /* SharedFileSubscriber.swift */; };
5CF937232B2503D000E1D781 /* NSESubscriber.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CF937212B25034A00E1D781 /* NSESubscriber.swift */; };
5CFA59C42860BC6200863A68 /* MigrateToAppGroupView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CFA59C32860BC6200863A68 /* MigrateToAppGroupView.swift */; };
5CFA59D12864782E00863A68 /* ChatArchiveView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CFA59CF286477B400863A68 /* ChatArchiveView.swift */; };
5CFE0921282EEAF60002594B /* ZoomableScrollView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CFE0920282EEAF60002594B /* ZoomableScrollView.swift */; };
@@ -162,6 +168,11 @@
64466DC829FC2B3B00E3D48D /* CreateSimpleXAddress.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64466DC729FC2B3B00E3D48D /* CreateSimpleXAddress.swift */; };
64466DCC29FFE3E800E3D48D /* MailView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64466DCB29FFE3E800E3D48D /* MailView.swift */; };
6448BBB628FA9D56000D2AB9 /* GroupLinkView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6448BBB528FA9D56000D2AB9 /* GroupLinkView.swift */; };
6449333A2AF8E51000AC506E /* libgmpxx.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 644933352AF8E51000AC506E /* libgmpxx.a */; };
6449333B2AF8E51000AC506E /* libgmp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 644933362AF8E51000AC506E /* libgmp.a */; };
6449333C2AF8E51000AC506E /* libffi.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 644933372AF8E51000AC506E /* libffi.a */; };
6449333D2AF8E51000AC506E /* libHSsimplex-chat-5.4.0.3-EnhmkSQK6HvJ11g1uZERg8-ghc9.6.3.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 644933382AF8E51000AC506E /* libHSsimplex-chat-5.4.0.3-EnhmkSQK6HvJ11g1uZERg8-ghc9.6.3.a */; };
6449333E2AF8E51000AC506E /* libHSsimplex-chat-5.4.0.3-EnhmkSQK6HvJ11g1uZERg8.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 644933392AF8E51000AC506E /* libHSsimplex-chat-5.4.0.3-EnhmkSQK6HvJ11g1uZERg8.a */; };
644EFFDE292BCD9D00525D5B /* ComposeVoiceView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 644EFFDD292BCD9D00525D5B /* ComposeVoiceView.swift */; };
644EFFE0292CFD7F00525D5B /* CIVoiceView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 644EFFDF292CFD7F00525D5B /* CIVoiceView.swift */; };
644EFFE2292D089800525D5B /* FramedCIVoiceView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 644EFFE1292D089800525D5B /* FramedCIVoiceView.swift */; };
@@ -182,6 +193,7 @@
64D0C2C629FAC1EC00B38D5F /* AddContactLearnMore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64D0C2C529FAC1EC00B38D5F /* AddContactLearnMore.swift */; };
64E972072881BB22008DBC02 /* CIGroupInvitationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64E972062881BB22008DBC02 /* CIGroupInvitationView.swift */; };
64F1CC3B28B39D8600CD1FB1 /* IncognitoHelp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64F1CC3A28B39D8600CD1FB1 /* IncognitoHelp.swift */; };
8C05382E2B39887E006436DC /* VideoUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8C05382D2B39887E006436DC /* VideoUtils.swift */; };
D7197A1829AE89660055C05A /* WebRTC in Frameworks */ = {isa = PBXBuildFile; productRef = D7197A1729AE89660055C05A /* WebRTC */; };
D72A9088294BD7A70047C86D /* NativeTextEditor.swift in Sources */ = {isa = PBXBuildFile; fileRef = D72A9087294BD7A70047C86D /* NativeTextEditor.swift */; };
D741547829AF89AF0022400A /* StoreKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D741547729AF89AF0022400A /* StoreKit.framework */; };
@@ -273,6 +285,11 @@
5C13730A28156D2700F43030 /* ContactConnectionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContactConnectionView.swift; sourceTree = "<group>"; };
5C13730C2815740A00F43030 /* DebugJSON.playground */ = {isa = PBXFileReference; lastKnownFileType = file.playground; path = DebugJSON.playground; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.swift; };
5C1A4C1D27A715B700EAD5AD /* ChatItemView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatItemView.swift; sourceTree = "<group>"; };
5C245F1E2B4EAA5E001CC39F /* libgmpxx.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libgmpxx.a; sourceTree = "<group>"; };
5C245F1F2B4EAA5E001CC39F /* libHSsimplex-chat-5.4.3.0-BrNBQIZf2Ju9TtaZoeJyIH-ghc9.6.3.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libHSsimplex-chat-5.4.3.0-BrNBQIZf2Ju9TtaZoeJyIH-ghc9.6.3.a"; sourceTree = "<group>"; };
5C245F202B4EAA5E001CC39F /* libgmp.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libgmp.a; sourceTree = "<group>"; };
5C245F212B4EAA5E001CC39F /* libHSsimplex-chat-5.4.3.0-BrNBQIZf2Ju9TtaZoeJyIH.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libHSsimplex-chat-5.4.3.0-BrNBQIZf2Ju9TtaZoeJyIH.a"; sourceTree = "<group>"; };
5C245F222B4EAA5E001CC39F /* libffi.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libffi.a; sourceTree = "<group>"; };
5C2E260627A2941F00F70299 /* SimpleXAPI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SimpleXAPI.swift; sourceTree = "<group>"; };
5C2E260A27A30CFA00F70299 /* ChatListView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatListView.swift; sourceTree = "<group>"; };
5C2E260E27A30FDC00F70299 /* ChatView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatView.swift; sourceTree = "<group>"; };
@@ -282,6 +299,7 @@
5C36027227F47AD5009F19D9 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
5C3A88CD27DF50170060F1C2 /* DetermineWidth.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DetermineWidth.swift; sourceTree = "<group>"; };
5C3A88D027DF57800060F1C2 /* FramedItemView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FramedItemView.swift; sourceTree = "<group>"; };
5C3CCFCB2AE6BD3100C3F0C3 /* ConnectDesktopView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConnectDesktopView.swift; sourceTree = "<group>"; };
5C3F1D552842B68D00EC8A82 /* IntegrityErrorItemView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IntegrityErrorItemView.swift; sourceTree = "<group>"; };
5C3F1D57284363C400EC8A82 /* PrivacySettings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PrivacySettings.swift; sourceTree = "<group>"; };
5C422A7C27A9A6FA0097A1E1 /* SimpleX (iOS).entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = "SimpleX (iOS).entitlements"; sourceTree = "<group>"; };
@@ -397,6 +415,8 @@
5CCB939B297EFCB100399E78 /* NavStackCompat.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavStackCompat.swift; sourceTree = "<group>"; };
5CCD403327A5F6DF00368C90 /* AddContactView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddContactView.swift; sourceTree = "<group>"; };
5CCD403627A5F9A200368C90 /* ScanToConnectView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScanToConnectView.swift; sourceTree = "<group>"; };
5CD67B8D2B0E858A00C510B1 /* hs_init.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = hs_init.h; sourceTree = "<group>"; };
5CD67B8E2B0E858A00C510B1 /* hs_init.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = hs_init.c; sourceTree = "<group>"; };
5CDCAD452818589900503DA2 /* SimpleX NSE.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = "SimpleX NSE.appex"; sourceTree = BUILT_PRODUCTS_DIR; };
5CDCAD472818589900503DA2 /* NotificationService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationService.swift; sourceTree = "<group>"; };
5CDCAD492818589900503DA2 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
@@ -423,11 +443,9 @@
5CEACCEC27DEA495000BD591 /* MsgContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MsgContentView.swift; sourceTree = "<group>"; };
5CEBD7452A5C0A8F00665FE2 /* KeyboardPadding.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeyboardPadding.swift; sourceTree = "<group>"; };
5CEBD7472A5F115D00665FE2 /* SetDeliveryReceiptsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SetDeliveryReceiptsView.swift; sourceTree = "<group>"; };
5CF4DF722AFF8D4D007893ED /* libffi.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libffi.a; sourceTree = "<group>"; };
5CF4DF732AFF8D4D007893ED /* libHSsimplex-chat-5.4.0.3-EnhmkSQK6HvJ11g1uZERg8-ghc9.6.3.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libHSsimplex-chat-5.4.0.3-EnhmkSQK6HvJ11g1uZERg8-ghc9.6.3.a"; sourceTree = "<group>"; };
5CF4DF742AFF8D4D007893ED /* libgmpxx.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libgmpxx.a; sourceTree = "<group>"; };
5CF4DF752AFF8D4E007893ED /* libgmp.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libgmp.a; sourceTree = "<group>"; };
5CF4DF762AFF8D4E007893ED /* libHSsimplex-chat-5.4.0.3-EnhmkSQK6HvJ11g1uZERg8.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libHSsimplex-chat-5.4.0.3-EnhmkSQK6HvJ11g1uZERg8.a"; sourceTree = "<group>"; };
5CF9371D2B23429500E1D781 /* ConcurrentQueue.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConcurrentQueue.swift; sourceTree = "<group>"; };
5CF9371F2B24DE8C00E1D781 /* SharedFileSubscriber.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SharedFileSubscriber.swift; sourceTree = "<group>"; };
5CF937212B25034A00E1D781 /* NSESubscriber.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSESubscriber.swift; sourceTree = "<group>"; };
5CFA59C32860BC6200863A68 /* MigrateToAppGroupView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MigrateToAppGroupView.swift; sourceTree = "<group>"; };
5CFA59CF286477B400863A68 /* ChatArchiveView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatArchiveView.swift; sourceTree = "<group>"; };
5CFE0920282EEAF60002594B /* ZoomableScrollView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = ZoomableScrollView.swift; path = Shared/Views/ZoomableScrollView.swift; sourceTree = SOURCE_ROOT; };
@@ -442,6 +460,11 @@
64466DC729FC2B3B00E3D48D /* CreateSimpleXAddress.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CreateSimpleXAddress.swift; sourceTree = "<group>"; };
64466DCB29FFE3E800E3D48D /* MailView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MailView.swift; sourceTree = "<group>"; };
6448BBB528FA9D56000D2AB9 /* GroupLinkView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GroupLinkView.swift; sourceTree = "<group>"; };
644933352AF8E51000AC506E /* libgmpxx.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libgmpxx.a; sourceTree = "<group>"; };
644933362AF8E51000AC506E /* libgmp.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libgmp.a; sourceTree = "<group>"; };
644933372AF8E51000AC506E /* libffi.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libffi.a; sourceTree = "<group>"; };
644933382AF8E51000AC506E /* libHSsimplex-chat-5.4.0.3-EnhmkSQK6HvJ11g1uZERg8-ghc9.6.3.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libHSsimplex-chat-5.4.0.3-EnhmkSQK6HvJ11g1uZERg8-ghc9.6.3.a"; sourceTree = "<group>"; };
644933392AF8E51000AC506E /* libHSsimplex-chat-5.4.0.3-EnhmkSQK6HvJ11g1uZERg8.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libHSsimplex-chat-5.4.0.3-EnhmkSQK6HvJ11g1uZERg8.a"; sourceTree = "<group>"; };
644EFFDD292BCD9D00525D5B /* ComposeVoiceView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComposeVoiceView.swift; sourceTree = "<group>"; };
644EFFDF292CFD7F00525D5B /* CIVoiceView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CIVoiceView.swift; sourceTree = "<group>"; };
644EFFE1292D089800525D5B /* FramedCIVoiceView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FramedCIVoiceView.swift; sourceTree = "<group>"; };
@@ -464,6 +487,7 @@
64DAE1502809D9F5000DA960 /* FileUtils.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FileUtils.swift; sourceTree = "<group>"; };
64E972062881BB22008DBC02 /* CIGroupInvitationView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CIGroupInvitationView.swift; sourceTree = "<group>"; };
64F1CC3A28B39D8600CD1FB1 /* IncognitoHelp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IncognitoHelp.swift; sourceTree = "<group>"; };
8C05382D2B39887E006436DC /* VideoUtils.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VideoUtils.swift; sourceTree = "<group>"; };
D72A9087294BD7A70047C86D /* NativeTextEditor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NativeTextEditor.swift; sourceTree = "<group>"; };
D741547729AF89AF0022400A /* StoreKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = StoreKit.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS16.1.sdk/System/Library/Frameworks/StoreKit.framework; sourceTree = DEVELOPER_DIR; };
D741547929AF90B00022400A /* PushKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = PushKit.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS16.1.sdk/System/Library/Frameworks/PushKit.framework; sourceTree = DEVELOPER_DIR; };
@@ -505,13 +529,13 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
5C245F232B4EAA5E001CC39F /* libgmpxx.a in Frameworks */,
5C245F262B4EAA5E001CC39F /* libHSsimplex-chat-5.4.3.0-BrNBQIZf2Ju9TtaZoeJyIH.a in Frameworks */,
5C245F252B4EAA5E001CC39F /* libgmp.a in Frameworks */,
5CE2BA93284534B000EC33A6 /* libiconv.tbd in Frameworks */,
5CF4DF792AFF8D4E007893ED /* libgmpxx.a in Frameworks */,
5CF4DF772AFF8D4E007893ED /* libffi.a in Frameworks */,
5C245F272B4EAA5E001CC39F /* libffi.a in Frameworks */,
5CE2BA94284534BB00EC33A6 /* libz.tbd in Frameworks */,
5CF4DF7A2AFF8D4E007893ED /* libgmp.a in Frameworks */,
5CF4DF7B2AFF8D4E007893ED /* libHSsimplex-chat-5.4.0.3-EnhmkSQK6HvJ11g1uZERg8.a in Frameworks */,
5CF4DF782AFF8D4E007893ED /* libHSsimplex-chat-5.4.0.3-EnhmkSQK6HvJ11g1uZERg8-ghc9.6.3.a in Frameworks */,
5C245F242B4EAA5E001CC39F /* libHSsimplex-chat-5.4.3.0-BrNBQIZf2Ju9TtaZoeJyIH-ghc9.6.3.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -544,6 +568,7 @@
5CB924DD27A8622200ACCCDD /* NewChat */,
5CFA59C22860B04D00863A68 /* Database */,
5CB634AB29E46CDB0066AD6B /* LocalAuth */,
5CA8D01B2AD9B076001FD661 /* RemoteAccess */,
5CB924DF27A8678B00ACCCDD /* UserSettings */,
5C2E261127A30FEA00F70299 /* TerminalView.swift */,
);
@@ -572,11 +597,11 @@
5C764E5C279C70B7000C6508 /* Libraries */ = {
isa = PBXGroup;
children = (
5CF4DF722AFF8D4D007893ED /* libffi.a */,
5CF4DF752AFF8D4E007893ED /* libgmp.a */,
5CF4DF742AFF8D4D007893ED /* libgmpxx.a */,
5CF4DF732AFF8D4D007893ED /* libHSsimplex-chat-5.4.0.3-EnhmkSQK6HvJ11g1uZERg8-ghc9.6.3.a */,
5CF4DF762AFF8D4E007893ED /* libHSsimplex-chat-5.4.0.3-EnhmkSQK6HvJ11g1uZERg8.a */,
5C245F222B4EAA5E001CC39F /* libffi.a */,
5C245F202B4EAA5E001CC39F /* libgmp.a */,
5C245F1E2B4EAA5E001CC39F /* libgmpxx.a */,
5C245F1F2B4EAA5E001CC39F /* libHSsimplex-chat-5.4.3.0-BrNBQIZf2Ju9TtaZoeJyIH-ghc9.6.3.a */,
5C245F212B4EAA5E001CC39F /* libHSsimplex-chat-5.4.3.0-BrNBQIZf2Ju9TtaZoeJyIH.a */,
);
path = Libraries;
sourceTree = "<group>";
@@ -601,6 +626,7 @@
5C35CFC727B2782E00FB6C6D /* BGManager.swift */,
5C35CFCA27B2E91D00FB6C6D /* NtfManager.swift */,
5CB346E42868AA7F001FD2EF /* SuspendChat.swift */,
5CF937212B25034A00E1D781 /* NSESubscriber.swift */,
5CB346E82869E8BA001FD2EF /* PushEnvironment.swift */,
5C93293E2928E0FD0090FFF9 /* AudioRecPlay.swift */,
5CBD2859295711D700EC2CF4 /* ImageUtils.swift */,
@@ -628,6 +654,7 @@
64466DCB29FFE3E800E3D48D /* MailView.swift */,
64C3B0202A0D359700E19930 /* CustomTimePicker.swift */,
5CEBD7452A5C0A8F00665FE2 /* KeyboardPadding.swift */,
8C05382D2B39887E006436DC /* VideoUtils.swift */,
);
path = Helpers;
sourceTree = "<group>";
@@ -684,6 +711,14 @@
path = "Tests iOS";
sourceTree = "<group>";
};
5CA8D01B2AD9B076001FD661 /* RemoteAccess */ = {
isa = PBXGroup;
children = (
5C3CCFCB2AE6BD3100C3F0C3 /* ConnectDesktopView.swift */,
);
path = RemoteAccess;
sourceTree = "<group>";
};
5CB0BA8C282711BC00B3292C /* Onboarding */ = {
isa = PBXGroup;
children = (
@@ -773,6 +808,7 @@
isa = PBXGroup;
children = (
5CDCAD5128186DE400503DA2 /* SimpleX NSE.entitlements */,
5CF9371D2B23429500E1D781 /* ConcurrentQueue.swift */,
5CDCAD472818589900503DA2 /* NotificationService.swift */,
5CDCAD492818589900503DA2 /* Info.plist */,
5CB0BA862826CB3A00B3292C /* InfoPlist.strings */,
@@ -793,10 +829,13 @@
64DAE1502809D9F5000DA960 /* FileUtils.swift */,
5C9D81182AA7A4F1001D49FD /* CryptoFile.swift */,
5C00168028C4FE760094D739 /* KeyChain.swift */,
5CF9371F2B24DE8C00E1D781 /* SharedFileSubscriber.swift */,
5CE2BA76284530BF00EC33A6 /* SimpleXChat.h */,
5CE2BA8A2845332200EC33A6 /* SimpleX.h */,
5CE2BA78284530CC00EC33A6 /* SimpleXChat.docc */,
5CE2BA96284537A800EC33A6 /* dummy.m */,
5CD67B8D2B0E858A00C510B1 /* hs_init.h */,
5CD67B8E2B0E858A00C510B1 /* hs_init.c */,
);
path = SimpleXChat;
sourceTree = "<group>";
@@ -881,6 +920,7 @@
buildActionMask = 2147483647;
files = (
5CE2BA77284530BF00EC33A6 /* SimpleXChat.h in Headers */,
5CD67B8F2B0E858A00C510B1 /* hs_init.h in Headers */,
5CE2BA952845354B00EC33A6 /* SimpleX.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
@@ -1162,6 +1202,7 @@
5C2E260F27A30FDC00F70299 /* ChatView.swift in Sources */,
5C2E260B27A30CFA00F70299 /* ChatListView.swift in Sources */,
6442E0BA287F169300CEC0F9 /* AddGroupView.swift in Sources */,
5CF937232B2503D000E1D781 /* NSESubscriber.swift in Sources */,
6419EC582AB97507004A607A /* CIMemberCreatedContactView.swift in Sources */,
64D0C2C229FA57AB00B38D5F /* UserAddressLearnMore.swift in Sources */,
64466DCC29FFE3E800E3D48D /* MailView.swift in Sources */,
@@ -1170,6 +1211,7 @@
6454036F2822A9750090DDFF /* ComposeFileView.swift in Sources */,
5C5DB70E289ABDD200730FFF /* AppearanceSettings.swift in Sources */,
5C5F2B6D27EBC3FE006A9D5F /* ImagePicker.swift in Sources */,
5C3CCFCC2AE6BD3100C3F0C3 /* ConnectDesktopView.swift in Sources */,
5C9C2DA92899DA6F00CC63B1 /* NetworkAndServers.swift in Sources */,
5C6BA667289BD954009B8ECC /* DismissSheets.swift in Sources */,
5C577F7D27C83AA10006112D /* MarkdownHelp.swift in Sources */,
@@ -1183,6 +1225,7 @@
5CCD403727A5F9A200368C90 /* ScanToConnectView.swift in Sources */,
5CFA59D12864782E00863A68 /* ChatArchiveView.swift in Sources */,
649BCDA22805D6EF00C3A862 /* CIImageView.swift in Sources */,
8C05382E2B39887E006436DC /* VideoUtils.swift in Sources */,
5CADE79C292131E900072E13 /* ContactPreferencesView.swift in Sources */,
5CB346E52868AA7F001FD2EF /* SuspendChat.swift in Sources */,
5C9C2DA52894777E00CC63B1 /* GroupProfileView.swift in Sources */,
@@ -1240,6 +1283,7 @@
files = (
5CDCAD482818589900503DA2 /* NotificationService.swift in Sources */,
5CFE0922282EEAF60002594B /* ZoomableScrollView.swift in Sources */,
5CF9371E2B23429500E1D781 /* ConcurrentQueue.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -1247,9 +1291,11 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
5CF937202B24DE8C00E1D781 /* SharedFileSubscriber.swift in Sources */,
5C00168128C4FE760094D739 /* KeyChain.swift in Sources */,
5CE2BA97284537A800EC33A6 /* dummy.m in Sources */,
5CE2BA922845340900EC33A6 /* FileUtils.swift in Sources */,
5CD67B902B0E858A00C510B1 /* hs_init.c in Sources */,
5CE2BA91284533A300EC33A6 /* Notifications.swift in Sources */,
5CE2BA79284530CC00EC33A6 /* SimpleXChat.docc in Sources */,
5CE2BA90284533A300EC33A6 /* JSON.swift in Sources */,
@@ -1482,7 +1528,7 @@
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = "SimpleX (iOS).entitlements";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 181;
CURRENT_PROJECT_VERSION = 188;
DEVELOPMENT_TEAM = 5NN7GUYB6T;
ENABLE_BITCODE = NO;
ENABLE_PREVIEWS = YES;
@@ -1490,6 +1536,7 @@
INFOPLIST_FILE = "SimpleX--iOS--Info.plist";
INFOPLIST_KEY_NSCameraUsageDescription = "SimpleX needs camera access to scan QR codes to connect to other users and for video calls.";
INFOPLIST_KEY_NSFaceIDUsageDescription = "SimpleX uses Face ID for local authentication";
INFOPLIST_KEY_NSLocalNetworkUsageDescription = "SimpleX uses local network access to allow using user chat profile via desktop app on the same network.";
INFOPLIST_KEY_NSMicrophoneUsageDescription = "SimpleX needs microphone access for audio and video calls, and to record voice messages.";
INFOPLIST_KEY_NSPhotoLibraryAddUsageDescription = "SimpleX needs access to Photo Library for saving captured and received media";
INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES;
@@ -1503,7 +1550,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 5.4;
MARKETING_VERSION = 5.4.3;
PRODUCT_BUNDLE_IDENTIFIER = chat.simplex.app;
PRODUCT_NAME = SimpleX;
SDKROOT = iphoneos;
@@ -1524,7 +1571,7 @@
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = "SimpleX (iOS).entitlements";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 181;
CURRENT_PROJECT_VERSION = 188;
DEVELOPMENT_TEAM = 5NN7GUYB6T;
ENABLE_BITCODE = NO;
ENABLE_PREVIEWS = YES;
@@ -1532,6 +1579,7 @@
INFOPLIST_FILE = "SimpleX--iOS--Info.plist";
INFOPLIST_KEY_NSCameraUsageDescription = "SimpleX needs camera access to scan QR codes to connect to other users and for video calls.";
INFOPLIST_KEY_NSFaceIDUsageDescription = "SimpleX uses Face ID for local authentication";
INFOPLIST_KEY_NSLocalNetworkUsageDescription = "SimpleX uses local network access to allow using user chat profile via desktop app on the same network.";
INFOPLIST_KEY_NSMicrophoneUsageDescription = "SimpleX needs microphone access for audio and video calls, and to record voice messages.";
INFOPLIST_KEY_NSPhotoLibraryAddUsageDescription = "SimpleX needs access to Photo Library for saving captured and received media";
INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES;
@@ -1545,7 +1593,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 5.4;
MARKETING_VERSION = 5.4.3;
PRODUCT_BUNDLE_IDENTIFIER = chat.simplex.app;
PRODUCT_NAME = SimpleX;
SDKROOT = iphoneos;
@@ -1604,7 +1652,7 @@
CODE_SIGN_ENTITLEMENTS = "SimpleX NSE/SimpleX NSE.entitlements";
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 181;
CURRENT_PROJECT_VERSION = 188;
DEVELOPMENT_TEAM = 5NN7GUYB6T;
ENABLE_BITCODE = NO;
GENERATE_INFOPLIST_FILE = YES;
@@ -1617,7 +1665,7 @@
"@executable_path/Frameworks",
"@executable_path/../../Frameworks",
);
MARKETING_VERSION = 5.4;
MARKETING_VERSION = 5.4.3;
PRODUCT_BUNDLE_IDENTIFIER = "chat.simplex.app.SimpleX-NSE";
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
@@ -1636,7 +1684,7 @@
CODE_SIGN_ENTITLEMENTS = "SimpleX NSE/SimpleX NSE.entitlements";
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 181;
CURRENT_PROJECT_VERSION = 188;
DEVELOPMENT_TEAM = 5NN7GUYB6T;
ENABLE_BITCODE = NO;
GENERATE_INFOPLIST_FILE = YES;
@@ -1649,7 +1697,7 @@
"@executable_path/Frameworks",
"@executable_path/../../Frameworks",
);
MARKETING_VERSION = 5.4;
MARKETING_VERSION = 5.4.3;
PRODUCT_BUNDLE_IDENTIFIER = "chat.simplex.app.SimpleX-NSE";
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
@@ -1668,7 +1716,7 @@
APPLICATION_EXTENSION_API_ONLY = YES;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 181;
CURRENT_PROJECT_VERSION = 188;
DEFINES_MODULE = YES;
DEVELOPMENT_TEAM = 5NN7GUYB6T;
DYLIB_COMPATIBILITY_VERSION = 1;
@@ -1692,7 +1740,7 @@
"$(inherited)",
"$(PROJECT_DIR)/Libraries/sim",
);
MARKETING_VERSION = 5.4;
MARKETING_VERSION = 5.4.3;
PRODUCT_BUNDLE_IDENTIFIER = chat.simplex.SimpleXChat;
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
SDKROOT = iphoneos;
@@ -1714,7 +1762,7 @@
APPLICATION_EXTENSION_API_ONLY = YES;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 181;
CURRENT_PROJECT_VERSION = 188;
DEFINES_MODULE = YES;
DEVELOPMENT_TEAM = 5NN7GUYB6T;
DYLIB_COMPATIBILITY_VERSION = 1;
@@ -1738,7 +1786,7 @@
"$(inherited)",
"$(PROJECT_DIR)/Libraries/sim",
);
MARKETING_VERSION = 5.4;
MARKETING_VERSION = 5.4.3;
PRODUCT_BUNDLE_IDENTIFIER = chat.simplex.SimpleXChat;
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
SDKROOT = iphoneos;

View File

@@ -41,7 +41,7 @@
</Testables>
</TestAction>
<LaunchAction
buildConfiguration = "Release"
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"

View File

@@ -2,7 +2,7 @@
<Scheme
LastUpgradeVersion = "1400"
wasCreatedForAppExtension = "YES"
version = "2.0">
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
@@ -47,16 +47,14 @@
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = ""
selectedLauncherIdentifier = "Xcode.IDEFoundation.Launcher.PosixSpawn"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
askForAppToLaunch = "Yes"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES"
launchAutomaticallySubstyle = "2">
allowLocationSimulation = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference

View File

@@ -12,12 +12,16 @@ private var chatController: chat_ctrl?
private var migrationResult: (Bool, DBMigrationResult)?
public func getChatCtrl(_ useKey: String? = nil) -> chat_ctrl {
public func hasChatCtrl() -> Bool {
chatController != nil
}
public func getChatCtrl() -> chat_ctrl {
if let controller = chatController { return controller }
fatalError("chat controller not initialized")
}
public func chatMigrateInit(_ useKey: String? = nil, confirmMigrations: MigrationConfirmation? = nil) -> (Bool, DBMigrationResult) {
public func chatMigrateInit(_ useKey: String? = nil, confirmMigrations: MigrationConfirmation? = nil, backgroundMode: Bool = false) -> (Bool, DBMigrationResult) {
if let res = migrationResult { return res }
let dbPath = getAppDatabasePath().path
var dbKey = ""
@@ -41,7 +45,7 @@ public func chatMigrateInit(_ useKey: String? = nil, confirmMigrations: Migratio
var cKey = dbKey.cString(using: .utf8)!
var cConfirm = confirm.rawValue.cString(using: .utf8)!
// the last parameter of chat_migrate_init is used to return the pointer to chat controller
let cjson = chat_migrate_init(&cPath, &cKey, &cConfirm, &chatController)!
let cjson = chat_migrate_init_key(&cPath, &cKey, 1, &cConfirm, backgroundMode ? 1 : 0, &chatController)!
let dbRes = dbMigrationResult(fromCString(cjson))
let encrypted = dbKey != ""
let keychainErr = dbRes == .ok && useKeychain && encrypted && !kcDatabasePassword.set(dbKey)
@@ -57,6 +61,13 @@ public func chatCloseStore() {
}
}
public func chatReopenStore() {
let err = fromCString(chat_reopen_store(getChatCtrl()))
if err != "" {
logger.error("chatReopenStore error: \(err)")
}
}
public func resetChatCtrl() {
chatController = nil
migrationResult = nil

View File

@@ -25,9 +25,9 @@ public enum ChatCommand {
case apiMuteUser(userId: Int64)
case apiUnmuteUser(userId: Int64)
case apiDeleteUser(userId: Int64, delSMPQueues: Bool, viewPwd: String?)
case startChat(subscribe: Bool, expire: Bool, xftp: Bool)
case startChat(mainApp: Bool)
case apiStopChat
case apiActivateChat
case apiActivateChat(restoreChat: Bool)
case apiSuspendChat(timeoutMicroseconds: Int)
case setTempFolder(tempFolder: String)
case setFilesFolder(filesFolder: String)
@@ -120,6 +120,16 @@ public enum ChatCommand {
case receiveFile(fileId: Int64, encrypted: Bool?, inline: Bool?)
case setFileToReceive(fileId: Int64, encrypted: Bool?)
case cancelFile(fileId: Int64)
// remote desktop commands
case setLocalDeviceName(displayName: String)
case connectRemoteCtrl(xrcpInvitation: String)
case findKnownRemoteCtrl
case confirmRemoteCtrl(remoteCtrlId: Int64)
case verifyRemoteCtrlSession(sessionCode: String)
case listRemoteCtrls
case stopRemoteCtrl
case deleteRemoteCtrl(remoteCtrlId: Int64)
// misc
case showVersion
case string(String)
@@ -144,9 +154,9 @@ public enum ChatCommand {
case let .apiMuteUser(userId): return "/_mute user \(userId)"
case let .apiUnmuteUser(userId): return "/_unmute user \(userId)"
case let .apiDeleteUser(userId, delSMPQueues, viewPwd): return "/_delete user \(userId) del_smp=\(onOff(delSMPQueues))\(maybePwd(viewPwd))"
case let .startChat(subscribe, expire, xftp): return "/_start subscribe=\(onOff(subscribe)) expire=\(onOff(expire)) xftp=\(onOff(xftp))"
case let .startChat(mainApp): return "/_start main=\(onOff(mainApp))"
case .apiStopChat: return "/_stop"
case .apiActivateChat: return "/_app activate"
case let .apiActivateChat(restore): return "/_app activate restore=\(onOff(restore))"
case let .apiSuspendChat(timeoutMicroseconds): return "/_app suspend \(timeoutMicroseconds)"
case let .setTempFolder(tempFolder): return "/_temp_folder \(tempFolder)"
case let .setFilesFolder(filesFolder): return "/_files_folder \(filesFolder)"
@@ -260,6 +270,14 @@ public enum ChatCommand {
case let .receiveFile(fileId, encrypt, inline): return "/freceive \(fileId)\(onOffParam("encrypt", encrypt))\(onOffParam("inline", inline))"
case let .setFileToReceive(fileId, encrypt): return "/_set_file_to_receive \(fileId)\(onOffParam("encrypt", encrypt))"
case let .cancelFile(fileId): return "/fcancel \(fileId)"
case let .setLocalDeviceName(displayName): return "/set device name \(displayName)"
case let .connectRemoteCtrl(xrcpInv): return "/connect remote ctrl \(xrcpInv)"
case .findKnownRemoteCtrl: return "/find remote ctrl"
case let .confirmRemoteCtrl(rcId): return "/confirm remote ctrl \(rcId)"
case let .verifyRemoteCtrlSession(sessCode): return "/verify remote ctrl \(sessCode)"
case .listRemoteCtrls: return "/list remote ctrls"
case .stopRemoteCtrl: return "/stop remote ctrl"
case let .deleteRemoteCtrl(rcId): return "/delete remote ctrl \(rcId)"
case .showVersion: return "/version"
case let .string(str): return str
}
@@ -375,6 +393,14 @@ public enum ChatCommand {
case .receiveFile: return "receiveFile"
case .setFileToReceive: return "setFileToReceive"
case .cancelFile: return "cancelFile"
case .setLocalDeviceName: return "setLocalDeviceName"
case .connectRemoteCtrl: return "connectRemoteCtrl"
case .findKnownRemoteCtrl: return "findKnownRemoteCtrl"
case .confirmRemoteCtrl: return "confirmRemoteCtrl"
case .verifyRemoteCtrlSession: return "verifyRemoteCtrlSession"
case .listRemoteCtrls: return "listRemoteCtrls"
case .stopRemoteCtrl: return "stopRemoteCtrl"
case .deleteRemoteCtrl: return "deleteRemoteCtrl"
case .showVersion: return "showVersion"
case .string: return "console command"
}
@@ -479,8 +505,8 @@ public enum ChatResponse: Decodable, Error {
case invitation(user: UserRef, connReqInvitation: String, connection: PendingContactConnection)
case connectionIncognitoUpdated(user: UserRef, toConnection: PendingContactConnection)
case connectionPlan(user: UserRef, connectionPlan: ConnectionPlan)
case sentConfirmation(user: UserRef)
case sentInvitation(user: UserRef)
case sentConfirmation(user: UserRef, connection: PendingContactConnection)
case sentInvitation(user: UserRef, connection: PendingContactConnection)
case sentInvitationToContact(user: UserRef, contact: Contact, customUserProfile: Profile?)
case contactAlreadyExists(user: UserRef, contact: Contact)
case contactRequestAlreadyAccepted(user: UserRef, contact: Contact)
@@ -578,9 +604,17 @@ public enum ChatResponse: Decodable, Error {
case callInvitations(callInvitations: [RcvCallInvitation])
case ntfTokenStatus(status: NtfTknStatus)
case ntfToken(token: DeviceToken, status: NtfTknStatus, ntfMode: NotificationsMode)
case ntfMessages(user_: User?, connEntity: ConnectionEntity?, msgTs: Date?, ntfMessages: [NtfMsgInfo])
case newContactConnection(user: UserRef, connection: PendingContactConnection)
case ntfMessages(user_: User?, connEntity_: ConnectionEntity?, msgTs: Date?, ntfMessages: [NtfMsgInfo])
case ntfMessage(user: UserRef, connEntity: ConnectionEntity, ntfMessage: NtfMsgInfo)
case contactConnectionDeleted(user: UserRef, connection: PendingContactConnection)
// remote desktop responses/events
case remoteCtrlList(remoteCtrls: [RemoteCtrlInfo])
case remoteCtrlFound(remoteCtrl: RemoteCtrlInfo, ctrlAppInfo_: CtrlAppInfo?, appVersion: String, compatible: Bool)
case remoteCtrlConnecting(remoteCtrl_: RemoteCtrlInfo?, ctrlAppInfo: CtrlAppInfo, appVersion: String)
case remoteCtrlSessionCode(remoteCtrl_: RemoteCtrlInfo?, sessionCode: String)
case remoteCtrlConnected(remoteCtrl: RemoteCtrlInfo)
case remoteCtrlStopped(rcsState: RemoteCtrlSessionState, rcStopReason: RemoteCtrlStopReason)
// misc
case versionInfo(versionInfo: CoreVersionInfo, chatMigrations: [UpMigration], agentMigrations: [UpMigration])
case cmdOk(user: UserRef?)
case chatCmdError(user_: UserRef?, chatError: ChatError)
@@ -718,8 +752,14 @@ public enum ChatResponse: Decodable, Error {
case .ntfTokenStatus: return "ntfTokenStatus"
case .ntfToken: return "ntfToken"
case .ntfMessages: return "ntfMessages"
case .newContactConnection: return "newContactConnection"
case .ntfMessage: return "ntfMessage"
case .contactConnectionDeleted: return "contactConnectionDeleted"
case .remoteCtrlList: return "remoteCtrlList"
case .remoteCtrlFound: return "remoteCtrlFound"
case .remoteCtrlConnecting: return "remoteCtrlConnecting"
case .remoteCtrlSessionCode: return "remoteCtrlSessionCode"
case .remoteCtrlConnected: return "remoteCtrlConnected"
case .remoteCtrlStopped: return "remoteCtrlStopped"
case .versionInfo: return "versionInfo"
case .cmdOk: return "cmdOk"
case .chatCmdError: return "chatCmdError"
@@ -763,11 +803,11 @@ public enum ChatResponse: Decodable, Error {
case let .contactCode(u, contact, connectionCode): return withUser(u, "contact: \(String(describing: contact))\nconnectionCode: \(connectionCode)")
case let .groupMemberCode(u, groupInfo, member, connectionCode): return withUser(u, "groupInfo: \(String(describing: groupInfo))\nmember: \(String(describing: member))\nconnectionCode: \(connectionCode)")
case let .connectionVerified(u, verified, expectedCode): return withUser(u, "verified: \(verified)\nconnectionCode: \(expectedCode)")
case let .invitation(u, connReqInvitation, _): return withUser(u, connReqInvitation)
case let .invitation(u, connReqInvitation, connection): return withUser(u, "connReqInvitation: \(connReqInvitation)\nconnection: \(connection)")
case let .connectionIncognitoUpdated(u, toConnection): return withUser(u, String(describing: toConnection))
case let .connectionPlan(u, connectionPlan): return withUser(u, String(describing: connectionPlan))
case .sentConfirmation: return noDetails
case .sentInvitation: return noDetails
case let .sentConfirmation(u, connection): return withUser(u, String(describing: connection))
case let .sentInvitation(u, connection): return withUser(u, String(describing: connection))
case let .sentInvitationToContact(u, contact, _): return withUser(u, String(describing: contact))
case let .contactAlreadyExists(u, contact): return withUser(u, String(describing: contact))
case let .contactRequestAlreadyAccepted(u, contact): return withUser(u, String(describing: contact))
@@ -860,8 +900,14 @@ public enum ChatResponse: Decodable, Error {
case let .ntfTokenStatus(status): return String(describing: status)
case let .ntfToken(token, status, ntfMode): return "token: \(token)\nstatus: \(status.rawValue)\nntfMode: \(ntfMode.rawValue)"
case let .ntfMessages(u, connEntity, msgTs, ntfMessages): return withUser(u, "connEntity: \(String(describing: connEntity))\nmsgTs: \(String(describing: msgTs))\nntfMessages: \(String(describing: ntfMessages))")
case let .newContactConnection(u, connection): return withUser(u, String(describing: connection))
case let .ntfMessage(u, connEntity, ntfMessage): return withUser(u, "connEntity: \(String(describing: connEntity))\nntfMessage: \(String(describing: ntfMessage))")
case let .contactConnectionDeleted(u, connection): return withUser(u, String(describing: connection))
case let .remoteCtrlList(remoteCtrls): return String(describing: remoteCtrls)
case let .remoteCtrlFound(remoteCtrl, ctrlAppInfo_, appVersion, compatible): return "remoteCtrl:\n\(String(describing: remoteCtrl))\nctrlAppInfo_:\n\(String(describing: ctrlAppInfo_))\nappVersion: \(appVersion)\ncompatible: \(compatible)"
case let .remoteCtrlConnecting(remoteCtrl_, ctrlAppInfo, appVersion): return "remoteCtrl_:\n\(String(describing: remoteCtrl_))\nctrlAppInfo:\n\(String(describing: ctrlAppInfo))\nappVersion: \(appVersion)"
case let .remoteCtrlSessionCode(remoteCtrl_, sessionCode): return "remoteCtrl_:\n\(String(describing: remoteCtrl_))\nsessionCode: \(sessionCode)"
case let .remoteCtrlConnected(remoteCtrl): return String(describing: remoteCtrl)
case .remoteCtrlStopped: return noDetails
case let .versionInfo(versionInfo, chatMigrations, agentMigrations): return "\(String(describing: versionInfo))\n\nchat migrations: \(chatMigrations.map(\.upName))\n\nagent migrations: \(agentMigrations.map(\.upName))"
case .cmdOk: return noDetails
case let .chatCmdError(u, chatError): return withUser(u, String(describing: chatError))
@@ -1161,9 +1207,9 @@ public struct NetCfg: Codable, Equatable {
public static let defaults: NetCfg = NetCfg(
socksProxy: nil,
sessionMode: TransportSessionMode.user,
tcpConnectTimeout: 15_000_000,
tcpTimeout: 10_000_000,
tcpTimeoutPerKb: 30_000,
tcpConnectTimeout: 20_000_000,
tcpTimeout: 15_000_000,
tcpTimeoutPerKb: 45_000,
tcpKeepAlive: KeepAliveOpts.defaults,
smpPingInterval: 1200_000_000,
smpPingCount: 3,
@@ -1452,6 +1498,8 @@ public enum PushProvider: String, Decodable {
}
}
// This notification mode is for app core, UI uses AppNotificationsMode.off to mean completely disable,
// and .local for periodic background checks
public enum NotificationsMode: String, Decodable, SelectableItem {
case off = "OFF"
case periodic = "PERIODIC"
@@ -1459,9 +1507,9 @@ public enum NotificationsMode: String, Decodable, SelectableItem {
public var label: LocalizedStringKey {
switch self {
case .off: return "Off (Local)"
case .periodic: return "Periodically"
case .instant: return "Instantly"
case .off: "Local"
case .periodic: "Periodically"
case .instant: "Instantly"
}
}
@@ -1488,6 +1536,41 @@ public enum NotificationPreviewMode: String, SelectableItem {
public static var values: [NotificationPreviewMode] = [.message, .contact, .hidden]
}
public struct RemoteCtrlInfo: Decodable {
public var remoteCtrlId: Int64
public var ctrlDeviceName: String
public var sessionState: RemoteCtrlSessionState?
public var deviceViewName: String {
ctrlDeviceName == "" ? "\(remoteCtrlId)" : ctrlDeviceName
}
}
public enum RemoteCtrlSessionState: Decodable {
case starting
case searching
case connecting
case pendingConfirmation(sessionCode: String)
case connected(sessionCode: String)
}
public enum RemoteCtrlStopReason: Decodable {
case discoveryFailed(chatError: ChatError)
case connectionFailed(chatError: ChatError)
case setupFailed(chatError: ChatError)
case disconnected
}
public struct CtrlAppInfo: Decodable {
public var appVersionRange: AppVersionRange
public var deviceName: String
}
public struct AppVersionRange: Decodable {
public var minVersion: String
public var maxVersion: String
}
public struct CoreVersionInfo: Decodable {
public var version: String
public var simplexmqVersion: String
@@ -1515,6 +1598,7 @@ public enum ChatError: Decodable {
case errorAgent(agentError: AgentErrorType)
case errorStore(storeError: StoreError)
case errorDatabase(databaseError: DatabaseError)
case errorRemoteCtrl(remoteCtrlError: RemoteCtrlError)
case invalidJSON(json: String)
}
@@ -1674,6 +1758,7 @@ public enum AgentErrorType: Decodable {
case SMP(smpErr: ProtocolErrorType)
case NTF(ntfErr: ProtocolErrorType)
case XFTP(xftpErr: XFTPErrorType)
case RCP(rcpErr: RCErrorType)
case BROKER(brokerAddress: String, brokerErr: BrokerErrorType)
case AGENT(agentErr: SMPAgentError)
case INTERNAL(internalErr: String)
@@ -1731,6 +1816,22 @@ public enum XFTPErrorType: Decodable {
case INTERNAL
}
public enum RCErrorType: Decodable {
case `internal`(internalErr: String)
case identity
case noLocalAddress
case tlsStartFailed
case exception(exception: String)
case ctrlAuth
case ctrlNotFound
case ctrlError(ctrlErr: String)
case version
case encrypt
case decrypt
case blockSize
case syntax(syntaxErr: String)
}
public enum ProtocolCommandError: Decodable {
case UNKNOWN
case SYNTAX
@@ -1766,3 +1867,14 @@ public enum ArchiveError: Decodable {
case `import`(chatError: ChatError)
case importFile(file: String, chatError: ChatError)
}
public enum RemoteCtrlError: Decodable {
case inactive
case badState
case busy
case timeout
case disconnected(remoteCtrlId: Int64, reason: String)
case badInvitation
case badVersion(appVersion: String)
// case protocolError(protocolError: RemoteProtocolError)
}

View File

@@ -9,12 +9,16 @@
import Foundation
import SwiftUI
public let appSuspendTimeout: Int = 15 // seconds
let GROUP_DEFAULT_APP_STATE = "appState"
let GROUP_DEFAULT_NSE_STATE = "nseState"
let GROUP_DEFAULT_DB_CONTAINER = "dbContainer"
public let GROUP_DEFAULT_CHAT_LAST_START = "chatLastStart"
public let GROUP_DEFAULT_CHAT_LAST_BACKGROUND_RUN = "chatLastBackgroundRun"
let GROUP_DEFAULT_NTF_PREVIEW_MODE = "ntfPreviewMode"
public let GROUP_DEFAULT_NTF_ENABLE_LOCAL = "ntfEnableLocal"
public let GROUP_DEFAULT_NTF_ENABLE_PERIODIC = "ntfEnablePeriodic"
public let GROUP_DEFAULT_NTF_ENABLE_LOCAL = "ntfEnableLocal" // no longer used
public let GROUP_DEFAULT_NTF_ENABLE_PERIODIC = "ntfEnablePeriodic" // no longer used
let GROUP_DEFAULT_PRIVACY_ACCEPT_IMAGES = "privacyAcceptImages"
public let GROUP_DEFAULT_PRIVACY_TRANSFER_IMAGES_INLINE = "privacyTransferImagesInline" // no longer used
public let GROUP_DEFAULT_PRIVACY_ENCRYPT_LOCAL_FILES = "privacyEncryptLocalFiles"
@@ -66,13 +70,23 @@ public func registerGroupDefaults() {
])
}
public enum AppState: String {
public enum AppState: String, Codable {
case active
case activating
case bgRefresh
case suspending
case suspended
case stopped
public var running: Bool {
switch self {
case .active: return true
case .activating: return true
case .bgRefresh: return true
default: return false
}
}
public var inactive: Bool {
switch self {
case .suspending: return true
@@ -84,23 +98,57 @@ public enum AppState: String {
public var canSuspend: Bool {
switch self {
case .active: return true
case .activating: return true
case .bgRefresh: return true
default: return false
}
}
}
public enum NSEState: String, Codable {
case created
case starting
case active
case suspending
case suspended
public var inactive: Bool {
switch self {
case .created: true
case .suspended: true
default: false
}
}
public var canSuspend: Bool {
if case .active = self { true } else { false }
}
}
public enum DBContainer: String {
case documents
case group
}
// appStateGroupDefault must not be used in the app directly, only via AppChatState singleton
public let appStateGroupDefault = EnumDefault<AppState>(
defaults: groupDefaults,
forKey: GROUP_DEFAULT_APP_STATE,
withDefault: .active
)
// nseStateGroupDefault must not be used in NSE directly, only via NSEChatState singleton
public let nseStateGroupDefault = EnumDefault<NSEState>(
defaults: groupDefaults,
forKey: GROUP_DEFAULT_NSE_STATE,
withDefault: .suspended // so that NSE that was never launched does not delay the app from resuming
)
// inactive app states do not include "stopped" state
public func allowBackgroundRefresh() -> Bool {
appStateGroupDefault.get().inactive && nseStateGroupDefault.get().inactive
}
public let dbContainerGroupDefault = EnumDefault<DBContainer>(
defaults: groupDefaults,
forKey: GROUP_DEFAULT_DB_CONTAINER,
@@ -109,6 +157,8 @@ public let dbContainerGroupDefault = EnumDefault<DBContainer>(
public let chatLastStartGroupDefault = DateDefault(defaults: groupDefaults, forKey: GROUP_DEFAULT_CHAT_LAST_START)
public let chatLastBackgroundRunGroupDefault = DateDefault(defaults: groupDefaults, forKey: GROUP_DEFAULT_CHAT_LAST_BACKGROUND_RUN)
public let ntfPreviewModeGroupDefault = EnumDefault<NotificationPreviewMode>(
defaults: groupDefaults,
forKey: GROUP_DEFAULT_NTF_PREVIEW_MODE,
@@ -117,10 +167,6 @@ public let ntfPreviewModeGroupDefault = EnumDefault<NotificationPreviewMode>(
public let incognitoGroupDefault = BoolDefault(defaults: groupDefaults, forKey: GROUP_DEFAULT_INCOGNITO)
public let ntfEnableLocalGroupDefault = BoolDefault(defaults: groupDefaults, forKey: GROUP_DEFAULT_NTF_ENABLE_LOCAL)
public let ntfEnablePeriodicGroupDefault = BoolDefault(defaults: groupDefaults, forKey: GROUP_DEFAULT_NTF_ENABLE_PERIODIC)
public let privacyAcceptImagesGroupDefault = BoolDefault(defaults: groupDefaults, forKey: GROUP_DEFAULT_PRIVACY_ACCEPT_IMAGES)
public let privacyEncryptLocalFilesGroupDefault = BoolDefault(defaults: groupDefaults, forKey: GROUP_DEFAULT_PRIVACY_ENCRYPT_LOCAL_FILES)

View File

@@ -1847,7 +1847,7 @@ public struct GroupMember: Identifiable, Decodable {
public func canChangeRoleTo(groupInfo: GroupInfo) -> [GroupMemberRole]? {
if !canBeRemoved(groupInfo: groupInfo) { return nil }
let userRole = groupInfo.membership.memberRole
return GroupMemberRole.allCases.filter { $0 <= userRole }
return GroupMemberRole.allCases.filter { $0 <= userRole && $0 != .author }
}
public var memberIncognito: Bool {
@@ -1887,6 +1887,7 @@ public struct GroupMemberIds: Decodable {
public enum GroupMemberRole: String, Identifiable, CaseIterable, Comparable, Decodable {
case observer = "observer"
case author = "author"
case member = "member"
case admin = "admin"
case owner = "owner"
@@ -1896,6 +1897,7 @@ public enum GroupMemberRole: String, Identifiable, CaseIterable, Comparable, Dec
public var text: String {
switch self {
case .observer: return NSLocalizedString("observer", comment: "member role")
case .author: return NSLocalizedString("author", comment: "member role")
case .member: return NSLocalizedString("member", comment: "member role")
case .admin: return NSLocalizedString("admin", comment: "member role")
case .owner: return NSLocalizedString("owner", comment: "member role")
@@ -1905,9 +1907,10 @@ public enum GroupMemberRole: String, Identifiable, CaseIterable, Comparable, Dec
private var comparisonValue: Int {
switch self {
case .observer: return 0
case .member: return 1
case .admin: return 2
case .owner: return 3
case .author: return 1
case .member: return 2
case .admin: return 3
case .owner: return 4
}
}
@@ -2013,7 +2016,8 @@ public enum ConnectionEntity: Decodable {
}
public struct NtfMsgInfo: Decodable {
public var msgId: String
public var msgTs: Date
}
public struct AChatItem: Decodable {
@@ -2676,6 +2680,7 @@ public enum MsgDecryptError: String, Decodable {
case tooManySkipped
case ratchetEarlier
case other
case ratchetSync
var text: String {
switch self {
@@ -2683,6 +2688,7 @@ public enum MsgDecryptError: String, Decodable {
case .tooManySkipped: return NSLocalizedString("Permanent decryption error", comment: "message decrypt error item")
case .ratchetEarlier: return NSLocalizedString("Decryption error", comment: "message decrypt error item")
case .other: return NSLocalizedString("Decryption error", comment: "message decrypt error item")
case .ratchetSync: return NSLocalizedString("Encryption re-negotiation error", comment: "message decrypt error item")
}
}
}

View File

@@ -17,7 +17,7 @@ public func writeCryptoFile(path: String, data: Data) throws -> CryptoFileArgs {
let ptr: UnsafeMutableRawPointer = malloc(data.count)
memcpy(ptr, (data as NSData).bytes, data.count)
var cPath = path.cString(using: .utf8)!
let cjson = chat_write_file(&cPath, ptr, Int32(data.count))!
let cjson = chat_write_file(getChatCtrl(), &cPath, ptr, Int32(data.count))!
let d = fromCString(cjson).data(using: .utf8)!
switch try jsonDecoder.decode(WriteFileResult.self, from: d) {
case let .result(cfArgs): return cfArgs
@@ -50,7 +50,7 @@ public func readCryptoFile(path: String, cryptoArgs: CryptoFileArgs) throws -> D
public func encryptCryptoFile(fromPath: String, toPath: String) throws -> CryptoFileArgs {
var cFromPath = fromPath.cString(using: .utf8)!
var cToPath = toPath.cString(using: .utf8)!
let cjson = chat_encrypt_file(&cFromPath, &cToPath)!
let cjson = chat_encrypt_file(getChatCtrl(), &cFromPath, &cToPath)!
let d = fromCString(cjson).data(using: .utf8)!
switch try jsonDecoder.decode(WriteFileResult.self, from: d) {
case let .result(cfArgs): return cfArgs

View File

@@ -146,6 +146,13 @@ public func createErrorNtf(_ dbStatus: DBMigrationResult) -> UNMutableNotificati
)
}
public func createAppStoppedNtf() -> UNMutableNotificationContent {
return createNotification(
categoryIdentifier: ntfCategoryConnectionEvent,
title: NSLocalizedString("Encrypted message: app is stopped", comment: "notification")
)
}
private func groupMsgNtfTitle(_ groupInfo: GroupInfo, _ groupMember: GroupMember, hideContent: Bool) -> String {
hideContent
? NSLocalizedString("Group message:", comment: "notification")

View File

@@ -0,0 +1,99 @@
//
// SharedFileSubscriber.swift
// SimpleXChat
//
// Created by Evgeny on 09/12/2023.
// Copyright © 2023 SimpleX Chat. All rights reserved.
//
import Foundation
public typealias AppSubscriber = SharedFileSubscriber<ProcessMessage<AppProcessMessage>>
public typealias NSESubscriber = SharedFileSubscriber<ProcessMessage<NSEProcessMessage>>
public class SharedFileSubscriber<Message: Codable>: NSObject, NSFilePresenter {
var fileURL: URL
public var presentedItemURL: URL?
public var presentedItemOperationQueue: OperationQueue = .main
var subscriber: (Message) -> Void
init(fileURL: URL, onMessage: @escaping (Message) -> Void) {
self.fileURL = fileURL
presentedItemURL = fileURL
subscriber = onMessage
super.init()
NSFileCoordinator.addFilePresenter(self)
}
public func presentedItemDidChange() {
do {
let data = try Data(contentsOf: fileURL)
let msg = try jsonDecoder.decode(Message.self, from: data)
subscriber(msg)
} catch let error {
logger.error("presentedItemDidChange error: \(error)")
}
}
static func notify(url: URL, message: Message) {
let fc = NSFileCoordinator(filePresenter: nil)
fc.coordinate(writingItemAt: url, options: [], error: nil) { newURL in
do {
let data = try jsonEncoder.encode(message)
try data.write(to: newURL, options: [.atomic])
} catch {
logger.error("notifyViaSharedFile error: \(error)")
}
}
}
deinit {
NSFileCoordinator.removeFilePresenter(self)
}
}
let appMessagesSharedFile = getGroupContainerDirectory().appendingPathComponent("chat.simplex.app.messages", isDirectory: false)
let nseMessagesSharedFile = getGroupContainerDirectory().appendingPathComponent("chat.simplex.app.SimpleX-NSE.messages", isDirectory: false)
public struct ProcessMessage<Message: Codable>: Codable {
var createdAt: Date = Date.now
var message: Message
}
public enum AppProcessMessage: Codable {
case state(state: AppState)
}
public enum NSEProcessMessage: Codable {
case state(state: NSEState)
}
public func sendAppProcessMessage(_ message: AppProcessMessage) {
SharedFileSubscriber.notify(url: appMessagesSharedFile, message: ProcessMessage(message: message))
}
public func sendNSEProcessMessage(_ message: NSEProcessMessage) {
SharedFileSubscriber.notify(url: nseMessagesSharedFile, message: ProcessMessage(message: message))
}
public func appMessageSubscriber(onMessage: @escaping (AppProcessMessage) -> Void) -> AppSubscriber {
SharedFileSubscriber(fileURL: appMessagesSharedFile) { (msg: ProcessMessage<AppProcessMessage>) in
onMessage(msg.message)
}
}
public func nseMessageSubscriber(onMessage: @escaping (NSEProcessMessage) -> Void) -> NSESubscriber {
SharedFileSubscriber(fileURL: nseMessagesSharedFile) { (msg: ProcessMessage<NSEProcessMessage>) in
onMessage(msg.message)
}
}
public func sendAppState(_ state: AppState) {
sendAppProcessMessage(.state(state: state))
}
public func sendNSEState(_ state: NSEState) {
sendNSEProcessMessage(.state(state: state))
}

View File

@@ -9,27 +9,27 @@
#ifndef SimpleX_h
#define SimpleX_h
#endif /* SimpleX_h */
#include "hs_init.h"
extern void hs_init(int argc, char **argv[]);
typedef void* chat_ctrl;
// the last parameter is used to return the pointer to chat controller
extern char *chat_migrate_init(char *path, char *key, char *confirm, chat_ctrl *ctrl);
extern char *chat_migrate_init_key(char *path, char *key, int keepKey, char *confirm, int backgroundMode, chat_ctrl *ctrl);
extern char *chat_close_store(chat_ctrl ctl);
extern char *chat_reopen_store(chat_ctrl ctl);
extern char *chat_send_cmd(chat_ctrl ctl, char *cmd);
extern char *chat_recv_msg(chat_ctrl ctl);
extern char *chat_recv_msg_wait(chat_ctrl ctl, int wait);
extern char *chat_parse_markdown(char *str);
extern char *chat_parse_server(char *str);
extern char *chat_password_hash(char *pwd, char *salt);
extern char *chat_valid_name(char *name);
extern char *chat_encrypt_media(char *key, char *frame, int len);
extern char *chat_encrypt_media(chat_ctrl ctl, char *key, char *frame, int len);
extern char *chat_decrypt_media(char *key, char *frame, int len);
// chat_write_file returns null-terminated string with JSON of WriteFileResult
extern char *chat_write_file(char *path, char *data, int len);
extern char *chat_write_file(chat_ctrl ctl, char *path, char *data, int len);
// chat_read_file returns a buffer with:
// result status (1 byte), then if
@@ -38,7 +38,9 @@ extern char *chat_write_file(char *path, char *data, int len);
extern char *chat_read_file(char *path, char *key, char *nonce);
// chat_encrypt_file returns null-terminated string with JSON of WriteFileResult
extern char *chat_encrypt_file(char *fromPath, char *toPath);
extern char *chat_encrypt_file(chat_ctrl ctl, char *fromPath, char *toPath);
// chat_decrypt_file returns null-terminated string with the error message
extern char *chat_decrypt_file(char *fromPath, char *key, char *nonce, char *toPath);
#endif /* SimpleX_h */

View File

@@ -0,0 +1,41 @@
//
// hs_init.c
// SimpleXChat
//
// Created by Evgeny on 22/11/2023.
// Copyright © 2023 SimpleX Chat. All rights reserved.
//
#include "hs_init.h"
extern void hs_init_with_rtsopts(int * argc, char **argv[]);
void haskell_init(void) {
int argc = 5;
char *argv[] = {
"simplex",
"+RTS", // requires `hs_init_with_rtsopts`
"-A16m", // chunk size for new allocations
"-H64m", // initial heap size
"-xn", // non-moving GC
0
};
char **pargv = argv;
hs_init_with_rtsopts(&argc, &pargv);
}
void haskell_init_nse(void) {
int argc = 7;
char *argv[] = {
"simplex",
"+RTS", // requires `hs_init_with_rtsopts`
"-A1m", // chunk size for new allocations
"-H1m", // initial heap size
"-F0.5", // heap growth triggering GC
"-Fd1", // memory return
"-c", // compacting garbage collector
0
};
char **pargv = argv;
hs_init_with_rtsopts(&argc, &pargv);
}

View File

@@ -0,0 +1,16 @@
//
// hs_init.h
// SimpleXChat
//
// Created by Evgeny on 22/11/2023.
// Copyright © 2023 SimpleX Chat. All rights reserved.
//
#ifndef hs_init_h
#define hs_init_h
void haskell_init(void);
void haskell_init_nse(void);
#endif /* hs_init_h */

View File

@@ -25,6 +25,9 @@
/* No comment provided by engineer. */
"- more stable message delivery.\n- a bit better groups.\n- and more!" = "- stabilere Zustellung von Nachrichten.\n- ein bisschen verbesserte Gruppen.\n- und mehr!";
/* No comment provided by engineer. */
"- optionally notify deleted contacts.\n- profile names with spaces.\n- and more!" = "- Optionale Benachrichtigung von gelöschten Kontakten.\n- Profilnamen mit Leerzeichen.\n- Und mehr!";
/* No comment provided by engineer. */
"- voice messages up to 5 minutes.\n- custom time to disappear.\n- editing history." = "- Bis zu 5 Minuten lange Sprachnachrichten.\n- Zeitdauer für verschwindende Nachrichten anpassen.\n- Nachrichten-Historie bearbeiten.";
@@ -43,6 +46,12 @@
/* No comment provided by engineer. */
"(" = "(";
/* No comment provided by engineer. */
"(new)" = "(Neu)";
/* No comment provided by engineer. */
"(this device v%@)" = "(Dieses Gerät hat v%@)";
/* No comment provided by engineer. */
")" = ")";
@@ -119,11 +128,17 @@
"%@ %@" = "%@ %@";
/* No comment provided by engineer. */
"%@ and %@ connected" = "%@ und %@ wurden verbunden";
"%@ and %@" = "%@ und %@";
/* No comment provided by engineer. */
"%@ and %@ connected" = "%@ und %@ wurden mit Ihnen verbunden";
/* copied message info, <sender> at <time> */
"%@ at %@:" = "%1$@ an %2$@:";
/* No comment provided by engineer. */
"%@ connected" = "%@ wurde mit Ihnen verbunden";
/* notification title */
"%@ is connected!" = "%@ ist mit Ihnen verbunden!";
@@ -140,7 +155,10 @@
"%@ wants to connect!" = "%@ will sich mit Ihnen verbinden!";
/* No comment provided by engineer. */
"%@, %@ and %lld other members connected" = "%@, %@ und %lld weitere Mitglieder wurden verbunden";
"%@, %@ and %lld members" = "%@, %@ und %lld Mitglieder";
/* No comment provided by engineer. */
"%@, %@ and %lld other members connected" = "%@, %@ und %lld weitere Mitglieder wurden mit Ihnen verbunden";
/* copied message info */
"%@:" = "%@:";
@@ -178,9 +196,21 @@
/* No comment provided by engineer. */
"%lld file(s) with total size of %@" = "%lld Datei(en) mit einem Gesamtspeicherverbrauch von %@";
/* No comment provided by engineer. */
"%lld group events" = "%lld Gruppenereignisse";
/* No comment provided by engineer. */
"%lld members" = "%lld Mitglieder";
/* No comment provided by engineer. */
"%lld messages blocked" = "%lld Nachrichten blockiert";
/* No comment provided by engineer. */
"%lld messages marked deleted" = "%lld Nachrichten als gelöscht markiert";
/* No comment provided by engineer. */
"%lld messages moderated by %@" = "%lld Nachrichten von %@ moderiert";
/* No comment provided by engineer. */
"%lld minutes" = "%lld Minuten";
@@ -229,6 +259,9 @@
/* No comment provided by engineer. */
"~strike~" = "\\~durchstreichen~";
/* time to disappear */
"0 sec" = "0 sek";
/* No comment provided by engineer. */
"0s" = "0s";
@@ -371,6 +404,9 @@
/* No comment provided by engineer. */
"All messages will be deleted - this cannot be undone! The messages will be deleted ONLY for you." = "Alle Nachrichten werden gelöscht - dies kann nicht rückgängig gemacht werden! Die Nachrichten werden NUR bei Ihnen gelöscht.";
/* No comment provided by engineer. */
"All new messages from %@ will be hidden!" = "Alle neuen Nachrichten von %@ werden verborgen!";
/* No comment provided by engineer. */
"All your contacts will remain connected." = "Alle Ihre Kontakte bleiben verbunden.";
@@ -434,6 +470,12 @@
/* No comment provided by engineer. */
"Already connected?" = "Sind Sie bereits verbunden?";
/* No comment provided by engineer. */
"Already connecting!" = "Bereits verbunden!";
/* No comment provided by engineer. */
"Already joining the group!" = "Sie sind bereits Mitglied der Gruppe!";
/* pref value */
"always" = "Immer";
@@ -443,6 +485,9 @@
/* No comment provided by engineer. */
"An empty chat profile with the provided name is created, and the app opens as usual." = "Es wurde ein leeres Chat-Profil mit dem eingegebenen Namen erstellt und die App öffnet wie gewohnt.";
/* No comment provided by engineer. */
"and %lld other events" = "und %lld weitere Ereignisse";
/* No comment provided by engineer. */
"Answer call" = "Anruf annehmen";
@@ -500,6 +545,9 @@
/* No comment provided by engineer. */
"Authentication unavailable" = "Authentifizierung nicht verfügbar";
/* member role */
"author" = "Autor";
/* No comment provided by engineer. */
"Auto-accept" = "Automatisch akzeptieren";
@@ -512,6 +560,9 @@
/* No comment provided by engineer. */
"Back" = "Zurück";
/* No comment provided by engineer. */
"Bad desktop address" = "Falsche Desktop-Adresse";
/* integrity error chat item */
"bad message hash" = "Ungültiger Nachrichten-Hash";
@@ -524,9 +575,27 @@
/* No comment provided by engineer. */
"Bad message ID" = "Falsche Nachrichten-ID";
/* No comment provided by engineer. */
"Better groups" = "Bessere Gruppen";
/* No comment provided by engineer. */
"Better messages" = "Verbesserungen bei Nachrichten";
/* No comment provided by engineer. */
"Block" = "Blockieren";
/* No comment provided by engineer. */
"Block group members" = "Gruppenmitglieder blockieren";
/* No comment provided by engineer. */
"Block member" = "Mitglied blockieren";
/* No comment provided by engineer. */
"Block member?" = "Mitglied blockieren?";
/* No comment provided by engineer. */
"blocked" = "blockiert";
/* No comment provided by engineer. */
"bold" = "fett";
@@ -720,12 +789,30 @@
/* server test step */
"Connect" = "Verbinden";
/* No comment provided by engineer. */
"Connect automatically" = "Automatisch verbinden";
/* No comment provided by engineer. */
"Connect incognito" = "Inkognito verbinden";
/* No comment provided by engineer. */
"Connect to desktop" = "Mit dem Desktop verbinden";
/* No comment provided by engineer. */
"connect to SimpleX Chat developers." = "Mit den SimpleX Chat-Entwicklern verbinden.";
/* No comment provided by engineer. */
"Connect to yourself?" = "Mit Ihnen selbst verbinden?";
/* No comment provided by engineer. */
"Connect to yourself?\nThis is your own one-time link!" = "Mit Ihnen selbst verbinden?\nDas ist Ihr eigener Einmal-Link!";
/* No comment provided by engineer. */
"Connect to yourself?\nThis is your own SimpleX address!" = "Mit Ihnen selbst verbinden?\nDas ist Ihre eigene SimpleX-Adresse!";
/* No comment provided by engineer. */
"Connect via contact address" = "Über die Kontakt-Adresse verbinden";
/* No comment provided by engineer. */
"Connect via link" = "Über einen Link verbinden";
@@ -735,12 +822,21 @@
/* No comment provided by engineer. */
"Connect via one-time link" = "Über einen Einmal-Link verbinden";
/* No comment provided by engineer. */
"Connect with %@" = "Mit %@ verbinden";
/* No comment provided by engineer. */
"connected" = "Verbunden";
/* No comment provided by engineer. */
"Connected desktop" = "Verbundener Desktop";
/* rcv group event chat item */
"connected directly" = "Direkt miteinander verbunden";
/* No comment provided by engineer. */
"Connected to desktop" = "Mit dem Desktop verbunden";
/* No comment provided by engineer. */
"connecting" = "verbinde";
@@ -765,6 +861,9 @@
/* No comment provided by engineer. */
"Connecting server… (error: %@)" = "Mit dem Server verbinden… (Fehler: %@)";
/* No comment provided by engineer. */
"Connecting to desktop" = "Mit dem Desktop verbinden";
/* chat list item title */
"connecting…" = "Verbinde…";
@@ -783,6 +882,9 @@
/* No comment provided by engineer. */
"Connection request sent!" = "Verbindungsanfrage wurde gesendet!";
/* No comment provided by engineer. */
"Connection terminated" = "Verbindung beendet";
/* No comment provided by engineer. */
"Connection timeout" = "Verbindungszeitüberschreitung";
@@ -831,15 +933,24 @@
/* No comment provided by engineer. */
"Core version: v%@" = "Core Version: v%@";
/* No comment provided by engineer. */
"Correct name to %@?" = "Richtiger Name für %@?";
/* No comment provided by engineer. */
"Create" = "Erstellen";
/* No comment provided by engineer. */
"Create a group using a random profile." = "Erstellen Sie eine Gruppe mit einem zufälligen Profil.";
/* No comment provided by engineer. */
"Create an address to let people connect with you." = "Erstellen Sie eine Adresse, damit sich Personen mit Ihnen verbinden können.";
/* server test step */
"Create file" = "Datei erstellen";
/* No comment provided by engineer. */
"Create group" = "Gruppe erstellen";
/* No comment provided by engineer. */
"Create group link" = "Gruppenlink erstellen";
@@ -852,6 +963,9 @@
/* No comment provided by engineer. */
"Create one-time invitation link" = "Einmal-Einladungslink erstellen";
/* No comment provided by engineer. */
"Create profile" = "Profil erstellen";
/* server test step */
"Create queue" = "Erzeuge Warteschlange";
@@ -966,6 +1080,9 @@
/* chat item action */
"Delete" = "Löschen";
/* No comment provided by engineer. */
"Delete %lld messages?" = "%lld Nachrichten löschen?";
/* No comment provided by engineer. */
"Delete address" = "Adresse löschen";
@@ -978,6 +1095,9 @@
/* No comment provided by engineer. */
"Delete all files" = "Alle Dateien löschen";
/* No comment provided by engineer. */
"Delete and notify contact" = "Kontakt löschen und benachrichtigen";
/* No comment provided by engineer. */
"Delete archive" = "Archiv löschen";
@@ -999,6 +1119,9 @@
/* No comment provided by engineer. */
"Delete Contact" = "Kontakt löschen";
/* No comment provided by engineer. */
"Delete contact?\nThis cannot be undone!" = "Kontakt löschen?\nDas kann nicht rückgängig gemacht werden!";
/* No comment provided by engineer. */
"Delete database" = "Datenbank löschen";
@@ -1074,6 +1197,9 @@
/* copied message info */
"Deleted at: %@" = "Gelöscht um: %@";
/* rcv direct event chat item */
"deleted contact" = "Gelöschter Kontakt";
/* rcv group event chat item */
"deleted group" = "Gruppe gelöscht";
@@ -1089,6 +1215,15 @@
/* No comment provided by engineer. */
"Description" = "Beschreibung";
/* No comment provided by engineer. */
"Desktop address" = "Desktop-Adresse";
/* No comment provided by engineer. */
"Desktop app version %@ is not compatible with this app." = "Desktop App-Version %@ ist mit dieser App nicht kompatibel.";
/* No comment provided by engineer. */
"Desktop devices" = "Desktop-Geräte";
/* No comment provided by engineer. */
"Develop" = "Entwicklung";
@@ -1152,9 +1287,15 @@
/* server test step */
"Disconnect" = "Trennen";
/* No comment provided by engineer. */
"Disconnect desktop?" = "Desktop-Verbindung trennen?";
/* No comment provided by engineer. */
"Discover and join groups" = "Gruppen entdecken und ihnen beitreten";
/* No comment provided by engineer. */
"Discover via local network" = "Lokales Netzwerk durchsuchen";
/* No comment provided by engineer. */
"Do it later" = "Später wiederholen";
@@ -1290,6 +1431,12 @@
/* chat item text */
"encryption re-negotiation allowed for %@" = "Neuaushandlung der Verschlüsselung von %@ erlaubt";
/* message decrypt error item */
"Encryption re-negotiation error" = "Fehler bei der Neuverhandlung der Verschlüsselung";
/* No comment provided by engineer. */
"Encryption re-negotiation failed." = "Neuverhandlung der Verschlüsselung fehlgeschlagen.";
/* chat item text */
"encryption re-negotiation required" = "Neuaushandlung der Verschlüsselung notwendig";
@@ -1305,6 +1452,9 @@
/* No comment provided by engineer. */
"Enter correct passphrase." = "Geben Sie das korrekte Passwort ein.";
/* No comment provided by engineer. */
"Enter group name…" = "Geben Sie den Gruppennamen ein…";
/* No comment provided by engineer. */
"Enter Passcode" = "Zugangscode eingeben";
@@ -1317,12 +1467,18 @@
/* No comment provided by engineer. */
"Enter server manually" = "Geben Sie den Server manuell ein";
/* No comment provided by engineer. */
"Enter this device name…" = "Geben Sie diesen Gerätenamen ein…";
/* placeholder */
"Enter welcome message…" = "Geben Sie eine Begrüßungsmeldung ein …";
/* placeholder */
"Enter welcome message… (optional)" = "Geben Sie eine Begrüßungsmeldung ein … (optional)";
/* No comment provided by engineer. */
"Enter your name…" = "Geben Sie Ihren Namen ein…";
/* No comment provided by engineer. */
"error" = "Fehler";
@@ -1494,6 +1650,9 @@
/* No comment provided by engineer. */
"Exit without saving" = "Beenden ohne Speichern";
/* chat item action */
"Expand" = "Erweitern";
/* No comment provided by engineer. */
"Export database" = "Datenbank exportieren";
@@ -1512,6 +1671,9 @@
/* No comment provided by engineer. */
"Fast and no wait until the sender is online!" = "Schnell und ohne warten auf den Absender, bis er online ist!";
/* No comment provided by engineer. */
"Faster joining and more reliable messages." = "Schnellerer Gruppenbeitritt und zuverlässigere Nachrichtenzustellung.";
/* No comment provided by engineer. */
"Favorite" = "Favorit";
@@ -1569,6 +1731,9 @@
/* No comment provided by engineer. */
"For console" = "Für Konsole";
/* No comment provided by engineer. */
"Found desktop" = "Gefundener Desktop";
/* No comment provided by engineer. */
"French interface" = "Französische Bedienoberfläche";
@@ -1581,6 +1746,9 @@
/* No comment provided by engineer. */
"Full name:" = "Vollständiger Name:";
/* No comment provided by engineer. */
"Fully decentralized visible only to members." = "Vollständig dezentralisiert nur für Mitglieder sichtbar.";
/* No comment provided by engineer. */
"Fully re-implemented - work in background!" = "Komplett neu umgesetzt - arbeitet nun im Hintergrund!";
@@ -1593,6 +1761,12 @@
/* No comment provided by engineer. */
"Group" = "Gruppe";
/* No comment provided by engineer. */
"Group already exists" = "Die Gruppe besteht bereits";
/* No comment provided by engineer. */
"Group already exists!" = "Die Gruppe besteht bereits!";
/* No comment provided by engineer. */
"group deleted" = "Gruppe gelöscht";
@@ -1764,6 +1938,9 @@
/* No comment provided by engineer. */
"Incognito" = "Inkognito";
/* No comment provided by engineer. */
"Incognito groups" = "Inkognito-Gruppen";
/* No comment provided by engineer. */
"Incognito mode" = "Inkognito-Modus";
@@ -1791,6 +1968,9 @@
/* No comment provided by engineer. */
"Incompatible database version" = "Inkompatible Datenbank-Version";
/* No comment provided by engineer. */
"Incompatible version" = "Inkompatible Version";
/* PIN entry */
"Incorrect passcode" = "Zugangscode ist falsch";
@@ -1830,6 +2010,9 @@
/* invalid chat item */
"invalid data" = "Ungültige Daten";
/* No comment provided by engineer. */
"Invalid name!" = "Ungültiger Name!";
/* No comment provided by engineer. */
"Invalid server address!" = "Ungültige Serveradresse!";
@@ -1888,7 +2071,7 @@
"It can happen when:\n1. The messages expired in the sending client after 2 days or on the server after 30 days.\n2. Message decryption failed, because you or your contact used old database backup.\n3. The connection was compromised." = "Dies kann unter folgenden Umständen passieren:\n1. Die Nachrichten verfallen auf dem sendenden Client-System nach 2 Tagen oder auf dem Server nach 30 Tagen.\n2. Die Nachrichten-Entschlüsselung ist fehlgeschlagen, da von Ihnen oder Ihrem Kontakt ein altes Datenbank-Backup genutzt wurde.\n3. Die Verbindung wurde kompromittiert.";
/* No comment provided by engineer. */
"It seems like you are already connected via this link. If it is not the case, there was an error (%@)." = "Es sieht so aus, dass Sie bereits über diesen Link verbunden sind. Wenn das nicht der Fall, gab es einen Fehler (%@).";
"It seems like you are already connected via this link. If it is not the case, there was an error (%@)." = "Es sieht so aus, als ob Sie bereits über diesen Link verbunden sind. Wenn das nicht der Fall ist, gab es einen Fehler (%@).";
/* No comment provided by engineer. */
"Italian interface" = "Italienische Bedienoberfläche";
@@ -1908,12 +2091,24 @@
/* No comment provided by engineer. */
"Join group" = "Treten Sie der Gruppe bei";
/* No comment provided by engineer. */
"Join group?" = "Der Gruppe beitreten?";
/* No comment provided by engineer. */
"Join incognito" = "Inkognito beitreten";
/* No comment provided by engineer. */
"Join with current profile" = "Mit dem aktuellen Profil beitreten";
/* No comment provided by engineer. */
"Join your group?\nThis is your link for group %@!" = "Ihrer Gruppe beitreten?\nDas ist Ihr Link für die Gruppe %@!";
/* No comment provided by engineer. */
"Joining group" = "Der Gruppe beitreten";
/* No comment provided by engineer. */
"Keep the app open to use it from desktop" = "Die App muss geöffnet bleiben, um sie vom Desktop aus nutzen zu können";
/* No comment provided by engineer. */
"Keep your connections" = "Ihre Verbindungen beibehalten";
@@ -1950,6 +2145,15 @@
/* No comment provided by engineer. */
"Limitations" = "Einschränkungen";
/* No comment provided by engineer. */
"Link mobile and desktop apps! 🔗" = "Verknüpfe Mobiltelefon- und Desktop-Apps! 🔗";
/* No comment provided by engineer. */
"Linked desktop options" = "Verknüpfte Desktop-Optionen";
/* No comment provided by engineer. */
"Linked desktops" = "Verknüpfte Desktops";
/* No comment provided by engineer. */
"LIVE" = "LIVE";
@@ -2055,6 +2259,9 @@
/* No comment provided by engineer. */
"Messages & files" = "Nachrichten";
/* No comment provided by engineer. */
"Messages from %@ will be shown!" = "Die Nachrichten von %@ werden angezeigt!";
/* No comment provided by engineer. */
"Migrating database archive…" = "Datenbank-Archiv wird migriert…";
@@ -2202,6 +2409,9 @@
/* copied message info in history */
"no text" = "Kein Text";
/* No comment provided by engineer. */
"Not compatible!" = "Nicht kompatibel!";
/* No comment provided by engineer. */
"Notifications" = "Benachrichtigungen";
@@ -2306,6 +2516,9 @@
/* authentication reason */
"Open chat console" = "Chat-Konsole öffnen";
/* No comment provided by engineer. */
"Open group" = "Gruppe öffnen";
/* No comment provided by engineer. */
"Open Settings" = "Geräte-Einstellungen öffnen";
@@ -2342,6 +2555,9 @@
/* No comment provided by engineer. */
"Paste" = "Einfügen";
/* No comment provided by engineer. */
"Paste desktop address" = "Desktop-Adresse einfügen";
/* No comment provided by engineer. */
"Paste image" = "Bild einfügen";
@@ -2438,6 +2654,12 @@
/* No comment provided by engineer. */
"Profile image" = "Profilbild";
/* No comment provided by engineer. */
"Profile name" = "Profilname";
/* No comment provided by engineer. */
"Profile name:" = "Profilname:";
/* No comment provided by engineer. */
"Profile password" = "Passwort für Profil";
@@ -2603,6 +2825,12 @@
/* No comment provided by engineer. */
"Renegotiate encryption?" = "Verschlüsselung neu aushandeln?";
/* No comment provided by engineer. */
"Repeat connection request?" = "Verbindungsanfrage wiederholen?";
/* No comment provided by engineer. */
"Repeat join request?" = "Verbindungsanfrage wiederholen?";
/* chat item action */
"Reply" = "Antwort";
@@ -2714,6 +2942,9 @@
/* No comment provided by engineer. */
"Scan QR code" = "QR-Code scannen";
/* No comment provided by engineer. */
"Scan QR code from desktop" = "Den QR-Code vom Desktop scannen";
/* No comment provided by engineer. */
"Scan security code from your contact's app." = "Scannen Sie den Sicherheitscode von der App Ihres Kontakts.";
@@ -2858,6 +3089,9 @@
/* No comment provided by engineer. */
"Servers" = "Server";
/* No comment provided by engineer. */
"Session code" = "Sitzungscode";
/* No comment provided by engineer. */
"Set 1 day" = "Einen Tag festlegen";
@@ -3044,6 +3278,9 @@
/* No comment provided by engineer. */
"Tap to activate profile." = "Tippen Sie auf das Profil um es zu aktivieren.";
/* No comment provided by engineer. */
"Tap to Connect" = "Zum Verbinden antippen";
/* No comment provided by engineer. */
"Tap to join" = "Zum Beitreten tippen";
@@ -3164,12 +3401,21 @@
/* notification title */
"this contact" = "Dieser Kontakt";
/* No comment provided by engineer. */
"This device name" = "Dieser Gerätename";
/* No comment provided by engineer. */
"This group has over %lld members, delivery receipts are not sent." = "Es werden keine Empfangsbestätigungen gesendet, da diese Gruppe über %lld Mitglieder hat.";
/* No comment provided by engineer. */
"This group no longer exists." = "Diese Gruppe existiert nicht mehr.";
/* No comment provided by engineer. */
"This is your own one-time link!" = "Das ist Ihr eigener Einmal-Link!";
/* No comment provided by engineer. */
"This is your own SimpleX address!" = "Das ist Ihre eigene SimpleX-Adresse!";
/* No comment provided by engineer. */
"This setting applies to messages in your current chat profile **%@**." = "Diese Einstellung gilt für Nachrichten in Ihrem aktuellen Chat-Profil **%@**.";
@@ -3179,6 +3425,9 @@
/* No comment provided by engineer. */
"To connect, your contact can scan QR code or use the link in the app." = "Um eine Verbindung herzustellen, kann Ihr Kontakt den QR-Code scannen oder den Link in der App verwenden.";
/* No comment provided by engineer. */
"To hide unwanted messages." = "Um unerwünschte Nachrichten zu verbergen.";
/* No comment provided by engineer. */
"To make a new connection" = "Um eine Verbindung mit einem neuen Kontakt zu erstellen";
@@ -3195,7 +3444,7 @@
"To record voice message please grant permission to use Microphone." = "Bitte erlauben Sie die Nutzung des Mikrofons, um Sprachnachrichten aufnehmen zu können.";
/* No comment provided by engineer. */
"To reveal your hidden profile, enter a full password into a search field in **Your chat profiles** page." = "Geben Sie ein vollständiges Passwort in das Suchfeld auf der Seite **Meine Chat-Profile** ein, um Ihr verborgenes Profil zu sehen.";
"To reveal your hidden profile, enter a full password into a search field in **Your chat profiles** page." = "Geben Sie ein vollständiges Passwort in das Suchfeld auf der Seite **Ihre Chat-Profile** ein, um Ihr verborgenes Profil zu sehen.";
/* No comment provided by engineer. */
"To support instant push notifications the chat database has to be migrated." = "Um sofortige Push-Benachrichtigungen zu unterstützen, muss die Chat-Datenbank migriert werden.";
@@ -3227,6 +3476,15 @@
/* No comment provided by engineer. */
"Unable to record voice message" = "Die Aufnahme einer Sprachnachricht ist nicht möglich";
/* No comment provided by engineer. */
"Unblock" = "Freigeben";
/* No comment provided by engineer. */
"Unblock member" = "Mitglied freigeben";
/* No comment provided by engineer. */
"Unblock member?" = "Mitglied freigeben?";
/* item status description */
"Unexpected error: %@" = "Unerwarteter Fehler: %@";
@@ -3266,6 +3524,12 @@
/* No comment provided by engineer. */
"Unless your contact deleted the connection or this link was already used, it might be a bug - please report it.\nTo connect, please ask your contact to create another connection link and check that you have a stable network connection." = "Entweder hat Ihr Kontakt die Verbindung gelöscht, oder dieser Link wurde bereits verwendet, es könnte sich um einen Fehler handeln - Bitte melden Sie es uns.\nBitten Sie Ihren Kontakt darum einen weiteren Verbindungs-Link zu erzeugen, um sich neu verbinden zu können und stellen Sie sicher, dass Sie eine stabile Netzwerk-Verbindung haben.";
/* No comment provided by engineer. */
"Unlink" = "Entkoppeln";
/* No comment provided by engineer. */
"Unlink desktop?" = "Desktop entkoppeln?";
/* No comment provided by engineer. */
"Unlock" = "Entsperren";
@@ -3320,6 +3584,9 @@
/* No comment provided by engineer. */
"Use for new connections" = "Für neue Verbindungen nutzen";
/* No comment provided by engineer. */
"Use from desktop" = "Vom Desktop aus nutzen";
/* No comment provided by engineer. */
"Use iOS call interface" = "iOS Anrufschnittstelle nutzen";
@@ -3341,12 +3608,24 @@
/* No comment provided by engineer. */
"Using SimpleX Chat servers." = "Verwendung von SimpleX-Chat-Servern.";
/* No comment provided by engineer. */
"v%@" = "v%@";
/* No comment provided by engineer. */
"v%@ (%@)" = "v%@ (%@)";
/* No comment provided by engineer. */
"Verify code with desktop" = "Code mit dem Desktop überprüfen";
/* No comment provided by engineer. */
"Verify connection" = "Verbindung überprüfen";
/* No comment provided by engineer. */
"Verify connection security" = "Sicherheit der Verbindung überprüfen";
/* No comment provided by engineer. */
"Verify connections" = "Verbindungen überprüfen";
/* No comment provided by engineer. */
"Verify security code" = "Sicherheitscode überprüfen";
@@ -3365,6 +3644,9 @@
/* No comment provided by engineer. */
"via relay" = "über Relais";
/* No comment provided by engineer. */
"Via secure quantum resistant protocol." = "Über ein sicheres quantenbeständiges Protokoll.";
/* No comment provided by engineer. */
"Video call" = "Videoanruf";
@@ -3404,6 +3686,9 @@
/* No comment provided by engineer. */
"waiting for confirmation…" = "Warten auf Bestätigung…";
/* No comment provided by engineer. */
"Waiting for desktop..." = "Es wird auf den Desktop gewartet...";
/* No comment provided by engineer. */
"Waiting for file" = "Warte auf Datei";
@@ -3459,7 +3744,7 @@
"yes" = "Ja";
/* No comment provided by engineer. */
"You" = "Meine Daten";
"You" = "Ihre Daten";
/* No comment provided by engineer. */
"You accepted connection" = "Sie haben die Verbindung akzeptiert";
@@ -3473,6 +3758,27 @@
/* No comment provided by engineer. */
"You are already connected to %@." = "Sie sind bereits mit %@ verbunden.";
/* No comment provided by engineer. */
"You are already connecting to %@." = "Sie sind bereits mit %@ verbunden.";
/* No comment provided by engineer. */
"You are already connecting via this one-time link!" = "Sie sind bereits über diesen Einmal-Link verbunden!";
/* No comment provided by engineer. */
"You are already in group %@." = "Sie sind bereits Mitglied der Gruppe %@.";
/* No comment provided by engineer. */
"You are already joining the group %@." = "Sie sind bereits Mitglied der Gruppe %@.";
/* No comment provided by engineer. */
"You are already joining the group via this link!" = "Sie sind über diesen Link bereits Mitglied der Gruppe!";
/* No comment provided by engineer. */
"You are already joining the group via this link." = "Sie sind über diesen Link bereits Mitglied der Gruppe.";
/* No comment provided by engineer. */
"You are already joining the group!\nRepeat join request?" = "Sie sind bereits Mitglied dieser Gruppe!\nVerbindungsanfrage wiederholen?";
/* No comment provided by engineer. */
"You are connected to the server used to receive messages from this contact." = "Sie sind mit dem Server verbunden, der für den Empfang von Nachrichten mit diesem Kontakt genutzt wird.";
@@ -3548,6 +3854,12 @@
/* No comment provided by engineer. */
"You could not be verified; please try again." = "Sie konnten nicht überprüft werden; bitte versuchen Sie es erneut.";
/* No comment provided by engineer. */
"You have already requested connection via this address!" = "Sie haben über diese Adresse bereits eine Verbindung beantragt!";
/* No comment provided by engineer. */
"You have already requested connection!\nRepeat connection request?" = "Sie haben bereits ein Verbindungsanfrage beantragt!\nVerbindungsanfrage wiederholen?";
/* No comment provided by engineer. */
"You have no chats" = "Sie haben keine Chats";
@@ -3590,6 +3902,9 @@
/* No comment provided by engineer. */
"You will be connected to group when the group host's device is online, please wait or check later!" = "Sie werden mit der Gruppe verbunden, sobald das Endgerät des Gruppen-Hosts online ist. Bitte warten oder schauen Sie später nochmal nach!";
/* No comment provided by engineer. */
"You will be connected when group link host's device is online, please wait or check later!" = "Sie werden verbunden, sobald das Endgerät des Gruppenlink-Hosts online ist. Bitte warten oder schauen Sie später nochmal nach!";
/* No comment provided by engineer. */
"You will be connected when your connection request is accepted, please wait or check later!" = "Sie werden verbunden, sobald Ihre Verbindungsanfrage akzeptiert wird. Bitte warten oder schauen Sie später nochmal nach!";
@@ -3599,6 +3914,9 @@
/* No comment provided by engineer. */
"You will be required to authenticate when you start or resume the app after 30 seconds in background." = "Sie müssen sich authentifizieren, wenn Sie die im Hintergrund befindliche App nach 30 Sekunden starten oder fortsetzen.";
/* No comment provided by engineer. */
"You will connect to all group members." = "Sie werden mit allen Gruppenmitgliedern verbunden.";
/* No comment provided by engineer. */
"You will still receive calls and notifications from muted profiles when they are active." = "Sie können Anrufe und Benachrichtigungen auch von stummgeschalteten Profilen empfangen, solange diese aktiv sind.";
@@ -3630,7 +3948,7 @@
"Your chat database is not encrypted - set passphrase to encrypt it." = "Ihre Chat-Datenbank ist nicht verschlüsselt. Bitte legen Sie ein Passwort fest, um sie zu schützen.";
/* No comment provided by engineer. */
"Your chat profiles" = "Meine Chat-Profile";
"Your chat profiles" = "Ihre Chat-Profile";
/* No comment provided by engineer. */
"Your contact needs to be online for the connection to complete.\nYou can cancel this connection and remove the contact (and try later with a new link)." = "Damit die Verbindung hergestellt werden kann, muss Ihr Kontakt online sein.\nSie können diese Verbindung abbrechen und den Kontakt entfernen (und es später nochmals mit einem neuen Link versuchen).";
@@ -3657,10 +3975,13 @@
"Your ICE servers" = "Ihre ICE-Server";
/* No comment provided by engineer. */
"Your preferences" = "Meine Präferenzen";
"Your preferences" = "Ihre Präferenzen";
/* No comment provided by engineer. */
"Your privacy" = "Meine Privatsphäre";
"Your privacy" = "Ihre Privatsphäre";
/* No comment provided by engineer. */
"Your profile" = "Mein Profil";
/* No comment provided by engineer. */
"Your profile **%@** will be shared." = "Ihr Profil **%@** wird geteilt.";
@@ -3681,10 +4002,10 @@
"Your server address" = "Ihre Serveradresse";
/* No comment provided by engineer. */
"Your settings" = "Meine Einstellungen";
"Your settings" = "Ihre Einstellungen";
/* No comment provided by engineer. */
"Your SimpleX address" = "Meine SimpleX-Adresse";
"Your SimpleX address" = "Ihre SimpleX-Adresse";
/* No comment provided by engineer. */
"Your SMP servers" = "Ihre SMP-Server";

View File

@@ -7,6 +7,9 @@
/* Privacy - Face ID Usage Description */
"NSFaceIDUsageDescription" = "Face ID wird von SimpleX für die lokale Authentifizierung genutzt";
/* Privacy - Local Network Usage Description */
"NSLocalNetworkUsageDescription" = "SimpleX nutzt den lokalen Netzwerkzugriff, um die Nutzung von Benutzer-Chatprofilen über eine Desktop-App im gleichen Netzwerk zu erlauben.";
/* Privacy - Microphone Usage Description */
"NSMicrophoneUsageDescription" = "SimpleX benötigt Zugriff auf das Mikrofon, um Audio- und Videoanrufe und die Aufnahme von Sprachnachrichten zu ermöglichen.";

View File

@@ -25,6 +25,9 @@
/* No comment provided by engineer. */
"- more stable message delivery.\n- a bit better groups.\n- and more!" = "- une diffusion plus stable des messages.\n- des groupes un peu plus performants.\n- et bien d'autres choses encore !";
/* No comment provided by engineer. */
"- optionally notify deleted contacts.\n- profile names with spaces.\n- and more!" = "- option pour notifier les contacts supprimés.\n- noms de profil avec espaces.\n- et plus encore !";
/* No comment provided by engineer. */
"- voice messages up to 5 minutes.\n- custom time to disappear.\n- editing history." = "- messages vocaux pouvant durer jusqu'à 5 minutes.\n- délai personnalisé de disparition.\n- l'historique de modification.";
@@ -43,6 +46,12 @@
/* No comment provided by engineer. */
"(" = "(";
/* No comment provided by engineer. */
"(new)" = "(nouveau)";
/* No comment provided by engineer. */
"(this device v%@)" = "(cet appareil v%@)";
/* No comment provided by engineer. */
")" = ")";
@@ -118,12 +127,18 @@
/* No comment provided by engineer. */
"%@ %@" = "%@ %@";
/* No comment provided by engineer. */
"%@ and %@" = "%@ et %@";
/* No comment provided by engineer. */
"%@ and %@ connected" = "%@ et %@ sont connecté.es";
/* copied message info, <sender> at <time> */
"%@ at %@:" = "%1$@ à %2$@:";
/* No comment provided by engineer. */
"%@ connected" = "%@ connecté(e)";
/* notification title */
"%@ is connected!" = "%@ est connecté·e !";
@@ -139,6 +154,9 @@
/* notification title */
"%@ wants to connect!" = "%@ veut se connecter !";
/* No comment provided by engineer. */
"%@, %@ and %lld members" = "%@, %@ et %lld membres";
/* No comment provided by engineer. */
"%@, %@ and %lld other members connected" = "%@, %@ et %lld autres membres sont connectés";
@@ -178,9 +196,21 @@
/* No comment provided by engineer. */
"%lld file(s) with total size of %@" = "%lld fichier·s pour une taille totale de %@";
/* No comment provided by engineer. */
"%lld group events" = "%lld événements de groupe";
/* No comment provided by engineer. */
"%lld members" = "%lld membres";
/* No comment provided by engineer. */
"%lld messages blocked" = "%lld messages bloqués";
/* No comment provided by engineer. */
"%lld messages marked deleted" = "%lld messages marqués comme supprimés";
/* No comment provided by engineer. */
"%lld messages moderated by %@" = "%lld messages modérés par %@";
/* No comment provided by engineer. */
"%lld minutes" = "%lld minutes";
@@ -229,6 +259,9 @@
/* No comment provided by engineer. */
"~strike~" = "\\~barré~";
/* time to disappear */
"0 sec" = "0 sec";
/* No comment provided by engineer. */
"0s" = "0s";
@@ -371,6 +404,9 @@
/* No comment provided by engineer. */
"All messages will be deleted - this cannot be undone! The messages will be deleted ONLY for you." = "Tous les messages seront supprimés - impossible de revenir en arrière ! Les messages seront supprimés UNIQUEMENT pour vous.";
/* No comment provided by engineer. */
"All new messages from %@ will be hidden!" = "Tous les nouveaux messages de %@ seront cachés !";
/* No comment provided by engineer. */
"All your contacts will remain connected." = "Tous vos contacts resteront connectés.";
@@ -434,6 +470,12 @@
/* No comment provided by engineer. */
"Already connected?" = "Déjà connecté ?";
/* No comment provided by engineer. */
"Already connecting!" = "Déjà en connexion !";
/* No comment provided by engineer. */
"Already joining the group!" = "Groupe déjà rejoint !";
/* pref value */
"always" = "toujours";
@@ -443,6 +485,9 @@
/* No comment provided by engineer. */
"An empty chat profile with the provided name is created, and the app opens as usual." = "Un profil de chat vierge portant le nom fourni est créé et l'application s'ouvre normalement.";
/* No comment provided by engineer. */
"and %lld other events" = "et %lld autres événements";
/* No comment provided by engineer. */
"Answer call" = "Répondre à l'appel";
@@ -500,6 +545,9 @@
/* No comment provided by engineer. */
"Authentication unavailable" = "Authentification indisponible";
/* member role */
"author" = "auteur";
/* No comment provided by engineer. */
"Auto-accept" = "Auto-accepter";
@@ -512,6 +560,9 @@
/* No comment provided by engineer. */
"Back" = "Retour";
/* No comment provided by engineer. */
"Bad desktop address" = "Mauvaise adresse de bureau";
/* integrity error chat item */
"bad message hash" = "hash de message incorrect";
@@ -524,9 +575,27 @@
/* No comment provided by engineer. */
"Bad message ID" = "Mauvais ID de message";
/* No comment provided by engineer. */
"Better groups" = "Des groupes plus performants";
/* No comment provided by engineer. */
"Better messages" = "Meilleurs messages";
/* No comment provided by engineer. */
"Block" = "Bloquer";
/* No comment provided by engineer. */
"Block group members" = "Bloquer des membres d'un groupe";
/* No comment provided by engineer. */
"Block member" = "Bloquer ce membre";
/* No comment provided by engineer. */
"Block member?" = "Bloquer ce membre ?";
/* No comment provided by engineer. */
"blocked" = "blocké";
/* No comment provided by engineer. */
"bold" = "gras";
@@ -720,12 +789,30 @@
/* server test step */
"Connect" = "Se connecter";
/* No comment provided by engineer. */
"Connect automatically" = "Connexion automatique";
/* No comment provided by engineer. */
"Connect incognito" = "Se connecter incognito";
/* No comment provided by engineer. */
"Connect to desktop" = "Se connecter au bureau";
/* No comment provided by engineer. */
"connect to SimpleX Chat developers." = "se connecter aux developpeurs de SimpleX Chat.";
/* No comment provided by engineer. */
"Connect to yourself?" = "Se connecter à soi-même ?";
/* No comment provided by engineer. */
"Connect to yourself?\nThis is your own one-time link!" = "Se connecter à soi-même ?\nIl s'agit de votre propre lien unique !";
/* No comment provided by engineer. */
"Connect to yourself?\nThis is your own SimpleX address!" = "Se connecter à soi-même ?\nC'est votre propre adresse SimpleX !";
/* No comment provided by engineer. */
"Connect via contact address" = "Se connecter via l'adresse de contact";
/* No comment provided by engineer. */
"Connect via link" = "Se connecter via un lien";
@@ -735,12 +822,21 @@
/* No comment provided by engineer. */
"Connect via one-time link" = "Se connecter via un lien unique";
/* No comment provided by engineer. */
"Connect with %@" = "Se connecter avec %@";
/* No comment provided by engineer. */
"connected" = "connecté";
/* No comment provided by engineer. */
"Connected desktop" = "Bureau connecté";
/* rcv group event chat item */
"connected directly" = "s'est connecté.e de manière directe";
/* No comment provided by engineer. */
"Connected to desktop" = "Connecté au bureau";
/* No comment provided by engineer. */
"connecting" = "connexion";
@@ -765,6 +861,9 @@
/* No comment provided by engineer. */
"Connecting server… (error: %@)" = "Connexion au serveur… (erreur : %@)";
/* No comment provided by engineer. */
"Connecting to desktop" = "Connexion au bureau";
/* chat list item title */
"connecting…" = "connexion…";
@@ -783,6 +882,9 @@
/* No comment provided by engineer. */
"Connection request sent!" = "Demande de connexion envoyée !";
/* No comment provided by engineer. */
"Connection terminated" = "Connexion terminée";
/* No comment provided by engineer. */
"Connection timeout" = "Délai de connexion";
@@ -831,15 +933,24 @@
/* No comment provided by engineer. */
"Core version: v%@" = "Version du cœur : v%@";
/* No comment provided by engineer. */
"Correct name to %@?" = "Corriger le nom pour %@ ?";
/* No comment provided by engineer. */
"Create" = "Créer";
/* No comment provided by engineer. */
"Create a group using a random profile." = "Création de groupes via un profil aléatoire.";
/* No comment provided by engineer. */
"Create an address to let people connect with you." = "Créez une adresse pour permettre aux gens de vous contacter.";
/* server test step */
"Create file" = "Créer un fichier";
/* No comment provided by engineer. */
"Create group" = "Créer un groupe";
/* No comment provided by engineer. */
"Create group link" = "Créer un lien de groupe";
@@ -852,6 +963,9 @@
/* No comment provided by engineer. */
"Create one-time invitation link" = "Créer un lien d'invitation unique";
/* No comment provided by engineer. */
"Create profile" = "Créer le profil";
/* server test step */
"Create queue" = "Créer une file d'attente";
@@ -966,6 +1080,9 @@
/* chat item action */
"Delete" = "Supprimer";
/* No comment provided by engineer. */
"Delete %lld messages?" = "Supprimer %lld messages ?";
/* No comment provided by engineer. */
"Delete address" = "Supprimer l'adresse";
@@ -978,6 +1095,9 @@
/* No comment provided by engineer. */
"Delete all files" = "Effacer tous les fichiers";
/* No comment provided by engineer. */
"Delete and notify contact" = "Supprimer et en informer le contact";
/* No comment provided by engineer. */
"Delete archive" = "Supprimer l'archive";
@@ -999,6 +1119,9 @@
/* No comment provided by engineer. */
"Delete Contact" = "Supprimer le contact";
/* No comment provided by engineer. */
"Delete contact?\nThis cannot be undone!" = "Supprimer le contact ?\nCette opération ne peut être annulée !";
/* No comment provided by engineer. */
"Delete database" = "Supprimer la base de données";
@@ -1074,6 +1197,9 @@
/* copied message info */
"Deleted at: %@" = "Supprimé à : %@";
/* rcv direct event chat item */
"deleted contact" = "contact supprimé";
/* rcv group event chat item */
"deleted group" = "groupe supprimé";
@@ -1089,6 +1215,15 @@
/* No comment provided by engineer. */
"Description" = "Description";
/* No comment provided by engineer. */
"Desktop address" = "Adresse de bureau";
/* No comment provided by engineer. */
"Desktop app version %@ is not compatible with this app." = "La version de l'application de bureau %@ n'est pas compatible avec cette application.";
/* No comment provided by engineer. */
"Desktop devices" = "Appareils de bureau";
/* No comment provided by engineer. */
"Develop" = "Développer";
@@ -1152,9 +1287,15 @@
/* server test step */
"Disconnect" = "Se déconnecter";
/* No comment provided by engineer. */
"Disconnect desktop?" = "Déconnecter le bureau ?";
/* No comment provided by engineer. */
"Discover and join groups" = "Découvrir et rejoindre des groupes";
/* No comment provided by engineer. */
"Discover via local network" = "Rechercher sur le réseau";
/* No comment provided by engineer. */
"Do it later" = "Faites-le plus tard";
@@ -1290,6 +1431,12 @@
/* chat item text */
"encryption re-negotiation allowed for %@" = "renégociation de chiffrement autorisée pour %@";
/* message decrypt error item */
"Encryption re-negotiation error" = "Erreur lors de la renégociation du chiffrement";
/* No comment provided by engineer. */
"Encryption re-negotiation failed." = "La renégociation du chiffrement a échoué.";
/* chat item text */
"encryption re-negotiation required" = "renégociation de chiffrement requise";
@@ -1305,6 +1452,9 @@
/* No comment provided by engineer. */
"Enter correct passphrase." = "Entrez la phrase secrète correcte.";
/* No comment provided by engineer. */
"Enter group name…" = "Entrer un nom de groupe…";
/* No comment provided by engineer. */
"Enter Passcode" = "Entrer le code d'accès";
@@ -1317,12 +1467,18 @@
/* No comment provided by engineer. */
"Enter server manually" = "Entrer un serveur manuellement";
/* No comment provided by engineer. */
"Enter this device name…" = "Entrez le nom de l'appareil…";
/* placeholder */
"Enter welcome message…" = "Entrez un message de bienvenue…";
/* placeholder */
"Enter welcome message… (optional)" = "Entrez un message de bienvenue… (facultatif)";
/* No comment provided by engineer. */
"Enter your name…" = "Entrez votre nom…";
/* No comment provided by engineer. */
"error" = "erreur";
@@ -1494,6 +1650,9 @@
/* No comment provided by engineer. */
"Exit without saving" = "Quitter sans sauvegarder";
/* chat item action */
"Expand" = "Développer";
/* No comment provided by engineer. */
"Export database" = "Exporter la base de données";
@@ -1512,6 +1671,9 @@
/* No comment provided by engineer. */
"Fast and no wait until the sender is online!" = "Rapide et ne nécessitant pas d'attendre que l'expéditeur soit en ligne !";
/* No comment provided by engineer. */
"Faster joining and more reliable messages." = "Connexion plus rapide et messages plus fiables.";
/* No comment provided by engineer. */
"Favorite" = "Favoris";
@@ -1569,6 +1731,9 @@
/* No comment provided by engineer. */
"For console" = "Pour la console";
/* No comment provided by engineer. */
"Found desktop" = "Bureau trouvé";
/* No comment provided by engineer. */
"French interface" = "Interface en français";
@@ -1581,6 +1746,9 @@
/* No comment provided by engineer. */
"Full name:" = "Nom complet :";
/* No comment provided by engineer. */
"Fully decentralized visible only to members." = "Entièrement décentralisé visible que par ses membres.";
/* No comment provided by engineer. */
"Fully re-implemented - work in background!" = "Entièrement réimplémenté - fonctionne en arrière-plan !";
@@ -1593,6 +1761,12 @@
/* No comment provided by engineer. */
"Group" = "Groupe";
/* No comment provided by engineer. */
"Group already exists" = "Le groupe existe déjà";
/* No comment provided by engineer. */
"Group already exists!" = "Ce groupe existe déjà !";
/* No comment provided by engineer. */
"group deleted" = "groupe supprimé";
@@ -1764,6 +1938,9 @@
/* No comment provided by engineer. */
"Incognito" = "Incognito";
/* No comment provided by engineer. */
"Incognito groups" = "Groupes incognito";
/* No comment provided by engineer. */
"Incognito mode" = "Mode Incognito";
@@ -1791,6 +1968,9 @@
/* No comment provided by engineer. */
"Incompatible database version" = "Version de la base de données incompatible";
/* No comment provided by engineer. */
"Incompatible version" = "Version incompatible";
/* PIN entry */
"Incorrect passcode" = "Code d'accès erroné";
@@ -1830,6 +2010,9 @@
/* invalid chat item */
"invalid data" = "données invalides";
/* No comment provided by engineer. */
"Invalid name!" = "Nom invalide !";
/* No comment provided by engineer. */
"Invalid server address!" = "Adresse de serveur invalide !";
@@ -1908,12 +2091,24 @@
/* No comment provided by engineer. */
"Join group" = "Rejoindre le groupe";
/* No comment provided by engineer. */
"Join group?" = "Rejoindre le groupe ?";
/* No comment provided by engineer. */
"Join incognito" = "Rejoindre en incognito";
/* No comment provided by engineer. */
"Join with current profile" = "Rejoindre avec le profil actuel";
/* No comment provided by engineer. */
"Join your group?\nThis is your link for group %@!" = "Rejoindre votre groupe ?\nVoici votre lien pour le groupe %@ !";
/* No comment provided by engineer. */
"Joining group" = "Entrain de rejoindre le groupe";
/* No comment provided by engineer. */
"Keep the app open to use it from desktop" = "Garder l'application ouverte pour l'utiliser depuis le bureau";
/* No comment provided by engineer. */
"Keep your connections" = "Conserver vos connexions";
@@ -1950,6 +2145,15 @@
/* No comment provided by engineer. */
"Limitations" = "Limitations";
/* No comment provided by engineer. */
"Link mobile and desktop apps! 🔗" = "Liez vos applications mobiles et de bureau ! 🔗";
/* No comment provided by engineer. */
"Linked desktop options" = "Options de bureau lié";
/* No comment provided by engineer. */
"Linked desktops" = "Bureaux liés";
/* No comment provided by engineer. */
"LIVE" = "LIVE";
@@ -2055,6 +2259,9 @@
/* No comment provided by engineer. */
"Messages & files" = "Messages";
/* No comment provided by engineer. */
"Messages from %@ will be shown!" = "Les messages de %@ seront affichés !";
/* No comment provided by engineer. */
"Migrating database archive…" = "Migration de l'archive de la base de données…";
@@ -2202,6 +2409,9 @@
/* copied message info in history */
"no text" = "aucun texte";
/* No comment provided by engineer. */
"Not compatible!" = "Non compatible !";
/* No comment provided by engineer. */
"Notifications" = "Notifications";
@@ -2306,6 +2516,9 @@
/* authentication reason */
"Open chat console" = "Ouvrir la console du chat";
/* No comment provided by engineer. */
"Open group" = "Ouvrir le groupe";
/* No comment provided by engineer. */
"Open Settings" = "Ouvrir les Paramètres";
@@ -2342,6 +2555,9 @@
/* No comment provided by engineer. */
"Paste" = "Coller";
/* No comment provided by engineer. */
"Paste desktop address" = "Coller l'adresse du bureau";
/* No comment provided by engineer. */
"Paste image" = "Coller l'image";
@@ -2438,6 +2654,12 @@
/* No comment provided by engineer. */
"Profile image" = "Image de profil";
/* No comment provided by engineer. */
"Profile name" = "Nom du profil";
/* No comment provided by engineer. */
"Profile name:" = "Nom du profil :";
/* No comment provided by engineer. */
"Profile password" = "Mot de passe de profil";
@@ -2603,6 +2825,12 @@
/* No comment provided by engineer. */
"Renegotiate encryption?" = "Renégocier le chiffrement?";
/* No comment provided by engineer. */
"Repeat connection request?" = "Répéter la demande de connexion ?";
/* No comment provided by engineer. */
"Repeat join request?" = "Répéter la requête d'adhésion ?";
/* chat item action */
"Reply" = "Répondre";
@@ -2714,6 +2942,9 @@
/* No comment provided by engineer. */
"Scan QR code" = "Scanner un code QR";
/* No comment provided by engineer. */
"Scan QR code from desktop" = "Scanner le code QR du bureau";
/* No comment provided by engineer. */
"Scan security code from your contact's app." = "Scannez le code de sécurité depuis l'application de votre contact.";
@@ -2858,6 +3089,9 @@
/* No comment provided by engineer. */
"Servers" = "Serveurs";
/* No comment provided by engineer. */
"Session code" = "Code de session";
/* No comment provided by engineer. */
"Set 1 day" = "Définir 1 jour";
@@ -3044,6 +3278,9 @@
/* No comment provided by engineer. */
"Tap to activate profile." = "Appuyez pour activer un profil.";
/* No comment provided by engineer. */
"Tap to Connect" = "Tapez pour vous connecter";
/* No comment provided by engineer. */
"Tap to join" = "Appuyez pour rejoindre";
@@ -3164,12 +3401,21 @@
/* notification title */
"this contact" = "ce contact";
/* No comment provided by engineer. */
"This device name" = "Ce nom d'appareil";
/* No comment provided by engineer. */
"This group has over %lld members, delivery receipts are not sent." = "Ce groupe compte plus de %lld membres, les accusés de réception ne sont pas envoyés.";
/* No comment provided by engineer. */
"This group no longer exists." = "Ce groupe n'existe plus.";
/* No comment provided by engineer. */
"This is your own one-time link!" = "Voici votre propre lien unique !";
/* No comment provided by engineer. */
"This is your own SimpleX address!" = "Voici votre propre adresse SimpleX !";
/* No comment provided by engineer. */
"This setting applies to messages in your current chat profile **%@**." = "Ce paramètre s'applique aux messages de votre profil de chat actuel **%@**.";
@@ -3179,6 +3425,9 @@
/* No comment provided by engineer. */
"To connect, your contact can scan QR code or use the link in the app." = "Pour se connecter, votre contact peut scanner le code QR ou utiliser le lien dans l'application.";
/* No comment provided by engineer. */
"To hide unwanted messages." = "Pour cacher les messages indésirables.";
/* No comment provided by engineer. */
"To make a new connection" = "Pour établir une nouvelle connexion";
@@ -3227,6 +3476,15 @@
/* No comment provided by engineer. */
"Unable to record voice message" = "Impossible d'enregistrer un message vocal";
/* No comment provided by engineer. */
"Unblock" = "Débloquer";
/* No comment provided by engineer. */
"Unblock member" = "Débloquer ce membre";
/* No comment provided by engineer. */
"Unblock member?" = "Débloquer ce membre ?";
/* item status description */
"Unexpected error: %@" = "Erreur inattendue: %@";
@@ -3266,6 +3524,12 @@
/* No comment provided by engineer. */
"Unless your contact deleted the connection or this link was already used, it might be a bug - please report it.\nTo connect, please ask your contact to create another connection link and check that you have a stable network connection." = "A moins que votre contact ait supprimé la connexion ou que ce lien ait déjà été utilisé, il peut s'agir d'un bug - veuillez le signaler.\nPour vous connecter, veuillez demander à votre contact de créer un autre lien de connexion et vérifiez que vous disposez d'une connexion réseau stable.";
/* No comment provided by engineer. */
"Unlink" = "Délier";
/* No comment provided by engineer. */
"Unlink desktop?" = "Délier le bureau ?";
/* No comment provided by engineer. */
"Unlock" = "Déverrouiller";
@@ -3320,6 +3584,9 @@
/* No comment provided by engineer. */
"Use for new connections" = "Utiliser pour les nouvelles connexions";
/* No comment provided by engineer. */
"Use from desktop" = "Utilisation depuis le bureau";
/* No comment provided by engineer. */
"Use iOS call interface" = "Utiliser l'interface d'appel d'iOS";
@@ -3341,12 +3608,24 @@
/* No comment provided by engineer. */
"Using SimpleX Chat servers." = "Utilisation des serveurs SimpleX Chat.";
/* No comment provided by engineer. */
"v%@" = "v%@";
/* No comment provided by engineer. */
"v%@ (%@)" = "v%@ (%@)";
/* No comment provided by engineer. */
"Verify code with desktop" = "Vérifier le code avec le bureau";
/* No comment provided by engineer. */
"Verify connection" = "Vérifier la connexion";
/* No comment provided by engineer. */
"Verify connection security" = "Vérifier la sécurité de la connexion";
/* No comment provided by engineer. */
"Verify connections" = "Vérifier les connexions";
/* No comment provided by engineer. */
"Verify security code" = "Vérifier le code de sécurité";
@@ -3365,6 +3644,9 @@
/* No comment provided by engineer. */
"via relay" = "via relais";
/* No comment provided by engineer. */
"Via secure quantum resistant protocol." = "Via un protocole sécurisé de cryptographie post-quantique.";
/* No comment provided by engineer. */
"Video call" = "Appel vidéo";
@@ -3404,6 +3686,9 @@
/* No comment provided by engineer. */
"waiting for confirmation…" = "en attente de confirmation…";
/* No comment provided by engineer. */
"Waiting for desktop..." = "En attente du bureau...";
/* No comment provided by engineer. */
"Waiting for file" = "En attente du fichier";
@@ -3473,6 +3758,27 @@
/* No comment provided by engineer. */
"You are already connected to %@." = "Vous êtes déjà connecté·e à %@ via ce lien.";
/* No comment provided by engineer. */
"You are already connecting to %@." = "Vous êtes déjà en train de vous connecter à %@.";
/* No comment provided by engineer. */
"You are already connecting via this one-time link!" = "Vous êtes déjà connecté(e) via ce lien unique !";
/* No comment provided by engineer. */
"You are already in group %@." = "Vous êtes déjà dans le groupe %@.";
/* No comment provided by engineer. */
"You are already joining the group %@." = "Vous êtes déjà en train de rejoindre le groupe %@.";
/* No comment provided by engineer. */
"You are already joining the group via this link!" = "Vous êtes déjà en train de rejoindre le groupe via ce lien !";
/* No comment provided by engineer. */
"You are already joining the group via this link." = "Vous êtes déjà en train de rejoindre le groupe via ce lien.";
/* No comment provided by engineer. */
"You are already joining the group!\nRepeat join request?" = "Vous êtes déjà membre de ce groupe !\nRépéter la demande d'adhésion ?";
/* No comment provided by engineer. */
"You are connected to the server used to receive messages from this contact." = "Vous êtes connecté·e au serveur utilisé pour recevoir les messages de ce contact.";
@@ -3548,6 +3854,12 @@
/* No comment provided by engineer. */
"You could not be verified; please try again." = "Vous n'avez pas pu être vérifié·e; veuillez réessayer.";
/* No comment provided by engineer. */
"You have already requested connection via this address!" = "Vous avez déjà demandé une connexion via cette adresse !";
/* No comment provided by engineer. */
"You have already requested connection!\nRepeat connection request?" = "Vous avez déjà demandé une connexion !\nRépéter la demande de connexion ?";
/* No comment provided by engineer. */
"You have no chats" = "Vous n'avez aucune discussion";
@@ -3590,6 +3902,9 @@
/* No comment provided by engineer. */
"You will be connected to group when the group host's device is online, please wait or check later!" = "Vous serez connecté·e au groupe lorsque l'appareil de l'hôte sera en ligne, veuillez attendre ou vérifier plus tard !";
/* No comment provided by engineer. */
"You will be connected when group link host's device is online, please wait or check later!" = "Vous serez connecté(e) lorsque l'appareil de l'hôte du lien de groupe sera en ligne, veuillez patienter ou vérifier plus tard !";
/* No comment provided by engineer. */
"You will be connected when your connection request is accepted, please wait or check later!" = "Vous serez connecté·e lorsque votre demande de connexion sera acceptée, veuillez attendre ou vérifier plus tard !";
@@ -3599,6 +3914,9 @@
/* No comment provided by engineer. */
"You will be required to authenticate when you start or resume the app after 30 seconds in background." = "Il vous sera demandé de vous authentifier lorsque vous démarrez ou reprenez l'application après 30 secondes en arrière-plan.";
/* No comment provided by engineer. */
"You will connect to all group members." = "Vous vous connecterez à tous les membres du groupe.";
/* No comment provided by engineer. */
"You will still receive calls and notifications from muted profiles when they are active." = "Vous continuerez à recevoir des appels et des notifications des profils mis en sourdine lorsqu'ils sont actifs.";
@@ -3662,6 +3980,9 @@
/* No comment provided by engineer. */
"Your privacy" = "Votre vie privée";
/* No comment provided by engineer. */
"Your profile" = "Votre profil";
/* No comment provided by engineer. */
"Your profile **%@** will be shared." = "Votre profil **%@** sera partagé.";

View File

@@ -7,6 +7,9 @@
/* Privacy - Face ID Usage Description */
"NSFaceIDUsageDescription" = "SimpleGroup not found!X utilise Face ID pour l'authentification locale";
/* Privacy - Local Network Usage Description */
"NSLocalNetworkUsageDescription" = "SimpleX utilise un accès au réseau local pour permettre l'utilisation du profil de chat de l'utilisateur via l'application de bureau au sein de ce même réseau.";
/* Privacy - Microphone Usage Description */
"NSMicrophoneUsageDescription" = "SimpleX a besoin d'un accès au microphone pour les appels audio et vidéo ainsi que pour enregistrer des messages vocaux.";

View File

@@ -25,6 +25,9 @@
/* No comment provided by engineer. */
"- more stable message delivery.\n- a bit better groups.\n- and more!" = "- recapito dei messaggi più stabile.\n- gruppi un po' migliorati.\n- e altro ancora!";
/* No comment provided by engineer. */
"- optionally notify deleted contacts.\n- profile names with spaces.\n- and more!" = "- avvisa facoltativamente i contatti eliminati.\n- nomi del profilo con spazi.\n- e molto altro!";
/* No comment provided by engineer. */
"- voice messages up to 5 minutes.\n- custom time to disappear.\n- editing history." = "- messaggi vocali fino a 5 minuti.\n- tempo di scomparsa personalizzato.\n- cronologia delle modifiche.";
@@ -43,6 +46,12 @@
/* No comment provided by engineer. */
"(" = "(";
/* No comment provided by engineer. */
"(new)" = "(nuovo)";
/* No comment provided by engineer. */
"(this device v%@)" = "(questo dispositivo v%@)";
/* No comment provided by engineer. */
")" = ")";
@@ -118,12 +127,18 @@
/* No comment provided by engineer. */
"%@ %@" = "%@ %@";
/* No comment provided by engineer. */
"%@ and %@" = "%@ e %@";
/* No comment provided by engineer. */
"%@ and %@ connected" = "%@ e %@ sono connessi/e";
/* copied message info, <sender> at <time> */
"%@ at %@:" = "%1$@ alle %2$@:";
/* No comment provided by engineer. */
"%@ connected" = "%@ si è connesso/a";
/* notification title */
"%@ is connected!" = "%@ è connesso/a!";
@@ -139,6 +154,9 @@
/* notification title */
"%@ wants to connect!" = "%@ si vuole connettere!";
/* No comment provided by engineer. */
"%@, %@ and %lld members" = "%@, %@ e %lld membri";
/* No comment provided by engineer. */
"%@, %@ and %lld other members connected" = "%@, %@ e altri %lld membri sono connessi";
@@ -178,9 +196,21 @@
/* No comment provided by engineer. */
"%lld file(s) with total size of %@" = "%lld file con dimensione totale di %@";
/* No comment provided by engineer. */
"%lld group events" = "%lld eventi del gruppo";
/* No comment provided by engineer. */
"%lld members" = "%lld membri";
/* No comment provided by engineer. */
"%lld messages blocked" = "%lld messaggi bloccati";
/* No comment provided by engineer. */
"%lld messages marked deleted" = "%lld messaggi contrassegnati eliminati";
/* No comment provided by engineer. */
"%lld messages moderated by %@" = "%lld messaggi moderati da %@";
/* No comment provided by engineer. */
"%lld minutes" = "%lld minuti";
@@ -229,6 +259,9 @@
/* No comment provided by engineer. */
"~strike~" = "\\~barrato~";
/* time to disappear */
"0 sec" = "0 sec";
/* No comment provided by engineer. */
"0s" = "0s";
@@ -371,6 +404,9 @@
/* No comment provided by engineer. */
"All messages will be deleted - this cannot be undone! The messages will be deleted ONLY for you." = "Tutti i messaggi verranno eliminati, non è reversibile! I messaggi verranno eliminati SOLO per te.";
/* No comment provided by engineer. */
"All new messages from %@ will be hidden!" = "Tutti i nuovi messaggi da %@ verrranno nascosti!";
/* No comment provided by engineer. */
"All your contacts will remain connected." = "Tutti i tuoi contatti resteranno connessi.";
@@ -434,6 +470,12 @@
/* No comment provided by engineer. */
"Already connected?" = "Già connesso/a?";
/* No comment provided by engineer. */
"Already connecting!" = "Già in connessione!";
/* No comment provided by engineer. */
"Already joining the group!" = "Già in ingresso nel gruppo!";
/* pref value */
"always" = "sempre";
@@ -443,6 +485,9 @@
/* No comment provided by engineer. */
"An empty chat profile with the provided name is created, and the app opens as usual." = "Viene creato un profilo di chat vuoto con il nome scelto e l'app si apre come al solito.";
/* No comment provided by engineer. */
"and %lld other events" = "e altri %lld eventi";
/* No comment provided by engineer. */
"Answer call" = "Rispondi alla chiamata";
@@ -512,6 +557,9 @@
/* No comment provided by engineer. */
"Back" = "Indietro";
/* No comment provided by engineer. */
"Bad desktop address" = "Indirizzo desktop errato";
/* integrity error chat item */
"bad message hash" = "hash del messaggio errato";
@@ -524,9 +572,27 @@
/* No comment provided by engineer. */
"Bad message ID" = "ID del messaggio errato";
/* No comment provided by engineer. */
"Better groups" = "Gruppi migliorati";
/* No comment provided by engineer. */
"Better messages" = "Messaggi migliorati";
/* No comment provided by engineer. */
"Block" = "Blocca";
/* No comment provided by engineer. */
"Block group members" = "Blocca i membri dei gruppi";
/* No comment provided by engineer. */
"Block member" = "Blocca membro";
/* No comment provided by engineer. */
"Block member?" = "Bloccare il membro?";
/* No comment provided by engineer. */
"blocked" = "bloccato";
/* No comment provided by engineer. */
"bold" = "grassetto";
@@ -622,7 +688,7 @@
"changed address for you" = "indirizzo cambiato per te";
/* rcv group event chat item */
"changed role of %@ to %@" = "cambiato il ruolo di %1$@ in %2$@";
"changed role of %@ to %@" = "ha cambiato il ruolo di %1$@ in %2$@";
/* rcv group event chat item */
"changed your role to %@" = "cambiato il tuo ruolo in %@";
@@ -723,9 +789,24 @@
/* No comment provided by engineer. */
"Connect incognito" = "Connetti in incognito";
/* No comment provided by engineer. */
"Connect to desktop" = "Connetti al desktop";
/* No comment provided by engineer. */
"connect to SimpleX Chat developers." = "connettiti agli sviluppatori di SimpleX Chat.";
/* No comment provided by engineer. */
"Connect to yourself?" = "Connettersi a te stesso?";
/* No comment provided by engineer. */
"Connect to yourself?\nThis is your own one-time link!" = "Connettersi a te stesso?\nQuesto è il tuo link una tantum!";
/* No comment provided by engineer. */
"Connect to yourself?\nThis is your own SimpleX address!" = "Connettersi a te stesso?\nQuesto è il tuo indirizzo SimpleX!";
/* No comment provided by engineer. */
"Connect via contact address" = "Connettere via indirizzo del contatto";
/* No comment provided by engineer. */
"Connect via link" = "Connetti via link";
@@ -735,12 +816,21 @@
/* No comment provided by engineer. */
"Connect via one-time link" = "Connetti via link una tantum";
/* No comment provided by engineer. */
"Connect with %@" = "Connettersi con %@";
/* No comment provided by engineer. */
"connected" = "connesso/a";
/* No comment provided by engineer. */
"Connected desktop" = "Desktop connesso";
/* rcv group event chat item */
"connected directly" = "si è connesso/a direttamente";
/* No comment provided by engineer. */
"Connected to desktop" = "Connesso al desktop";
/* No comment provided by engineer. */
"connecting" = "in connessione";
@@ -765,6 +855,9 @@
/* No comment provided by engineer. */
"Connecting server… (error: %@)" = "Connessione al server… (errore: %@)";
/* No comment provided by engineer. */
"Connecting to desktop" = "Connessione al desktop";
/* chat list item title */
"connecting…" = "in connessione…";
@@ -783,6 +876,9 @@
/* No comment provided by engineer. */
"Connection request sent!" = "Richiesta di connessione inviata!";
/* No comment provided by engineer. */
"Connection terminated" = "Connessione terminata";
/* No comment provided by engineer. */
"Connection timeout" = "Connessione scaduta";
@@ -831,15 +927,24 @@
/* No comment provided by engineer. */
"Core version: v%@" = "Versione core: v%@";
/* No comment provided by engineer. */
"Correct name to %@?" = "Correggere il nome a %@?";
/* No comment provided by engineer. */
"Create" = "Crea";
/* No comment provided by engineer. */
"Create a group using a random profile." = "Crea un gruppo usando un profilo casuale.";
/* No comment provided by engineer. */
"Create an address to let people connect with you." = "Crea un indirizzo per consentire alle persone di connettersi con te.";
/* server test step */
"Create file" = "Crea file";
/* No comment provided by engineer. */
"Create group" = "Crea gruppo";
/* No comment provided by engineer. */
"Create group link" = "Crea link del gruppo";
@@ -852,6 +957,9 @@
/* No comment provided by engineer. */
"Create one-time invitation link" = "Crea link di invito una tantum";
/* No comment provided by engineer. */
"Create profile" = "Crea profilo";
/* server test step */
"Create queue" = "Crea coda";
@@ -966,6 +1074,9 @@
/* chat item action */
"Delete" = "Elimina";
/* No comment provided by engineer. */
"Delete %lld messages?" = "Eliminare %lld messaggi?";
/* No comment provided by engineer. */
"Delete address" = "Elimina indirizzo";
@@ -978,6 +1089,9 @@
/* No comment provided by engineer. */
"Delete all files" = "Elimina tutti i file";
/* No comment provided by engineer. */
"Delete and notify contact" = "Elimina e avvisa il contatto";
/* No comment provided by engineer. */
"Delete archive" = "Elimina archivio";
@@ -999,6 +1113,9 @@
/* No comment provided by engineer. */
"Delete Contact" = "Elimina contatto";
/* No comment provided by engineer. */
"Delete contact?\nThis cannot be undone!" = "Eliminare il contatto?\nNon è reversibile!";
/* No comment provided by engineer. */
"Delete database" = "Elimina database";
@@ -1074,6 +1191,9 @@
/* copied message info */
"Deleted at: %@" = "Eliminato il: %@";
/* rcv direct event chat item */
"deleted contact" = "contatto eliminato";
/* rcv group event chat item */
"deleted group" = "gruppo eliminato";
@@ -1089,6 +1209,15 @@
/* No comment provided by engineer. */
"Description" = "Descrizione";
/* No comment provided by engineer. */
"Desktop address" = "Indirizzo desktop";
/* No comment provided by engineer. */
"Desktop app version %@ is not compatible with this app." = "La versione dell'app desktop %@ non è compatibile con questa app.";
/* No comment provided by engineer. */
"Desktop devices" = "Dispositivi desktop";
/* No comment provided by engineer. */
"Develop" = "Sviluppa";
@@ -1152,6 +1281,9 @@
/* server test step */
"Disconnect" = "Disconnetti";
/* No comment provided by engineer. */
"Disconnect desktop?" = "Disconnettere il desktop?";
/* No comment provided by engineer. */
"Discover and join groups" = "Scopri ed unisciti ai gruppi";
@@ -1290,6 +1422,12 @@
/* chat item text */
"encryption re-negotiation allowed for %@" = "rinegoziazione della crittografia consentita per %@";
/* message decrypt error item */
"Encryption re-negotiation error" = "Errore di rinegoziazione crittografia";
/* No comment provided by engineer. */
"Encryption re-negotiation failed." = "Rinegoziazione crittografia fallita.";
/* chat item text */
"encryption re-negotiation required" = "richiesta rinegoziazione della crittografia";
@@ -1305,6 +1443,9 @@
/* No comment provided by engineer. */
"Enter correct passphrase." = "Inserisci la password giusta.";
/* No comment provided by engineer. */
"Enter group name…" = "Inserisci il nome del gruppo…";
/* No comment provided by engineer. */
"Enter Passcode" = "Inserisci il codice di accesso";
@@ -1317,12 +1458,18 @@
/* No comment provided by engineer. */
"Enter server manually" = "Inserisci il server a mano";
/* No comment provided by engineer. */
"Enter this device name…" = "Inserisci il nome di questo dispositivo…";
/* placeholder */
"Enter welcome message…" = "Inserisci il messaggio di benvenuto…";
/* placeholder */
"Enter welcome message… (optional)" = "Inserisci il messaggio di benvenuto… (facoltativo)";
/* No comment provided by engineer. */
"Enter your name…" = "Inserisci il tuo nome…";
/* No comment provided by engineer. */
"error" = "errore";
@@ -1494,6 +1641,9 @@
/* No comment provided by engineer. */
"Exit without saving" = "Esci senza salvare";
/* chat item action */
"Expand" = "Espandi";
/* No comment provided by engineer. */
"Export database" = "Esporta database";
@@ -1512,6 +1662,9 @@
/* No comment provided by engineer. */
"Fast and no wait until the sender is online!" = "Veloce e senza aspettare che il mittente sia in linea!";
/* No comment provided by engineer. */
"Faster joining and more reliable messages." = "Ingresso più veloce e messaggi più affidabili.";
/* No comment provided by engineer. */
"Favorite" = "Preferito";
@@ -1581,6 +1734,9 @@
/* No comment provided by engineer. */
"Full name:" = "Nome completo:";
/* No comment provided by engineer. */
"Fully decentralized visible only to members." = "Completamente decentralizzato: visibile solo ai membri.";
/* No comment provided by engineer. */
"Fully re-implemented - work in background!" = "Completamente reimplementato - funziona in secondo piano!";
@@ -1593,6 +1749,12 @@
/* No comment provided by engineer. */
"Group" = "Gruppo";
/* No comment provided by engineer. */
"Group already exists" = "Il gruppo esiste già";
/* No comment provided by engineer. */
"Group already exists!" = "Il gruppo esiste già!";
/* No comment provided by engineer. */
"group deleted" = "gruppo eliminato";
@@ -1764,6 +1926,9 @@
/* No comment provided by engineer. */
"Incognito" = "Incognito";
/* No comment provided by engineer. */
"Incognito groups" = "Gruppi in incognito";
/* No comment provided by engineer. */
"Incognito mode" = "Modalità incognito";
@@ -1791,6 +1956,9 @@
/* No comment provided by engineer. */
"Incompatible database version" = "Versione del database incompatibile";
/* No comment provided by engineer. */
"Incompatible version" = "Versione incompatibile";
/* PIN entry */
"Incorrect passcode" = "Codice di accesso errato";
@@ -1830,6 +1998,9 @@
/* invalid chat item */
"invalid data" = "dati non validi";
/* No comment provided by engineer. */
"Invalid name!" = "Nome non valido!";
/* No comment provided by engineer. */
"Invalid server address!" = "Indirizzo del server non valido!";
@@ -1908,12 +2079,24 @@
/* No comment provided by engineer. */
"Join group" = "Entra nel gruppo";
/* No comment provided by engineer. */
"Join group?" = "Entrare nel gruppo?";
/* No comment provided by engineer. */
"Join incognito" = "Entra in incognito";
/* No comment provided by engineer. */
"Join with current profile" = "Entra con il profilo attuale";
/* No comment provided by engineer. */
"Join your group?\nThis is your link for group %@!" = "Entrare nel tuo gruppo?\nQuesto è il tuo link per il gruppo %@!";
/* No comment provided by engineer. */
"Joining group" = "Ingresso nel gruppo";
/* No comment provided by engineer. */
"Keep the app open to use it from desktop" = "Tieni aperta l'app per usarla dal desktop";
/* No comment provided by engineer. */
"Keep your connections" = "Mantieni le tue connessioni";
@@ -1950,6 +2133,15 @@
/* No comment provided by engineer. */
"Limitations" = "Limitazioni";
/* No comment provided by engineer. */
"Link mobile and desktop apps! 🔗" = "Collega le app mobile e desktop! 🔗";
/* No comment provided by engineer. */
"Linked desktop options" = "Opzioni del desktop collegato";
/* No comment provided by engineer. */
"Linked desktops" = "Desktop collegati";
/* No comment provided by engineer. */
"LIVE" = "IN DIRETTA";
@@ -2055,6 +2247,9 @@
/* No comment provided by engineer. */
"Messages & files" = "Messaggi";
/* No comment provided by engineer. */
"Messages from %@ will be shown!" = "I messaggi da %@ verranno mostrati!";
/* No comment provided by engineer. */
"Migrating database archive…" = "Migrazione archivio del database…";
@@ -2306,6 +2501,9 @@
/* authentication reason */
"Open chat console" = "Apri la console della chat";
/* No comment provided by engineer. */
"Open group" = "Apri gruppo";
/* No comment provided by engineer. */
"Open Settings" = "Apri le impostazioni";
@@ -2342,6 +2540,9 @@
/* No comment provided by engineer. */
"Paste" = "Incolla";
/* No comment provided by engineer. */
"Paste desktop address" = "Incolla l'indirizzo desktop";
/* No comment provided by engineer. */
"Paste image" = "Incolla immagine";
@@ -2438,6 +2639,12 @@
/* No comment provided by engineer. */
"Profile image" = "Immagine del profilo";
/* No comment provided by engineer. */
"Profile name" = "Nome del profilo";
/* No comment provided by engineer. */
"Profile name:" = "Nome del profilo:";
/* No comment provided by engineer. */
"Profile password" = "Password del profilo";
@@ -2603,6 +2810,12 @@
/* No comment provided by engineer. */
"Renegotiate encryption?" = "Rinegoziare la crittografia?";
/* No comment provided by engineer. */
"Repeat connection request?" = "Ripetere la richiesta di connessione?";
/* No comment provided by engineer. */
"Repeat join request?" = "Ripetere la richiesta di ingresso?";
/* chat item action */
"Reply" = "Rispondi";
@@ -2714,6 +2927,9 @@
/* No comment provided by engineer. */
"Scan QR code" = "Scansiona codice QR";
/* No comment provided by engineer. */
"Scan QR code from desktop" = "Scansiona codice QR dal desktop";
/* No comment provided by engineer. */
"Scan security code from your contact's app." = "Scansiona il codice di sicurezza dall'app del tuo contatto.";
@@ -2858,6 +3074,9 @@
/* No comment provided by engineer. */
"Servers" = "Server";
/* No comment provided by engineer. */
"Session code" = "Codice di sessione";
/* No comment provided by engineer. */
"Set 1 day" = "Imposta 1 giorno";
@@ -3044,6 +3263,9 @@
/* No comment provided by engineer. */
"Tap to activate profile." = "Tocca per attivare il profilo.";
/* No comment provided by engineer. */
"Tap to Connect" = "Tocca per connettere";
/* No comment provided by engineer. */
"Tap to join" = "Tocca per entrare";
@@ -3164,12 +3386,21 @@
/* notification title */
"this contact" = "questo contatto";
/* No comment provided by engineer. */
"This device name" = "Il nome di questo dispositivo";
/* No comment provided by engineer. */
"This group has over %lld members, delivery receipts are not sent." = "Questo gruppo ha più di %lld membri, le ricevute di consegna non vengono inviate.";
/* No comment provided by engineer. */
"This group no longer exists." = "Questo gruppo non esiste più.";
/* No comment provided by engineer. */
"This is your own one-time link!" = "Questo è il tuo link una tantum!";
/* No comment provided by engineer. */
"This is your own SimpleX address!" = "Questo è il tuo indirizzo SimpleX!";
/* No comment provided by engineer. */
"This setting applies to messages in your current chat profile **%@**." = "Questa impostazione si applica ai messaggi del profilo di chat attuale **%@**.";
@@ -3179,6 +3410,9 @@
/* No comment provided by engineer. */
"To connect, your contact can scan QR code or use the link in the app." = "Per connettervi, il tuo contatto può scansionare il codice QR o usare il link nell'app.";
/* No comment provided by engineer. */
"To hide unwanted messages." = "Per nascondere messaggi indesiderati.";
/* No comment provided by engineer. */
"To make a new connection" = "Per creare una nuova connessione";
@@ -3227,6 +3461,15 @@
/* No comment provided by engineer. */
"Unable to record voice message" = "Impossibile registrare il messaggio vocale";
/* No comment provided by engineer. */
"Unblock" = "Sblocca";
/* No comment provided by engineer. */
"Unblock member" = "Sblocca membro";
/* No comment provided by engineer. */
"Unblock member?" = "Sbloccare il membro?";
/* item status description */
"Unexpected error: %@" = "Errore imprevisto: % @";
@@ -3266,6 +3509,12 @@
/* No comment provided by engineer. */
"Unless your contact deleted the connection or this link was already used, it might be a bug - please report it.\nTo connect, please ask your contact to create another connection link and check that you have a stable network connection." = "A meno che il tuo contatto non abbia eliminato la connessione o che questo link non sia già stato usato, potrebbe essere un errore; per favore segnalalo.\nPer connetterti, chiedi al tuo contatto di creare un altro link di connessione e controlla di avere una connessione di rete stabile.";
/* No comment provided by engineer. */
"Unlink" = "Scollega";
/* No comment provided by engineer. */
"Unlink desktop?" = "Scollegare il desktop?";
/* No comment provided by engineer. */
"Unlock" = "Sblocca";
@@ -3320,6 +3569,9 @@
/* No comment provided by engineer. */
"Use for new connections" = "Usa per connessioni nuove";
/* No comment provided by engineer. */
"Use from desktop" = "Usa dal desktop";
/* No comment provided by engineer. */
"Use iOS call interface" = "Usa interfaccia di chiamata iOS";
@@ -3341,12 +3593,24 @@
/* No comment provided by engineer. */
"Using SimpleX Chat servers." = "Utilizzo dei server SimpleX Chat.";
/* No comment provided by engineer. */
"v%@" = "v%@";
/* No comment provided by engineer. */
"v%@ (%@)" = "v%@ (%@)";
/* No comment provided by engineer. */
"Verify code with desktop" = "Verifica il codice con il desktop";
/* No comment provided by engineer. */
"Verify connection" = "Verifica la connessione";
/* No comment provided by engineer. */
"Verify connection security" = "Verifica la sicurezza della connessione";
/* No comment provided by engineer. */
"Verify connections" = "Verifica le connessioni";
/* No comment provided by engineer. */
"Verify security code" = "Verifica codice di sicurezza";
@@ -3365,6 +3629,9 @@
/* No comment provided by engineer. */
"via relay" = "via relay";
/* No comment provided by engineer. */
"Via secure quantum resistant protocol." = "Tramite protocollo sicuro resistente alla quantistica.";
/* No comment provided by engineer. */
"Video call" = "Videochiamata";
@@ -3473,6 +3740,27 @@
/* No comment provided by engineer. */
"You are already connected to %@." = "Sei già connesso/a a %@.";
/* No comment provided by engineer. */
"You are already connecting to %@." = "Ti stai già connettendo a %@.";
/* No comment provided by engineer. */
"You are already connecting via this one-time link!" = "Ti stai già connettendo tramite questo link una tantum!";
/* No comment provided by engineer. */
"You are already in group %@." = "Sei già nel gruppo %@.";
/* No comment provided by engineer. */
"You are already joining the group %@." = "Stai già entrando nel gruppo %@.";
/* No comment provided by engineer. */
"You are already joining the group via this link!" = "Stai già entrando nel gruppo tramite questo link!";
/* No comment provided by engineer. */
"You are already joining the group via this link." = "Stai già entrando nel gruppo tramite questo link.";
/* No comment provided by engineer. */
"You are already joining the group!\nRepeat join request?" = "Stai già entrando nel gruppo!\nRipetere la richiesta di ingresso?";
/* No comment provided by engineer. */
"You are connected to the server used to receive messages from this contact." = "Sei connesso/a al server usato per ricevere messaggi da questo contatto.";
@@ -3548,6 +3836,12 @@
/* No comment provided by engineer. */
"You could not be verified; please try again." = "Non è stato possibile verificarti, riprova.";
/* No comment provided by engineer. */
"You have already requested connection via this address!" = "Hai già richiesto la connessione tramite questo indirizzo!";
/* No comment provided by engineer. */
"You have already requested connection!\nRepeat connection request?" = "Hai già richiesto la connessione!\nRipetere la richiesta di connessione?";
/* No comment provided by engineer. */
"You have no chats" = "Non hai chat";
@@ -3590,6 +3884,9 @@
/* No comment provided by engineer. */
"You will be connected to group when the group host's device is online, please wait or check later!" = "Verrai connesso/a al gruppo quando il dispositivo dell'host del gruppo sarà in linea, attendi o controlla più tardi!";
/* No comment provided by engineer. */
"You will be connected when group link host's device is online, please wait or check later!" = "Verrai connesso/a quando il dispositivo dell'host del gruppo sarà in linea, attendi o controlla più tardi!";
/* No comment provided by engineer. */
"You will be connected when your connection request is accepted, please wait or check later!" = "Verrai connesso/a quando la tua richiesta di connessione verrà accettata, attendi o controlla più tardi!";
@@ -3599,6 +3896,9 @@
/* No comment provided by engineer. */
"You will be required to authenticate when you start or resume the app after 30 seconds in background." = "Dovrai autenticarti quando avvii o riapri l'app dopo 30 secondi in secondo piano.";
/* No comment provided by engineer. */
"You will connect to all group members." = "Ti connetterai a tutti i membri del gruppo.";
/* No comment provided by engineer. */
"You will still receive calls and notifications from muted profiles when they are active." = "Continuerai a ricevere chiamate e notifiche da profili silenziati quando sono attivi.";
@@ -3662,6 +3962,9 @@
/* No comment provided by engineer. */
"Your privacy" = "La tua privacy";
/* No comment provided by engineer. */
"Your profile" = "Il tuo profilo";
/* No comment provided by engineer. */
"Your profile **%@** will be shared." = "Il tuo profilo **%@** verrà condiviso.";

View File

@@ -7,6 +7,9 @@
/* Privacy - Face ID Usage Description */
"NSFaceIDUsageDescription" = "SimpleX usa Face ID per l'autenticazione locale";
/* Privacy - Local Network Usage Description */
"NSLocalNetworkUsageDescription" = "SimpleX usa l'accesso alla rete locale per consentire di usare il profilo di chat tramite l'app desktop sulla stessa rete.";
/* Privacy - Microphone Usage Description */
"NSMicrophoneUsageDescription" = "SimpleX ha bisogno dell'accesso al microfono per le chiamate audio e video e per registrare messaggi vocali.";

View File

@@ -25,6 +25,9 @@
/* No comment provided by engineer. */
"- more stable message delivery.\n- a bit better groups.\n- and more!" = "- stabielere berichtbezorging.\n- een beetje betere groepen.\n- en meer!";
/* No comment provided by engineer. */
"- optionally notify deleted contacts.\n- profile names with spaces.\n- and more!" = "- optioneel verwijderde contacten op de hoogte stellen.\n- profielnamen met spaties.\n- en meer!";
/* No comment provided by engineer. */
"- voice messages up to 5 minutes.\n- custom time to disappear.\n- editing history." = "- spraakberichten tot 5 minuten.\n- aangepaste tijd om te verdwijnen.\n- bewerkingsgeschiedenis.";
@@ -43,6 +46,12 @@
/* No comment provided by engineer. */
"(" = "(";
/* No comment provided by engineer. */
"(new)" = "(nieuw)";
/* No comment provided by engineer. */
"(this device v%@)" = "(dit apparaat v%@)";
/* No comment provided by engineer. */
")" = ")";
@@ -118,12 +127,18 @@
/* No comment provided by engineer. */
"%@ %@" = "%@ %@";
/* No comment provided by engineer. */
"%@ and %@" = "%@ en %@";
/* No comment provided by engineer. */
"%@ and %@ connected" = "%@ en %@ verbonden";
/* copied message info, <sender> at <time> */
"%@ at %@:" = "%1$@ bij %2$@:";
/* No comment provided by engineer. */
"%@ connected" = "%@ verbonden";
/* notification title */
"%@ is connected!" = "%@ is verbonden!";
@@ -139,6 +154,9 @@
/* notification title */
"%@ wants to connect!" = "%@ wil verbinding maken!";
/* No comment provided by engineer. */
"%@, %@ and %lld members" = "%@, %@ en %lld leden";
/* No comment provided by engineer. */
"%@, %@ and %lld other members connected" = "%@, %@ en %lld andere leden hebben verbinding gemaakt";
@@ -178,9 +196,21 @@
/* No comment provided by engineer. */
"%lld file(s) with total size of %@" = "%lld bestand(en) met een totale grootte van %@";
/* No comment provided by engineer. */
"%lld group events" = "%lld groep gebeurtenissen";
/* No comment provided by engineer. */
"%lld members" = "%lld leden";
/* No comment provided by engineer. */
"%lld messages blocked" = "%lld berichten geblokkeerd";
/* No comment provided by engineer. */
"%lld messages marked deleted" = "%lld berichten gemarkeerd als verwijderd";
/* No comment provided by engineer. */
"%lld messages moderated by %@" = "%lld berichten gemodereerd door %@";
/* No comment provided by engineer. */
"%lld minutes" = "%lld minuten";
@@ -229,6 +259,9 @@
/* No comment provided by engineer. */
"~strike~" = "\\~staking~";
/* time to disappear */
"0 sec" = "0 sec";
/* No comment provided by engineer. */
"0s" = "0s";
@@ -371,6 +404,9 @@
/* No comment provided by engineer. */
"All messages will be deleted - this cannot be undone! The messages will be deleted ONLY for you." = "Alle berichten worden verwijderd, dit kan niet ongedaan worden gemaakt! De berichten worden ALLEEN voor jou verwijderd.";
/* No comment provided by engineer. */
"All new messages from %@ will be hidden!" = "Alle nieuwe berichten van %@ worden verborgen!";
/* No comment provided by engineer. */
"All your contacts will remain connected." = "Al uw contacten blijven verbonden.";
@@ -434,6 +470,12 @@
/* No comment provided by engineer. */
"Already connected?" = "Al verbonden?";
/* No comment provided by engineer. */
"Already connecting!" = "Al bezig met verbinden!";
/* No comment provided by engineer. */
"Already joining the group!" = "Al lid van de groep!";
/* pref value */
"always" = "altijd";
@@ -443,6 +485,9 @@
/* No comment provided by engineer. */
"An empty chat profile with the provided name is created, and the app opens as usual." = "Er wordt een leeg chatprofiel met de opgegeven naam gemaakt en de app wordt zoals gewoonlijk geopend.";
/* No comment provided by engineer. */
"and %lld other events" = "en %lld andere gebeurtenissen";
/* No comment provided by engineer. */
"Answer call" = "Beantwoord oproep";
@@ -500,6 +545,9 @@
/* No comment provided by engineer. */
"Authentication unavailable" = "Verificatie niet beschikbaar";
/* member role */
"author" = "auteur";
/* No comment provided by engineer. */
"Auto-accept" = "Automatisch accepteren";
@@ -512,6 +560,9 @@
/* No comment provided by engineer. */
"Back" = "Terug";
/* No comment provided by engineer. */
"Bad desktop address" = "Onjuist desktopadres";
/* integrity error chat item */
"bad message hash" = "Onjuiste bericht hash";
@@ -524,9 +575,27 @@
/* No comment provided by engineer. */
"Bad message ID" = "Onjuiste bericht-ID";
/* No comment provided by engineer. */
"Better groups" = "Betere groepen";
/* No comment provided by engineer. */
"Better messages" = "Betere berichten";
/* No comment provided by engineer. */
"Block" = "Blokkeren";
/* No comment provided by engineer. */
"Block group members" = "Groepsleden blokkeren";
/* No comment provided by engineer. */
"Block member" = "Lid blokkeren";
/* No comment provided by engineer. */
"Block member?" = "Lid blokkeren?";
/* No comment provided by engineer. */
"blocked" = "geblokkeerd";
/* No comment provided by engineer. */
"bold" = "vetgedrukt";
@@ -597,7 +666,7 @@
"Change lock mode" = "Wijzig de vergrendelings modus";
/* No comment provided by engineer. */
"Change member role?" = "Rol van gebruiker wijzigen?";
"Change member role?" = "Rol van lid wijzigen?";
/* authentication reason */
"Change passcode" = "Toegangscode wijzigen";
@@ -720,12 +789,30 @@
/* server test step */
"Connect" = "Verbind";
/* No comment provided by engineer. */
"Connect automatically" = "Automatisch verbinden";
/* No comment provided by engineer. */
"Connect incognito" = "Verbind incognito";
/* No comment provided by engineer. */
"Connect to desktop" = "Verbinden met desktop";
/* No comment provided by engineer. */
"connect to SimpleX Chat developers." = "maak verbinding met SimpleX Chat-ontwikkelaars.";
/* No comment provided by engineer. */
"Connect to yourself?" = "Verbinding maken met jezelf?";
/* No comment provided by engineer. */
"Connect to yourself?\nThis is your own one-time link!" = "Verbinding maken met jezelf?\nDit is uw eigen eenmalige link!";
/* No comment provided by engineer. */
"Connect to yourself?\nThis is your own SimpleX address!" = "Verbinding maken met jezelf?\nDit is uw eigen SimpleX adres!";
/* No comment provided by engineer. */
"Connect via contact address" = "Verbinding maken via contactadres";
/* No comment provided by engineer. */
"Connect via link" = "Maak verbinding via link";
@@ -735,12 +822,21 @@
/* No comment provided by engineer. */
"Connect via one-time link" = "Verbinden via een eenmalige link?";
/* No comment provided by engineer. */
"Connect with %@" = "Verbonden met %@";
/* No comment provided by engineer. */
"connected" = "verbonden";
/* No comment provided by engineer. */
"Connected desktop" = "Verbonden desktop";
/* rcv group event chat item */
"connected directly" = "direct verbonden";
/* No comment provided by engineer. */
"Connected to desktop" = "Verbonden met desktop";
/* No comment provided by engineer. */
"connecting" = "Verbinden";
@@ -765,6 +861,9 @@
/* No comment provided by engineer. */
"Connecting server… (error: %@)" = "Verbinden met server... (fout: %@)";
/* No comment provided by engineer. */
"Connecting to desktop" = "Verbinding maken met desktop";
/* chat list item title */
"connecting…" = "Verbinden…";
@@ -783,6 +882,9 @@
/* No comment provided by engineer. */
"Connection request sent!" = "Verbindingsverzoek verzonden!";
/* No comment provided by engineer. */
"Connection terminated" = "Verbinding beëindigd";
/* No comment provided by engineer. */
"Connection timeout" = "Timeout verbinding";
@@ -831,15 +933,24 @@
/* No comment provided by engineer. */
"Core version: v%@" = "Core versie: v% @";
/* No comment provided by engineer. */
"Correct name to %@?" = "Juiste naam voor %@?";
/* No comment provided by engineer. */
"Create" = "Maak";
/* No comment provided by engineer. */
"Create a group using a random profile." = "Maak een groep met een willekeurig profiel.";
/* No comment provided by engineer. */
"Create an address to let people connect with you." = "Maak een adres aan zodat mensen contact met je kunnen opnemen.";
/* server test step */
"Create file" = "Bestand maken";
/* No comment provided by engineer. */
"Create group" = "Groep aanmaken";
/* No comment provided by engineer. */
"Create group link" = "Groep link maken";
@@ -852,6 +963,9 @@
/* No comment provided by engineer. */
"Create one-time invitation link" = "Maak een eenmalige uitnodiging link";
/* No comment provided by engineer. */
"Create profile" = "Maak een profiel aan";
/* server test step */
"Create queue" = "Maak een wachtrij";
@@ -966,6 +1080,9 @@
/* chat item action */
"Delete" = "Verwijderen";
/* No comment provided by engineer. */
"Delete %lld messages?" = "%lld berichten verwijderen?";
/* No comment provided by engineer. */
"Delete address" = "Adres verwijderen";
@@ -978,6 +1095,9 @@
/* No comment provided by engineer. */
"Delete all files" = "Verwijder alle bestanden";
/* No comment provided by engineer. */
"Delete and notify contact" = "Contact verwijderen en op de hoogte stellen";
/* No comment provided by engineer. */
"Delete archive" = "Archief verwijderen";
@@ -999,6 +1119,9 @@
/* No comment provided by engineer. */
"Delete Contact" = "Verwijder contact";
/* No comment provided by engineer. */
"Delete contact?\nThis cannot be undone!" = "Verwijder contact?\nDit kan niet ongedaan gemaakt worden!";
/* No comment provided by engineer. */
"Delete database" = "Database verwijderen";
@@ -1074,6 +1197,9 @@
/* copied message info */
"Deleted at: %@" = "Verwijderd om: %@";
/* rcv direct event chat item */
"deleted contact" = "verwijderd contact";
/* rcv group event chat item */
"deleted group" = "verwijderde groep";
@@ -1089,6 +1215,15 @@
/* No comment provided by engineer. */
"Description" = "Beschrijving";
/* No comment provided by engineer. */
"Desktop address" = "Desktop adres";
/* No comment provided by engineer. */
"Desktop app version %@ is not compatible with this app." = "Desktop-app-versie %@ is niet compatibel met deze app.";
/* No comment provided by engineer. */
"Desktop devices" = "Desktop apparaten";
/* No comment provided by engineer. */
"Develop" = "Ontwikkelen";
@@ -1152,9 +1287,15 @@
/* server test step */
"Disconnect" = "verbinding verbreken";
/* No comment provided by engineer. */
"Disconnect desktop?" = "Desktop loskoppelen?";
/* No comment provided by engineer. */
"Discover and join groups" = "Ontdek en sluit je aan bij groepen";
/* No comment provided by engineer. */
"Discover via local network" = "Ontdek via het lokale netwerk";
/* No comment provided by engineer. */
"Do it later" = "Doe het later";
@@ -1290,6 +1431,12 @@
/* chat item text */
"encryption re-negotiation allowed for %@" = "versleuteling heronderhandeling toegestaan voor % @";
/* message decrypt error item */
"Encryption re-negotiation error" = "Fout bij heronderhandeling van codering";
/* No comment provided by engineer. */
"Encryption re-negotiation failed." = "Opnieuw onderhandelen over de codering is mislukt.";
/* chat item text */
"encryption re-negotiation required" = "heronderhandeling van versleuteling vereist";
@@ -1305,6 +1452,9 @@
/* No comment provided by engineer. */
"Enter correct passphrase." = "Voer het juiste wachtwoord in.";
/* No comment provided by engineer. */
"Enter group name…" = "Groep naam invoeren…";
/* No comment provided by engineer. */
"Enter Passcode" = "Voer toegangscode in";
@@ -1317,12 +1467,18 @@
/* No comment provided by engineer. */
"Enter server manually" = "Voer de server handmatig in";
/* No comment provided by engineer. */
"Enter this device name…" = "Voer deze apparaatnaam in…";
/* placeholder */
"Enter welcome message…" = "Welkomst bericht invoeren…";
/* placeholder */
"Enter welcome message… (optional)" = "Voer welkomst bericht in... (optioneel)";
/* No comment provided by engineer. */
"Enter your name…" = "Vul uw naam in…";
/* No comment provided by engineer. */
"error" = "fout";
@@ -1339,7 +1495,7 @@
"Error accessing database file" = "Fout bij toegang tot database bestand";
/* No comment provided by engineer. */
"Error adding member(s)" = "Fout bij het toevoegen van gebruiker(s)";
"Error adding member(s)" = "Fout bij het toevoegen van leden";
/* No comment provided by engineer. */
"Error changing address" = "Fout bij wijzigen van adres";
@@ -1417,7 +1573,7 @@
"Error receiving file" = "Fout bij ontvangen van bestand";
/* No comment provided by engineer. */
"Error removing member" = "Fout bij verwijderen van gebruiker";
"Error removing member" = "Fout bij verwijderen van lid";
/* No comment provided by engineer. */
"Error saving %@ servers" = "Fout bij opslaan van %@ servers";
@@ -1494,6 +1650,9 @@
/* No comment provided by engineer. */
"Exit without saving" = "Afsluiten zonder opslaan";
/* chat item action */
"Expand" = "Uitbreiden";
/* No comment provided by engineer. */
"Export database" = "Database exporteren";
@@ -1512,6 +1671,9 @@
/* No comment provided by engineer. */
"Fast and no wait until the sender is online!" = "Snel en niet wachten tot de afzender online is!";
/* No comment provided by engineer. */
"Faster joining and more reliable messages." = "Snellere deelname en betrouwbaardere berichten.";
/* No comment provided by engineer. */
"Favorite" = "Favoriet";
@@ -1569,6 +1731,9 @@
/* No comment provided by engineer. */
"For console" = "Voor console";
/* No comment provided by engineer. */
"Found desktop" = "Desktop gevonden";
/* No comment provided by engineer. */
"French interface" = "Franse interface";
@@ -1581,6 +1746,9 @@
/* No comment provided by engineer. */
"Full name:" = "Volledige naam:";
/* No comment provided by engineer. */
"Fully decentralized visible only to members." = "Volledig gedecentraliseerd alleen zichtbaar voor leden.";
/* No comment provided by engineer. */
"Fully re-implemented - work in background!" = "Volledig opnieuw geïmplementeerd - werk op de achtergrond!";
@@ -1593,6 +1761,12 @@
/* No comment provided by engineer. */
"Group" = "Groep";
/* No comment provided by engineer. */
"Group already exists" = "Groep bestaat al";
/* No comment provided by engineer. */
"Group already exists!" = "Groep bestaat al!";
/* No comment provided by engineer. */
"group deleted" = "groep verwijderd";
@@ -1764,6 +1938,9 @@
/* No comment provided by engineer. */
"Incognito" = "Incognito";
/* No comment provided by engineer. */
"Incognito groups" = "Incognitogroepen";
/* No comment provided by engineer. */
"Incognito mode" = "Incognito modus";
@@ -1791,6 +1968,9 @@
/* No comment provided by engineer. */
"Incompatible database version" = "Incompatibele database versie";
/* No comment provided by engineer. */
"Incompatible version" = "Incompatibele versie";
/* PIN entry */
"Incorrect passcode" = "Onjuiste toegangscode";
@@ -1830,6 +2010,9 @@
/* invalid chat item */
"invalid data" = "ongeldige gegevens";
/* No comment provided by engineer. */
"Invalid name!" = "Ongeldige naam!";
/* No comment provided by engineer. */
"Invalid server address!" = "Ongeldig server adres!";
@@ -1908,12 +2091,24 @@
/* No comment provided by engineer. */
"Join group" = "Word lid van groep";
/* No comment provided by engineer. */
"Join group?" = "Deelnemen aan groep?";
/* No comment provided by engineer. */
"Join incognito" = "Doe incognito mee";
/* No comment provided by engineer. */
"Join with current profile" = "Word lid met huidig profiel";
/* No comment provided by engineer. */
"Join your group?\nThis is your link for group %@!" = "Sluit u aan bij uw groep?\nDit is jouw link voor groep %@!";
/* No comment provided by engineer. */
"Joining group" = "Deel nemen aan groep";
/* No comment provided by engineer. */
"Keep the app open to use it from desktop" = "Houd de app geopend om deze vanaf de desktop te gebruiken";
/* No comment provided by engineer. */
"Keep your connections" = "Behoud uw verbindingen";
@@ -1950,6 +2145,15 @@
/* No comment provided by engineer. */
"Limitations" = "Beperkingen";
/* No comment provided by engineer. */
"Link mobile and desktop apps! 🔗" = "Koppel mobiele en desktop-apps! 🔗";
/* No comment provided by engineer. */
"Linked desktop options" = "Gekoppelde desktop opties";
/* No comment provided by engineer. */
"Linked desktops" = "Gelinkte desktops";
/* No comment provided by engineer. */
"LIVE" = "LIVE";
@@ -2008,22 +2212,22 @@
"Max 30 seconds, received instantly." = "Max 30 seconden, direct ontvangen.";
/* member role */
"member" = "gebruiker";
"member" = "lid";
/* No comment provided by engineer. */
"Member" = "Gebruiker";
"Member" = "Lid";
/* rcv group event chat item */
"member connected" = "is toegetreden";
/* No comment provided by engineer. */
"Member role will be changed to \"%@\". All group members will be notified." = "De rol van gebruiker wordt gewijzigd in \"%@\". Alle groepsleden worden op de hoogte gebracht.";
"Member role will be changed to \"%@\". All group members will be notified." = "De rol van lid wordt gewijzigd in \"%@\". Alle groepsleden worden op de hoogte gebracht.";
/* No comment provided by engineer. */
"Member role will be changed to \"%@\". The member will receive a new invitation." = "De rol van gebruiker wordt gewijzigd in \"%@\". Het lid ontvangt een nieuwe uitnodiging.";
"Member role will be changed to \"%@\". The member will receive a new invitation." = "De rol van lid wordt gewijzigd in \"%@\". Het lid ontvangt een nieuwe uitnodiging.";
/* No comment provided by engineer. */
"Member will be removed from group - this cannot be undone!" = "Gebruiker wordt uit de groep verwijderd, dit kan niet ongedaan worden gemaakt!";
"Member will be removed from group - this cannot be undone!" = "Lid wordt uit de groep verwijderd, dit kan niet ongedaan worden gemaakt!";
/* item status text */
"Message delivery error" = "Fout bij bezorging van bericht";
@@ -2055,6 +2259,9 @@
/* No comment provided by engineer. */
"Messages & files" = "Berichten";
/* No comment provided by engineer. */
"Messages from %@ will be shown!" = "Berichten van %@ worden getoond!";
/* No comment provided by engineer. */
"Migrating database archive…" = "Database archief migreren…";
@@ -2202,6 +2409,9 @@
/* copied message info in history */
"no text" = "geen tekst";
/* No comment provided by engineer. */
"Not compatible!" = "Niet compatibel!";
/* No comment provided by engineer. */
"Notifications" = "Meldingen";
@@ -2262,7 +2472,7 @@
"Only group owners can change group preferences." = "Alleen groep eigenaren kunnen groep voorkeuren wijzigen.";
/* No comment provided by engineer. */
"Only group owners can enable files and media." = "Alleen groepseigenaren kunnen bestanden en media inschakelen.";
"Only group owners can enable files and media." = "Alleen groep eigenaren kunnen bestanden en media inschakelen.";
/* No comment provided by engineer. */
"Only group owners can enable voice messages." = "Alleen groep eigenaren kunnen spraak berichten inschakelen.";
@@ -2306,6 +2516,9 @@
/* authentication reason */
"Open chat console" = "Chat console openen";
/* No comment provided by engineer. */
"Open group" = "Open groep";
/* No comment provided by engineer. */
"Open Settings" = "Open instellingen";
@@ -2342,6 +2555,9 @@
/* No comment provided by engineer. */
"Paste" = "Plakken";
/* No comment provided by engineer. */
"Paste desktop address" = "Desktopadres plakken";
/* No comment provided by engineer. */
"Paste image" = "Afbeelding plakken";
@@ -2438,6 +2654,12 @@
/* No comment provided by engineer. */
"Profile image" = "profielfoto";
/* No comment provided by engineer. */
"Profile name" = "Profielnaam";
/* No comment provided by engineer. */
"Profile name:" = "Profielnaam:";
/* No comment provided by engineer. */
"Profile password" = "Profiel wachtwoord";
@@ -2577,10 +2799,10 @@
"Remove" = "Verwijderen";
/* No comment provided by engineer. */
"Remove member" = "Gebruiker verwijderen";
"Remove member" = "Lid verwijderen";
/* No comment provided by engineer. */
"Remove member?" = "Gebruiker verwijderen?";
"Remove member?" = "Lid verwijderen?";
/* No comment provided by engineer. */
"Remove passphrase from keychain?" = "Wachtwoord van de keychain verwijderen?";
@@ -2603,6 +2825,12 @@
/* No comment provided by engineer. */
"Renegotiate encryption?" = "Heronderhandelen over versleuteling?";
/* No comment provided by engineer. */
"Repeat connection request?" = "Verbindingsverzoek herhalen?";
/* No comment provided by engineer. */
"Repeat join request?" = "Deelnameverzoek herhalen?";
/* chat item action */
"Reply" = "Antwoord";
@@ -2667,7 +2895,7 @@
"Save and notify contact" = "Opslaan en Contact melden";
/* No comment provided by engineer. */
"Save and notify group members" = "Opslaan en Groep leden melden";
"Save and notify group members" = "Opslaan en groep leden melden";
/* No comment provided by engineer. */
"Save and update group profile" = "Groep profiel opslaan en bijwerken";
@@ -2714,6 +2942,9 @@
/* No comment provided by engineer. */
"Scan QR code" = "Scan QR-code";
/* No comment provided by engineer. */
"Scan QR code from desktop" = "Scan QR-code vanaf uw desktop";
/* No comment provided by engineer. */
"Scan security code from your contact's app." = "Scan de beveiligingscode van de app van uw contact.";
@@ -2858,6 +3089,9 @@
/* No comment provided by engineer. */
"Servers" = "Servers";
/* No comment provided by engineer. */
"Session code" = "Sessie code";
/* No comment provided by engineer. */
"Set 1 day" = "Stel 1 dag in";
@@ -3045,10 +3279,13 @@
"Tap to activate profile." = "Tik om profiel te activeren.";
/* No comment provided by engineer. */
"Tap to join" = "Tik om mee te doen";
"Tap to Connect" = "Tik om verbinding te maken";
/* No comment provided by engineer. */
"Tap to join incognito" = "Tik om incognito deel te nemen";
"Tap to join" = "Tik om lid te worden";
/* No comment provided by engineer. */
"Tap to join incognito" = "Tik om incognito lid te worden";
/* No comment provided by engineer. */
"Tap to start a new chat" = "Tik om een nieuw gesprek te starten";
@@ -3164,12 +3401,21 @@
/* notification title */
"this contact" = "dit contact";
/* No comment provided by engineer. */
"This device name" = "Deze apparaatnaam";
/* No comment provided by engineer. */
"This group has over %lld members, delivery receipts are not sent." = "Deze groep heeft meer dan %lld -leden, ontvangstbevestigingen worden niet verzonden.";
/* No comment provided by engineer. */
"This group no longer exists." = "Deze groep bestaat niet meer.";
/* No comment provided by engineer. */
"This is your own one-time link!" = "Dit is uw eigen eenmalige link!";
/* No comment provided by engineer. */
"This is your own SimpleX address!" = "Dit is uw eigen SimpleX adres!";
/* No comment provided by engineer. */
"This setting applies to messages in your current chat profile **%@**." = "Deze instelling is van toepassing op berichten in je huidige chat profiel **%@**.";
@@ -3179,6 +3425,9 @@
/* No comment provided by engineer. */
"To connect, your contact can scan QR code or use the link in the app." = "Om verbinding te maken, kan uw contact de QR-code scannen of de link in de app gebruiken.";
/* No comment provided by engineer. */
"To hide unwanted messages." = "Om ongewenste berichten te verbergen.";
/* No comment provided by engineer. */
"To make a new connection" = "Om een nieuwe verbinding te maken";
@@ -3227,6 +3476,15 @@
/* No comment provided by engineer. */
"Unable to record voice message" = "Kan spraakbericht niet opnemen";
/* No comment provided by engineer. */
"Unblock" = "Deblokkeren";
/* No comment provided by engineer. */
"Unblock member" = "Lid deblokkeren";
/* No comment provided by engineer. */
"Unblock member?" = "Lid deblokkeren?";
/* item status description */
"Unexpected error: %@" = "Onverwachte fout: %@";
@@ -3266,6 +3524,12 @@
/* No comment provided by engineer. */
"Unless your contact deleted the connection or this link was already used, it might be a bug - please report it.\nTo connect, please ask your contact to create another connection link and check that you have a stable network connection." = "Tenzij uw contact de verbinding heeft verwijderd of deze link al is gebruikt, kan het een bug zijn. Meld het alstublieft.\nOm verbinding te maken, vraagt u uw contact om een andere verbinding link te maken en te controleren of u een stabiele netwerkverbinding heeft.";
/* No comment provided by engineer. */
"Unlink" = "Ontkoppelen";
/* No comment provided by engineer. */
"Unlink desktop?" = "Desktop ontkoppelen?";
/* No comment provided by engineer. */
"Unlock" = "Ontgrendelen";
@@ -3320,6 +3584,9 @@
/* No comment provided by engineer. */
"Use for new connections" = "Gebruik voor nieuwe verbindingen";
/* No comment provided by engineer. */
"Use from desktop" = "Gebruik vanaf desktop";
/* No comment provided by engineer. */
"Use iOS call interface" = "De iOS-oproepinterface gebruiken";
@@ -3341,12 +3608,24 @@
/* No comment provided by engineer. */
"Using SimpleX Chat servers." = "SimpleX Chat servers gebruiken.";
/* No comment provided by engineer. */
"v%@" = "v%@";
/* No comment provided by engineer. */
"v%@ (%@)" = "v%@ (%@)";
/* No comment provided by engineer. */
"Verify code with desktop" = "Code verifiëren met desktop";
/* No comment provided by engineer. */
"Verify connection" = "Controleer de verbinding";
/* No comment provided by engineer. */
"Verify connection security" = "Controleer de verbindingsbeveiliging";
/* No comment provided by engineer. */
"Verify connections" = "Controleer verbindingen";
/* No comment provided by engineer. */
"Verify security code" = "Controleer de beveiligingscode";
@@ -3365,6 +3644,9 @@
/* No comment provided by engineer. */
"via relay" = "via relais";
/* No comment provided by engineer. */
"Via secure quantum resistant protocol." = "Via een beveiligd kwantumbestendig protocol.";
/* No comment provided by engineer. */
"Video call" = "video oproep";
@@ -3404,6 +3686,9 @@
/* No comment provided by engineer. */
"waiting for confirmation…" = "Wachten op bevestiging…";
/* No comment provided by engineer. */
"Waiting for desktop..." = "Wachten op desktop...";
/* No comment provided by engineer. */
"Waiting for file" = "Wachten op bestand";
@@ -3473,6 +3758,27 @@
/* No comment provided by engineer. */
"You are already connected to %@." = "U bent al verbonden met %@.";
/* No comment provided by engineer. */
"You are already connecting to %@." = "U maakt al verbinding met %@.";
/* No comment provided by engineer. */
"You are already connecting via this one-time link!" = "Je maakt al verbinding via deze eenmalige link!";
/* No comment provided by engineer. */
"You are already in group %@." = "Je zit al in groep %@.";
/* No comment provided by engineer. */
"You are already joining the group %@." = "Je bent al lid van de groep %@.";
/* No comment provided by engineer. */
"You are already joining the group via this link!" = "Je wordt al lid van de groep via deze link!";
/* No comment provided by engineer. */
"You are already joining the group via this link." = "Je wordt al lid van de groep via deze link.";
/* No comment provided by engineer. */
"You are already joining the group!\nRepeat join request?" = "Je sluit je al aan bij de groep!\nDeelnameverzoek herhalen?";
/* No comment provided by engineer. */
"You are connected to the server used to receive messages from this contact." = "U bent verbonden met de server die wordt gebruikt om berichten van dit contact te ontvangen.";
@@ -3548,6 +3854,12 @@
/* No comment provided by engineer. */
"You could not be verified; please try again." = "U kon niet worden geverifieerd; probeer het opnieuw.";
/* No comment provided by engineer. */
"You have already requested connection via this address!" = "U heeft al een verbinding aangevraagd via dit adres!";
/* No comment provided by engineer. */
"You have already requested connection!\nRepeat connection request?" = "Je hebt al verbinding aangevraagd!\nVerbindingsverzoek herhalen?";
/* No comment provided by engineer. */
"You have no chats" = "Je hebt geen gesprekken";
@@ -3590,6 +3902,9 @@
/* No comment provided by engineer. */
"You will be connected to group when the group host's device is online, please wait or check later!" = "Je wordt verbonden met de groep wanneer het apparaat van de groep host online is, even geduld a.u.b. of controleer het later!";
/* No comment provided by engineer. */
"You will be connected when group link host's device is online, please wait or check later!" = "U wordt verbonden wanneer het apparaat van de groep link host online is. Wacht even of controleer het later opnieuw!";
/* No comment provided by engineer. */
"You will be connected when your connection request is accepted, please wait or check later!" = "U wordt verbonden wanneer uw verbindingsverzoek wordt geaccepteerd, even geduld a.u.b. of controleer later!";
@@ -3599,6 +3914,9 @@
/* No comment provided by engineer. */
"You will be required to authenticate when you start or resume the app after 30 seconds in background." = "U moet zich authenticeren wanneer u de app na 30 seconden op de achtergrond start of hervat.";
/* No comment provided by engineer. */
"You will connect to all group members." = "Je maakt verbinding met alle leden.";
/* No comment provided by engineer. */
"You will still receive calls and notifications from muted profiles when they are active." = "U ontvangt nog steeds oproepen en meldingen van gedempte profielen wanneer deze actief zijn.";
@@ -3662,6 +3980,9 @@
/* No comment provided by engineer. */
"Your privacy" = "Uw privacy";
/* No comment provided by engineer. */
"Your profile" = "Jouw profiel";
/* No comment provided by engineer. */
"Your profile **%@** will be shared." = "Uw profiel **%@** wordt gedeeld.";

View File

@@ -7,6 +7,9 @@
/* Privacy - Face ID Usage Description */
"NSFaceIDUsageDescription" = "SimpleX gebruikt Face-ID voor lokale authenticatie";
/* Privacy - Local Network Usage Description */
"NSLocalNetworkUsageDescription" = "SimpleX maakt gebruik van lokale netwerktoegang om het gebruik van een gebruikerschatprofiel via de desktop-app op hetzelfde netwerk mogelijk te maken.";
/* Privacy - Microphone Usage Description */
"NSMicrophoneUsageDescription" = "SimpleX heeft microfoon toegang nodig voor audio en video oproepen en om spraak berichten op te nemen.";

View File

@@ -25,6 +25,9 @@
/* No comment provided by engineer. */
"- more stable message delivery.\n- a bit better groups.\n- and more!" = "- bardziej stabilne dostarczanie wiadomości.\n- nieco lepsze grupy.\n- i więcej!";
/* No comment provided by engineer. */
"- optionally notify deleted contacts.\n- profile names with spaces.\n- and more!" = "- opcjonalnie powiadamiaj usunięte kontakty.\n- nazwy profili ze spacją.\n- i wiele więcej!";
/* No comment provided by engineer. */
"- voice messages up to 5 minutes.\n- custom time to disappear.\n- editing history." = "- wiadomości głosowe do 5 minut.\n- niestandardowy czas zniknięcia.\n- historia edycji.";
@@ -43,6 +46,12 @@
/* No comment provided by engineer. */
"(" = "(";
/* No comment provided by engineer. */
"(new)" = "(nowy)";
/* No comment provided by engineer. */
"(this device v%@)" = "(to urządzenie v%@)";
/* No comment provided by engineer. */
")" = ")";
@@ -118,12 +127,18 @@
/* No comment provided by engineer. */
"%@ %@" = "%@ %@";
/* No comment provided by engineer. */
"%@ and %@" = "%@ i %@";
/* No comment provided by engineer. */
"%@ and %@ connected" = "%@ i %@ połączeni";
/* copied message info, <sender> at <time> */
"%@ at %@:" = "%1$@ o %2$@:";
/* No comment provided by engineer. */
"%@ connected" = "%@ połączony";
/* notification title */
"%@ is connected!" = "%@ jest połączony!";
@@ -139,6 +154,9 @@
/* notification title */
"%@ wants to connect!" = "%@ chce się połączyć!";
/* No comment provided by engineer. */
"%@, %@ and %lld members" = "%@, %@ i %lld członków";
/* No comment provided by engineer. */
"%@, %@ and %lld other members connected" = "%@, %@ i %lld innych członków połączeni";
@@ -178,9 +196,21 @@
/* No comment provided by engineer. */
"%lld file(s) with total size of %@" = "%lld plik(i) o całkowitym rozmiarze %@";
/* No comment provided by engineer. */
"%lld group events" = "%lld wydarzeń grupy";
/* No comment provided by engineer. */
"%lld members" = "%lld członków";
/* No comment provided by engineer. */
"%lld messages blocked" = "%lld wiadomości zablokowanych";
/* No comment provided by engineer. */
"%lld messages marked deleted" = "%lld wiadomości oznaczonych do usunięcia";
/* No comment provided by engineer. */
"%lld messages moderated by %@" = "%lld wiadomości zmoderowanych przez %@";
/* No comment provided by engineer. */
"%lld minutes" = "%lld minut";
@@ -229,6 +259,9 @@
/* No comment provided by engineer. */
"~strike~" = "\\~strajk~";
/* time to disappear */
"0 sec" = "0 sek";
/* No comment provided by engineer. */
"0s" = "0s";
@@ -371,6 +404,9 @@
/* No comment provided by engineer. */
"All messages will be deleted - this cannot be undone! The messages will be deleted ONLY for you." = "Wszystkie wiadomości zostaną usunięte - nie można tego cofnąć! Wiadomości zostaną usunięte TYLKO dla Ciebie.";
/* No comment provided by engineer. */
"All new messages from %@ will be hidden!" = "Wszystkie nowe wiadomości z %@ zostaną ukryte!";
/* No comment provided by engineer. */
"All your contacts will remain connected." = "Wszystkie Twoje kontakty pozostaną połączone.";
@@ -434,6 +470,12 @@
/* No comment provided by engineer. */
"Already connected?" = "Już połączony?";
/* No comment provided by engineer. */
"Already connecting!" = "Już połączony!";
/* No comment provided by engineer. */
"Already joining the group!" = "Już dołączono do grupy!";
/* pref value */
"always" = "zawsze";
@@ -443,6 +485,9 @@
/* No comment provided by engineer. */
"An empty chat profile with the provided name is created, and the app opens as usual." = "Tworzony jest pusty profil czatu o podanej nazwie, a aplikacja otwiera się jak zwykle.";
/* No comment provided by engineer. */
"and %lld other events" = "i %lld innych wydarzeń";
/* No comment provided by engineer. */
"Answer call" = "Odbierz połączenie";
@@ -500,6 +545,9 @@
/* No comment provided by engineer. */
"Authentication unavailable" = "Uwierzytelnianie niedostępne";
/* member role */
"author" = "autor";
/* No comment provided by engineer. */
"Auto-accept" = "Automatycznie akceptuj";
@@ -512,6 +560,9 @@
/* No comment provided by engineer. */
"Back" = "Wstecz";
/* No comment provided by engineer. */
"Bad desktop address" = "Zły adres komputera";
/* integrity error chat item */
"bad message hash" = "zły hash wiadomości";
@@ -524,9 +575,27 @@
/* No comment provided by engineer. */
"Bad message ID" = "Zły identyfikator wiadomości";
/* No comment provided by engineer. */
"Better groups" = "Lepsze grupy";
/* No comment provided by engineer. */
"Better messages" = "Lepsze wiadomości";
/* No comment provided by engineer. */
"Block" = "Zablokuj";
/* No comment provided by engineer. */
"Block group members" = "Blokuj członków grupy";
/* No comment provided by engineer. */
"Block member" = "Zablokuj członka";
/* No comment provided by engineer. */
"Block member?" = "Zablokować członka?";
/* No comment provided by engineer. */
"blocked" = "zablokowany";
/* No comment provided by engineer. */
"bold" = "pogrubiona";
@@ -720,12 +789,30 @@
/* server test step */
"Connect" = "Połącz";
/* No comment provided by engineer. */
"Connect automatically" = "Łącz automatycznie";
/* No comment provided by engineer. */
"Connect incognito" = "Połącz incognito";
/* No comment provided by engineer. */
"Connect to desktop" = "Połącz do komputera";
/* No comment provided by engineer. */
"connect to SimpleX Chat developers." = "połącz się z deweloperami SimpleX Chat.";
/* No comment provided by engineer. */
"Connect to yourself?" = "Połączyć się ze sobą?";
/* No comment provided by engineer. */
"Connect to yourself?\nThis is your own one-time link!" = "Połączyć się ze sobą?\nTo jest twój jednorazowy link!";
/* No comment provided by engineer. */
"Connect to yourself?\nThis is your own SimpleX address!" = "Połączyć się ze sobą?\nTo jest twój własny adres SimpleX!";
/* No comment provided by engineer. */
"Connect via contact address" = "Połącz przez adres kontaktowy";
/* No comment provided by engineer. */
"Connect via link" = "Połącz się przez link";
@@ -735,12 +822,21 @@
/* No comment provided by engineer. */
"Connect via one-time link" = "Połącz przez jednorazowy link";
/* No comment provided by engineer. */
"Connect with %@" = "Połącz z %@";
/* No comment provided by engineer. */
"connected" = "połączony";
/* No comment provided by engineer. */
"Connected desktop" = "Połączony komputer";
/* rcv group event chat item */
"connected directly" = "połącz bezpośrednio";
/* No comment provided by engineer. */
"Connected to desktop" = "Połączony do komputera";
/* No comment provided by engineer. */
"connecting" = "łączenie";
@@ -765,6 +861,9 @@
/* No comment provided by engineer. */
"Connecting server… (error: %@)" = "Łączenie z serwerem... (błąd: %@)";
/* No comment provided by engineer. */
"Connecting to desktop" = "Łączenie z komputerem";
/* chat list item title */
"connecting…" = "łączenie…";
@@ -783,6 +882,9 @@
/* No comment provided by engineer. */
"Connection request sent!" = "Prośba o połączenie wysłana!";
/* No comment provided by engineer. */
"Connection terminated" = "Połączenie zakończone";
/* No comment provided by engineer. */
"Connection timeout" = "Czas połączenia minął";
@@ -831,15 +933,24 @@
/* No comment provided by engineer. */
"Core version: v%@" = "Wersja rdzenia: v%@";
/* No comment provided by engineer. */
"Correct name to %@?" = "Poprawić imię na %@?";
/* No comment provided by engineer. */
"Create" = "Utwórz";
/* No comment provided by engineer. */
"Create a group using a random profile." = "Utwórz grupę używając losowego profilu.";
/* No comment provided by engineer. */
"Create an address to let people connect with you." = "Utwórz adres, aby ludzie mogli się z Tobą połączyć.";
/* server test step */
"Create file" = "Utwórz plik";
/* No comment provided by engineer. */
"Create group" = "Utwórz grupę";
/* No comment provided by engineer. */
"Create group link" = "Utwórz link do grupy";
@@ -852,6 +963,9 @@
/* No comment provided by engineer. */
"Create one-time invitation link" = "Utwórz jednorazowy link do zaproszenia";
/* No comment provided by engineer. */
"Create profile" = "Utwórz profil";
/* server test step */
"Create queue" = "Utwórz kolejkę";
@@ -966,6 +1080,9 @@
/* chat item action */
"Delete" = "Usuń";
/* No comment provided by engineer. */
"Delete %lld messages?" = "Usunąć %lld wiadomości?";
/* No comment provided by engineer. */
"Delete address" = "Usuń adres";
@@ -978,6 +1095,9 @@
/* No comment provided by engineer. */
"Delete all files" = "Usuń wszystkie pliki";
/* No comment provided by engineer. */
"Delete and notify contact" = "Usuń i powiadom kontakt";
/* No comment provided by engineer. */
"Delete archive" = "Usuń archiwum";
@@ -999,6 +1119,9 @@
/* No comment provided by engineer. */
"Delete Contact" = "Usuń Kontakt";
/* No comment provided by engineer. */
"Delete contact?\nThis cannot be undone!" = "Usunąć kontakt?\nTo nie może być cofnięte!";
/* No comment provided by engineer. */
"Delete database" = "Usuń bazę danych";
@@ -1074,6 +1197,9 @@
/* copied message info */
"Deleted at: %@" = "Usunięto o: %@";
/* rcv direct event chat item */
"deleted contact" = "usunięto kontakt";
/* rcv group event chat item */
"deleted group" = "usunięta grupa";
@@ -1089,6 +1215,15 @@
/* No comment provided by engineer. */
"Description" = "Opis";
/* No comment provided by engineer. */
"Desktop address" = "Adres komputera";
/* No comment provided by engineer. */
"Desktop app version %@ is not compatible with this app." = "Wersja aplikacji komputerowej %@ nie jest kompatybilna z tą aplikacją.";
/* No comment provided by engineer. */
"Desktop devices" = "Urządzenia komputerowe";
/* No comment provided by engineer. */
"Develop" = "Deweloperskie";
@@ -1152,9 +1287,15 @@
/* server test step */
"Disconnect" = "Rozłącz";
/* No comment provided by engineer. */
"Disconnect desktop?" = "Rozłączyć komputer?";
/* No comment provided by engineer. */
"Discover and join groups" = "Odkrywaj i dołączaj do grup";
/* No comment provided by engineer. */
"Discover via local network" = "Odkryj przez sieć lokalną";
/* No comment provided by engineer. */
"Do it later" = "Zrób to później";
@@ -1290,6 +1431,12 @@
/* chat item text */
"encryption re-negotiation allowed for %@" = "renegocjacja szyfrowania dozwolona dla %@";
/* message decrypt error item */
"Encryption re-negotiation error" = "Błąd renegocjacji szyfrowania";
/* No comment provided by engineer. */
"Encryption re-negotiation failed." = "Renegocjacja szyfrowania nie powiodła się.";
/* chat item text */
"encryption re-negotiation required" = "renegocjacja szyfrowania wymagana";
@@ -1305,6 +1452,9 @@
/* No comment provided by engineer. */
"Enter correct passphrase." = "Wprowadź poprawne hasło.";
/* No comment provided by engineer. */
"Enter group name…" = "Wpisz nazwę grupy…";
/* No comment provided by engineer. */
"Enter Passcode" = "Wprowadź Pin";
@@ -1317,12 +1467,18 @@
/* No comment provided by engineer. */
"Enter server manually" = "Wprowadź serwer ręcznie";
/* No comment provided by engineer. */
"Enter this device name…" = "Podaj nazwę urządzenia…";
/* placeholder */
"Enter welcome message…" = "Wpisz wiadomość powitalną…";
/* placeholder */
"Enter welcome message… (optional)" = "Wpisz wiadomość powitalną… (opcjonalne)";
/* No comment provided by engineer. */
"Enter your name…" = "Wpisz swoją nazwę…";
/* No comment provided by engineer. */
"error" = "błąd";
@@ -1494,6 +1650,9 @@
/* No comment provided by engineer. */
"Exit without saving" = "Wyjdź bez zapisywania";
/* chat item action */
"Expand" = "Rozszerz";
/* No comment provided by engineer. */
"Export database" = "Eksportuj bazę danych";
@@ -1512,6 +1671,9 @@
/* No comment provided by engineer. */
"Fast and no wait until the sender is online!" = "Szybko i bez czekania aż nadawca będzie online!";
/* No comment provided by engineer. */
"Faster joining and more reliable messages." = "Szybsze dołączenie i bardziej niezawodne wiadomości.";
/* No comment provided by engineer. */
"Favorite" = "Ulubione";
@@ -1569,6 +1731,9 @@
/* No comment provided by engineer. */
"For console" = "Dla konsoli";
/* No comment provided by engineer. */
"Found desktop" = "Znaleziono komputer";
/* No comment provided by engineer. */
"French interface" = "Francuski interfejs";
@@ -1581,6 +1746,9 @@
/* No comment provided by engineer. */
"Full name:" = "Pełna nazwa:";
/* No comment provided by engineer. */
"Fully decentralized visible only to members." = "W pełni zdecentralizowana widoczna tylko dla członków.";
/* No comment provided by engineer. */
"Fully re-implemented - work in background!" = "W pełni ponownie zaimplementowany - praca w tle!";
@@ -1593,6 +1761,12 @@
/* No comment provided by engineer. */
"Group" = "Grupa";
/* No comment provided by engineer. */
"Group already exists" = "Grupa już istnieje";
/* No comment provided by engineer. */
"Group already exists!" = "Grupa już istnieje!";
/* No comment provided by engineer. */
"group deleted" = "grupa usunięta";
@@ -1764,6 +1938,9 @@
/* No comment provided by engineer. */
"Incognito" = "Incognito";
/* No comment provided by engineer. */
"Incognito groups" = "Grupy incognito";
/* No comment provided by engineer. */
"Incognito mode" = "Tryb incognito";
@@ -1791,6 +1968,9 @@
/* No comment provided by engineer. */
"Incompatible database version" = "Niekompatybilna wersja bazy danych";
/* No comment provided by engineer. */
"Incompatible version" = "Niekompatybilna wersja";
/* PIN entry */
"Incorrect passcode" = "Nieprawidłowy pin";
@@ -1830,6 +2010,9 @@
/* invalid chat item */
"invalid data" = "nieprawidłowe dane";
/* No comment provided by engineer. */
"Invalid name!" = "Nieprawidłowa nazwa!";
/* No comment provided by engineer. */
"Invalid server address!" = "Nieprawidłowy adres serwera!";
@@ -1908,12 +2091,24 @@
/* No comment provided by engineer. */
"Join group" = "Dołącz do grupy";
/* No comment provided by engineer. */
"Join group?" = "Dołączyć do grupy?";
/* No comment provided by engineer. */
"Join incognito" = "Dołącz incognito";
/* No comment provided by engineer. */
"Join with current profile" = "Dołącz z obecnym profilem";
/* No comment provided by engineer. */
"Join your group?\nThis is your link for group %@!" = "Dołączyć do twojej grupy?\nTo jest twój link do grupy %@!";
/* No comment provided by engineer. */
"Joining group" = "Dołączanie do grupy";
/* No comment provided by engineer. */
"Keep the app open to use it from desktop" = "Zostaw aplikację otwartą i używaj ją z komputera";
/* No comment provided by engineer. */
"Keep your connections" = "Zachowaj swoje połączenia";
@@ -1950,6 +2145,15 @@
/* No comment provided by engineer. */
"Limitations" = "Ograniczenia";
/* No comment provided by engineer. */
"Link mobile and desktop apps! 🔗" = "Połącz mobile i komputerowe aplikacje! 🔗";
/* No comment provided by engineer. */
"Linked desktop options" = "Połączone opcje komputera";
/* No comment provided by engineer. */
"Linked desktops" = "Połączone komputery";
/* No comment provided by engineer. */
"LIVE" = "NA ŻYWO";
@@ -2055,6 +2259,9 @@
/* No comment provided by engineer. */
"Messages & files" = "Wiadomości i pliki";
/* No comment provided by engineer. */
"Messages from %@ will be shown!" = "Wiadomości od %@ zostaną pokazane!";
/* No comment provided by engineer. */
"Migrating database archive…" = "Migrowanie archiwum bazy danych…";
@@ -2202,6 +2409,9 @@
/* copied message info in history */
"no text" = "brak tekstu";
/* No comment provided by engineer. */
"Not compatible!" = "Nie kompatybilny!";
/* No comment provided by engineer. */
"Notifications" = "Powiadomienia";
@@ -2306,6 +2516,9 @@
/* authentication reason */
"Open chat console" = "Otwórz konsolę czatu";
/* No comment provided by engineer. */
"Open group" = "Grupa otwarta";
/* No comment provided by engineer. */
"Open Settings" = "Otwórz Ustawienia";
@@ -2342,6 +2555,9 @@
/* No comment provided by engineer. */
"Paste" = "Wklej";
/* No comment provided by engineer. */
"Paste desktop address" = "Wklej adres komputera";
/* No comment provided by engineer. */
"Paste image" = "Wklej obraz";
@@ -2438,6 +2654,12 @@
/* No comment provided by engineer. */
"Profile image" = "Zdjęcie profilowe";
/* No comment provided by engineer. */
"Profile name" = "Nazwa profilu";
/* No comment provided by engineer. */
"Profile name:" = "Nazwa profilu:";
/* No comment provided by engineer. */
"Profile password" = "Hasło profilu";
@@ -2603,6 +2825,12 @@
/* No comment provided by engineer. */
"Renegotiate encryption?" = "Renegocjować szyfrowanie?";
/* No comment provided by engineer. */
"Repeat connection request?" = "Powtórzyć prośbę połączenia?";
/* No comment provided by engineer. */
"Repeat join request?" = "Powtórzyć prośbę dołączenia?";
/* chat item action */
"Reply" = "Odpowiedz";
@@ -2714,6 +2942,9 @@
/* No comment provided by engineer. */
"Scan QR code" = "Zeskanuj kod QR";
/* No comment provided by engineer. */
"Scan QR code from desktop" = "Zeskanuj kod QR z komputera";
/* No comment provided by engineer. */
"Scan security code from your contact's app." = "Zeskanuj kod bezpieczeństwa z aplikacji Twojego kontaktu.";
@@ -2858,6 +3089,9 @@
/* No comment provided by engineer. */
"Servers" = "Serwery";
/* No comment provided by engineer. */
"Session code" = "Kod sesji";
/* No comment provided by engineer. */
"Set 1 day" = "Ustaw 1 dzień";
@@ -3044,6 +3278,9 @@
/* No comment provided by engineer. */
"Tap to activate profile." = "Dotknij, aby aktywować profil.";
/* No comment provided by engineer. */
"Tap to Connect" = "Dotknij aby połączyć";
/* No comment provided by engineer. */
"Tap to join" = "Dotknij, aby dołączyć";
@@ -3164,12 +3401,21 @@
/* notification title */
"this contact" = "ten kontakt";
/* No comment provided by engineer. */
"This device name" = "Nazwa tego urządzenia";
/* No comment provided by engineer. */
"This group has over %lld members, delivery receipts are not sent." = "Ta grupa ma ponad %lld członków, potwierdzenia dostawy nie są wysyłane.";
/* No comment provided by engineer. */
"This group no longer exists." = "Ta grupa już nie istnieje.";
/* No comment provided by engineer. */
"This is your own one-time link!" = "To jest twój jednorazowy link!";
/* No comment provided by engineer. */
"This is your own SimpleX address!" = "To jest twój własny adres SimpleX!";
/* No comment provided by engineer. */
"This setting applies to messages in your current chat profile **%@**." = "To ustawienie dotyczy wiadomości Twojego bieżącego profilu czatu **%@**.";
@@ -3179,6 +3425,9 @@
/* No comment provided by engineer. */
"To connect, your contact can scan QR code or use the link in the app." = "Aby się połączyć, Twój kontakt może zeskanować kod QR lub skorzystać z linku w aplikacji.";
/* No comment provided by engineer. */
"To hide unwanted messages." = "Aby ukryć niechciane wiadomości.";
/* No comment provided by engineer. */
"To make a new connection" = "Aby nawiązać nowe połączenie";
@@ -3227,6 +3476,15 @@
/* No comment provided by engineer. */
"Unable to record voice message" = "Nie można nagrać wiadomości głosowej";
/* No comment provided by engineer. */
"Unblock" = "Odblokuj";
/* No comment provided by engineer. */
"Unblock member" = "Odblokuj członka";
/* No comment provided by engineer. */
"Unblock member?" = "Odblokować członka?";
/* item status description */
"Unexpected error: %@" = "Nieoczekiwany błąd: %@";
@@ -3266,6 +3524,12 @@
/* No comment provided by engineer. */
"Unless your contact deleted the connection or this link was already used, it might be a bug - please report it.\nTo connect, please ask your contact to create another connection link and check that you have a stable network connection." = "O ile Twój kontakt nie usunął połączenia lub ten link był już użyty, może to być błąd - zgłoś go.\nAby się połączyć, poproś Twój kontakt o utworzenie kolejnego linku połączenia i sprawdź, czy masz stabilne połączenie z siecią.";
/* No comment provided by engineer. */
"Unlink" = "Odłącz";
/* No comment provided by engineer. */
"Unlink desktop?" = "Odłączyć komputer?";
/* No comment provided by engineer. */
"Unlock" = "Odblokuj";
@@ -3320,6 +3584,9 @@
/* No comment provided by engineer. */
"Use for new connections" = "Użyj dla nowych połączeń";
/* No comment provided by engineer. */
"Use from desktop" = "Użyj z komputera";
/* No comment provided by engineer. */
"Use iOS call interface" = "Użyj interfejsu połączeń iOS";
@@ -3341,12 +3608,24 @@
/* No comment provided by engineer. */
"Using SimpleX Chat servers." = "Używanie serwerów SimpleX Chat.";
/* No comment provided by engineer. */
"v%@" = "v%@";
/* No comment provided by engineer. */
"v%@ (%@)" = "v%@ (%@)";
/* No comment provided by engineer. */
"Verify code with desktop" = "Zweryfikuj kod z komputera";
/* No comment provided by engineer. */
"Verify connection" = "Zweryfikuj połączenie";
/* No comment provided by engineer. */
"Verify connection security" = "Weryfikuj bezpieczeństwo połączenia";
/* No comment provided by engineer. */
"Verify connections" = "Zweryfikuj połączenia";
/* No comment provided by engineer. */
"Verify security code" = "Weryfikuj kod bezpieczeństwa";
@@ -3365,6 +3644,9 @@
/* No comment provided by engineer. */
"via relay" = "przez przekaźnik";
/* No comment provided by engineer. */
"Via secure quantum resistant protocol." = "Dzięki bezpiecznemu protokołowi odpornego kwantowo.";
/* No comment provided by engineer. */
"Video call" = "Połączenie wideo";
@@ -3404,6 +3686,9 @@
/* No comment provided by engineer. */
"waiting for confirmation…" = "oczekiwanie na potwierdzenie…";
/* No comment provided by engineer. */
"Waiting for desktop..." = "Oczekiwanie na komputer...";
/* No comment provided by engineer. */
"Waiting for file" = "Oczekiwanie na plik";
@@ -3473,6 +3758,27 @@
/* No comment provided by engineer. */
"You are already connected to %@." = "Jesteś już połączony z %@.";
/* No comment provided by engineer. */
"You are already connecting to %@." = "Już się łączysz z %@.";
/* No comment provided by engineer. */
"You are already connecting via this one-time link!" = "Już jesteś połączony z tym jednorazowym linkiem!";
/* No comment provided by engineer. */
"You are already in group %@." = "Już jesteś w grupie %@.";
/* No comment provided by engineer. */
"You are already joining the group %@." = "Już dołączasz do grupy %@.";
/* No comment provided by engineer. */
"You are already joining the group via this link!" = "Już dołączasz do grupy przez ten link!";
/* No comment provided by engineer. */
"You are already joining the group via this link." = "Już dołączasz do grupy przez ten link.";
/* No comment provided by engineer. */
"You are already joining the group!\nRepeat join request?" = "Już dołączasz do grupy!\nPowtórzyć prośbę dołączenia?";
/* No comment provided by engineer. */
"You are connected to the server used to receive messages from this contact." = "Jesteś połączony z serwerem używanym do odbierania wiadomości od tego kontaktu.";
@@ -3548,6 +3854,12 @@
/* No comment provided by engineer. */
"You could not be verified; please try again." = "Nie można zweryfikować użytkownika; proszę spróbować ponownie.";
/* No comment provided by engineer. */
"You have already requested connection via this address!" = "Już prosiłeś o połączenie na ten adres!";
/* No comment provided by engineer. */
"You have already requested connection!\nRepeat connection request?" = "Już prosiłeś o połączenie!\nPowtórzyć prośbę połączenia?";
/* No comment provided by engineer. */
"You have no chats" = "Nie masz czatów";
@@ -3590,6 +3902,9 @@
/* No comment provided by engineer. */
"You will be connected to group when the group host's device is online, please wait or check later!" = "Zostaniesz połączony do grupy, gdy urządzenie gospodarza grupy będzie online, proszę czekać lub sprawdzić później!";
/* No comment provided by engineer. */
"You will be connected when group link host's device is online, please wait or check later!" = "Zostaniesz połączony, gdy urządzenie hosta grupy będzie online, proszę czekać lub sprawdzić później!";
/* No comment provided by engineer. */
"You will be connected when your connection request is accepted, please wait or check later!" = "Zostaniesz połączony, gdy Twoje żądanie połączenia zostanie zaakceptowane, proszę czekać lub sprawdzić później!";
@@ -3599,6 +3914,9 @@
/* No comment provided by engineer. */
"You will be required to authenticate when you start or resume the app after 30 seconds in background." = "Uwierzytelnienie będzie wymagane przy uruchamianiu lub wznawianiu aplikacji po 30 sekundach w tle.";
/* No comment provided by engineer. */
"You will connect to all group members." = "Zostaniesz połączony ze wszystkimi członkami grupy.";
/* No comment provided by engineer. */
"You will still receive calls and notifications from muted profiles when they are active." = "Nadal będziesz otrzymywać połączenia i powiadomienia z wyciszonych profili, gdy są one aktywne.";
@@ -3662,6 +3980,9 @@
/* No comment provided by engineer. */
"Your privacy" = "Twoja prywatność";
/* No comment provided by engineer. */
"Your profile" = "Twój profil";
/* No comment provided by engineer. */
"Your profile **%@** will be shared." = "Twój profil **%@** zostanie udostępniony.";

Some files were not shown because too many files have changed in this diff Show More