mirror of
https://github.com/simplex-chat/simplex-chat.git
synced 2024-12-17 17:20:21 +01:00
Compare commits
174 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| ce1a57ad54 | |||
| 8c49d66e4b | |||
| 0064155825 | |||
| 69654e187e | |||
| f62ec7aaae | |||
| 8263106e19 | |||
| 71bea947a5 | |||
| f83154f44f | |||
| b7148fed06 | |||
| 56edfd176f | |||
| 9d58a37cd6 | |||
| d0d7e63f31 | |||
| 4d61cda551 | |||
| 7d4d30afe2 | |||
| 90d5abdff1 | |||
| 6407d5de63 | |||
| 9cba96082d | |||
| 2089fd8539 | |||
| 31c4ff2705 | |||
| 8e31b45be8 | |||
| 014c19fe3a | |||
| 33895b0330 | |||
| fe20a43232 | |||
| 087519c39d | |||
| 3b49817f17 | |||
| f94f0dea08 | |||
| d68a3ba80d | |||
| 7a4dca1e4c | |||
| fff29f8548 | |||
| 8cc03b6c21 | |||
| 7a5b04d523 | |||
| d7ab0aef14 | |||
| 41cb734d56 | |||
| 6adf8f29b0 | |||
| 4ca1b57e1b | |||
| 9432a5e5cd | |||
| a9ec1f9ec1 | |||
| 122387d180 | |||
| 23f54c1022 | |||
| 0b0b78293f | |||
| eef1e97ecc | |||
| 564b137f95 | |||
| 6edea46dad | |||
| 2fe3acf4df | |||
| 1c64b17545 | |||
| 700918f0ca | |||
| 94c552ca12 | |||
| dfe16991d0 | |||
| acb372a4ce | |||
| 121eaf6073 | |||
| 8cc075eda8 | |||
| 05e7f35037 | |||
| e582d2d742 | |||
| 043a4ed915 | |||
| 76cb9013f5 | |||
| f1e8c65aa1 | |||
| 8a6bf05773 | |||
| 0118e64ab4 | |||
| 0477b1aad3 | |||
| ae850c8ce8 | |||
| 94ae571ec3 | |||
| 4552860345 | |||
| a1579810bb | |||
| 4574198990 | |||
| 4d18174b11 | |||
| defd095a4f | |||
| ed60f28e56 | |||
| f0b889ffcf | |||
| c07df9e05f | |||
| efe8ed1739 | |||
| bcd50019be | |||
| 7b48c59f9f | |||
| 04033fc0b5 | |||
| 7b90e01b3a | |||
| ef1897f865 | |||
| f587179045 | |||
| 791489e943 | |||
| c485837910 | |||
| a95415fa1a | |||
| 8d48c4b14c | |||
| 9f44242e4c | |||
| 7e7d93c596 | |||
| 073818db55 | |||
| 519dd9e219 | |||
| 94218a1a7e | |||
| 996c6efddd | |||
| fd9c080103 | |||
| 5cb8badb22 | |||
| 0438f35539 | |||
| d5eb7b7811 | |||
| e04f74738e | |||
| 5f0ccb9f17 | |||
| b2d18f6960 | |||
| b52dfee078 | |||
| 70991debfd | |||
| 885aa9cfa5 | |||
| 75a468434c | |||
| 3b98032371 | |||
| 3a0921c093 | |||
| 3740805125 | |||
| b0e0b0beb8 | |||
| c823a4fa6c | |||
| 3c694e2841 | |||
| c159c2ede3 | |||
| 1d0d7bbd01 | |||
| 82c4d77c73 | |||
| 25938af62f | |||
| edfcced1fa | |||
| 5bff5a855e | |||
| 46a60d979b | |||
| f6ef57534f | |||
| 1e4479f736 | |||
| 789c762c81 | |||
| e9baeba31f | |||
| 2d5bbcdd61 | |||
| c3f67aff69 | |||
| 7cb3a499b2 | |||
| 32e7fd72d3 | |||
| 915bbed400 | |||
| 2ae5a8bffd | |||
| cd1550a14d | |||
| c72c461306 | |||
| 38fa4c231f | |||
| cb683d0706 | |||
| 84ae39b012 | |||
| 6a12f2dec8 | |||
| d1f704d160 | |||
| 9871ebb3b1 | |||
| 02c404593c | |||
| 1d9c5b7a0b | |||
| e20a4e54c3 | |||
| 1f8c69ec23 | |||
| 35c37263b8 | |||
| 9b70599cc5 | |||
| a4a11f99d2 | |||
| 7c8955fcdb | |||
| f922064f5c | |||
| 110839627f | |||
| c90b71120f | |||
| 3ec029e489 | |||
| f4c799aced | |||
| d970470702 | |||
| 9ee74bd36e | |||
| 0a4ff2e35f | |||
| a3550df893 | |||
| 3778698a6e | |||
| cf7a16e857 | |||
| bef1597fa1 | |||
| f06118835d | |||
| fa9e50a904 | |||
| 932a65630c | |||
| b649b64999 | |||
| e94ead3a4f | |||
| 42d7c20a47 | |||
| cf8fd2ea11 | |||
| 5006742577 | |||
| 38d46891a1 | |||
| 6a7e573b42 | |||
| b31a74567d | |||
| b3f0e71ded | |||
| ed50623ef5 | |||
| 53368713a0 | |||
| 5739b94808 | |||
| 0782408682 | |||
| 41576f80e7 | |||
| 2503a86f07 | |||
| dc713268e8 | |||
| d0c52e43a2 | |||
| 2e8e6cef7e | |||
| 239c815f3e | |||
| 1a6245fe51 | |||
| b3d15f97f0 | |||
| c0b8cfb3e2 | |||
| 818161c6ed |
@@ -5,12 +5,22 @@ on:
|
||||
branches:
|
||||
- master
|
||||
- stable
|
||||
- users
|
||||
tags:
|
||||
- "v*"
|
||||
- "!*-fdroid"
|
||||
- "!*-armv7a"
|
||||
pull_request:
|
||||
paths-ignore:
|
||||
- "apps/ios"
|
||||
- "apps/multiplatform"
|
||||
- "blog"
|
||||
- "docs"
|
||||
- "fastlane"
|
||||
- "images"
|
||||
- "packages"
|
||||
- "website"
|
||||
- "README.md"
|
||||
- "PRIVACY.md"
|
||||
|
||||
jobs:
|
||||
prepare-release:
|
||||
|
||||
@@ -61,6 +61,7 @@ website/package/generated*
|
||||
# Ignore build tool output, e.g. code coverage
|
||||
website/.nyc_output/
|
||||
website/coverage/
|
||||
result
|
||||
|
||||
# Ignore API documentation
|
||||
website/api-docs/
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
2. ↔️ [Connect to the team](#connect-to-the-team), [join user groups](#join-user-groups) and [follow our updates](#follow-our-updates).
|
||||
3. 🤝 [Make a private connection](#make-a-private-connection) with a friend.
|
||||
4. 🔤 [Help translating SimpleX Chat](#help-translating-simplex-chat).
|
||||
5. ⚡️ [Contribute](#contribute) and [help us with donations](#help-us-with-donations).
|
||||
5. ⚡️ [Contribute](#contribute) and [support us with donations](#please-support-us-with-your-donations).
|
||||
|
||||
[Learn more about SimpleX Chat](#contents).
|
||||
|
||||
@@ -150,7 +150,7 @@ We would love to have you join the development! You can help us with:
|
||||
- contributing to SimpleX Chat knowledge-base.
|
||||
- developing features - please connect to us via chat so we can help you get started.
|
||||
|
||||
## Help us with donations
|
||||
## Please support us with your donations
|
||||
|
||||
Huge thank you to everybody who donated to SimpleX Chat!
|
||||
|
||||
@@ -233,6 +233,8 @@ You can use SimpleX with your own servers and still communicate with people usin
|
||||
|
||||
Recent and important updates:
|
||||
|
||||
[Aug 14, 2024. SimpleX network: the investment from Jack Dorsey and Asymmetric, v6.0 released with the new user experience and private message routing](./blog/20240814-simplex-chat-vision-funding-v6-private-routing-new-user-experience.md)
|
||||
|
||||
[Jun 4, 2024. SimpleX network: private message routing, v5.8 released with IP address protection and chat themes](./blog/20240604-simplex-chat-v5.8-private-message-routing-chat-themes.md)
|
||||
|
||||
[Apr 26, 2024. SimpleX network: legally binding transparency, v5.7 released with better calls and messages.](./blog/20240426-simplex-legally-binding-transparency-v5-7-better-user-experience.md)
|
||||
@@ -298,25 +300,27 @@ What is already implemented:
|
||||
1. Instead of user profile identifiers used by all other platforms, even the most private ones, SimpleX uses [pairwise per-queue identifiers](./docs/GLOSSARY.md#pairwise-pseudonymous-identifier) (2 addresses for each unidirectional message queue, with an optional 3rd address for push notifications on iOS, 2 queues in each connection between the users). It makes observing the network graph on the application level more difficult, as for `n` users there can be up to `n * (n-1)` message queues.
|
||||
2. [End-to-end encryption](./docs/GLOSSARY.md#end-to-end-encryption) in each message queue using [NaCl cryptobox](https://nacl.cr.yp.to/box.html). This is added to allow redundancy in the future (passing each message via several servers), to avoid having the same ciphertext in different queues (that would only be visible to the attacker if TLS is compromised). The encryption keys used for this encryption are not rotated, instead we are planning to rotate the queues. Curve25519 keys are used for key negotiation.
|
||||
3. [Double ratchet](./docs/GLOSSARY.md#double-ratchet-algorithm) end-to-end encryption in each conversation between two users (or group members). This is the same algorithm that is used in Signal and many other messaging apps; it provides OTR messaging with [forward secrecy](./docs/GLOSSARY.md#forward-secrecy) (each message is encrypted by its own ephemeral key) and [break-in recovery](./docs/GLOSSARY.md#post-compromise-security) (the keys are frequently re-negotiated as part of the message exchange). Two pairs of Curve448 keys are used for the initial [key agreement](./docs/GLOSSARY.md#key-agreement-protocol), initiating party passes these keys via the connection link, accepting side - in the header of the confirmation message.
|
||||
4. Additional layer of encryption using NaCL cryptobox for the messages delivered from the server to the recipient. This layer avoids having any ciphertext in common between sent and received traffic of the server inside TLS (and there are no identifiers in common as well).
|
||||
5. Several levels of [content padding](./docs/GLOSSARY.md#message-padding) to frustrate message size attacks.
|
||||
6. All message metadata, including the time when the message was received by the server (rounded to a second) is sent to the recipients inside an encrypted envelope, so even if TLS is compromised it cannot be observed.
|
||||
7. Only TLS 1.2/1.3 are allowed for client-server connections, limited to cryptographic algorithms: CHACHA20POLY1305_SHA256, Ed25519/Ed448, Curve25519/Curve448.
|
||||
8. To protect against replay attacks SimpleX servers require [tlsunique channel binding](https://www.rfc-editor.org/rfc/rfc5929.html) as session ID in each client command signed with per-queue ephemeral key.
|
||||
9. To protect your IP address all SimpleX Chat clients support accessing messaging servers via Tor - see [v3.1 release announcement](./blog/20220808-simplex-chat-v3.1-chat-groups.md) for more details.
|
||||
10. Local database encryption with passphrase - your contacts, groups and all sent and received messages are stored encrypted. If you used SimpleX Chat before v4.0 you need to enable the encryption via the app settings.
|
||||
11. Transport isolation - different TCP connections and Tor circuits are used for traffic of different user profiles, optionally - for different contacts and group member connections.
|
||||
12. Manual messaging queue rotations to move conversation to another SMP relay.
|
||||
13. Sending end-to-end encrypted files using [XFTP protocol](https://simplex.chat/blog/20230301-simplex-file-transfer-protocol.html).
|
||||
14. Local files encryption.
|
||||
4. [Post-quantum resistant key exchange](./docs/GLOSSARY.md#post-quantum-cryptography) in double ratchet protocol *on every ratchet step*. Read more in [this post](./blog/20240314-simplex-chat-v5-6-quantum-resistance-signal-double-ratchet-algorithm.md) and also see this [publication by Apple]( https://security.apple.com/blog/imessage-pq3/) explaining the need for post-quantum key rotation.
|
||||
5. Additional layer of encryption using NaCL cryptobox for the messages delivered from the server to the recipient. This layer avoids having any ciphertext in common between sent and received traffic of the server inside TLS (and there are no identifiers in common as well).
|
||||
6. Several levels of [content padding](./docs/GLOSSARY.md#message-padding) to frustrate message size attacks.
|
||||
7. All message metadata, including the time when the message was received by the server (rounded to a second) is sent to the recipients inside an encrypted envelope, so even if TLS is compromised it cannot be observed.
|
||||
8. Only TLS 1.2/1.3 are allowed for client-server connections, limited to cryptographic algorithms: CHACHA20POLY1305_SHA256, Ed25519/Ed448, Curve25519/Curve448.
|
||||
9. To protect against replay attacks SimpleX servers require [tlsunique channel binding](https://www.rfc-editor.org/rfc/rfc5929.html) as session ID in each client command signed with per-queue ephemeral key.
|
||||
10. To protect your IP address from unknown messaging relays, and for per-message transport anonymity (compared with Tor/VPN per-connection anonymity), from v6.0 all SimpleX Chat clients use private message routing by default. Read more in [this post](./blog/20240604-simplex-chat-v5.8-private-message-routing-chat-themes.md#private-message-routing).
|
||||
11. To protect your IP address from unknown file relays, when SOCKS proxy is not enabled SimpleX Chat clients ask for a confirmation before downloading the files from unknown servers.
|
||||
12. To protect your IP address from known servers all SimpleX Chat clients support accessing messaging servers via Tor - see [v3.1 release announcement](./blog/20220808-simplex-chat-v3.1-chat-groups.md) for more details.
|
||||
13. Local database encryption with passphrase - your contacts, groups and all sent and received messages are stored encrypted. If you used SimpleX Chat before v4.0 you need to enable the encryption via the app settings.
|
||||
14. Transport isolation - different TCP connections and Tor circuits are used for traffic of different user profiles, optionally - for different contacts and group member connections.
|
||||
15. Manual messaging queue rotations to move conversation to another SMP relay.
|
||||
16. Sending end-to-end encrypted files using [XFTP protocol](https://simplex.chat/blog/20230301-simplex-file-transfer-protocol.html).
|
||||
17. Local files encryption.
|
||||
|
||||
We plan to add:
|
||||
|
||||
1. Senders' SMP relays and recipients' XFTP relays to reduce traffic and conceal IP addresses from the relays chosen, and potentially controlled, by another party.
|
||||
2. Post-quantum resistant key exchange in double ratchet protocol.
|
||||
3. Automatic message queue rotation and redundancy. Currently the queues created between two users are used until the queue is manually changed by the user or contact is deleted. We are planning to add automatic queue rotation to make these identifiers temporary and rotate based on some schedule TBC (e.g., every X messages, or every X hours/days).
|
||||
4. Message "mixing" - adding latency to message delivery, to protect against traffic correlation by message time.
|
||||
5. Reproducible builds – this is the limitation of the development stack, but we will be investing into solving this problem. Users can still build all applications and services from the source code.
|
||||
1. Automatic message queue rotation and redundancy. Currently the queues created between two users are used until the queue is manually changed by the user or contact is deleted. We are planning to add automatic queue rotation to make these identifiers temporary and rotate based on some schedule TBC (e.g., every X messages, or every X hours/days).
|
||||
2. Message "mixing" - adding latency to message delivery, to protect against traffic correlation by message time.
|
||||
3. Reproducible builds – this is the limitation of the development stack, but we will be investing into solving this problem. Users can still build all applications and services from the source code.
|
||||
4. Recipients' XFTP relays to reduce traffic and conceal IP addresses from the relays chosen, and potentially controlled, by another party.
|
||||
|
||||
## For developers
|
||||
|
||||
|
||||
@@ -15,31 +15,12 @@ class AppDelegate: NSObject, UIApplicationDelegate {
|
||||
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
|
||||
logger.debug("AppDelegate: didFinishLaunchingWithOptions")
|
||||
application.registerForRemoteNotifications()
|
||||
if #available(iOS 17.0, *) { trackKeyboard() }
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(pasteboardChanged), name: UIPasteboard.changedNotification, object: nil)
|
||||
removePasscodesIfReinstalled()
|
||||
prepareForLaunch()
|
||||
return true
|
||||
}
|
||||
|
||||
@available(iOS 17.0, *)
|
||||
private func trackKeyboard() {
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow), name: UIResponder.keyboardWillShowNotification, object: nil)
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide), name: UIResponder.keyboardWillHideNotification, object: nil)
|
||||
}
|
||||
|
||||
@available(iOS 17.0, *)
|
||||
@objc func keyboardWillShow(_ notification: Notification) {
|
||||
if let keyboardFrame: NSValue = notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue {
|
||||
ChatModel.shared.keyboardHeight = keyboardFrame.cgRectValue.height
|
||||
}
|
||||
}
|
||||
|
||||
@available(iOS 17.0, *)
|
||||
@objc func keyboardWillHide(_ notification: Notification) {
|
||||
ChatModel.shared.keyboardHeight = 0
|
||||
}
|
||||
|
||||
@objc func pasteboardChanged() {
|
||||
ChatModel.shared.pasteboardHasStrings = UIPasteboard.general.hasStrings
|
||||
}
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"info": {
|
||||
"author": "xcode",
|
||||
"version": 1
|
||||
},
|
||||
"symbols": [
|
||||
{
|
||||
"filename": "checkmark.2.svg",
|
||||
"idiom": "universal"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,227 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="3300px" height="2200px" viewBox="0 0 3300 2200" version="1.1" xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<title>checkmark.2</title>
|
||||
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="double.checkmark">
|
||||
<g id="Notes">
|
||||
<rect id="artboard" fill="#FFFFFF" fill-rule="nonzero" x="0" y="0" width="3300" height="2200"></rect>
|
||||
<line x1="263" y1="292" x2="3036" y2="292" id="Path" stroke="#000000" stroke-width="0.5"></line>
|
||||
<text id="Weight/Scale-Variations" fill="#000000" fill-rule="nonzero" font-family="Helvetica"
|
||||
font-size="13" font-weight="normal">
|
||||
<tspan x="263" y="322">Weight/Scale Variations</tspan>
|
||||
</text>
|
||||
<text id="Ultralight" fill="#000000" fill-rule="nonzero" font-family="Helvetica" font-size="13"
|
||||
font-weight="normal">
|
||||
<tspan x="533.711" y="322">Ultralight</tspan>
|
||||
</text>
|
||||
<text id="Thin" fill="#000000" fill-rule="nonzero" font-family="Helvetica" font-size="13"
|
||||
font-weight="normal">
|
||||
<tspan x="843.422" y="322">Thin</tspan>
|
||||
</text>
|
||||
<text id="Light" fill="#000000" fill-rule="nonzero" font-family="Helvetica" font-size="13"
|
||||
font-weight="normal">
|
||||
<tspan x="1138.63" y="322">Light</tspan>
|
||||
</text>
|
||||
<text id="Regular" fill="#000000" fill-rule="nonzero" font-family="Helvetica" font-size="13"
|
||||
font-weight="normal">
|
||||
<tspan x="1426.84" y="322">Regular</tspan>
|
||||
</text>
|
||||
<text id="Medium" fill="#000000" fill-rule="nonzero" font-family="Helvetica" font-size="13"
|
||||
font-weight="normal">
|
||||
<tspan x="1723.06" y="322">Medium</tspan>
|
||||
</text>
|
||||
<text id="Semibold" fill="#000000" fill-rule="nonzero" font-family="Helvetica" font-size="13"
|
||||
font-weight="normal">
|
||||
<tspan x="2015.77" y="322">Semibold</tspan>
|
||||
</text>
|
||||
<text id="Bold" fill="#000000" fill-rule="nonzero" font-family="Helvetica" font-size="13"
|
||||
font-weight="normal">
|
||||
<tspan x="2326.48" y="322">Bold</tspan>
|
||||
</text>
|
||||
<text id="Heavy" fill="#000000" fill-rule="nonzero" font-family="Helvetica" font-size="13"
|
||||
font-weight="normal">
|
||||
<tspan x="2618.19" y="322">Heavy</tspan>
|
||||
</text>
|
||||
<text id="Black" fill="#000000" fill-rule="nonzero" font-family="Helvetica" font-size="13"
|
||||
font-weight="normal">
|
||||
<tspan x="2917.4" y="322">Black</tspan>
|
||||
</text>
|
||||
<line x1="263" y1="1903" x2="3036" y2="1903" id="Path" stroke="#000000" stroke-width="0.5"></line>
|
||||
<g id="Group" transform="translate(264.3672, 1918.0684)" fill="#000000" fill-rule="nonzero">
|
||||
<path
|
||||
d="M7.88088,15.76172 C12.18752,15.76172 15.7715,12.1875 15.7715,7.88086 C15.7715,3.57422 12.17774,0 7.8711,0 C3.57422,0 0,3.57422 0,7.88086 C0,12.1875 3.58398,15.76172 7.88086,15.76172 L7.88088,15.76172 Z M7.88088,14.277344 C4.33596,14.277344 1.50392,11.435544 1.50392,7.880864 C1.50392,4.326184 4.32618,1.484384 7.8711,1.484384 C11.42578,1.484384 14.27734,4.326184 14.27734,7.880864 C14.27734,11.435544 11.43554,14.277344 7.88086,14.277344 L7.88088,14.277344 Z M4.28712,7.880864 C4.28712,8.310552 4.589854,8.60352 5.039074,8.60352 L7.138674,8.60352 L7.138674,10.72266 C7.138674,11.162114 7.431642,11.464848 7.86133,11.464848 C8.310548,11.464848 8.603518,11.162114 8.603518,10.72266 L8.603518,8.60352 L10.722658,8.60352 C11.162112,8.60352 11.464846,8.310552 11.464846,7.880864 C11.464846,7.44141 11.162112,7.138676 10.722658,7.138676 L8.603518,7.138676 L8.603518,5.029296 C8.603518,4.580078 8.31055,4.277342 7.86133,4.277342 C7.431642,4.277342 7.138674,4.580076 7.138674,5.029296 L7.138674,7.138676 L5.039074,7.138676 C4.589856,7.138676 4.28712,7.44141 4.28712,7.880864 Z"
|
||||
id="Shape"></path>
|
||||
</g>
|
||||
<g id="Group" transform="translate(283.254, 1915.9883)" fill="#000000" fill-rule="nonzero">
|
||||
<path
|
||||
d="M9.96094,19.92188 C15.41016,19.92188 19.92188,15.4004 19.92188,9.96094 C19.92188,4.51172 15.4004,0 9.95118,0 C4.51172,0 0,4.51172 0,9.96094 C0,15.4004 4.52148,19.92188 9.96094,19.92188 Z M9.96094,18.261724 C5.35156,18.261724 1.66992,14.570324 1.66992,9.960944 C1.66992,5.351564 5.3418,1.660164 9.95116,1.660164 C14.56052,1.660164 18.2617,5.351564 18.2617,9.960944 C18.2617,14.570324 14.5703,18.261724 9.96092,18.261724 L9.96094,18.261724 Z M5.4297,9.960944 C5.4297,10.43946 5.761732,10.761726 6.259778,10.761726 L9.130878,10.761726 L9.130878,13.642586 C9.130878,14.130868 9.46291,14.472664 9.941424,14.472664 C10.4297,14.472664 10.771502,14.140632 10.771502,13.642586 L10.771502,10.761726 L13.652362,10.761726 C14.140644,10.761726 14.48244,10.43946 14.48244,9.960944 C14.48244,9.472662 14.140644,9.130866 13.652362,9.130866 L10.771502,9.130866 L10.771502,6.259766 C10.771502,5.76172 10.4297,5.419922 9.941424,5.419922 C9.462908,5.419922 9.130878,5.761718 9.130878,6.259766 L9.130878,9.130866 L6.259778,9.130866 C5.761732,9.130866 5.4297,9.472662 5.4297,9.960944 Z"
|
||||
id="Shape"></path>
|
||||
</g>
|
||||
<g id="Group" transform="translate(307.1798, 1913.2246)" fill="#000000" fill-rule="nonzero">
|
||||
<path
|
||||
d="M12.71486,25.43944 C19.67776,25.43944 25.43946,19.67772 25.43946,12.7246 C25.43946,5.7617 19.66798,0 12.70508,0 C5.75196,0 -1.42108547e-15,5.76172 -1.42108547e-15,12.7246 C-1.42108547e-15,19.67772 5.76172,25.43944 12.71484,25.43944 L12.71486,25.43944 Z M12.71486,23.623034 C6.6797,23.623034 1.82618,18.759754 1.82618,12.724594 C1.82618,6.679674 6.66994,1.826154 12.70508,1.826154 C18.75,1.826154 23.61328,6.679674 23.61328,12.724594 C23.61328,18.759754 18.75976,23.623034 12.71484,23.623034 L12.71486,23.623034 Z M6.94338,12.724594 C6.94338,13.242172 7.314474,13.6035 7.861348,13.6035 L11.806668,13.6035 L11.806668,17.55858 C11.806668,18.09569 12.177762,18.476548 12.69534,18.476548 C13.23245,18.476548 13.603544,18.105454 13.603544,17.55858 L13.603544,13.6035 L17.558624,13.6035 C18.095734,13.6035 18.476592,13.242172 18.476592,12.724594 C18.476592,12.177718 18.105498,11.806626 17.558624,11.806626 L13.603544,11.806626 L13.603544,7.861306 C13.603544,7.31443 13.23245,6.933572 12.69534,6.933572 C12.177762,6.933572 11.806668,7.314432 11.806668,7.861306 L11.806668,11.806626 L7.861348,11.806626 C7.314472,11.806626 6.94338,12.17772 6.94338,12.724594 Z"
|
||||
id="Shape"></path>
|
||||
</g>
|
||||
<text id="Design-Variations" fill="#000000" fill-rule="nonzero" font-family="Helvetica" font-size="13"
|
||||
font-weight="normal">
|
||||
<tspan x="263" y="1953">Design Variations</tspan>
|
||||
</text>
|
||||
<text id="Symbols-are-supported-in-up-to-nine-weights-and-three-scales." fill="#000000"
|
||||
fill-rule="nonzero" font-family="Helvetica" font-size="13" font-weight="normal">
|
||||
<tspan x="263" y="1971">Symbols are supported in up to nine weights and three scales.</tspan>
|
||||
</text>
|
||||
<text id="For-optimal-layout-with-text-and-other-symbols,-vertically-align" fill="#000000"
|
||||
fill-rule="nonzero" font-family="Helvetica" font-size="13" font-weight="normal">
|
||||
<tspan x="263" y="1989">For optimal layout with text and other symbols, vertically align</tspan>
|
||||
</text>
|
||||
<text id="symbols-with-the-adjacent-text." fill="#000000" fill-rule="nonzero" font-family="Helvetica"
|
||||
font-size="13" font-weight="normal">
|
||||
<tspan x="263" y="2007">symbols with the adjacent text.</tspan>
|
||||
</text>
|
||||
<line x1="776" y1="1919" x2="776" y2="1933" id="Path" stroke="#00AEEF" stroke-width="0.5"></line>
|
||||
<g id="Group" transform="translate(778.4902, 1918.7324)" fill="#000000" fill-rule="nonzero">
|
||||
<path
|
||||
d="M0.8203116,14.423832 C1.3378896,14.423832 1.5917956,14.2285116 1.7773436,13.681636 L3.0371096,10.234376 L8.7988296,10.234376 L10.0585956,13.681636 C10.2441424,14.228512 10.4980496,14.423832 11.0058616,14.423832 C11.5234396,14.423832 11.8554716,14.111324 11.8554716,13.623042 C11.8554716,13.4570264 11.8261748,13.300776 11.7480498,13.095698 L7.1679698,0.898438 C6.9433598,0.302734 6.5429698,0 5.9179698,0 C5.3125018,0 4.9023458,0.292968 4.6875018,0.888672 L0.1074218,13.105472 C0.0292968,13.31055 -3.55271368e-16,13.4668 -3.55271368e-16,13.632816 C-3.55271368e-16,14.121098 0.3125,14.423832 0.820312,14.423832 L0.8203116,14.423832 Z M3.5156316,8.750004 L5.8886716,2.177744 L5.9374998,2.177744 L8.3105398,8.750004 L3.5156316,8.750004 Z"
|
||||
id="Shape"></path>
|
||||
</g>
|
||||
<line x1="792.836" y1="1919" x2="792.836" y2="1933" id="Path" stroke="#00AEEF" stroke-width="0.5">
|
||||
</line>
|
||||
<text id="Margins" fill="#000000" fill-rule="nonzero" font-family="Helvetica" font-size="13"
|
||||
font-weight="normal">
|
||||
<tspan x="776" y="1953">Margins</tspan>
|
||||
</text>
|
||||
<text id="Leading-and-trailing-margins-on-the-left-and-right-side-of-each-symbol" fill="#000000"
|
||||
fill-rule="nonzero" font-family="Helvetica" font-size="13" font-weight="normal">
|
||||
<tspan x="776" y="1971">Leading and trailing margins on the left and right side of each symbol
|
||||
</tspan>
|
||||
</text>
|
||||
<text id="can-be-adjusted-by-modifying-the-x-location-of-the-margin-guidelines." fill="#000000"
|
||||
fill-rule="nonzero" font-family="Helvetica" font-size="13" font-weight="normal">
|
||||
<tspan x="776" y="1989">can be adjusted by modifying the x-location of the margin guidelines.
|
||||
</tspan>
|
||||
</text>
|
||||
<text id="Modifications-are-automatically-applied-proportionally-to-all" fill="#000000"
|
||||
fill-rule="nonzero" font-family="Helvetica" font-size="13" font-weight="normal">
|
||||
<tspan x="776" y="2007">Modifications are automatically applied proportionally to all</tspan>
|
||||
</text>
|
||||
<text id="scales-and-weights." fill="#000000" fill-rule="nonzero" font-family="Helvetica" font-size="13"
|
||||
font-weight="normal">
|
||||
<tspan x="776" y="2025">scales and weights.</tspan>
|
||||
</text>
|
||||
<g id="Group" transform="translate(1291.2481, 1914.5174)" fill="#000000" fill-rule="nonzero">
|
||||
<path
|
||||
d="M0.593687825,20.3477978 L2.29290583,22.0567818 C3.15228183,22.9259218 4.13860983,22.8673278 5.06634583,21.8419378 L15.7597058,10.0548378 L14.7929098,9.07827578 L4.17766983,20.7579558 C3.82610783,21.1583458 3.49407583,21.2560018 3.02532583,20.7872526 L1.85344983,19.6251426 C1.38469983,19.1661586 1.49212183,18.8243606 1.89251223,18.4630326 L13.3671122,7.66225258 L12.3905502,6.69545658 L0.798750225,17.5841366 C-0.187577775,18.5021046 -0.265703775,19.4786686 0.593672225,20.3478166 L0.593687825,20.3477978 Z M7.00970783,2.15443778 C6.58978583,2.56459378 6.56048983,3.14076578 6.79486383,3.53139178 C7.02923983,3.89271978 7.48822383,4.12709578 8.13275383,3.96107978 C9.59759783,3.61928378 11.1210338,3.56068978 12.5468138,4.49818978 L11.9608758,5.95326778 C11.6190798,6.78334578 11.7948602,7.36928378 12.3319698,7.91615778 L14.6268898,10.2306178 C15.1151718,10.7188998 15.5253278,10.7384298 16.0917338,10.6407738 L17.1561878,10.4454614 L17.8202498,11.1192894 L17.7811874,11.6759294 C17.742125,12.1739754 17.869078,12.5548354 18.3573594,13.0333514 L19.1190774,13.7755394 C19.5975934,14.2540554 20.2128274,14.2833514 20.6815774,13.8146018 L23.5917374,10.8946818 C24.0604874,10.4259318 24.0409554,9.83022778 23.5624406,9.35171378 L22.7909566,8.58999578 C22.3124406,8.11147978 21.9413466,7.95522978 21.4628326,7.99429178 L20.8866606,8.04311998 L20.2421286,7.40835398 L20.4862686,6.28530798 C20.6132218,5.71890198 20.4569718,5.27944798 19.8710346,4.69351198 L17.6737746,2.50601198 C14.3339346,-0.814308021 9.90033463,-0.736168021 7.00971463,2.15444998 L7.00970783,2.15443778 Z M8.50384783,2.52553178 C10.9354878,0.748187779 14.2265078,1.05092178 16.4530678,3.27748578 L18.8847078,5.68958578 C19.1190838,5.92396178 19.1581458,6.10950778 19.0897858,6.45130378 L18.7675198,7.93567978 L20.2714258,9.42005578 L21.2577538,9.36146198 C21.5116598,9.35169636 21.5897858,9.3712276 21.7850978,9.56653998 L22.3612698,10.142712 L19.9198698,12.584112 L19.3436978,12.00794 C19.1483854,11.8126276 19.1190878,11.734502 19.1288538,11.47083 L19.1972132,10.494268 L17.7030732,9.00989198 L16.1796352,9.26379798 C15.8573692,9.33215738 15.7108852,9.30286038 15.4667452,9.06848558 L13.4647852,7.06652558 C13.2108792,6.83214958 13.1815812,6.66613558 13.337832,6.29504158 L14.216738,4.20520158 C12.654238,2.75012358 10.622978,2.12512158 8.59173803,2.72082558 C8.43548803,2.75988798 8.37689403,2.63293498 8.50384743,2.52551318 L8.50384783,2.52553178 Z"
|
||||
id="Shape"></path>
|
||||
</g>
|
||||
<text id="Exporting" fill="#000000" fill-rule="nonzero" font-family="Helvetica" font-size="13"
|
||||
font-weight="normal">
|
||||
<tspan x="1289" y="1953">Exporting</tspan>
|
||||
</text>
|
||||
<text id="Symbols-should-be-outlined-when-exporting-to-ensure-the" fill="#000000" fill-rule="nonzero"
|
||||
font-family="Helvetica" font-size="13" font-weight="normal">
|
||||
<tspan x="1289" y="1971">Symbols should be outlined when exporting to ensure the</tspan>
|
||||
</text>
|
||||
<text id="design-is-preserved-when-submitting-to-Xcode." fill="#000000" fill-rule="nonzero"
|
||||
font-family="Helvetica" font-size="13" font-weight="normal">
|
||||
<tspan x="1289" y="1989">design is preserved when submitting to Xcode.</tspan>
|
||||
</text>
|
||||
<text id="template-version" fill="#000000" fill-rule="nonzero" font-family="Helvetica" font-size="13"
|
||||
font-weight="normal">
|
||||
<tspan x="2952" y="1933">Template v.5.0</tspan>
|
||||
</text>
|
||||
<text id="Requires-Xcode-15-or-greater" fill="#000000" fill-rule="nonzero" font-family="Helvetica"
|
||||
font-size="13" font-weight="normal">
|
||||
<tspan x="2865" y="1951">Requires Xcode 15 or greater</tspan>
|
||||
</text>
|
||||
<text id="descriptive-name" fill="#000000" fill-rule="nonzero" font-family="Helvetica" font-size="13"
|
||||
font-weight="normal">
|
||||
<tspan x="2835" y="1969">Generated from double.checkmark</tspan>
|
||||
</text>
|
||||
<text id="Typeset-at-100.0-points" fill="#000000" fill-rule="nonzero" font-family="Helvetica"
|
||||
font-size="13" font-weight="normal">
|
||||
<tspan x="2901" y="1987">Typeset at 100.0 points</tspan>
|
||||
</text>
|
||||
<text id="Small" fill="#000000" fill-rule="nonzero" font-family="Helvetica" font-size="13"
|
||||
font-weight="normal">
|
||||
<tspan x="263" y="726">Small</tspan>
|
||||
</text>
|
||||
<text id="Medium" fill="#000000" fill-rule="nonzero" font-family="Helvetica" font-size="13"
|
||||
font-weight="normal">
|
||||
<tspan x="263" y="1156">Medium</tspan>
|
||||
</text>
|
||||
<text id="Large" fill="#000000" fill-rule="nonzero" font-family="Helvetica" font-size="13"
|
||||
font-weight="normal">
|
||||
<tspan x="263" y="1586">Large</tspan>
|
||||
</text>
|
||||
</g>
|
||||
<g id="Guides" transform="translate(263, 600.785)">
|
||||
<g id="H-reference" transform="translate(76.9937, 24.756)" fill="#27AAE1" fill-rule="nonzero">
|
||||
<path
|
||||
d="M0,70.459 L2.644096,70.459 L28.334446,3.3267 L29.036646,3.3267 L29.036646,0 L27.128946,0 L0,70.459 Z M10.694846,45.9791 L45.987846,45.9791 L45.237846,43.7305 L11.444846,43.7305 L10.694846,45.9791 Z M54.125946,70.459 L56.770046,70.459 L29.644546,0 L28.438946,0 L28.438946,3.3267 L54.125946,70.459 Z"
|
||||
id="Shape"></path>
|
||||
</g>
|
||||
<line x1="0" y1="95.215" x2="2773" y2="95.215" id="Baseline-S" stroke="#27AAE1" stroke-width="0.5">
|
||||
</line>
|
||||
<line x1="0" y1="24.756" x2="2773" y2="24.756" id="Capline-S" stroke="#27AAE1" stroke-width="0.5">
|
||||
</line>
|
||||
<g id="H-reference" transform="translate(76.9937, 454.756)" fill="#27AAE1" fill-rule="nonzero">
|
||||
<path
|
||||
d="M0,70.459 L2.644096,70.459 L28.334446,3.3267 L29.036646,3.3267 L29.036646,0 L27.128946,0 L0,70.459 Z M10.694846,45.9791 L45.987846,45.9791 L45.237846,43.7305 L11.444846,43.7305 L10.694846,45.9791 Z M54.125946,70.459 L56.770046,70.459 L29.644546,0 L28.438946,0 L28.438946,3.3267 L54.125946,70.459 Z"
|
||||
id="Shape"></path>
|
||||
</g>
|
||||
<line x1="0" y1="525.215" x2="2773" y2="525.215" id="Baseline-M" stroke="#27AAE1" stroke-width="0.5">
|
||||
</line>
|
||||
<line x1="0" y1="454.755" x2="2773" y2="454.755" id="Capline-M" stroke="#27AAE1" stroke-width="0.5">
|
||||
</line>
|
||||
<g id="H-reference" transform="translate(76.9937, 884.756)" fill="#27AAE1" fill-rule="nonzero">
|
||||
<path
|
||||
d="M0,70.459 L2.644096,70.459 L28.334446,3.3267 L29.036646,3.3267 L29.036646,0 L27.128946,0 L0,70.459 Z M10.694846,45.9791 L45.987846,45.9791 L45.237846,43.7305 L11.444846,43.7305 L10.694846,45.9791 Z M54.125946,70.459 L56.770046,70.459 L29.644546,0 L28.438946,0 L28.438946,3.3267 L54.125946,70.459 Z"
|
||||
id="Shape"></path>
|
||||
</g>
|
||||
<line x1="0" y1="955.215" x2="2773" y2="955.215" id="Baseline-L" stroke="#27AAE1" stroke-width="0.5">
|
||||
</line>
|
||||
<line x1="0" y1="884.755" x2="2773" y2="884.755" id="Capline-L" stroke="#27AAE1" stroke-width="0.5">
|
||||
</line>
|
||||
<line x1="256.625" y1="1.13686838e-13" x2="256.625" y2="119.336" id="left-margin-Ultralight-S"
|
||||
stroke="#00AEEF" stroke-width="0.5"></line>
|
||||
<line x1="348.798" y1="1.13686838e-13" x2="348.798" y2="119.336" id="right-margin-Ultralight-S"
|
||||
stroke="#00AEEF" stroke-width="0.5"></line>
|
||||
<line x1="1143.53" y1="1.13686838e-13" x2="1143.53" y2="119.336" id="left-margin-Regular-S"
|
||||
stroke="#00AEEF" stroke-width="0.5"></line>
|
||||
<line x1="1257.15" y1="1.13686838e-13" x2="1257.15" y2="119.336" id="right-margin-Regular-S"
|
||||
stroke="#00AEEF" stroke-width="0.5"></line>
|
||||
<line x1="2622.62" y1="1.13686838e-13" x2="2622.62" y2="119.336" id="left-margin-Black-S"
|
||||
stroke="#00AEEF" stroke-width="0.5"></line>
|
||||
<line x1="2760.18" y1="1.13686838e-13" x2="2760.18" y2="119.336" id="right-margin-Black-S"
|
||||
stroke="#00AEEF" stroke-width="0.5"></line>
|
||||
</g>
|
||||
<g id="Symbols" transform="translate(529.3906, 625.2969)" stroke="#000000" stroke-width="0.5">
|
||||
<g id="Black-S" transform="translate(2365.995, 0)">
|
||||
<path
|
||||
d="M67.46878,71.191381 C71.17968,71.191381 74.06058,69.873022 76.01368,66.99216 L111.07228,15.2343 C112.43948,13.2324 113.02538,11.1328 113.02538,9.2773 C113.02538,4.0039 108.82618,0 103.35738,0 C99.69528,0 97.30278,1.3183 95.05668,4.834 L67.32228,47.9492 L53.69918,32.6172 C51.79488,30.4687 49.54888,29.4433 46.52148,29.4433 C41.05278,29.4433 37,33.4472 37,38.7695 C37,41.2109 37.63478,43.1152 39.73438,45.459 L59.36328,67.67576 C61.51168,70.117162 64.14848,71.191381 67.46878,71.191381 Z"
|
||||
id="Path"></path>
|
||||
<path
|
||||
d="M9.52148,29.4433 C12.54888,29.4433 14.79488,30.4687 16.69918,32.6172 L30.32228,47.9492 L32.291,44.888 L44.484,58.915 L39.01368,66.99216 C37.1235832,69.780091 34.3645791,71.1046997 30.825305,71.1872572 L30.46878,71.191381 C27.14848,71.191381 24.51168,70.117162 22.36328,67.67576 L2.73438,45.459 C0.63478,43.1152 0,41.2109 0,38.7695 C0,33.4472 4.05278,29.4433 9.52148,29.4433 Z M66.35738,0 C71.82618,0 76.02538,4.0039 76.02538,9.2773 C76.02538,11.1328 75.43948,13.2324 74.07228,15.2343 L61.951,33.129 L49.252,18.52 L58.05668,4.834 C60.2386057,1.41874857 62.5586852,0.0771252245 66.0465687,0.00324899359 Z"
|
||||
id="Combined-Shape"></path>
|
||||
</g>
|
||||
<g id="Regular-S" transform="translate(886.905, 3.7109)">
|
||||
<path
|
||||
d="M55.87888,66.113294 C57.78318,66.113294 59.29688,65.28322 60.37108,63.62306 L95.96678,7.3242 C96.79688,6.0547 97.08988,5.0293 97.08988,4.0039 C97.08988,1.6113 95.52738,0 93.08598,0 C91.32818,0 90.35158,0.586 89.27738,2.2949 L55.68358,56.2012 L38.00778,32.3731 C36.88478,30.8594 35.81058,30.2246 34.19918,30.2246 C31.75778,30.2246 30,31.9336 30,34.375 C30,35.4004 30.43948,36.5234 31.26958,37.5977 L51.24028,63.5254 C52.60738,65.28322 53.97458,66.113294 55.87888,66.113294 Z"
|
||||
id="Path"></path>
|
||||
<path
|
||||
d="M4.19918,30.2246 C5.81058,30.2246 6.88478,30.8594 8.00778,32.3731 L25.68358,56.2012 L30.332,48.741 L35.554,55.426 L30.37108,63.62306 C29.3457073,65.2077582 27.919881,66.0361177 26.1361316,66.1081489 L25.87888,66.113294 C23.97458,66.113294 22.60738,65.28322 21.24028,63.5254 L1.26958,37.5977 C0.43948,36.5234 0,35.4004 0,34.375 C0,31.9336 1.75778,30.2246 4.19918,30.2246 Z M63.08598,0 C65.52738,0 67.08988,1.6113 67.08988,4.0039 C67.08988,5.0293 66.79688,6.0547 65.96678,7.3242 L48.893,34.328 L43.564,27.508 L59.27738,2.2949 C60.3068217,0.657204167 61.2466272,0.0507828125 62.8702602,0.00309092159 Z"
|
||||
id="Combined-Shape"></path>
|
||||
</g>
|
||||
<g id="Ultralight-S" transform="translate(0, 4.4375)">
|
||||
<path
|
||||
d="M36.79298,62.07178 C37.24418,62.07178 37.53178,61.87744 37.78868,61.53417 L76.33598,2.0112 C76.57578,1.6045 76.64168,1.3965 76.64168,1.1885 C76.64168,0.5215 76.12358,0 75.45318,0 C75.01228,0 74.71678,0.1772 74.50538,0.5693 L36.73398,58.97114 L18.24078,37.7768 C17.98048,37.3984 17.67828,37.2177 17.20218,37.2177 C16.48638,37.2177 16,37.7006 16,38.371 C16,38.6699 16.12159,38.9755 16.40678,39.2778 L35.65088,61.52733 C36.01908,61.96826 36.29638,62.07178 36.79298,62.07178 Z"
|
||||
id="Path"></path>
|
||||
<path
|
||||
d="M1.20218,37.2177 C1.67828,37.2177 1.98048,37.3984 2.24078,37.7768 L20.73398,58.97114 L23.078,55.345 L24.636,57.137 L21.78868,61.53417 C21.5603244,61.8392989 21.3077121,62.0267547 20.937503,62.0646445 L20.79298,62.07178 C20.29638,62.07178 20.01908,61.96826 19.65088,61.52733 L0.40678,39.2778 C0.12159,38.9755 0,38.6699 0,38.371 C0,37.7006 0.48638,37.2177 1.20218,37.2177 Z M59.45318,0 C60.12358,0 60.64168,0.5215 60.64168,1.1885 C60.64168,1.3965 60.57578,1.6045 60.33598,2.0112 L32.216,45.432 L30.652,43.634 L58.50538,0.5693 C58.6932911,0.220766667 58.9476516,0.0420308642 59.3115144,0.00661467764 Z"
|
||||
id="Combined-Shape"></path>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 24 KiB |
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"info": {
|
||||
"author": "xcode",
|
||||
"version": 1
|
||||
},
|
||||
"symbols": [
|
||||
{
|
||||
"filename": "checkmark.wide.svg",
|
||||
"idiom": "universal"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,218 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="3300px" height="2200px" viewBox="0 0 3300 2200" version="1.1" xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<title>checkmark.wide</title>
|
||||
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="double.checkmark">
|
||||
<g id="Notes">
|
||||
<rect id="artboard" fill="#FFFFFF" fill-rule="nonzero" x="0" y="0" width="3300" height="2200"></rect>
|
||||
<line x1="263" y1="292" x2="3036" y2="292" id="Path" stroke="#000000" stroke-width="0.5"></line>
|
||||
<text id="Weight/Scale-Variations" fill="#000000" fill-rule="nonzero" font-family="Helvetica"
|
||||
font-size="13" font-weight="normal">
|
||||
<tspan x="263" y="322">Weight/Scale Variations</tspan>
|
||||
</text>
|
||||
<text id="Ultralight" fill="#000000" fill-rule="nonzero" font-family="Helvetica" font-size="13"
|
||||
font-weight="normal">
|
||||
<tspan x="533.711" y="322">Ultralight</tspan>
|
||||
</text>
|
||||
<text id="Thin" fill="#000000" fill-rule="nonzero" font-family="Helvetica" font-size="13"
|
||||
font-weight="normal">
|
||||
<tspan x="843.422" y="322">Thin</tspan>
|
||||
</text>
|
||||
<text id="Light" fill="#000000" fill-rule="nonzero" font-family="Helvetica" font-size="13"
|
||||
font-weight="normal">
|
||||
<tspan x="1138.63" y="322">Light</tspan>
|
||||
</text>
|
||||
<text id="Regular" fill="#000000" fill-rule="nonzero" font-family="Helvetica" font-size="13"
|
||||
font-weight="normal">
|
||||
<tspan x="1426.84" y="322">Regular</tspan>
|
||||
</text>
|
||||
<text id="Medium" fill="#000000" fill-rule="nonzero" font-family="Helvetica" font-size="13"
|
||||
font-weight="normal">
|
||||
<tspan x="1723.06" y="322">Medium</tspan>
|
||||
</text>
|
||||
<text id="Semibold" fill="#000000" fill-rule="nonzero" font-family="Helvetica" font-size="13"
|
||||
font-weight="normal">
|
||||
<tspan x="2015.77" y="322">Semibold</tspan>
|
||||
</text>
|
||||
<text id="Bold" fill="#000000" fill-rule="nonzero" font-family="Helvetica" font-size="13"
|
||||
font-weight="normal">
|
||||
<tspan x="2326.48" y="322">Bold</tspan>
|
||||
</text>
|
||||
<text id="Heavy" fill="#000000" fill-rule="nonzero" font-family="Helvetica" font-size="13"
|
||||
font-weight="normal">
|
||||
<tspan x="2618.19" y="322">Heavy</tspan>
|
||||
</text>
|
||||
<text id="Black" fill="#000000" fill-rule="nonzero" font-family="Helvetica" font-size="13"
|
||||
font-weight="normal">
|
||||
<tspan x="2917.4" y="322">Black</tspan>
|
||||
</text>
|
||||
<line x1="263" y1="1903" x2="3036" y2="1903" id="Path" stroke="#000000" stroke-width="0.5"></line>
|
||||
<g id="Group" transform="translate(264.3672, 1918.0684)" fill="#000000" fill-rule="nonzero">
|
||||
<path
|
||||
d="M7.88088,15.76172 C12.18752,15.76172 15.7715,12.1875 15.7715,7.88086 C15.7715,3.57422 12.17774,0 7.8711,0 C3.57422,0 0,3.57422 0,7.88086 C0,12.1875 3.58398,15.76172 7.88086,15.76172 L7.88088,15.76172 Z M7.88088,14.277344 C4.33596,14.277344 1.50392,11.435544 1.50392,7.880864 C1.50392,4.326184 4.32618,1.484384 7.8711,1.484384 C11.42578,1.484384 14.27734,4.326184 14.27734,7.880864 C14.27734,11.435544 11.43554,14.277344 7.88086,14.277344 L7.88088,14.277344 Z M4.28712,7.880864 C4.28712,8.310552 4.589854,8.60352 5.039074,8.60352 L7.138674,8.60352 L7.138674,10.72266 C7.138674,11.162114 7.431642,11.464848 7.86133,11.464848 C8.310548,11.464848 8.603518,11.162114 8.603518,10.72266 L8.603518,8.60352 L10.722658,8.60352 C11.162112,8.60352 11.464846,8.310552 11.464846,7.880864 C11.464846,7.44141 11.162112,7.138676 10.722658,7.138676 L8.603518,7.138676 L8.603518,5.029296 C8.603518,4.580078 8.31055,4.277342 7.86133,4.277342 C7.431642,4.277342 7.138674,4.580076 7.138674,5.029296 L7.138674,7.138676 L5.039074,7.138676 C4.589856,7.138676 4.28712,7.44141 4.28712,7.880864 Z"
|
||||
id="Shape"></path>
|
||||
</g>
|
||||
<g id="Group" transform="translate(283.254, 1915.9883)" fill="#000000" fill-rule="nonzero">
|
||||
<path
|
||||
d="M9.96094,19.92188 C15.41016,19.92188 19.92188,15.4004 19.92188,9.96094 C19.92188,4.51172 15.4004,0 9.95118,0 C4.51172,0 0,4.51172 0,9.96094 C0,15.4004 4.52148,19.92188 9.96094,19.92188 Z M9.96094,18.261724 C5.35156,18.261724 1.66992,14.570324 1.66992,9.960944 C1.66992,5.351564 5.3418,1.660164 9.95116,1.660164 C14.56052,1.660164 18.2617,5.351564 18.2617,9.960944 C18.2617,14.570324 14.5703,18.261724 9.96092,18.261724 L9.96094,18.261724 Z M5.4297,9.960944 C5.4297,10.43946 5.761732,10.761726 6.259778,10.761726 L9.130878,10.761726 L9.130878,13.642586 C9.130878,14.130868 9.46291,14.472664 9.941424,14.472664 C10.4297,14.472664 10.771502,14.140632 10.771502,13.642586 L10.771502,10.761726 L13.652362,10.761726 C14.140644,10.761726 14.48244,10.43946 14.48244,9.960944 C14.48244,9.472662 14.140644,9.130866 13.652362,9.130866 L10.771502,9.130866 L10.771502,6.259766 C10.771502,5.76172 10.4297,5.419922 9.941424,5.419922 C9.462908,5.419922 9.130878,5.761718 9.130878,6.259766 L9.130878,9.130866 L6.259778,9.130866 C5.761732,9.130866 5.4297,9.472662 5.4297,9.960944 Z"
|
||||
id="Shape"></path>
|
||||
</g>
|
||||
<g id="Group" transform="translate(307.1798, 1913.2246)" fill="#000000" fill-rule="nonzero">
|
||||
<path
|
||||
d="M12.71486,25.43944 C19.67776,25.43944 25.43946,19.67772 25.43946,12.7246 C25.43946,5.7617 19.66798,0 12.70508,0 C5.75196,0 -1.42108547e-15,5.76172 -1.42108547e-15,12.7246 C-1.42108547e-15,19.67772 5.76172,25.43944 12.71484,25.43944 L12.71486,25.43944 Z M12.71486,23.623034 C6.6797,23.623034 1.82618,18.759754 1.82618,12.724594 C1.82618,6.679674 6.66994,1.826154 12.70508,1.826154 C18.75,1.826154 23.61328,6.679674 23.61328,12.724594 C23.61328,18.759754 18.75976,23.623034 12.71484,23.623034 L12.71486,23.623034 Z M6.94338,12.724594 C6.94338,13.242172 7.314474,13.6035 7.861348,13.6035 L11.806668,13.6035 L11.806668,17.55858 C11.806668,18.09569 12.177762,18.476548 12.69534,18.476548 C13.23245,18.476548 13.603544,18.105454 13.603544,17.55858 L13.603544,13.6035 L17.558624,13.6035 C18.095734,13.6035 18.476592,13.242172 18.476592,12.724594 C18.476592,12.177718 18.105498,11.806626 17.558624,11.806626 L13.603544,11.806626 L13.603544,7.861306 C13.603544,7.31443 13.23245,6.933572 12.69534,6.933572 C12.177762,6.933572 11.806668,7.314432 11.806668,7.861306 L11.806668,11.806626 L7.861348,11.806626 C7.314472,11.806626 6.94338,12.17772 6.94338,12.724594 Z"
|
||||
id="Shape"></path>
|
||||
</g>
|
||||
<text id="Design-Variations" fill="#000000" fill-rule="nonzero" font-family="Helvetica" font-size="13"
|
||||
font-weight="normal">
|
||||
<tspan x="263" y="1953">Design Variations</tspan>
|
||||
</text>
|
||||
<text id="Symbols-are-supported-in-up-to-nine-weights-and-three-scales." fill="#000000"
|
||||
fill-rule="nonzero" font-family="Helvetica" font-size="13" font-weight="normal">
|
||||
<tspan x="263" y="1971">Symbols are supported in up to nine weights and three scales.</tspan>
|
||||
</text>
|
||||
<text id="For-optimal-layout-with-text-and-other-symbols,-vertically-align" fill="#000000"
|
||||
fill-rule="nonzero" font-family="Helvetica" font-size="13" font-weight="normal">
|
||||
<tspan x="263" y="1989">For optimal layout with text and other symbols, vertically align</tspan>
|
||||
</text>
|
||||
<text id="symbols-with-the-adjacent-text." fill="#000000" fill-rule="nonzero" font-family="Helvetica"
|
||||
font-size="13" font-weight="normal">
|
||||
<tspan x="263" y="2007">symbols with the adjacent text.</tspan>
|
||||
</text>
|
||||
<line x1="776" y1="1919" x2="776" y2="1933" id="Path" stroke="#00AEEF" stroke-width="0.5"></line>
|
||||
<g id="Group" transform="translate(778.4902, 1918.7324)" fill="#000000" fill-rule="nonzero">
|
||||
<path
|
||||
d="M0.8203116,14.423832 C1.3378896,14.423832 1.5917956,14.2285116 1.7773436,13.681636 L3.0371096,10.234376 L8.7988296,10.234376 L10.0585956,13.681636 C10.2441424,14.228512 10.4980496,14.423832 11.0058616,14.423832 C11.5234396,14.423832 11.8554716,14.111324 11.8554716,13.623042 C11.8554716,13.4570264 11.8261748,13.300776 11.7480498,13.095698 L7.1679698,0.898438 C6.9433598,0.302734 6.5429698,0 5.9179698,0 C5.3125018,0 4.9023458,0.292968 4.6875018,0.888672 L0.1074218,13.105472 C0.0292968,13.31055 -3.55271368e-16,13.4668 -3.55271368e-16,13.632816 C-3.55271368e-16,14.121098 0.3125,14.423832 0.820312,14.423832 L0.8203116,14.423832 Z M3.5156316,8.750004 L5.8886716,2.177744 L5.9374998,2.177744 L8.3105398,8.750004 L3.5156316,8.750004 Z"
|
||||
id="Shape"></path>
|
||||
</g>
|
||||
<line x1="792.836" y1="1919" x2="792.836" y2="1933" id="Path" stroke="#00AEEF" stroke-width="0.5">
|
||||
</line>
|
||||
<text id="Margins" fill="#000000" fill-rule="nonzero" font-family="Helvetica" font-size="13"
|
||||
font-weight="normal">
|
||||
<tspan x="776" y="1953">Margins</tspan>
|
||||
</text>
|
||||
<text id="Leading-and-trailing-margins-on-the-left-and-right-side-of-each-symbol" fill="#000000"
|
||||
fill-rule="nonzero" font-family="Helvetica" font-size="13" font-weight="normal">
|
||||
<tspan x="776" y="1971">Leading and trailing margins on the left and right side of each symbol
|
||||
</tspan>
|
||||
</text>
|
||||
<text id="can-be-adjusted-by-modifying-the-x-location-of-the-margin-guidelines." fill="#000000"
|
||||
fill-rule="nonzero" font-family="Helvetica" font-size="13" font-weight="normal">
|
||||
<tspan x="776" y="1989">can be adjusted by modifying the x-location of the margin guidelines.
|
||||
</tspan>
|
||||
</text>
|
||||
<text id="Modifications-are-automatically-applied-proportionally-to-all" fill="#000000"
|
||||
fill-rule="nonzero" font-family="Helvetica" font-size="13" font-weight="normal">
|
||||
<tspan x="776" y="2007">Modifications are automatically applied proportionally to all</tspan>
|
||||
</text>
|
||||
<text id="scales-and-weights." fill="#000000" fill-rule="nonzero" font-family="Helvetica" font-size="13"
|
||||
font-weight="normal">
|
||||
<tspan x="776" y="2025">scales and weights.</tspan>
|
||||
</text>
|
||||
<g id="Group" transform="translate(1291.2481, 1914.5174)" fill="#000000" fill-rule="nonzero">
|
||||
<path
|
||||
d="M0.593687825,20.3477978 L2.29290583,22.0567818 C3.15228183,22.9259218 4.13860983,22.8673278 5.06634583,21.8419378 L15.7597058,10.0548378 L14.7929098,9.07827578 L4.17766983,20.7579558 C3.82610783,21.1583458 3.49407583,21.2560018 3.02532583,20.7872526 L1.85344983,19.6251426 C1.38469983,19.1661586 1.49212183,18.8243606 1.89251223,18.4630326 L13.3671122,7.66225258 L12.3905502,6.69545658 L0.798750225,17.5841366 C-0.187577775,18.5021046 -0.265703775,19.4786686 0.593672225,20.3478166 L0.593687825,20.3477978 Z M7.00970783,2.15443778 C6.58978583,2.56459378 6.56048983,3.14076578 6.79486383,3.53139178 C7.02923983,3.89271978 7.48822383,4.12709578 8.13275383,3.96107978 C9.59759783,3.61928378 11.1210338,3.56068978 12.5468138,4.49818978 L11.9608758,5.95326778 C11.6190798,6.78334578 11.7948602,7.36928378 12.3319698,7.91615778 L14.6268898,10.2306178 C15.1151718,10.7188998 15.5253278,10.7384298 16.0917338,10.6407738 L17.1561878,10.4454614 L17.8202498,11.1192894 L17.7811874,11.6759294 C17.742125,12.1739754 17.869078,12.5548354 18.3573594,13.0333514 L19.1190774,13.7755394 C19.5975934,14.2540554 20.2128274,14.2833514 20.6815774,13.8146018 L23.5917374,10.8946818 C24.0604874,10.4259318 24.0409554,9.83022778 23.5624406,9.35171378 L22.7909566,8.58999578 C22.3124406,8.11147978 21.9413466,7.95522978 21.4628326,7.99429178 L20.8866606,8.04311998 L20.2421286,7.40835398 L20.4862686,6.28530798 C20.6132218,5.71890198 20.4569718,5.27944798 19.8710346,4.69351198 L17.6737746,2.50601198 C14.3339346,-0.814308021 9.90033463,-0.736168021 7.00971463,2.15444998 L7.00970783,2.15443778 Z M8.50384783,2.52553178 C10.9354878,0.748187779 14.2265078,1.05092178 16.4530678,3.27748578 L18.8847078,5.68958578 C19.1190838,5.92396178 19.1581458,6.10950778 19.0897858,6.45130378 L18.7675198,7.93567978 L20.2714258,9.42005578 L21.2577538,9.36146198 C21.5116598,9.35169636 21.5897858,9.3712276 21.7850978,9.56653998 L22.3612698,10.142712 L19.9198698,12.584112 L19.3436978,12.00794 C19.1483854,11.8126276 19.1190878,11.734502 19.1288538,11.47083 L19.1972132,10.494268 L17.7030732,9.00989198 L16.1796352,9.26379798 C15.8573692,9.33215738 15.7108852,9.30286038 15.4667452,9.06848558 L13.4647852,7.06652558 C13.2108792,6.83214958 13.1815812,6.66613558 13.337832,6.29504158 L14.216738,4.20520158 C12.654238,2.75012358 10.622978,2.12512158 8.59173803,2.72082558 C8.43548803,2.75988798 8.37689403,2.63293498 8.50384743,2.52551318 L8.50384783,2.52553178 Z"
|
||||
id="Shape"></path>
|
||||
</g>
|
||||
<text id="Exporting" fill="#000000" fill-rule="nonzero" font-family="Helvetica" font-size="13"
|
||||
font-weight="normal">
|
||||
<tspan x="1289" y="1953">Exporting</tspan>
|
||||
</text>
|
||||
<text id="Symbols-should-be-outlined-when-exporting-to-ensure-the" fill="#000000" fill-rule="nonzero"
|
||||
font-family="Helvetica" font-size="13" font-weight="normal">
|
||||
<tspan x="1289" y="1971">Symbols should be outlined when exporting to ensure the</tspan>
|
||||
</text>
|
||||
<text id="design-is-preserved-when-submitting-to-Xcode." fill="#000000" fill-rule="nonzero"
|
||||
font-family="Helvetica" font-size="13" font-weight="normal">
|
||||
<tspan x="1289" y="1989">design is preserved when submitting to Xcode.</tspan>
|
||||
</text>
|
||||
<text id="template-version" fill="#000000" fill-rule="nonzero" font-family="Helvetica" font-size="13"
|
||||
font-weight="normal">
|
||||
<tspan x="2952" y="1933">Template v.5.0</tspan>
|
||||
</text>
|
||||
<text id="Requires-Xcode-15-or-greater" fill="#000000" fill-rule="nonzero" font-family="Helvetica"
|
||||
font-size="13" font-weight="normal">
|
||||
<tspan x="2865" y="1951">Requires Xcode 15 or greater</tspan>
|
||||
</text>
|
||||
<text id="descriptive-name" fill="#000000" fill-rule="nonzero" font-family="Helvetica" font-size="13"
|
||||
font-weight="normal">
|
||||
<tspan x="2835" y="1969">Generated from double.checkmark</tspan>
|
||||
</text>
|
||||
<text id="Typeset-at-100.0-points" fill="#000000" fill-rule="nonzero" font-family="Helvetica"
|
||||
font-size="13" font-weight="normal">
|
||||
<tspan x="2901" y="1987">Typeset at 100.0 points</tspan>
|
||||
</text>
|
||||
<text id="Small" fill="#000000" fill-rule="nonzero" font-family="Helvetica" font-size="13"
|
||||
font-weight="normal">
|
||||
<tspan x="263" y="726">Small</tspan>
|
||||
</text>
|
||||
<text id="Medium" fill="#000000" fill-rule="nonzero" font-family="Helvetica" font-size="13"
|
||||
font-weight="normal">
|
||||
<tspan x="263" y="1156">Medium</tspan>
|
||||
</text>
|
||||
<text id="Large" fill="#000000" fill-rule="nonzero" font-family="Helvetica" font-size="13"
|
||||
font-weight="normal">
|
||||
<tspan x="263" y="1586">Large</tspan>
|
||||
</text>
|
||||
</g>
|
||||
<g id="Guides" transform="translate(263, 600.785)">
|
||||
<g id="H-reference" transform="translate(76.9937, 24.756)" fill="#27AAE1" fill-rule="nonzero">
|
||||
<path
|
||||
d="M0,70.459 L2.644096,70.459 L28.334446,3.3267 L29.036646,3.3267 L29.036646,0 L27.128946,0 L0,70.459 Z M10.694846,45.9791 L45.987846,45.9791 L45.237846,43.7305 L11.444846,43.7305 L10.694846,45.9791 Z M54.125946,70.459 L56.770046,70.459 L29.644546,0 L28.438946,0 L28.438946,3.3267 L54.125946,70.459 Z"
|
||||
id="Shape"></path>
|
||||
</g>
|
||||
<line x1="0" y1="95.215" x2="2773" y2="95.215" id="Baseline-S" stroke="#27AAE1" stroke-width="0.5">
|
||||
</line>
|
||||
<line x1="0" y1="24.756" x2="2773" y2="24.756" id="Capline-S" stroke="#27AAE1" stroke-width="0.5">
|
||||
</line>
|
||||
<g id="H-reference" transform="translate(76.9937, 454.756)" fill="#27AAE1" fill-rule="nonzero">
|
||||
<path
|
||||
d="M0,70.459 L2.644096,70.459 L28.334446,3.3267 L29.036646,3.3267 L29.036646,0 L27.128946,0 L0,70.459 Z M10.694846,45.9791 L45.987846,45.9791 L45.237846,43.7305 L11.444846,43.7305 L10.694846,45.9791 Z M54.125946,70.459 L56.770046,70.459 L29.644546,0 L28.438946,0 L28.438946,3.3267 L54.125946,70.459 Z"
|
||||
id="Shape"></path>
|
||||
</g>
|
||||
<line x1="0" y1="525.215" x2="2773" y2="525.215" id="Baseline-M" stroke="#27AAE1" stroke-width="0.5">
|
||||
</line>
|
||||
<line x1="0" y1="454.755" x2="2773" y2="454.755" id="Capline-M" stroke="#27AAE1" stroke-width="0.5">
|
||||
</line>
|
||||
<g id="H-reference" transform="translate(76.9937, 884.756)" fill="#27AAE1" fill-rule="nonzero">
|
||||
<path
|
||||
d="M0,70.459 L2.644096,70.459 L28.334446,3.3267 L29.036646,3.3267 L29.036646,0 L27.128946,0 L0,70.459 Z M10.694846,45.9791 L45.987846,45.9791 L45.237846,43.7305 L11.444846,43.7305 L10.694846,45.9791 Z M54.125946,70.459 L56.770046,70.459 L29.644546,0 L28.438946,0 L28.438946,3.3267 L54.125946,70.459 Z"
|
||||
id="Shape"></path>
|
||||
</g>
|
||||
<line x1="0" y1="955.215" x2="2773" y2="955.215" id="Baseline-L" stroke="#27AAE1" stroke-width="0.5">
|
||||
</line>
|
||||
<line x1="0" y1="884.755" x2="2773" y2="884.755" id="Capline-L" stroke="#27AAE1" stroke-width="0.5">
|
||||
</line>
|
||||
<line x1="256.625" y1="1.13686838e-13" x2="256.625" y2="119.336" id="left-margin-Ultralight-S"
|
||||
stroke="#00AEEF" stroke-width="0.5"></line>
|
||||
<line x1="348.798" y1="1.13686838e-13" x2="348.798" y2="119.336" id="right-margin-Ultralight-S"
|
||||
stroke="#00AEEF" stroke-width="0.5"></line>
|
||||
<line x1="1143.53" y1="1.13686838e-13" x2="1143.53" y2="119.336" id="left-margin-Regular-S"
|
||||
stroke="#00AEEF" stroke-width="0.5"></line>
|
||||
<line x1="1257.15" y1="1.13686838e-13" x2="1257.15" y2="119.336" id="right-margin-Regular-S"
|
||||
stroke="#00AEEF" stroke-width="0.5"></line>
|
||||
<line x1="2622.62" y1="1.13686838e-13" x2="2622.62" y2="119.336" id="left-margin-Black-S"
|
||||
stroke="#00AEEF" stroke-width="0.5"></line>
|
||||
<line x1="2760.18" y1="1.13686838e-13" x2="2760.18" y2="119.336" id="right-margin-Black-S"
|
||||
stroke="#00AEEF" stroke-width="0.5"></line>
|
||||
</g>
|
||||
<g id="Symbols" transform="translate(529.3906, 625.2969)" stroke="#000000" stroke-width="0.5">
|
||||
<g id="Black-S" transform="translate(2365.995, 0)">
|
||||
<path
|
||||
d="M30.46878,71.191381 C34.17968,71.191381 37.06058,69.873022 39.01368,66.99216 L74.07228,15.2343 C75.43948,13.2324 76.02538,11.1328 76.02538,9.2773 C76.02538,4.0039 71.82618,0 66.35738,0 C62.69528,0 60.30278,1.3183 58.05668,4.834 L30.32228,47.9492 L16.69918,32.6172 C14.79488,30.4687 12.54888,29.4433 9.52148,29.4433 C4.05278,29.4433 0,33.4472 0,38.7695 C0,41.2109 0.63478,43.1152 2.73438,45.459 L22.36328,67.67576 C24.51168,70.117162 27.14848,71.191381 30.46878,71.191381 Z"
|
||||
id="Path"></path>
|
||||
</g>
|
||||
<g id="Regular-S" transform="translate(886.905, 3.7109)">
|
||||
<path
|
||||
d="M25.87888,66.113294 C27.78318,66.113294 29.29688,65.28322 30.37108,63.62306 L65.96678,7.3242 C66.79688,6.0547 67.08988,5.0293 67.08988,4.0039 C67.08988,1.6113 65.52738,0 63.08598,0 C61.32818,0 60.35158,0.586 59.27738,2.2949 L25.68358,56.2012 L8.00778,32.3731 C6.88478,30.8594 5.81058,30.2246 4.19918,30.2246 C1.75778,30.2246 0,31.9336 0,34.375 C0,35.4004 0.43948,36.5234 1.26958,37.5977 L21.24028,63.5254 C22.60738,65.28322 23.97458,66.113294 25.87888,66.113294 Z"
|
||||
id="Path"></path>
|
||||
</g>
|
||||
<g id="Ultralight-S" transform="translate(0, 4.4375)">
|
||||
<path
|
||||
d="M20.79298,62.07178 C21.24418,62.07178 21.53178,61.87744 21.78868,61.53417 L60.33598,2.0112 C60.57578,1.6045 60.64168,1.3965 60.64168,1.1885 C60.64168,0.5215 60.12358,0 59.45318,0 C59.01228,0 58.71678,0.1772 58.50538,0.5693 L20.73398,58.97114 L2.24078,37.7768 C1.98048,37.3984 1.67828,37.2177 1.20218,37.2177 C0.48638,37.2177 0,37.7006 0,38.371 C0,38.6699 0.12159,38.9755 0.40678,39.2778 L19.65088,61.52733 C20.01908,61.96826 20.29638,62.07178 20.79298,62.07178 Z"
|
||||
id="Path"></path>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 22 KiB |
@@ -36,7 +36,7 @@ struct ContentView: View {
|
||||
@State private var waitingForOrPassedAuth = true
|
||||
@State private var chatListActionSheet: ChatListActionSheet? = nil
|
||||
|
||||
private let callTopPadding: CGFloat = 50
|
||||
private let callTopPadding: CGFloat = 40
|
||||
|
||||
private enum ChatListActionSheet: Identifiable {
|
||||
case planAndConnectSheet(sheet: PlanAndConnectActionSheet)
|
||||
@@ -151,12 +151,12 @@ struct ContentView: View {
|
||||
}
|
||||
}
|
||||
.onAppear {
|
||||
reactOnDarkThemeChanges()
|
||||
reactOnDarkThemeChanges(systemInDarkThemeCurrently)
|
||||
}
|
||||
.onChange(of: colorScheme) { scheme in
|
||||
// It's needed to update UI colors when iOS wants to make screenshot after going to background,
|
||||
// so when a user changes his global theme from dark to light or back, the app will adapt to it
|
||||
reactOnDarkThemeChanges()
|
||||
reactOnDarkThemeChanges(scheme == .dark)
|
||||
}
|
||||
.onChange(of: theme.name) { _ in
|
||||
ThemeManager.adjustWindowStyle()
|
||||
@@ -207,7 +207,7 @@ struct ContentView: View {
|
||||
CallDuration(call: call)
|
||||
}
|
||||
.padding(.horizontal)
|
||||
.frame(height: callTopPadding - 10)
|
||||
.frame(height: callTopPadding)
|
||||
.background(Color(uiColor: UIColor(red: 47/255, green: 208/255, blue: 88/255, alpha: 1)))
|
||||
.onTapGesture {
|
||||
chatModel.activeCallViewIsCollapsed = false
|
||||
|
||||
@@ -50,12 +50,85 @@ class ItemsModel: ObservableObject {
|
||||
var reversedChatItems: [ChatItem] = [] {
|
||||
willSet { publisher.send() }
|
||||
}
|
||||
var itemAdded = false {
|
||||
willSet { publisher.send() }
|
||||
}
|
||||
|
||||
// Publishes directly to `objectWillChange` publisher,
|
||||
// this will cause reversedChatItems to be rendered without throttling
|
||||
@Published var isLoading = false
|
||||
@Published var showLoadingProgress = false
|
||||
|
||||
init() {
|
||||
publisher
|
||||
.throttle(for: 0.25, scheduler: DispatchQueue.main, latest: true)
|
||||
.sink { self.objectWillChange.send() }
|
||||
.store(in: &bag)
|
||||
}
|
||||
|
||||
func loadOpenChat(_ chatId: ChatId, willNavigate: @escaping () -> Void = {}) {
|
||||
let navigationTimeout = Task {
|
||||
do {
|
||||
try await Task.sleep(nanoseconds: 250_000000)
|
||||
await MainActor.run {
|
||||
willNavigate()
|
||||
ChatModel.shared.chatId = chatId
|
||||
}
|
||||
} catch {}
|
||||
}
|
||||
let progressTimeout = Task {
|
||||
do {
|
||||
try await Task.sleep(nanoseconds: 1500_000000)
|
||||
await MainActor.run { showLoadingProgress = true }
|
||||
} catch {}
|
||||
}
|
||||
Task {
|
||||
if let chat = ChatModel.shared.getChat(chatId) {
|
||||
await MainActor.run { self.isLoading = true }
|
||||
// try? await Task.sleep(nanoseconds: 5000_000000)
|
||||
await loadChat(chat: chat)
|
||||
navigationTimeout.cancel()
|
||||
progressTimeout.cancel()
|
||||
await MainActor.run {
|
||||
self.isLoading = false
|
||||
self.showLoadingProgress = false
|
||||
willNavigate()
|
||||
ChatModel.shared.chatId = chatId
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class NetworkModel: ObservableObject {
|
||||
// map of connections network statuses, key is agent connection id
|
||||
@Published var networkStatuses: Dictionary<String, NetworkStatus> = [:]
|
||||
|
||||
static let shared = NetworkModel()
|
||||
|
||||
private init() { }
|
||||
|
||||
func setContactNetworkStatus(_ contact: Contact, _ status: NetworkStatus) {
|
||||
if let conn = contact.activeConn {
|
||||
networkStatuses[conn.agentConnId] = status
|
||||
}
|
||||
}
|
||||
|
||||
func contactNetworkStatus(_ contact: Contact) -> NetworkStatus {
|
||||
if let conn = contact.activeConn {
|
||||
networkStatuses[conn.agentConnId] ?? .unknown
|
||||
} else {
|
||||
.unknown
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// ChatItemWithMenu can depend on previous or next item for it's appearance
|
||||
/// This dummy model is used to force an update of all chat items,
|
||||
/// when they might have changed appearance.
|
||||
class ChatItemDummyModel: ObservableObject {
|
||||
static let shared = ChatItemDummyModel()
|
||||
func sendUpdate() { objectWillChange.send() }
|
||||
}
|
||||
|
||||
final class ChatModel: ObservableObject {
|
||||
@@ -78,10 +151,8 @@ final class ChatModel: ObservableObject {
|
||||
@Published var contentViewAccessAuthenticated: Bool = false
|
||||
@Published var laRequest: LocalAuthRequest?
|
||||
// list of chat "previews"
|
||||
@Published var chats: [Chat] = []
|
||||
@Published private(set) var chats: [Chat] = []
|
||||
@Published var deletedChats: Set<String> = []
|
||||
// map of connections network statuses, key is agent connection id
|
||||
@Published var networkStatuses: Dictionary<String, NetworkStatus> = [:]
|
||||
// current chat
|
||||
@Published var chatId: String?
|
||||
var chatItemStatuses: Dictionary<Int64, CIStatus> = [:]
|
||||
@@ -120,8 +191,6 @@ final class ChatModel: ObservableObject {
|
||||
@Published var stopPreviousRecPlay: URL? = nil // coordinates currently playing source
|
||||
@Published var draft: ComposeState?
|
||||
@Published var draftChatId: String?
|
||||
// tracks keyboard height via subscription in AppDelegate
|
||||
@Published var keyboardHeight: CGFloat = 0
|
||||
@Published var pasteboardHasStrings: Bool = UIPasteboard.general.hasStrings
|
||||
@Published var networkInfo = UserNetworkInfo(networkType: .other, online: true)
|
||||
|
||||
@@ -228,10 +297,17 @@ final class ChatModel: ObservableObject {
|
||||
chats.firstIndex(where: { $0.id == id })
|
||||
}
|
||||
|
||||
func addChat(_ chat: Chat, at position: Int = 0) {
|
||||
withAnimation {
|
||||
chats.insert(chat, at: position)
|
||||
func addChat(_ chat: Chat) {
|
||||
if chatId == nil {
|
||||
withAnimation { addChat_(chat, at: 0) }
|
||||
} else {
|
||||
addChat_(chat, at: 0)
|
||||
}
|
||||
popChatCollector.throttlePopChat(chat.chatInfo.id, currentPosition: 0)
|
||||
}
|
||||
|
||||
func addChat_(_ chat: Chat, at position: Int = 0) {
|
||||
chats.insert(chat, at: position)
|
||||
}
|
||||
|
||||
func updateChatInfo(_ cInfo: ChatInfo) {
|
||||
@@ -289,26 +365,10 @@ final class ChatModel: ObservableObject {
|
||||
}
|
||||
}
|
||||
|
||||
func updateChats(with newChats: [ChatData]) {
|
||||
for i in 0..<newChats.count {
|
||||
let c = newChats[i]
|
||||
if let j = getChatIndex(c.id) {
|
||||
let chat = chats[j]
|
||||
chat.chatInfo = c.chatInfo
|
||||
chat.chatItems = c.chatItems
|
||||
chat.chatStats = c.chatStats
|
||||
if i != j {
|
||||
if chatId != c.chatInfo.id {
|
||||
popChat_(j, to: i)
|
||||
} else if i == 0 {
|
||||
chatToTop = c.chatInfo.id
|
||||
}
|
||||
}
|
||||
} else {
|
||||
addChat(Chat(c), at: i)
|
||||
}
|
||||
}
|
||||
func updateChats(_ newChats: [ChatData]) {
|
||||
chats = newChats.map { Chat($0) }
|
||||
NtfManager.shared.setNtfBadgeCount(totalUnreadCountForAllUsers())
|
||||
popChatCollector.clear()
|
||||
}
|
||||
|
||||
// func addGroup(_ group: SimpleXChat.Group) {
|
||||
@@ -316,6 +376,12 @@ final class ChatModel: ObservableObject {
|
||||
// }
|
||||
|
||||
func addChatItem(_ cInfo: ChatInfo, _ cItem: ChatItem) {
|
||||
// mark chat non deleted
|
||||
if case let .direct(contact) = cInfo, contact.chatDeleted {
|
||||
var updatedContact = contact
|
||||
updatedContact.chatDeleted = false
|
||||
updateContact(updatedContact)
|
||||
}
|
||||
// update previews
|
||||
if let i = getChatIndex(cInfo.id) {
|
||||
chats[i].chatItems = switch cInfo {
|
||||
@@ -335,7 +401,7 @@ final class ChatModel: ObservableObject {
|
||||
if case .rcvNew = cItem.meta.itemStatus {
|
||||
unreadCollector.changeUnreadCounter(cInfo.id, by: 1)
|
||||
}
|
||||
popChatCollector.addChat(cInfo.id)
|
||||
popChatCollector.throttlePopChat(cInfo.id, currentPosition: i)
|
||||
} else {
|
||||
addChat(Chat(chatInfo: cInfo, chatItems: [cItem]))
|
||||
}
|
||||
@@ -370,18 +436,17 @@ final class ChatModel: ObservableObject {
|
||||
|
||||
private func _upsertChatItem(_ cInfo: ChatInfo, _ cItem: ChatItem) -> Bool {
|
||||
if let i = getChatItemIndex(cItem) {
|
||||
withConditionalAnimation {
|
||||
_updateChatItem(at: i, with: cItem)
|
||||
}
|
||||
_updateChatItem(at: i, with: cItem)
|
||||
ChatItemDummyModel.shared.sendUpdate()
|
||||
return false
|
||||
} else {
|
||||
withConditionalAnimation(itemAnimation()) {
|
||||
var ci = cItem
|
||||
if let status = chatItemStatuses.removeValue(forKey: ci.id), case .sndNew = ci.meta.itemStatus {
|
||||
ci.meta.itemStatus = status
|
||||
}
|
||||
im.reversedChatItems.insert(ci, at: hasLiveDummy ? 1 : 0)
|
||||
var ci = cItem
|
||||
if let status = chatItemStatuses.removeValue(forKey: ci.id), case .sndNew = ci.meta.itemStatus {
|
||||
ci.meta.itemStatus = status
|
||||
}
|
||||
im.reversedChatItems.insert(ci, at: hasLiveDummy ? 1 : 0)
|
||||
im.itemAdded = true
|
||||
ChatItemDummyModel.shared.sendUpdate()
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -475,6 +540,7 @@ final class ChatModel: ObservableObject {
|
||||
let cItem = ChatItem.liveDummy(chatInfo.chatType)
|
||||
withAnimation {
|
||||
im.reversedChatItems.insert(cItem, at: 0)
|
||||
im.itemAdded = true
|
||||
}
|
||||
return cItem
|
||||
}
|
||||
@@ -610,29 +676,61 @@ final class ChatModel: ObservableObject {
|
||||
class PopChatCollector {
|
||||
private let subject = PassthroughSubject<Void, Never>()
|
||||
private var bag = Set<AnyCancellable>()
|
||||
private var chatsToPop: [ChatId: Date] = [:]
|
||||
private let popTsComparator = KeyPathComparator<Chat>(\.popTs, order: .reverse)
|
||||
|
||||
init() {
|
||||
subject
|
||||
.throttle(for: 2, scheduler: DispatchQueue.main, latest: true)
|
||||
.sink {
|
||||
let m = ChatModel.shared
|
||||
if m.chatId == nil {
|
||||
withAnimation {
|
||||
m.chats = m.chats.sorted(using: KeyPathComparator(\.popTs, order: .reverse))
|
||||
}
|
||||
} else {
|
||||
m.chats = m.chats.sorted(using: KeyPathComparator(\.popTs, order: .reverse))
|
||||
}
|
||||
}
|
||||
.sink { self.popCollectedChats() }
|
||||
.store(in: &bag)
|
||||
}
|
||||
|
||||
func addChat(_ chatId: ChatId) {
|
||||
if let index = ChatModel.shared.getChatIndex(chatId) {
|
||||
ChatModel.shared.chats[index].popTs = CFAbsoluteTimeGetCurrent()
|
||||
func throttlePopChat(_ chatId: ChatId, currentPosition: Int) {
|
||||
let m = ChatModel.shared
|
||||
if currentPosition > 0 && m.chatId == chatId {
|
||||
m.chatToTop = chatId
|
||||
}
|
||||
if currentPosition > 0 || !chatsToPop.isEmpty {
|
||||
chatsToPop[chatId] = Date.now
|
||||
subject.send()
|
||||
}
|
||||
}
|
||||
|
||||
func clear() {
|
||||
chatsToPop = [:]
|
||||
}
|
||||
|
||||
func popCollectedChats() {
|
||||
let m = ChatModel.shared
|
||||
var ixs: IndexSet = []
|
||||
var chs: [Chat] = []
|
||||
// collect chats that received updates
|
||||
for (chatId, popTs) in self.chatsToPop {
|
||||
// Currently opened chat is excluded, removing it from the list would navigate out of it
|
||||
// It will be popped to top later when user exits from the list.
|
||||
if m.chatId != chatId, let i = m.getChatIndex(chatId) {
|
||||
ixs.insert(i)
|
||||
let ch = m.chats[i]
|
||||
ch.popTs = popTs
|
||||
chs.append(ch)
|
||||
}
|
||||
}
|
||||
|
||||
let removeInsert = {
|
||||
m.chats.remove(atOffsets: ixs)
|
||||
// sort chats by pop timestamp in descending order
|
||||
m.chats.insert(contentsOf: chs.sorted(using: self.popTsComparator), at: 0)
|
||||
}
|
||||
|
||||
if m.chatId == nil {
|
||||
withAnimation { removeInsert() }
|
||||
} else {
|
||||
removeInsert()
|
||||
}
|
||||
|
||||
self.chatsToPop = [:]
|
||||
}
|
||||
}
|
||||
|
||||
private func markChatItemRead_(_ i: Int) {
|
||||
@@ -729,6 +827,7 @@ final class ChatModel: ObservableObject {
|
||||
|
||||
func popChat(_ id: String) {
|
||||
if let i = getChatIndex(id) {
|
||||
// no animation here, for it not to look like it just moved when leaving the chat
|
||||
popChat_(i)
|
||||
}
|
||||
}
|
||||
@@ -789,43 +888,6 @@ final class ChatModel: ObservableObject {
|
||||
_ = upsertGroupMember(groupInfo, updatedMember)
|
||||
}
|
||||
}
|
||||
|
||||
func unreadChatItemCounts(itemsInView: Set<String>) -> UnreadChatItemCounts {
|
||||
var i = 0
|
||||
var totalBelow = 0
|
||||
var unreadBelow = 0
|
||||
while i < im.reversedChatItems.count - 1 && !itemsInView.contains(im.reversedChatItems[i].viewId) {
|
||||
totalBelow += 1
|
||||
if im.reversedChatItems[i].isRcvNew {
|
||||
unreadBelow += 1
|
||||
}
|
||||
i += 1
|
||||
}
|
||||
return UnreadChatItemCounts(isNearBottom: totalBelow < 16, unreadBelow: unreadBelow)
|
||||
}
|
||||
|
||||
func topItemInView(itemsInView: Set<String>) -> ChatItem? {
|
||||
let maxIx = im.reversedChatItems.count - 1
|
||||
var i = 0
|
||||
let inView = { itemsInView.contains(self.im.reversedChatItems[$0].viewId) }
|
||||
while i < maxIx && !inView(i) { i += 1 }
|
||||
while i < maxIx && inView(i) { i += 1 }
|
||||
return im.reversedChatItems[min(i - 1, maxIx)]
|
||||
}
|
||||
|
||||
func setContactNetworkStatus(_ contact: Contact, _ status: NetworkStatus) {
|
||||
if let conn = contact.activeConn {
|
||||
networkStatuses[conn.agentConnId] = status
|
||||
}
|
||||
}
|
||||
|
||||
func contactNetworkStatus(_ contact: Contact) -> NetworkStatus {
|
||||
if let conn = contact.activeConn {
|
||||
networkStatuses[conn.agentConnId] ?? .unknown
|
||||
} else {
|
||||
.unknown
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct ShowingInvitation {
|
||||
@@ -838,17 +900,12 @@ struct NTFContactRequest {
|
||||
var chatId: String
|
||||
}
|
||||
|
||||
struct UnreadChatItemCounts: Equatable {
|
||||
var isNearBottom: Bool
|
||||
var unreadBelow: Int
|
||||
}
|
||||
|
||||
final class Chat: ObservableObject, Identifiable, ChatLike {
|
||||
@Published var chatInfo: ChatInfo
|
||||
@Published var chatItems: [ChatItem]
|
||||
@Published var chatStats: ChatStats
|
||||
var created = Date.now
|
||||
var popTs: CFAbsoluteTime?
|
||||
fileprivate var popTs: Date?
|
||||
|
||||
init(_ cData: ChatData) {
|
||||
self.chatInfo = cData.chatInfo
|
||||
|
||||
@@ -57,7 +57,9 @@ class NtfManager: NSObject, UNUserNotificationCenterDelegate, ObservableObject {
|
||||
chatModel.ntfCallInvitationAction = (chatId, ntfAction)
|
||||
}
|
||||
} else {
|
||||
chatModel.chatId = content.targetContentIdentifier
|
||||
if let chatId = content.targetContentIdentifier {
|
||||
ItemsModel.shared.loadOpenChat(chatId)
|
||||
}
|
||||
}
|
||||
handler()
|
||||
}
|
||||
|
||||
@@ -112,9 +112,9 @@ func chatSendCmdSync(_ cmd: ChatCommand, bgTask: Bool = true, bgDelay: Double? =
|
||||
return resp
|
||||
}
|
||||
|
||||
func chatSendCmd(_ cmd: ChatCommand, bgTask: Bool = true, bgDelay: Double? = nil, _ ctrl: chat_ctrl? = nil) async -> ChatResponse {
|
||||
func chatSendCmd(_ cmd: ChatCommand, bgTask: Bool = true, bgDelay: Double? = nil, _ ctrl: chat_ctrl? = nil, log: Bool = true) async -> ChatResponse {
|
||||
await withCheckedContinuation { cont in
|
||||
cont.resume(returning: chatSendCmdSync(cmd, bgTask: bgTask, bgDelay: bgDelay, ctrl))
|
||||
cont.resume(returning: chatSendCmdSync(cmd, bgTask: bgTask, bgDelay: bgDelay, ctrl, log: log))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -320,8 +320,8 @@ private func apiChatsResponse(_ r: ChatResponse) throws -> [ChatData] {
|
||||
|
||||
let loadItemsPerPage = 50
|
||||
|
||||
func apiGetChat(type: ChatType, id: Int64, search: String = "") throws -> Chat {
|
||||
let r = chatSendCmdSync(.apiGetChat(type: type, id: id, pagination: .last(count: loadItemsPerPage), search: search))
|
||||
func apiGetChat(type: ChatType, id: Int64, search: String = "") async throws -> Chat {
|
||||
let r = await chatSendCmd(.apiGetChat(type: type, id: id, pagination: .last(count: loadItemsPerPage), search: search))
|
||||
if case let .apiChat(_, chat) = r { return Chat.init(chat) }
|
||||
throw r
|
||||
}
|
||||
@@ -332,22 +332,20 @@ func apiGetChatItems(type: ChatType, id: Int64, pagination: ChatPagination, sear
|
||||
throw r
|
||||
}
|
||||
|
||||
func loadChat(chat: Chat, search: String = "") {
|
||||
func loadChat(chat: Chat, search: String = "", clearItems: Bool = true) async {
|
||||
do {
|
||||
let cInfo = chat.chatInfo
|
||||
let m = ChatModel.shared
|
||||
let im = ItemsModel.shared
|
||||
m.chatItemStatuses = [:]
|
||||
im.reversedChatItems = []
|
||||
let chat = try apiGetChat(type: cInfo.chatType, id: cInfo.apiId, search: search)
|
||||
if case let .direct(contact) = chat.chatInfo, !cInfo.chatDeleted, chat.chatInfo.chatDeleted {
|
||||
var updatedContact = contact
|
||||
updatedContact.chatDeleted = false
|
||||
m.updateContact(updatedContact)
|
||||
} else {
|
||||
if clearItems {
|
||||
await MainActor.run { im.reversedChatItems = [] }
|
||||
}
|
||||
let chat = try await apiGetChat(type: cInfo.chatType, id: cInfo.apiId, search: search)
|
||||
await MainActor.run {
|
||||
im.reversedChatItems = chat.chatItems.reversed()
|
||||
m.updateChatInfo(chat.chatInfo)
|
||||
}
|
||||
im.reversedChatItems = chat.chatItems.reversed()
|
||||
} catch let error {
|
||||
logger.error("loadChat error: \(responseError(error))")
|
||||
}
|
||||
@@ -359,17 +357,17 @@ func apiGetChatItemInfo(type: ChatType, id: Int64, itemId: Int64) async throws -
|
||||
throw r
|
||||
}
|
||||
|
||||
func apiForwardChatItem(toChatType: ChatType, toChatId: Int64, fromChatType: ChatType, fromChatId: Int64, itemId: Int64, ttl: Int?) async -> ChatItem? {
|
||||
let cmd: ChatCommand = .apiForwardChatItem(toChatType: toChatType, toChatId: toChatId, fromChatType: fromChatType, fromChatId: fromChatId, itemId: itemId, ttl: ttl)
|
||||
func apiForwardChatItems(toChatType: ChatType, toChatId: Int64, fromChatType: ChatType, fromChatId: Int64, itemIds: [Int64], ttl: Int?) async -> [ChatItem]? {
|
||||
let cmd: ChatCommand = .apiForwardChatItems(toChatType: toChatType, toChatId: toChatId, fromChatType: fromChatType, fromChatId: fromChatId, itemIds: itemIds, ttl: ttl)
|
||||
return await processSendMessageCmd(toChatType: toChatType, cmd: cmd)
|
||||
}
|
||||
|
||||
func apiSendMessage(type: ChatType, id: Int64, file: CryptoFile?, quotedItemId: Int64?, msg: MsgContent, live: Bool = false, ttl: Int? = nil) async -> ChatItem? {
|
||||
let cmd: ChatCommand = .apiSendMessage(type: type, id: id, file: file, quotedItemId: quotedItemId, msg: msg, live: live, ttl: ttl)
|
||||
func apiSendMessages(type: ChatType, id: Int64, live: Bool = false, ttl: Int? = nil, composedMessages: [ComposedMessage]) async -> [ChatItem]? {
|
||||
let cmd: ChatCommand = .apiSendMessages(type: type, id: id, live: live, ttl: ttl, composedMessages: composedMessages)
|
||||
return await processSendMessageCmd(toChatType: type, cmd: cmd)
|
||||
}
|
||||
|
||||
private func processSendMessageCmd(toChatType: ChatType, cmd: ChatCommand) async -> ChatItem? {
|
||||
private func processSendMessageCmd(toChatType: ChatType, cmd: ChatCommand) async -> [ChatItem]? {
|
||||
let chatModel = ChatModel.shared
|
||||
let r: ChatResponse
|
||||
if toChatType == .direct {
|
||||
@@ -382,10 +380,13 @@ private func processSendMessageCmd(toChatType: ChatType, cmd: ChatCommand) async
|
||||
}
|
||||
})
|
||||
r = await chatSendCmd(cmd, bgTask: false)
|
||||
if case let .newChatItem(_, aChatItem) = r {
|
||||
cItem = aChatItem.chatItem
|
||||
chatModel.messageDelivery[aChatItem.chatItem.id] = endTask
|
||||
return cItem
|
||||
if case let .newChatItems(_, aChatItems) = r {
|
||||
let cItems = aChatItems.map { $0.chatItem }
|
||||
if let cItemLast = cItems.last {
|
||||
cItem = cItemLast
|
||||
chatModel.messageDelivery[cItemLast.id] = endTask
|
||||
}
|
||||
return cItems
|
||||
}
|
||||
if let networkErrorAlert = networkErrorAlert(r) {
|
||||
AlertManager.shared.showAlert(networkErrorAlert)
|
||||
@@ -396,18 +397,18 @@ private func processSendMessageCmd(toChatType: ChatType, cmd: ChatCommand) async
|
||||
return nil
|
||||
} else {
|
||||
r = await chatSendCmd(cmd, bgDelay: msgDelay)
|
||||
if case let .newChatItem(_, aChatItem) = r {
|
||||
return aChatItem.chatItem
|
||||
if case let .newChatItems(_, aChatItems) = r {
|
||||
return aChatItems.map { $0.chatItem }
|
||||
}
|
||||
sendMessageErrorAlert(r)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func apiCreateChatItem(noteFolderId: Int64, file: CryptoFile?, msg: MsgContent) async -> ChatItem? {
|
||||
let r = await chatSendCmd(.apiCreateChatItem(noteFolderId: noteFolderId, file: file, msg: msg))
|
||||
if case let .newChatItem(_, aChatItem) = r { return aChatItem.chatItem }
|
||||
createChatItemErrorAlert(r)
|
||||
func apiCreateChatItems(noteFolderId: Int64, composedMessages: [ComposedMessage]) async -> [ChatItem]? {
|
||||
let r = await chatSendCmd(.apiCreateChatItems(noteFolderId: noteFolderId, composedMessages: composedMessages))
|
||||
if case let .newChatItems(_, aChatItems) = r { return aChatItems.map { $0.chatItem } }
|
||||
createChatItemsErrorAlert(r)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -419,8 +420,8 @@ private func sendMessageErrorAlert(_ r: ChatResponse) {
|
||||
)
|
||||
}
|
||||
|
||||
private func createChatItemErrorAlert(_ r: ChatResponse) {
|
||||
logger.error("apiCreateChatItem error: \(String(describing: r))")
|
||||
private func createChatItemsErrorAlert(_ r: ChatResponse) {
|
||||
logger.error("apiCreateChatItems error: \(String(describing: r))")
|
||||
AlertManager.shared.showAlertMsg(
|
||||
title: "Error creating message",
|
||||
message: "Error: \(responseError(r))"
|
||||
@@ -584,13 +585,13 @@ func apiGroupMemberInfo(_ groupId: Int64, _ groupMemberId: Int64) throws -> (Gro
|
||||
throw r
|
||||
}
|
||||
|
||||
func apiContactQueueInfo(_ contactId: Int64) async throws -> (RcvMsgInfo?, QueueInfo) {
|
||||
func apiContactQueueInfo(_ contactId: Int64) async throws -> (RcvMsgInfo?, ServerQueueInfo) {
|
||||
let r = await chatSendCmd(.apiContactQueueInfo(contactId: contactId))
|
||||
if case let .queueInfo(_, rcvMsgInfo, queueInfo) = r { return (rcvMsgInfo, queueInfo) }
|
||||
throw r
|
||||
}
|
||||
|
||||
func apiGroupMemberQueueInfo(_ groupId: Int64, _ groupMemberId: Int64) async throws -> (RcvMsgInfo?, QueueInfo) {
|
||||
func apiGroupMemberQueueInfo(_ groupId: Int64, _ groupMemberId: Int64) async throws -> (RcvMsgInfo?, ServerQueueInfo) {
|
||||
let r = await chatSendCmd(.apiGroupMemberQueueInfo(groupId: groupId, groupMemberId: groupMemberId))
|
||||
if case let .queueInfo(_, rcvMsgInfo, queueInfo) = r { return (rcvMsgInfo, queueInfo) }
|
||||
throw r
|
||||
@@ -675,6 +676,13 @@ func apiSetConnectionIncognito(connId: Int64, incognito: Bool) async throws -> P
|
||||
throw r
|
||||
}
|
||||
|
||||
func apiChangeConnectionUser(connId: Int64, userId: Int64) async throws -> PendingContactConnection? {
|
||||
let r = await chatSendCmd(.apiChangeConnectionUser(connId: connId, userId: userId))
|
||||
|
||||
if case let .connectionUserChanged(_, _, toConnection, _) = r {return toConnection}
|
||||
throw r
|
||||
}
|
||||
|
||||
func apiConnectPlan(connReq: String) async throws -> ConnectionPlan {
|
||||
let userId = try currentUserId("apiConnectPlan")
|
||||
let r = await chatSendCmd(.apiConnectPlan(userId: userId, connReq: connReq))
|
||||
@@ -707,7 +715,7 @@ func apiConnect_(incognito: Bool, connReq: String) async -> ((ConnReqType, Pendi
|
||||
return ((.contact, connection), nil)
|
||||
case let .contactAlreadyExists(_, contact):
|
||||
if let c = m.getContactChat(contact.contactId) {
|
||||
await MainActor.run { m.chatId = c.id }
|
||||
ItemsModel.shared.loadOpenChat(c.id)
|
||||
}
|
||||
let alert = contactAlreadyExistsAlert(contact)
|
||||
return (nil, alert)
|
||||
@@ -1171,12 +1179,12 @@ func acceptContactRequest(incognito: Bool, contactRequest: UserContactRequest) a
|
||||
let chat = Chat(chatInfo: ChatInfo.direct(contact: contact), chatItems: [])
|
||||
await MainActor.run {
|
||||
ChatModel.shared.replaceChat(contactRequest.id, chat)
|
||||
ChatModel.shared.setContactNetworkStatus(contact, .connected)
|
||||
NetworkModel.shared.setContactNetworkStatus(contact, .connected)
|
||||
}
|
||||
if contact.sndReady {
|
||||
DispatchQueue.main.async {
|
||||
dismissAllSheets(animated: true) {
|
||||
ChatModel.shared.chatId = chat.id
|
||||
ItemsModel.shared.loadOpenChat(chat.id)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1220,12 +1228,18 @@ func apiEndCall(_ contact: Contact) async throws {
|
||||
try await sendCommandOkResp(.apiEndCall(contact: contact))
|
||||
}
|
||||
|
||||
func apiGetCallInvitations() throws -> [RcvCallInvitation] {
|
||||
func apiGetCallInvitationsSync() throws -> [RcvCallInvitation] {
|
||||
let r = chatSendCmdSync(.apiGetCallInvitations)
|
||||
if case let .callInvitations(invs) = r { return invs }
|
||||
throw r
|
||||
}
|
||||
|
||||
func apiGetCallInvitations() async throws -> [RcvCallInvitation] {
|
||||
let r = await chatSendCmd(.apiGetCallInvitations)
|
||||
if case let .callInvitations(invs) = r { return invs }
|
||||
throw r
|
||||
}
|
||||
|
||||
func apiCallStatus(_ contact: Contact, _ status: String) async throws {
|
||||
if let callStatus = WebRTCCallStatus.init(rawValue: status) {
|
||||
try await sendCommandOkResp(.apiCallStatus(contact: contact, callStatus: callStatus))
|
||||
@@ -1422,9 +1436,9 @@ func apiGetVersion() throws -> CoreVersionInfo {
|
||||
throw r
|
||||
}
|
||||
|
||||
func getAgentSubsTotal() throws -> (SMPServerSubs, Bool) {
|
||||
func getAgentSubsTotal() async throws -> (SMPServerSubs, Bool) {
|
||||
let userId = try currentUserId("getAgentSubsTotal")
|
||||
let r = chatSendCmdSync(.getAgentSubsTotal(userId: userId), log: false)
|
||||
let r = await chatSendCmd(.getAgentSubsTotal(userId: userId), log: false)
|
||||
if case let .agentSubsTotal(_, subsTotal, hasSession) = r { return (subsTotal, hasSession) }
|
||||
logger.error("getAgentSubsTotal error: \(String(describing: r))")
|
||||
throw r
|
||||
@@ -1519,7 +1533,7 @@ func startChat(refreshInvitations: Bool = true) throws {
|
||||
try getUserChatData()
|
||||
NtfManager.shared.setNtfBadgeCount(m.totalUnreadCountForAllUsers())
|
||||
if (refreshInvitations) {
|
||||
try refreshCallInvitations()
|
||||
Task { try await refreshCallInvitations() }
|
||||
}
|
||||
(m.savedToken, m.tokenStatus, m.notificationMode, m.notificationServer) = apiGetNtfToken()
|
||||
_ = try apiStartChat()
|
||||
@@ -1593,7 +1607,7 @@ func getUserChatData() throws {
|
||||
m.userAddress = try apiGetUserAddress()
|
||||
m.chatItemTTL = try getChatItemTTL()
|
||||
let chats = try apiGetChats()
|
||||
m.chats = chats.map { Chat.init($0) }
|
||||
m.updateChats(chats)
|
||||
}
|
||||
|
||||
private func getUserChatDataAsync() async throws {
|
||||
@@ -1605,12 +1619,12 @@ private func getUserChatDataAsync() async throws {
|
||||
await MainActor.run {
|
||||
m.userAddress = userAddress
|
||||
m.chatItemTTL = chatItemTTL
|
||||
m.chats = chats.map { Chat.init($0) }
|
||||
m.updateChats(chats)
|
||||
}
|
||||
} else {
|
||||
await MainActor.run {
|
||||
m.userAddress = nil
|
||||
m.chats = []
|
||||
m.updateChats([])
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1660,6 +1674,7 @@ func processReceivedMsg(_ res: ChatResponse) async {
|
||||
await TerminalItems.shared.add(.resp(.now, res))
|
||||
}
|
||||
let m = ChatModel.shared
|
||||
let n = NetworkModel.shared
|
||||
logger.debug("processReceivedMsg: \(res.responseType)")
|
||||
switch res {
|
||||
case let .contactDeletedByContact(user, contact):
|
||||
@@ -1682,7 +1697,7 @@ func processReceivedMsg(_ res: ChatResponse) async {
|
||||
NtfManager.shared.notifyContactConnected(user, contact)
|
||||
}
|
||||
await MainActor.run {
|
||||
m.setContactNetworkStatus(contact, .connected)
|
||||
n.setContactNetworkStatus(contact, .connected)
|
||||
}
|
||||
case let .contactConnecting(user, contact):
|
||||
if active(user) && contact.directOrUsed {
|
||||
@@ -1705,7 +1720,7 @@ func processReceivedMsg(_ res: ChatResponse) async {
|
||||
}
|
||||
}
|
||||
await MainActor.run {
|
||||
m.setContactNetworkStatus(contact, .connected)
|
||||
n.setContactNetworkStatus(contact, .connected)
|
||||
}
|
||||
case let .receivedContactRequest(user, contactRequest):
|
||||
if active(user) {
|
||||
@@ -1739,7 +1754,7 @@ func processReceivedMsg(_ res: ChatResponse) async {
|
||||
if active(user) && m.hasChat(mergedContact.id) {
|
||||
await MainActor.run {
|
||||
if m.chatId == mergedContact.id {
|
||||
m.chatId = intoContact.id
|
||||
ItemsModel.shared.loadOpenChat(mergedContact.id)
|
||||
}
|
||||
m.removeChat(mergedContact.id)
|
||||
}
|
||||
@@ -1747,51 +1762,48 @@ func processReceivedMsg(_ res: ChatResponse) async {
|
||||
case let .networkStatus(status, connections):
|
||||
// dispatch queue to synchronize access
|
||||
networkStatusesLock.sync {
|
||||
var ns = m.networkStatuses
|
||||
var ns = n.networkStatuses
|
||||
// slow loop is on the background thread
|
||||
for cId in connections {
|
||||
ns[cId] = status
|
||||
}
|
||||
// fast model update is on the main thread
|
||||
DispatchQueue.main.sync {
|
||||
m.networkStatuses = ns
|
||||
n.networkStatuses = ns
|
||||
}
|
||||
}
|
||||
case let .networkStatuses(_, statuses): ()
|
||||
// dispatch queue to synchronize access
|
||||
networkStatusesLock.sync {
|
||||
var ns = m.networkStatuses
|
||||
var ns = n.networkStatuses
|
||||
// slow loop is on the background thread
|
||||
for s in statuses {
|
||||
ns[s.agentConnId] = s.networkStatus
|
||||
}
|
||||
// fast model update is on the main thread
|
||||
DispatchQueue.main.sync {
|
||||
m.networkStatuses = ns
|
||||
n.networkStatuses = ns
|
||||
}
|
||||
}
|
||||
case let .newChatItem(user, aChatItem):
|
||||
let cInfo = aChatItem.chatInfo
|
||||
let cItem = aChatItem.chatItem
|
||||
await MainActor.run {
|
||||
if active(user) {
|
||||
if case let .direct(contact) = cInfo, contact.chatDeleted {
|
||||
var updatedContact = contact
|
||||
updatedContact.chatDeleted = false
|
||||
m.updateContact(updatedContact)
|
||||
case let .newChatItems(user, chatItems):
|
||||
for chatItem in chatItems {
|
||||
let cInfo = chatItem.chatInfo
|
||||
let cItem = chatItem.chatItem
|
||||
await MainActor.run {
|
||||
if active(user) {
|
||||
m.addChatItem(cInfo, cItem)
|
||||
} else if cItem.isRcvNew && cInfo.ntfsEnabled {
|
||||
m.increaseUnreadCounter(user: user)
|
||||
}
|
||||
m.addChatItem(cInfo, cItem)
|
||||
} else if cItem.isRcvNew && cInfo.ntfsEnabled {
|
||||
m.increaseUnreadCounter(user: user)
|
||||
}
|
||||
}
|
||||
if let file = cItem.autoReceiveFile() {
|
||||
Task {
|
||||
await receiveFile(user: user, fileId: file.fileId, auto: true)
|
||||
if let file = cItem.autoReceiveFile() {
|
||||
Task {
|
||||
await receiveFile(user: user, fileId: file.fileId, auto: true)
|
||||
}
|
||||
}
|
||||
if cItem.showNotification {
|
||||
NtfManager.shared.notifyMessageReceived(user, cInfo, cItem)
|
||||
}
|
||||
}
|
||||
if cItem.showNotification {
|
||||
NtfManager.shared.notifyMessageReceived(user, cInfo, cItem)
|
||||
}
|
||||
case let .chatItemStatusUpdated(user, aChatItem):
|
||||
let cInfo = aChatItem.chatInfo
|
||||
@@ -1801,10 +1813,15 @@ func processReceivedMsg(_ res: ChatResponse) async {
|
||||
}
|
||||
if let endTask = m.messageDelivery[cItem.id] {
|
||||
switch cItem.meta.itemStatus {
|
||||
case .sndNew: ()
|
||||
case .sndSent: endTask()
|
||||
case .sndRcvd: endTask()
|
||||
case .sndErrorAuth: endTask()
|
||||
case .sndError: endTask()
|
||||
default: ()
|
||||
case .sndWarning: endTask()
|
||||
case .rcvNew: ()
|
||||
case .rcvRead: ()
|
||||
case .invalid: ()
|
||||
}
|
||||
}
|
||||
case let .chatItemUpdated(user, aChatItem):
|
||||
@@ -1913,7 +1930,7 @@ func processReceivedMsg(_ res: ChatResponse) async {
|
||||
}
|
||||
if let contact = memberContact {
|
||||
await MainActor.run {
|
||||
m.setContactNetworkStatus(contact, .connected)
|
||||
n.setContactNetworkStatus(contact, .connected)
|
||||
}
|
||||
}
|
||||
case let .groupUpdated(user, toGroup):
|
||||
@@ -2094,6 +2111,8 @@ func processReceivedMsg(_ res: ChatResponse) async {
|
||||
m.remoteCtrlSession = nil
|
||||
dismissAllSheets() {
|
||||
switch rcStopReason {
|
||||
case .disconnected:
|
||||
()
|
||||
case .connectionFailed(.errorAgent(.RCP(.identity))):
|
||||
AlertManager.shared.showAlertMsg(
|
||||
title: "Connection with desktop stopped",
|
||||
@@ -2136,12 +2155,13 @@ func processReceivedMsg(_ res: ChatResponse) async {
|
||||
|
||||
func switchToLocalSession() {
|
||||
let m = ChatModel.shared
|
||||
let n = NetworkModel.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)
|
||||
n.networkStatuses = Dictionary(uniqueKeysWithValues: statuses)
|
||||
} catch let error {
|
||||
logger.debug("error updating chat data: \(responseError(error))")
|
||||
}
|
||||
@@ -2164,32 +2184,42 @@ func chatItemSimpleUpdate(_ user: any UserLike, _ aChatItem: AChatItem) async {
|
||||
}
|
||||
}
|
||||
|
||||
func refreshCallInvitations() throws {
|
||||
func refreshCallInvitations() async throws {
|
||||
let m = ChatModel.shared
|
||||
let callInvitations = try justRefreshCallInvitations()
|
||||
if let (chatId, ntfAction) = m.ntfCallInvitationAction,
|
||||
let invitation = m.callInvitations.removeValue(forKey: chatId) {
|
||||
m.ntfCallInvitationAction = nil
|
||||
CallController.shared.callAction(invitation: invitation, action: ntfAction)
|
||||
} else if let invitation = callInvitations.last(where: { $0.user.showNotifications }) {
|
||||
activateCall(invitation)
|
||||
let callInvitations = try await apiGetCallInvitations()
|
||||
await MainActor.run {
|
||||
m.callInvitations = callsByChat(callInvitations)
|
||||
if let (chatId, ntfAction) = m.ntfCallInvitationAction,
|
||||
let invitation = m.callInvitations.removeValue(forKey: chatId) {
|
||||
m.ntfCallInvitationAction = nil
|
||||
CallController.shared.callAction(invitation: invitation, action: ntfAction)
|
||||
} else if let invitation = callInvitations.last(where: { $0.user.showNotifications }) {
|
||||
activateCall(invitation)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func justRefreshCallInvitations() throws -> [RcvCallInvitation] {
|
||||
let m = ChatModel.shared
|
||||
let callInvitations = try apiGetCallInvitations()
|
||||
m.callInvitations = callInvitations.reduce(into: [ChatId: RcvCallInvitation]()) { result, inv in result[inv.contact.id] = inv }
|
||||
return callInvitations
|
||||
func justRefreshCallInvitations() async throws {
|
||||
let callInvitations = try apiGetCallInvitationsSync()
|
||||
await MainActor.run {
|
||||
ChatModel.shared.callInvitations = callsByChat(callInvitations)
|
||||
}
|
||||
}
|
||||
|
||||
private func callsByChat(_ callInvitations: [RcvCallInvitation]) -> [ChatId: RcvCallInvitation] {
|
||||
callInvitations.reduce(into: [ChatId: RcvCallInvitation]()) {
|
||||
result, inv in result[inv.contact.id] = inv
|
||||
}
|
||||
}
|
||||
|
||||
func activateCall(_ callInvitation: RcvCallInvitation) {
|
||||
if !callInvitation.user.showNotifications { return }
|
||||
let m = ChatModel.shared
|
||||
logger.debug("reportNewIncomingCall activeCallUUID \(String(describing: m.activeCall?.callUUID)) invitationUUID \(String(describing: callInvitation.callUUID))")
|
||||
if !callInvitation.user.showNotifications || m.activeCall?.callUUID == callInvitation.callUUID { return }
|
||||
CallController.shared.reportNewIncomingCall(invitation: callInvitation) { error in
|
||||
if let error = error {
|
||||
DispatchQueue.main.async {
|
||||
m.callInvitations[callInvitation.contact.id]?.callkitUUID = nil
|
||||
m.callInvitations[callInvitation.contact.id]?.callUUID = nil
|
||||
}
|
||||
logger.error("reportNewIncomingCall error: \(error.localizedDescription)")
|
||||
} else {
|
||||
|
||||
@@ -58,6 +58,7 @@ struct SimpleXApp: App {
|
||||
}
|
||||
.onChange(of: scenePhase) { phase in
|
||||
logger.debug("scenePhase was \(String(describing: scenePhase)), now \(String(describing: phase))")
|
||||
AppSheetState.shared.scenePhaseActive = phase == .active
|
||||
switch (phase) {
|
||||
case .background:
|
||||
// --- authentication
|
||||
@@ -82,9 +83,11 @@ struct SimpleXApp: App {
|
||||
if appState != .stopped {
|
||||
startChatAndActivate {
|
||||
if appState.inactive && chatModel.chatRunning == true {
|
||||
updateChats()
|
||||
if !chatModel.showCallView && !CallController.shared.hasActiveCalls() {
|
||||
updateCallInvitations()
|
||||
Task {
|
||||
await updateChats()
|
||||
if !chatModel.showCallView && !CallController.shared.hasActiveCalls() {
|
||||
await updateCallInvitations()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -129,16 +132,16 @@ struct SimpleXApp: App {
|
||||
}
|
||||
}
|
||||
|
||||
private func updateChats() {
|
||||
private func updateChats() async {
|
||||
do {
|
||||
let chats = try apiGetChats()
|
||||
chatModel.updateChats(with: chats)
|
||||
let chats = try await apiGetChatsAsync()
|
||||
await MainActor.run { chatModel.updateChats(chats) }
|
||||
if let id = chatModel.chatId,
|
||||
let chat = chatModel.getChat(id) {
|
||||
loadChat(chat: chat)
|
||||
Task { await loadChat(chat: chat, clearItems: false) }
|
||||
}
|
||||
if let ncr = chatModel.ntfContactRequest {
|
||||
chatModel.ntfContactRequest = nil
|
||||
await MainActor.run { chatModel.ntfContactRequest = nil }
|
||||
if case let .contactRequest(contactRequest) = chatModel.getChat(ncr.chatId)?.chatInfo {
|
||||
Task { await acceptContactRequest(incognito: ncr.incognito, contactRequest: contactRequest) }
|
||||
}
|
||||
@@ -148,9 +151,9 @@ struct SimpleXApp: App {
|
||||
}
|
||||
}
|
||||
|
||||
private func updateCallInvitations() {
|
||||
private func updateCallInvitations() async {
|
||||
do {
|
||||
try refreshCallInvitations()
|
||||
try await refreshCallInvitations()
|
||||
} catch let error {
|
||||
logger.error("apiGetCallInvitations: cannot update call invitations \(responseError(error))")
|
||||
}
|
||||
|
||||
@@ -91,8 +91,8 @@ var systemInDarkThemeCurrently: Bool {
|
||||
return UITraitCollection.current.userInterfaceStyle == .dark
|
||||
}
|
||||
|
||||
func reactOnDarkThemeChanges() {
|
||||
if currentThemeDefault.get() == DefaultTheme.SYSTEM_THEME_NAME && CurrentColors.colors.isLight == systemInDarkThemeCurrently {
|
||||
func reactOnDarkThemeChanges(_ inDarkNow: Bool) {
|
||||
if currentThemeDefault.get() == DefaultTheme.SYSTEM_THEME_NAME && CurrentColors.colors.isLight == inDarkNow {
|
||||
// Change active colors from light to dark and back based on system theme
|
||||
ThemeManager.applyTheme(DefaultTheme.SYSTEM_THEME_NAME)
|
||||
}
|
||||
@@ -102,7 +102,7 @@ extension ThemeWallpaper {
|
||||
public func importFromString() -> ThemeWallpaper {
|
||||
if preset == nil, let image {
|
||||
// Need to save image from string and to save its path
|
||||
if let parsed = UIImage(base64Encoded: image),
|
||||
if let parsed = imageFromBase64(image),
|
||||
let filename = saveWallpaperFile(image: parsed) {
|
||||
var copy = self
|
||||
copy.image = nil
|
||||
|
||||
@@ -53,7 +53,7 @@ class ThemeManager {
|
||||
return perUserTheme
|
||||
}
|
||||
let defaultTheme = defaultActiveTheme(appSettingsTheme)
|
||||
return ThemeModeOverride(mode: CurrentColors.base.mode, colors: defaultTheme?.colors ?? ThemeColors(), wallpaper: defaultTheme?.wallpaper)
|
||||
return ThemeModeOverride(mode: CurrentColors.base.mode, colors: defaultTheme?.colors ?? ThemeColors(), wallpaper: defaultTheme?.wallpaper ?? ThemeWallpaper.from(PresetWallpaper.school.toType(CurrentColors.base), nil, nil))
|
||||
}
|
||||
|
||||
static func currentColors(_ themeOverridesForType: WallpaperType?, _ perChatTheme: ThemeModeOverride?, _ perUserTheme: ThemeModeOverrides?, _ appSettingsTheme: [ThemeOverrides]) -> ActiveTheme {
|
||||
|
||||
@@ -185,7 +185,7 @@ struct ActiveCallView: View {
|
||||
case .ended:
|
||||
closeCallView(client)
|
||||
call.callState = .ended
|
||||
if let uuid = call.callkitUUID {
|
||||
if let uuid = call.callUUID {
|
||||
CallController.shared.endCall(callUUID: uuid)
|
||||
}
|
||||
case .ok:
|
||||
@@ -382,7 +382,7 @@ struct ActiveCallOverlay: View {
|
||||
private func endCallButton() -> some View {
|
||||
let cc = CallController.shared
|
||||
return callButton("phone.down.fill", width: 60, height: 60) {
|
||||
if let uuid = call.callkitUUID {
|
||||
if let uuid = call.callUUID {
|
||||
cc.endCall(callUUID: uuid)
|
||||
} else {
|
||||
cc.endCall(call: call) {}
|
||||
@@ -462,9 +462,9 @@ struct ActiveCallOverlay: View {
|
||||
struct ActiveCallOverlay_Previews: PreviewProvider {
|
||||
static var previews: some View {
|
||||
Group{
|
||||
ActiveCallOverlay(call: Call(direction: .incoming, contact: Contact.sampleData, callkitUUID: UUID(), callState: .offerSent, localMedia: .video), client: WebRTCClient(Binding.constant(nil), { _ in }, Binding.constant(nil)))
|
||||
ActiveCallOverlay(call: Call(direction: .incoming, contact: Contact.sampleData, callUUID: UUID().uuidString.lowercased(), callState: .offerSent, localMedia: .video), client: WebRTCClient(Binding.constant(nil), { _ in }, Binding.constant(nil)))
|
||||
.background(.black)
|
||||
ActiveCallOverlay(call: Call(direction: .incoming, contact: Contact.sampleData, callkitUUID: UUID(), callState: .offerSent, localMedia: .audio), client: WebRTCClient(Binding.constant(nil), { _ in }, Binding.constant(nil)))
|
||||
ActiveCallOverlay(call: Call(direction: .incoming, contact: Contact.sampleData, callUUID: UUID().uuidString.lowercased(), callState: .offerSent, localMedia: .audio), client: WebRTCClient(Binding.constant(nil), { _ in }, Binding.constant(nil)))
|
||||
.background(.black)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,7 +51,7 @@ class CallController: NSObject, CXProviderDelegate, PKPushRegistryDelegate, Obse
|
||||
|
||||
func provider(_ provider: CXProvider, perform action: CXStartCallAction) {
|
||||
logger.debug("CallController.provider CXStartCallAction")
|
||||
if callManager.startOutgoingCall(callUUID: action.callUUID) {
|
||||
if callManager.startOutgoingCall(callUUID: action.callUUID.uuidString.lowercased()) {
|
||||
action.fulfill()
|
||||
provider.reportOutgoingCall(with: action.callUUID, startedConnectingAt: nil)
|
||||
} else {
|
||||
@@ -61,12 +61,30 @@ class CallController: NSObject, CXProviderDelegate, PKPushRegistryDelegate, Obse
|
||||
|
||||
func provider(_ provider: CXProvider, perform action: CXAnswerCallAction) {
|
||||
logger.debug("CallController.provider CXAnswerCallAction")
|
||||
if callManager.answerIncomingCall(callUUID: action.callUUID) {
|
||||
// WebRTC call should be in connected state to fulfill.
|
||||
// Otherwise no audio and mic working on lockscreen
|
||||
fulfillOnConnect = action
|
||||
} else {
|
||||
action.fail()
|
||||
Task {
|
||||
let chatIsReady = await waitUntilChatStarted(timeoutMs: 30_000, stepMs: 500)
|
||||
logger.debug("CallController chat started \(chatIsReady) \(ChatModel.shared.chatInitialized) \(ChatModel.shared.chatRunning == true) \(String(describing: AppChatState.shared.value))")
|
||||
if !chatIsReady {
|
||||
action.fail()
|
||||
return
|
||||
}
|
||||
if !ChatModel.shared.callInvitations.values.contains(where: { inv in inv.callUUID == action.callUUID.uuidString.lowercased() }) {
|
||||
try? await justRefreshCallInvitations()
|
||||
logger.debug("CallController: updated call invitations chat")
|
||||
}
|
||||
await MainActor.run {
|
||||
logger.debug("CallController.provider will answer on call")
|
||||
|
||||
if callManager.answerIncomingCall(callUUID: action.callUUID.uuidString.lowercased()) {
|
||||
logger.debug("CallController.provider answered on call")
|
||||
// WebRTC call should be in connected state to fulfill.
|
||||
// Otherwise no audio and mic working on lockscreen
|
||||
fulfillOnConnect = action
|
||||
} else {
|
||||
logger.debug("CallController.provider will fail the call")
|
||||
action.fail()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -75,7 +93,7 @@ class CallController: NSObject, CXProviderDelegate, PKPushRegistryDelegate, Obse
|
||||
// Should be nil here if connection was in connected state
|
||||
fulfillOnConnect?.fail()
|
||||
fulfillOnConnect = nil
|
||||
callManager.endCall(callUUID: action.callUUID) { ok in
|
||||
callManager.endCall(callUUID: action.callUUID.uuidString.lowercased()) { ok in
|
||||
if ok {
|
||||
action.fulfill()
|
||||
} else {
|
||||
@@ -86,7 +104,7 @@ class CallController: NSObject, CXProviderDelegate, PKPushRegistryDelegate, Obse
|
||||
}
|
||||
|
||||
func provider(_ provider: CXProvider, perform action: CXSetMutedCallAction) {
|
||||
if callManager.enableMedia(media: .audio, enable: !action.isMuted, callUUID: action.callUUID) {
|
||||
if callManager.enableMedia(media: .audio, enable: !action.isMuted, callUUID: action.callUUID.uuidString.lowercased()) {
|
||||
action.fulfill()
|
||||
} else {
|
||||
action.fail()
|
||||
@@ -156,6 +174,19 @@ class CallController: NSObject, CXProviderDelegate, PKPushRegistryDelegate, Obse
|
||||
}
|
||||
}
|
||||
|
||||
private func waitUntilChatStarted(timeoutMs: UInt64, stepMs: UInt64) async -> Bool {
|
||||
logger.debug("CallController waiting until chat started")
|
||||
var t: UInt64 = 0
|
||||
repeat {
|
||||
if ChatModel.shared.chatInitialized, ChatModel.shared.chatRunning == true, case .active = AppChatState.shared.value {
|
||||
return true
|
||||
}
|
||||
_ = try? await Task.sleep(nanoseconds: stepMs * 1000000)
|
||||
t += stepMs
|
||||
} while t < timeoutMs
|
||||
return false
|
||||
}
|
||||
|
||||
@objc(pushRegistry:didUpdatePushCredentials:forType:)
|
||||
func pushRegistry(_ registry: PKPushRegistry, didUpdate pushCredentials: PKPushCredentials, for type: PKPushType) {
|
||||
logger.debug("CallController: didUpdate push credentials for type \(type.rawValue)")
|
||||
@@ -171,32 +202,19 @@ class CallController: NSObject, CXProviderDelegate, PKPushRegistryDelegate, Obse
|
||||
self.reportExpiredCall(payload: payload, completion)
|
||||
return
|
||||
}
|
||||
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 = self.cxCallUpdate(invitation: invitation)
|
||||
if let uuid = invitation.callkitUUID {
|
||||
let displayName = payload.dictionaryPayload["displayName"] as? String,
|
||||
let callUUID = payload.dictionaryPayload["callUUID"] as? String,
|
||||
let uuid = UUID(uuidString: callUUID),
|
||||
let callTsInterval = payload.dictionaryPayload["callTs"] as? TimeInterval,
|
||||
let mediaStr = payload.dictionaryPayload["media"] as? String,
|
||||
let media = CallMediaType(rawValue: mediaStr) {
|
||||
let update = self.cxCallUpdate(contactId, displayName, media)
|
||||
let callTs = Date(timeIntervalSince1970: callTsInterval)
|
||||
if callTs.timeIntervalSinceNow >= -180 {
|
||||
logger.debug("CallController: report pushkit call via CallKit")
|
||||
let update = self.cxCallUpdate(invitation: invitation)
|
||||
self.provider.reportNewIncomingCall(with: uuid, update: update) { error in
|
||||
if error != nil {
|
||||
m.callInvitations.removeValue(forKey: contactId)
|
||||
@@ -205,11 +223,31 @@ class CallController: NSObject, CXProviderDelegate, PKPushRegistryDelegate, Obse
|
||||
completion()
|
||||
}
|
||||
} else {
|
||||
logger.debug("CallController will expire call 1")
|
||||
self.reportExpiredCall(update: update, completion)
|
||||
}
|
||||
} else {
|
||||
logger.debug("CallController will expire call 2")
|
||||
self.reportExpiredCall(payload: payload, completion)
|
||||
}
|
||||
|
||||
//DispatchQueue.main.asyncAfter(deadline: .now() + 10) {
|
||||
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)")
|
||||
if let call = ChatModel.shared.activeCall {
|
||||
self.endCall(call: call, completed: completion)
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
logger.debug("CallController: initialized chat")
|
||||
startChatForCall()
|
||||
logger.debug("CallController: started chat")
|
||||
self.shouldSuspendChat = true
|
||||
}
|
||||
|
||||
// This function fulfils the requirement to always report a call when PushKit notification is received,
|
||||
@@ -239,8 +277,8 @@ class CallController: NSObject, CXProviderDelegate, PKPushRegistryDelegate, Obse
|
||||
}
|
||||
|
||||
func reportNewIncomingCall(invitation: RcvCallInvitation, completion: @escaping (Error?) -> Void) {
|
||||
logger.debug("CallController.reportNewIncomingCall, UUID=\(String(describing: invitation.callkitUUID))")
|
||||
if CallController.useCallKit(), let uuid = invitation.callkitUUID {
|
||||
logger.debug("CallController.reportNewIncomingCall, UUID=\(String(describing: invitation.callUUID))")
|
||||
if CallController.useCallKit(), let callUUID = invitation.callUUID, let uuid = UUID(uuidString: callUUID) {
|
||||
if invitation.callTs.timeIntervalSinceNow >= -180 {
|
||||
let update = cxCallUpdate(invitation: invitation)
|
||||
provider.reportNewIncomingCall(with: uuid, update: update, completion: completion)
|
||||
@@ -261,6 +299,14 @@ class CallController: NSObject, CXProviderDelegate, PKPushRegistryDelegate, Obse
|
||||
return update
|
||||
}
|
||||
|
||||
private func cxCallUpdate(_ contactId: String, _ displayName: String, _ media: CallMediaType) -> CXCallUpdate {
|
||||
let update = CXCallUpdate()
|
||||
update.remoteHandle = CXHandle(type: .generic, value: contactId)
|
||||
update.hasVideo = media == .video
|
||||
update.localizedCallerName = displayName
|
||||
return update
|
||||
}
|
||||
|
||||
func reportIncomingCall(call: Call, connectedAt dateConnected: Date?) {
|
||||
logger.debug("CallController: reporting incoming call connected")
|
||||
if CallController.useCallKit() {
|
||||
@@ -272,14 +318,14 @@ class CallController: NSObject, CXProviderDelegate, PKPushRegistryDelegate, Obse
|
||||
|
||||
func reportOutgoingCall(call: Call, connectedAt dateConnected: Date?) {
|
||||
logger.debug("CallController: reporting outgoing call connected")
|
||||
if CallController.useCallKit(), let uuid = call.callkitUUID {
|
||||
if CallController.useCallKit(), let callUUID = call.callUUID, let uuid = UUID(uuidString: callUUID) {
|
||||
provider.reportOutgoingCall(with: uuid, connectedAt: dateConnected)
|
||||
}
|
||||
}
|
||||
|
||||
func reportCallRemoteEnded(invitation: RcvCallInvitation) {
|
||||
logger.debug("CallController: reporting remote ended")
|
||||
if CallController.useCallKit(), let uuid = invitation.callkitUUID {
|
||||
if CallController.useCallKit(), let callUUID = invitation.callUUID, let uuid = UUID(uuidString: callUUID) {
|
||||
provider.reportCall(with: uuid, endedAt: nil, reason: .remoteEnded)
|
||||
} else if invitation.contact.id == activeCallInvitation?.contact.id {
|
||||
activeCallInvitation = nil
|
||||
@@ -288,14 +334,17 @@ class CallController: NSObject, CXProviderDelegate, PKPushRegistryDelegate, Obse
|
||||
|
||||
func reportCallRemoteEnded(call: Call) {
|
||||
logger.debug("CallController: reporting remote ended")
|
||||
if CallController.useCallKit(), let uuid = call.callkitUUID {
|
||||
if CallController.useCallKit(), let callUUID = call.callUUID, let uuid = UUID(uuidString: callUUID) {
|
||||
provider.reportCall(with: uuid, endedAt: nil, reason: .remoteEnded)
|
||||
}
|
||||
}
|
||||
|
||||
func startCall(_ contact: Contact, _ media: CallMediaType) {
|
||||
logger.debug("CallController.startCall")
|
||||
let uuid = callManager.newOutgoingCall(contact, media)
|
||||
let callUUID = callManager.newOutgoingCall(contact, media)
|
||||
guard let uuid = UUID(uuidString: callUUID) else {
|
||||
return
|
||||
}
|
||||
if CallController.useCallKit() {
|
||||
let handle = CXHandle(type: .generic, value: contact.id)
|
||||
let action = CXStartCallAction(call: uuid, handle: handle)
|
||||
@@ -307,8 +356,8 @@ class CallController: NSObject, CXProviderDelegate, PKPushRegistryDelegate, Obse
|
||||
update.localizedCallerName = contact.displayName
|
||||
self.provider.reportCall(with: uuid, updated: update)
|
||||
}
|
||||
} else if callManager.startOutgoingCall(callUUID: uuid) {
|
||||
if callManager.startOutgoingCall(callUUID: uuid) {
|
||||
} else if callManager.startOutgoingCall(callUUID: callUUID) {
|
||||
if callManager.startOutgoingCall(callUUID: callUUID) {
|
||||
logger.debug("CallController.startCall: call started")
|
||||
} else {
|
||||
logger.error("CallController.startCall: no active call")
|
||||
@@ -318,8 +367,8 @@ class CallController: NSObject, CXProviderDelegate, PKPushRegistryDelegate, Obse
|
||||
|
||||
func answerCall(invitation: RcvCallInvitation) {
|
||||
logger.debug("CallController: answering a call")
|
||||
if CallController.useCallKit(), let callUUID = invitation.callkitUUID {
|
||||
requestTransaction(with: CXAnswerCallAction(call: callUUID))
|
||||
if CallController.useCallKit(), let callUUID = invitation.callUUID, let uuid = UUID(uuidString: callUUID) {
|
||||
requestTransaction(with: CXAnswerCallAction(call: uuid))
|
||||
} else {
|
||||
callManager.answerIncomingCall(invitation: invitation)
|
||||
}
|
||||
@@ -328,10 +377,13 @@ class CallController: NSObject, CXProviderDelegate, PKPushRegistryDelegate, Obse
|
||||
}
|
||||
}
|
||||
|
||||
func endCall(callUUID: UUID) {
|
||||
logger.debug("CallController: ending the call with UUID \(callUUID.uuidString)")
|
||||
func endCall(callUUID: String) {
|
||||
let uuid = UUID(uuidString: callUUID)
|
||||
logger.debug("CallController: ending the call with UUID \(callUUID)")
|
||||
if CallController.useCallKit() {
|
||||
requestTransaction(with: CXEndCallAction(call: callUUID))
|
||||
if let uuid {
|
||||
requestTransaction(with: CXEndCallAction(call: uuid))
|
||||
}
|
||||
} else {
|
||||
callManager.endCall(callUUID: callUUID) { ok in
|
||||
if ok {
|
||||
|
||||
@@ -10,17 +10,17 @@ import Foundation
|
||||
import SimpleXChat
|
||||
|
||||
class CallManager {
|
||||
func newOutgoingCall(_ contact: Contact, _ media: CallMediaType) -> UUID {
|
||||
let uuid = UUID()
|
||||
let call = Call(direction: .outgoing, contact: contact, callkitUUID: uuid, callState: .waitCapabilities, localMedia: media)
|
||||
func newOutgoingCall(_ contact: Contact, _ media: CallMediaType) -> String {
|
||||
let uuid = UUID().uuidString.lowercased()
|
||||
let call = Call(direction: .outgoing, contact: contact, callUUID: uuid, callState: .waitCapabilities, localMedia: media)
|
||||
call.speakerEnabled = media == .video
|
||||
ChatModel.shared.activeCall = call
|
||||
return uuid
|
||||
}
|
||||
|
||||
func startOutgoingCall(callUUID: UUID) -> Bool {
|
||||
func startOutgoingCall(callUUID: String) -> Bool {
|
||||
let m = ChatModel.shared
|
||||
if let call = m.activeCall, call.callkitUUID == callUUID {
|
||||
if let call = m.activeCall, call.callUUID == callUUID {
|
||||
m.showCallView = true
|
||||
Task { await m.callCommand.processCommand(.capabilities(media: call.localMedia)) }
|
||||
return true
|
||||
@@ -28,7 +28,7 @@ class CallManager {
|
||||
return false
|
||||
}
|
||||
|
||||
func answerIncomingCall(callUUID: UUID) -> Bool {
|
||||
func answerIncomingCall(callUUID: String) -> Bool {
|
||||
if let invitation = getCallInvitation(callUUID) {
|
||||
answerIncomingCall(invitation: invitation)
|
||||
return true
|
||||
@@ -42,7 +42,7 @@ class CallManager {
|
||||
let call = Call(
|
||||
direction: .incoming,
|
||||
contact: invitation.contact,
|
||||
callkitUUID: invitation.callkitUUID,
|
||||
callUUID: invitation.callUUID,
|
||||
callState: .invitationAccepted,
|
||||
localMedia: invitation.callType.media,
|
||||
sharedKey: invitation.sharedKey
|
||||
@@ -68,8 +68,8 @@ class CallManager {
|
||||
}
|
||||
}
|
||||
|
||||
func enableMedia(media: CallMediaType, enable: Bool, callUUID: UUID) -> Bool {
|
||||
if let call = ChatModel.shared.activeCall, call.callkitUUID == callUUID {
|
||||
func enableMedia(media: CallMediaType, enable: Bool, callUUID: String) -> Bool {
|
||||
if let call = ChatModel.shared.activeCall, call.callUUID == callUUID {
|
||||
let m = ChatModel.shared
|
||||
Task { await m.callCommand.processCommand(.media(media: media, enable: enable)) }
|
||||
return true
|
||||
@@ -77,8 +77,8 @@ class CallManager {
|
||||
return false
|
||||
}
|
||||
|
||||
func endCall(callUUID: UUID, completed: @escaping (Bool) -> Void) {
|
||||
if let call = ChatModel.shared.activeCall, call.callkitUUID == callUUID {
|
||||
func endCall(callUUID: String, completed: @escaping (Bool) -> Void) {
|
||||
if let call = ChatModel.shared.activeCall, call.callUUID == callUUID {
|
||||
endCall(call: call) { completed(true) }
|
||||
} else if let invitation = getCallInvitation(callUUID) {
|
||||
endCall(invitation: invitation) { completed(true) }
|
||||
@@ -126,8 +126,8 @@ class CallManager {
|
||||
}
|
||||
}
|
||||
|
||||
private func getCallInvitation(_ callUUID: UUID) -> RcvCallInvitation? {
|
||||
if let (_, invitation) = ChatModel.shared.callInvitations.first(where: { (_, inv) in inv.callkitUUID == callUUID }) {
|
||||
private func getCallInvitation(_ callUUID: String) -> RcvCallInvitation? {
|
||||
if let (_, invitation) = ChatModel.shared.callInvitations.first(where: { (_, inv) in inv.callUUID == callUUID }) {
|
||||
return invitation
|
||||
}
|
||||
return nil
|
||||
|
||||
@@ -38,6 +38,7 @@ struct IncomingCallView: View {
|
||||
}
|
||||
HStack {
|
||||
ProfilePreview(profileOf: invitation.contact, color: .white)
|
||||
.padding(.vertical, 6)
|
||||
Spacer()
|
||||
|
||||
callButton("Reject", "phone.down.fill", .red) {
|
||||
|
||||
@@ -18,7 +18,7 @@ class Call: ObservableObject, Equatable {
|
||||
|
||||
var direction: CallDirection
|
||||
var contact: Contact
|
||||
var callkitUUID: UUID?
|
||||
var callUUID: String?
|
||||
var localMedia: CallMediaType
|
||||
@Published var callState: CallState
|
||||
@Published var localCapabilities: CallCapabilities?
|
||||
@@ -33,14 +33,14 @@ class Call: ObservableObject, Equatable {
|
||||
init(
|
||||
direction: CallDirection,
|
||||
contact: Contact,
|
||||
callkitUUID: UUID?,
|
||||
callUUID: String?,
|
||||
callState: CallState,
|
||||
localMedia: CallMediaType,
|
||||
sharedKey: String? = nil
|
||||
) {
|
||||
self.direction = direction
|
||||
self.contact = contact
|
||||
self.callkitUUID = callkitUUID
|
||||
self.callUUID = callUUID
|
||||
self.callState = callState
|
||||
self.localMedia = localMedia
|
||||
self.sharedKey = sharedKey
|
||||
|
||||
@@ -411,6 +411,15 @@ final class WebRTCClient: NSObject, RTCVideoViewDelegate, RTCFrameEncryptorDeleg
|
||||
}
|
||||
|
||||
func endCall() {
|
||||
if #available(iOS 16.0, *) {
|
||||
_endCall()
|
||||
} else {
|
||||
// Fixes `connection.close()` getting locked up in iOS15
|
||||
DispatchQueue.global(qos: .utility).async { self._endCall() }
|
||||
}
|
||||
}
|
||||
|
||||
private func _endCall() {
|
||||
guard let call = activeCall.wrappedValue else { return }
|
||||
logger.debug("WebRTCClient: ending the call")
|
||||
activeCall.wrappedValue = nil
|
||||
|
||||
@@ -92,6 +92,7 @@ struct ChatInfoView: View {
|
||||
@EnvironmentObject var chatModel: ChatModel
|
||||
@EnvironmentObject var theme: AppTheme
|
||||
@Environment(\.dismiss) var dismiss: DismissAction
|
||||
@ObservedObject var networkModel = NetworkModel.shared
|
||||
@ObservedObject var chat: Chat
|
||||
@State var contact: Contact
|
||||
@State var localAlias: String
|
||||
@@ -502,14 +503,14 @@ struct ChatInfoView: View {
|
||||
.foregroundColor(theme.colors.primary)
|
||||
.font(.system(size: 14))
|
||||
Spacer()
|
||||
Text(chatModel.contactNetworkStatus(contact).statusString)
|
||||
Text(networkModel.contactNetworkStatus(contact).statusString)
|
||||
.foregroundColor(theme.colors.secondary)
|
||||
serverImage()
|
||||
}
|
||||
}
|
||||
|
||||
private func serverImage() -> some View {
|
||||
let status = chatModel.contactNetworkStatus(contact)
|
||||
let status = networkModel.contactNetworkStatus(contact)
|
||||
return Image(systemName: status.imageName)
|
||||
.foregroundColor(status == .connected ? .green : theme.colors.secondary)
|
||||
.font(.system(size: 12))
|
||||
@@ -557,7 +558,7 @@ struct ChatInfoView: View {
|
||||
private func networkStatusAlert() -> Alert {
|
||||
Alert(
|
||||
title: Text("Network status"),
|
||||
message: Text(chatModel.contactNetworkStatus(contact).statusExplanation)
|
||||
message: Text(networkModel.contactNetworkStatus(contact).statusExplanation)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -670,7 +671,14 @@ private struct CallButton: View {
|
||||
|
||||
InfoViewButton(image: image, title: title, disabledLook: !canCall, width: width) {
|
||||
if canCall {
|
||||
CallController.shared.startCall(contact, mediaType)
|
||||
if CallController.useCallKit() {
|
||||
CallController.shared.startCall(contact, mediaType)
|
||||
} else {
|
||||
// When CallKit is not used, colorscheme will be changed and it will be visible if not hiding sheets first
|
||||
dismissAllSheets(animated: true) {
|
||||
CallController.shared.startCall(contact, mediaType)
|
||||
}
|
||||
}
|
||||
} else if contact.nextSendGrpInv {
|
||||
showAlert(SomeAlert(
|
||||
alert: mkAlert(
|
||||
@@ -934,7 +942,7 @@ func syncConnectionForceAlert(_ syncConnectionForce: @escaping () -> Void) -> Al
|
||||
)
|
||||
}
|
||||
|
||||
func queueInfoText(_ info: (RcvMsgInfo?, QueueInfo)) -> String {
|
||||
func queueInfoText(_ info: (RcvMsgInfo?, ServerQueueInfo)) -> String {
|
||||
let (rcvMsgInfo, qInfo) = info
|
||||
var msgInfo: String
|
||||
if let rcvMsgInfo { msgInfo = encodeJSON(rcvMsgInfo) } else { msgInfo = "none" }
|
||||
|
||||
@@ -12,6 +12,7 @@ import SimpleXChat
|
||||
struct CIGroupInvitationView: View {
|
||||
@EnvironmentObject var chatModel: ChatModel
|
||||
@EnvironmentObject var theme: AppTheme
|
||||
@Environment(\.showTimestamp) var showTimestamp: Bool
|
||||
@ObservedObject var chat: Chat
|
||||
var chatItem: ChatItem
|
||||
var groupInvitation: CIGroupInvitation
|
||||
@@ -45,7 +46,7 @@ struct CIGroupInvitationView: View {
|
||||
.foregroundColor(inProgress ? theme.colors.secondary : chatIncognito ? .indigo : theme.colors.primary)
|
||||
.font(.callout)
|
||||
+ Text(" ")
|
||||
+ ciMetaText(chatItem.meta, chatTTL: nil, encrypted: nil, transparent: true, showStatus: false, showEdited: false, showViaProxy: showSentViaProxy)
|
||||
+ ciMetaText(chatItem.meta, chatTTL: nil, encrypted: nil, transparent: true, showStatus: false, showEdited: false, showViaProxy: showSentViaProxy, showTimesamp: showTimestamp)
|
||||
)
|
||||
.overlay(DetermineWidth())
|
||||
}
|
||||
@@ -53,7 +54,7 @@ struct CIGroupInvitationView: View {
|
||||
(
|
||||
groupInvitationText()
|
||||
+ Text(" ")
|
||||
+ ciMetaText(chatItem.meta, chatTTL: nil, encrypted: nil, transparent: true, showStatus: false, showEdited: false, showViaProxy: showSentViaProxy)
|
||||
+ ciMetaText(chatItem.meta, chatTTL: nil, encrypted: nil, transparent: true, showStatus: false, showEdited: false, showViaProxy: showSentViaProxy, showTimesamp: showTimestamp)
|
||||
)
|
||||
.overlay(DetermineWidth())
|
||||
}
|
||||
@@ -69,7 +70,7 @@ struct CIGroupInvitationView: View {
|
||||
}
|
||||
.padding(.horizontal, 12)
|
||||
.padding(.vertical, 6)
|
||||
.background(chatItemFrameColor(chatItem, theme))
|
||||
.background { chatItemFrameColor(chatItem, theme).modifier(ChatTailPadding()) }
|
||||
.textSelection(.disabled)
|
||||
.onPreferenceChange(DetermineWidth.Key.self) { frameWidth = $0 }
|
||||
.onChange(of: inProgress) { inProgress in
|
||||
|
||||
@@ -16,7 +16,7 @@ struct CILinkView: View {
|
||||
|
||||
var body: some View {
|
||||
VStack(alignment: .center, spacing: 6) {
|
||||
if let uiImage = UIImage(base64Encoded: linkPreview.image) {
|
||||
if let uiImage = imageFromBase64(linkPreview.image) {
|
||||
Image(uiImage: uiImage)
|
||||
.resizable()
|
||||
.scaledToFit()
|
||||
|
||||
@@ -12,6 +12,7 @@ import SimpleXChat
|
||||
struct CIMetaView: View {
|
||||
@ObservedObject var chat: Chat
|
||||
@EnvironmentObject var theme: AppTheme
|
||||
@Environment(\.showTimestamp) var showTimestamp: Bool
|
||||
var chatItem: ChatItem
|
||||
var metaColor: Color
|
||||
var paleMetaColor = Color(UIColor.tertiaryLabel)
|
||||
@@ -24,41 +25,22 @@ struct CIMetaView: View {
|
||||
if chatItem.isDeletedContent {
|
||||
chatItem.timestampText.font(.caption).foregroundColor(metaColor)
|
||||
} else {
|
||||
let meta = chatItem.meta
|
||||
let ttl = chat.chatInfo.timedMessagesTTL
|
||||
let encrypted = chatItem.encryptedFile
|
||||
switch meta.itemStatus {
|
||||
case let .sndSent(sndProgress):
|
||||
switch sndProgress {
|
||||
case .complete: ciMetaText(meta, chatTTL: ttl, encrypted: encrypted, color: metaColor, sent: .sent, showStatus: showStatus, showEdited: showEdited, showViaProxy: showSentViaProxy)
|
||||
case .partial: ciMetaText(meta, chatTTL: ttl, encrypted: encrypted, color: paleMetaColor, sent: .sent, showStatus: showStatus, showEdited: showEdited, showViaProxy: showSentViaProxy)
|
||||
}
|
||||
case let .sndRcvd(_, sndProgress):
|
||||
switch sndProgress {
|
||||
case .complete:
|
||||
ZStack {
|
||||
ciMetaText(meta, chatTTL: ttl, encrypted: encrypted, color: metaColor, sent: .rcvd1, showStatus: showStatus, showEdited: showEdited, showViaProxy: showSentViaProxy)
|
||||
ciMetaText(meta, chatTTL: ttl, encrypted: encrypted, color: metaColor, sent: .rcvd2, showStatus: showStatus, showEdited: showEdited, showViaProxy: showSentViaProxy)
|
||||
}
|
||||
case .partial:
|
||||
ZStack {
|
||||
ciMetaText(meta, chatTTL: ttl, encrypted: encrypted, color: paleMetaColor, sent: .rcvd1, showStatus: showStatus, showEdited: showEdited, showViaProxy: showSentViaProxy)
|
||||
ciMetaText(meta, chatTTL: ttl, encrypted: encrypted, color: paleMetaColor, sent: .rcvd2, showStatus: showStatus, showEdited: showEdited, showViaProxy: showSentViaProxy)
|
||||
}
|
||||
}
|
||||
default:
|
||||
ciMetaText(meta, chatTTL: ttl, encrypted: encrypted, color: metaColor, showStatus: showStatus, showEdited: showEdited, showViaProxy: showSentViaProxy)
|
||||
}
|
||||
ciMetaText(
|
||||
chatItem.meta,
|
||||
chatTTL: chat.chatInfo.timedMessagesTTL,
|
||||
encrypted: chatItem.encryptedFile,
|
||||
color: chatItem.meta.itemStatus.sndProgress == .partial
|
||||
? paleMetaColor
|
||||
: metaColor,
|
||||
showStatus: showStatus,
|
||||
showEdited: showEdited,
|
||||
showViaProxy: showSentViaProxy,
|
||||
showTimesamp: showTimestamp
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enum SentCheckmark {
|
||||
case sent
|
||||
case rcvd1
|
||||
case rcvd2
|
||||
}
|
||||
|
||||
func ciMetaText(
|
||||
_ meta: CIMeta,
|
||||
chatTTL: Int?,
|
||||
@@ -66,10 +48,10 @@ func ciMetaText(
|
||||
color: Color = .clear,
|
||||
primaryColor: Color = .accentColor,
|
||||
transparent: Bool = false,
|
||||
sent: SentCheckmark? = nil,
|
||||
showStatus: Bool = true,
|
||||
showEdited: Bool = true,
|
||||
showViaProxy: Bool
|
||||
showViaProxy: Bool,
|
||||
showTimesamp: Bool
|
||||
) -> Text {
|
||||
var r = Text("")
|
||||
if showEdited, meta.itemEdited {
|
||||
@@ -87,17 +69,8 @@ func ciMetaText(
|
||||
r = r + statusIconText("arrow.forward", color.opacity(0.67)).font(.caption2)
|
||||
}
|
||||
if showStatus {
|
||||
if let (icon, statusColor) = meta.statusIcon(color, primaryColor) {
|
||||
let t = Text(Image(systemName: icon)).font(.caption2)
|
||||
let gap = Text(" ").kerning(-1.25)
|
||||
let t1 = t.foregroundColor(transparent ? .clear : statusColor.opacity(0.67))
|
||||
switch sent {
|
||||
case nil: r = r + t1
|
||||
case .sent: r = r + t1 + gap
|
||||
case .rcvd1: r = r + t.foregroundColor(transparent ? .clear : statusColor.opacity(0.67)) + gap
|
||||
case .rcvd2: r = r + gap + t1
|
||||
}
|
||||
r = r + Text(" ")
|
||||
if let (image, statusColor) = meta.itemStatus.statusIcon(color, primaryColor) {
|
||||
r = r + Text(image).foregroundColor(transparent ? .clear : statusColor) + Text(" ")
|
||||
} else if !meta.disappearing {
|
||||
r = r + statusIconText("circlebadge.fill", .clear) + Text(" ")
|
||||
}
|
||||
@@ -105,7 +78,9 @@ func ciMetaText(
|
||||
if let enc = encrypted {
|
||||
r = r + statusIconText(enc ? "lock" : "lock.open", color) + Text(" ")
|
||||
}
|
||||
r = r + meta.timestampText.foregroundColor(color)
|
||||
if showTimesamp {
|
||||
r = r + meta.timestampText.foregroundColor(color)
|
||||
}
|
||||
return r.font(.caption)
|
||||
}
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@ struct CIRcvDecryptionError: View {
|
||||
@EnvironmentObject var m: ChatModel
|
||||
@EnvironmentObject var theme: AppTheme
|
||||
@ObservedObject var chat: Chat
|
||||
@Environment(\.showTimestamp) var showTimestamp: Bool
|
||||
var msgDecryptError: MsgDecryptError
|
||||
var msgCount: UInt32
|
||||
var chatItem: ChatItem
|
||||
@@ -68,37 +69,40 @@ struct CIRcvDecryptionError: View {
|
||||
}
|
||||
|
||||
@ViewBuilder private func viewBody() -> some View {
|
||||
if case let .direct(contact) = chat.chatInfo,
|
||||
let contactStats = contact.activeConn?.connectionStats {
|
||||
if contactStats.ratchetSyncAllowed {
|
||||
decryptionErrorItemFixButton(syncSupported: true) {
|
||||
alert = .syncAllowedAlert { syncContactConnection(contact) }
|
||||
Group {
|
||||
if case let .direct(contact) = chat.chatInfo,
|
||||
let contactStats = contact.activeConn?.connectionStats {
|
||||
if contactStats.ratchetSyncAllowed {
|
||||
decryptionErrorItemFixButton(syncSupported: true) {
|
||||
alert = .syncAllowedAlert { syncContactConnection(contact) }
|
||||
}
|
||||
} else if !contactStats.ratchetSyncSupported {
|
||||
decryptionErrorItemFixButton(syncSupported: false) {
|
||||
alert = .syncNotSupportedContactAlert
|
||||
}
|
||||
} else {
|
||||
basicDecryptionErrorItem()
|
||||
}
|
||||
} else if !contactStats.ratchetSyncSupported {
|
||||
decryptionErrorItemFixButton(syncSupported: false) {
|
||||
alert = .syncNotSupportedContactAlert
|
||||
} else if case let .group(groupInfo) = chat.chatInfo,
|
||||
case let .groupRcv(groupMember) = chatItem.chatDir,
|
||||
let mem = m.getGroupMember(groupMember.groupMemberId),
|
||||
let memberStats = mem.wrapped.activeConn?.connectionStats {
|
||||
if memberStats.ratchetSyncAllowed {
|
||||
decryptionErrorItemFixButton(syncSupported: true) {
|
||||
alert = .syncAllowedAlert { syncMemberConnection(groupInfo, groupMember) }
|
||||
}
|
||||
} else if !memberStats.ratchetSyncSupported {
|
||||
decryptionErrorItemFixButton(syncSupported: false) {
|
||||
alert = .syncNotSupportedMemberAlert
|
||||
}
|
||||
} else {
|
||||
basicDecryptionErrorItem()
|
||||
}
|
||||
} else {
|
||||
basicDecryptionErrorItem()
|
||||
}
|
||||
} else if case let .group(groupInfo) = chat.chatInfo,
|
||||
case let .groupRcv(groupMember) = chatItem.chatDir,
|
||||
let mem = m.getGroupMember(groupMember.groupMemberId),
|
||||
let memberStats = mem.wrapped.activeConn?.connectionStats {
|
||||
if memberStats.ratchetSyncAllowed {
|
||||
decryptionErrorItemFixButton(syncSupported: true) {
|
||||
alert = .syncAllowedAlert { syncMemberConnection(groupInfo, groupMember) }
|
||||
}
|
||||
} else if !memberStats.ratchetSyncSupported {
|
||||
decryptionErrorItemFixButton(syncSupported: false) {
|
||||
alert = .syncNotSupportedMemberAlert
|
||||
}
|
||||
} else {
|
||||
basicDecryptionErrorItem()
|
||||
}
|
||||
} else {
|
||||
basicDecryptionErrorItem()
|
||||
}
|
||||
.background { chatItemFrameColor(chatItem, theme).modifier(ChatTailPadding()) }
|
||||
}
|
||||
|
||||
private func basicDecryptionErrorItem() -> some View {
|
||||
@@ -122,7 +126,7 @@ struct CIRcvDecryptionError: View {
|
||||
.foregroundColor(syncSupported ? theme.colors.primary : theme.colors.secondary)
|
||||
.font(.callout)
|
||||
+ Text(" ")
|
||||
+ ciMetaText(chatItem.meta, chatTTL: nil, encrypted: nil, transparent: true, showViaProxy: showSentViaProxy)
|
||||
+ ciMetaText(chatItem.meta, chatTTL: nil, encrypted: nil, transparent: true, showViaProxy: showSentViaProxy, showTimesamp: showTimestamp)
|
||||
)
|
||||
}
|
||||
.padding(.horizontal, 12)
|
||||
@@ -131,7 +135,6 @@ struct CIRcvDecryptionError: View {
|
||||
}
|
||||
.onTapGesture(perform: { onClick() })
|
||||
.padding(.vertical, 6)
|
||||
.background(Color(uiColor: .tertiarySystemGroupedBackground))
|
||||
.textSelection(.disabled)
|
||||
}
|
||||
|
||||
@@ -142,7 +145,7 @@ struct CIRcvDecryptionError: View {
|
||||
.foregroundColor(.red)
|
||||
.italic()
|
||||
+ Text(" ")
|
||||
+ ciMetaText(chatItem.meta, chatTTL: nil, encrypted: nil, transparent: true, showViaProxy: showSentViaProxy)
|
||||
+ ciMetaText(chatItem.meta, chatTTL: nil, encrypted: nil, transparent: true, showViaProxy: showSentViaProxy, showTimesamp: showTimestamp)
|
||||
}
|
||||
.padding(.horizontal, 12)
|
||||
CIMetaView(chat: chat, chatItem: chatItem, metaColor: theme.colors.secondary)
|
||||
@@ -150,7 +153,6 @@ struct CIRcvDecryptionError: View {
|
||||
}
|
||||
.onTapGesture(perform: { onClick() })
|
||||
.padding(.vertical, 6)
|
||||
.background(Color(uiColor: .tertiarySystemGroupedBackground))
|
||||
.textSelection(.disabled)
|
||||
}
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ import SimpleXChat
|
||||
struct FramedItemView: View {
|
||||
@EnvironmentObject var m: ChatModel
|
||||
@EnvironmentObject var theme: AppTheme
|
||||
@EnvironmentObject var scrollModel: ReverseListScrollModel<ChatItem>
|
||||
@EnvironmentObject var scrollModel: ReverseListScrollModel
|
||||
@ObservedObject var chat: Chat
|
||||
var chatItem: ChatItem
|
||||
var preview: UIImage?
|
||||
@@ -71,8 +71,8 @@ struct FramedItemView: View {
|
||||
.overlay(DetermineWidth())
|
||||
.accessibilityLabel("")
|
||||
}
|
||||
}
|
||||
.background(chatItemFrameColorMaybeImageOrVideo(chatItem, theme))
|
||||
}
|
||||
.background { chatItemFrameColorMaybeImageOrVideo(chatItem, theme).modifier(ChatTailPadding()) }
|
||||
.onPreferenceChange(DetermineWidth.Key.self) { msgWidth = $0 }
|
||||
|
||||
if let (title, text) = chatItem.meta.itemStatus.statusInfo {
|
||||
@@ -185,7 +185,7 @@ struct FramedItemView: View {
|
||||
let v = ZStack(alignment: .topTrailing) {
|
||||
switch (qi.content) {
|
||||
case let .image(_, image):
|
||||
if let uiImage = UIImage(base64Encoded: image) {
|
||||
if let uiImage = imageFromBase64(image) {
|
||||
ciQuotedMsgView(qi)
|
||||
.padding(.trailing, 70).frame(minWidth: msgWidth, alignment: .leading)
|
||||
Image(uiImage: uiImage)
|
||||
@@ -197,7 +197,7 @@ struct FramedItemView: View {
|
||||
ciQuotedMsgView(qi)
|
||||
}
|
||||
case let .video(_, image, _):
|
||||
if let uiImage = UIImage(base64Encoded: image) {
|
||||
if let uiImage = imageFromBase64(image) {
|
||||
ciQuotedMsgView(qi)
|
||||
.padding(.trailing, 70).frame(minWidth: msgWidth, alignment: .leading)
|
||||
Image(uiImage: uiImage)
|
||||
@@ -294,7 +294,6 @@ struct FramedItemView: View {
|
||||
.padding(.horizontal, 12)
|
||||
.overlay(DetermineWidth())
|
||||
.frame(minWidth: 0, alignment: .leading)
|
||||
.textSelection(.enabled)
|
||||
|
||||
if let mediaWidth = maxMediaWidth(), mediaWidth < maxWidth {
|
||||
v.frame(maxWidth: mediaWidth, alignment: .leading)
|
||||
|
||||
@@ -13,7 +13,7 @@ import AVKit
|
||||
|
||||
struct FullScreenMediaView: View {
|
||||
@EnvironmentObject var m: ChatModel
|
||||
@EnvironmentObject var scrollModel: ReverseListScrollModel<ChatItem>
|
||||
@EnvironmentObject var scrollModel: ReverseListScrollModel
|
||||
@State var chatItem: ChatItem
|
||||
@State var image: UIImage?
|
||||
@State var player: AVPlayer? = nil
|
||||
|
||||
@@ -69,7 +69,7 @@ struct CIMsgError: View {
|
||||
}
|
||||
.padding(.leading, 12)
|
||||
.padding(.vertical, 6)
|
||||
.background(Color(uiColor: .tertiarySystemGroupedBackground))
|
||||
.background { chatItemFrameColor(chatItem, theme).modifier(ChatTailPadding()) }
|
||||
.textSelection(.disabled)
|
||||
.onTapGesture(perform: onTap)
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ struct MarkedDeletedItemView: View {
|
||||
.foregroundColor(theme.colors.secondary)
|
||||
.padding(.horizontal, 12)
|
||||
.padding(.vertical, 6)
|
||||
.background(chatItemFrameColor(chatItem, theme))
|
||||
.background { chatItemFrameColor(chatItem, theme).modifier(ChatTailPadding()) }
|
||||
.textSelection(.disabled)
|
||||
}
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@ private func typing(_ w: Font.Weight = .light) -> Text {
|
||||
|
||||
struct MsgContentView: View {
|
||||
@ObservedObject var chat: Chat
|
||||
@Environment(\.showTimestamp) var showTimestamp: Bool
|
||||
@EnvironmentObject var theme: AppTheme
|
||||
var text: String
|
||||
var formattedText: [FormattedText]? = nil
|
||||
@@ -84,7 +85,7 @@ struct MsgContentView: View {
|
||||
}
|
||||
|
||||
private func reserveSpaceForMeta(_ mt: CIMeta) -> Text {
|
||||
(rightToLeft ? Text("\n") : Text(" ")) + ciMetaText(mt, chatTTL: chat.chatInfo.timedMessagesTTL, encrypted: nil, transparent: true, showViaProxy: showSentViaProxy)
|
||||
(rightToLeft ? Text("\n") : Text(" ")) + ciMetaText(mt, chatTTL: chat.chatInfo.timedMessagesTTL, encrypted: nil, transparent: true, showViaProxy: showSentViaProxy, showTimesamp: showTimestamp)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -97,7 +97,7 @@ struct ChatItemForwardingView: View {
|
||||
)
|
||||
} else {
|
||||
composeState = ComposeState.init(forwardingItem: ci, fromChatInfo: fromChatInfo)
|
||||
chatModel.chatId = chat.id
|
||||
ItemsModel.shared.loadOpenChat(chat.id)
|
||||
}
|
||||
}
|
||||
} label: {
|
||||
|
||||
@@ -351,7 +351,7 @@ struct ChatItemInfoView: View {
|
||||
Button {
|
||||
Task {
|
||||
await MainActor.run {
|
||||
chatModel.chatId = forwardedFromItem.chatInfo.id
|
||||
ItemsModel.shared.loadOpenChat(forwardedFromItem.chatInfo.id)
|
||||
dismiss()
|
||||
}
|
||||
}
|
||||
@@ -450,20 +450,8 @@ struct ChatItemInfoView: View {
|
||||
.foregroundColor(theme.colors.secondary).opacity(0.67)
|
||||
}
|
||||
let v = Group {
|
||||
let (icon, statusColor) = status.statusIcon(theme.colors.secondary, theme.colors.primary)
|
||||
switch status {
|
||||
case .rcvd:
|
||||
ZStack(alignment: .trailing) {
|
||||
Image(systemName: icon)
|
||||
.foregroundColor(statusColor.opacity(0.67))
|
||||
.padding(.trailing, 6)
|
||||
Image(systemName: icon)
|
||||
.foregroundColor(statusColor.opacity(0.67))
|
||||
}
|
||||
default:
|
||||
Image(systemName: icon)
|
||||
.foregroundColor(statusColor)
|
||||
}
|
||||
let (image, statusColor) = status.statusIcon(theme.colors.secondary, theme.colors.primary)
|
||||
image.foregroundColor(statusColor)
|
||||
}
|
||||
|
||||
if let (title, text) = status.statusInfo {
|
||||
|
||||
@@ -9,9 +9,21 @@
|
||||
import SwiftUI
|
||||
import SimpleXChat
|
||||
|
||||
extension EnvironmentValues {
|
||||
struct ShowTimestamp: EnvironmentKey {
|
||||
static let defaultValue: Bool = true
|
||||
}
|
||||
|
||||
var showTimestamp: Bool {
|
||||
get { self[ShowTimestamp.self] }
|
||||
set { self[ShowTimestamp.self] = newValue }
|
||||
}
|
||||
}
|
||||
|
||||
struct ChatItemView: View {
|
||||
@ObservedObject var chat: Chat
|
||||
@EnvironmentObject var theme: AppTheme
|
||||
@Environment(\.showTimestamp) var showTimestamp: Bool
|
||||
var chatItem: ChatItem
|
||||
var maxWidth: CGFloat = .infinity
|
||||
@Binding var revealed: Bool
|
||||
@@ -60,7 +72,7 @@ struct ChatItemView: View {
|
||||
default: nil
|
||||
}
|
||||
}
|
||||
.flatMap { UIImage(base64Encoded: $0) }
|
||||
.flatMap { imageFromBase64($0) }
|
||||
let adjustedMaxWidth = {
|
||||
if let preview, preview.size.width <= preview.size.height {
|
||||
maxWidth * 0.75
|
||||
|
||||
@@ -22,8 +22,8 @@ struct ChatView: View {
|
||||
@Environment(\.presentationMode) var presentationMode
|
||||
@Environment(\.scenePhase) var scenePhase
|
||||
@State @ObservedObject var chat: Chat
|
||||
@StateObject private var scrollModel = ReverseListScrollModel<ChatItem>()
|
||||
@StateObject private var floatingButtonModel = FloatingButtonModel()
|
||||
@StateObject private var scrollModel = ReverseListScrollModel()
|
||||
@StateObject private var floatingButtonModel: FloatingButtonModel = .shared
|
||||
@State private var showChatInfoSheet: Bool = false
|
||||
@State private var showAddMembersSheet: Bool = false
|
||||
@State private var composeState = ComposeState()
|
||||
@@ -47,65 +47,70 @@ struct ChatView: View {
|
||||
@State private var showDeleteSelectedMessages: Bool = false
|
||||
@State private var allowToDeleteSelectedMessagesForAll: Bool = false
|
||||
|
||||
@AppStorage(DEFAULT_TOOLBAR_MATERIAL) private var toolbarMaterial = ToolbarMaterial.defaultMaterial
|
||||
|
||||
var body: some View {
|
||||
if #available(iOS 16.0, *) {
|
||||
let v = viewBody
|
||||
.scrollDismissesKeyboard(.immediately)
|
||||
.keyboardPadding()
|
||||
if (searchMode) {
|
||||
v.toolbarBackground(.thinMaterial, for: .navigationBar)
|
||||
} else {
|
||||
v.toolbarBackground(.visible, for: .navigationBar)
|
||||
}
|
||||
viewBody
|
||||
.scrollDismissesKeyboard(.immediately)
|
||||
.toolbarBackground(.hidden, for: .navigationBar)
|
||||
} else {
|
||||
viewBody
|
||||
}
|
||||
}
|
||||
|
||||
@ViewBuilder
|
||||
private var viewBody: some View {
|
||||
let cInfo = chat.chatInfo
|
||||
return VStack(spacing: 0) {
|
||||
if searchMode {
|
||||
searchToolbar()
|
||||
ZStack {
|
||||
let wallpaperImage = theme.wallpaper.type.image
|
||||
let wallpaperType = theme.wallpaper.type
|
||||
let backgroundColor = theme.wallpaper.background ?? wallpaperType.defaultBackgroundColor(theme.base, theme.colors.background)
|
||||
let tintColor = theme.wallpaper.tint ?? wallpaperType.defaultTintColor(theme.base)
|
||||
Color.clear.ignoresSafeArea(.all)
|
||||
.if(wallpaperImage != nil) { view in
|
||||
view.modifier(
|
||||
ChatViewBackground(image: wallpaperImage!, imageType: wallpaperType, background: backgroundColor, tint: tintColor)
|
||||
)
|
||||
}
|
||||
VStack(spacing: 0) {
|
||||
ZStack(alignment: .bottomTrailing) {
|
||||
chatItemsList()
|
||||
// TODO: Extract into a separate view, to reduce the scope of `FloatingButtonModel` updates
|
||||
floatingButtons(unreadBelow: floatingButtonModel.unreadBelow, isNearBottom: floatingButtonModel.isNearBottom)
|
||||
}
|
||||
connectingText()
|
||||
if selectedChatItems == nil {
|
||||
ComposeView(
|
||||
chat: chat,
|
||||
composeState: $composeState,
|
||||
keyboardVisible: $keyboardVisible
|
||||
)
|
||||
.disabled(!cInfo.sendMsgEnabled)
|
||||
} else {
|
||||
SelectedItemsBottomToolbar(
|
||||
chatItems: ItemsModel.shared.reversedChatItems,
|
||||
selectedChatItems: $selectedChatItems,
|
||||
chatInfo: chat.chatInfo,
|
||||
deleteItems: { forAll in
|
||||
allowToDeleteSelectedMessagesForAll = forAll
|
||||
showDeleteSelectedMessages = true
|
||||
},
|
||||
moderateItems: {
|
||||
if case let .group(groupInfo) = chat.chatInfo {
|
||||
showModerateSelectedMessagesAlert(groupInfo)
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
.safeAreaInset(edge: .top) {
|
||||
VStack(spacing: .zero) {
|
||||
if searchMode { searchToolbar() }
|
||||
Divider()
|
||||
}
|
||||
ZStack(alignment: .bottomTrailing) {
|
||||
let wallpaperImage = theme.wallpaper.type.image
|
||||
let wallpaperType = theme.wallpaper.type
|
||||
let backgroundColor = theme.wallpaper.background ?? wallpaperType.defaultBackgroundColor(theme.base, theme.colors.background)
|
||||
let tintColor = theme.wallpaper.tint ?? wallpaperType.defaultTintColor(theme.base)
|
||||
chatItemsList()
|
||||
.if(wallpaperImage != nil) { view in
|
||||
view.modifier(
|
||||
ChatViewBackground(image: wallpaperImage!, imageType: wallpaperType, background: backgroundColor, tint: tintColor)
|
||||
)
|
||||
}
|
||||
floatingButtons(counts: floatingButtonModel.unreadChatItemCounts)
|
||||
}
|
||||
connectingText()
|
||||
if selectedChatItems == nil {
|
||||
ComposeView(
|
||||
chat: chat,
|
||||
composeState: $composeState,
|
||||
keyboardVisible: $keyboardVisible
|
||||
)
|
||||
.disabled(!cInfo.sendMsgEnabled)
|
||||
} else {
|
||||
SelectedItemsBottomToolbar(
|
||||
chatItems: ItemsModel.shared.reversedChatItems,
|
||||
selectedChatItems: $selectedChatItems,
|
||||
chatInfo: chat.chatInfo,
|
||||
deleteItems: { forAll in
|
||||
allowToDeleteSelectedMessagesForAll = forAll
|
||||
showDeleteSelectedMessages = true
|
||||
},
|
||||
moderateItems: {
|
||||
if case let .group(groupInfo) = chat.chatInfo {
|
||||
showModerateSelectedMessagesAlert(groupInfo)
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
.background(ToolbarMaterial.material(toolbarMaterial))
|
||||
}
|
||||
.navigationTitle(cInfo.chatViewName)
|
||||
.background(theme.colors.background)
|
||||
@@ -125,16 +130,23 @@ struct ChatView: View {
|
||||
}
|
||||
}
|
||||
}
|
||||
.appSheet(item: $selectedMember) { member in
|
||||
Group {
|
||||
if case let .group(groupInfo) = chat.chatInfo {
|
||||
GroupMemberInfoView(groupInfo: groupInfo, groupMember: member, navigation: true)
|
||||
}
|
||||
}
|
||||
}
|
||||
.onAppear {
|
||||
loadChat(chat: chat)
|
||||
initChatView()
|
||||
selectedChatItems = nil
|
||||
initChatView()
|
||||
}
|
||||
.onChange(of: chatModel.chatId) { cId in
|
||||
showChatInfoSheet = false
|
||||
selectedChatItems = nil
|
||||
scrollModel.scrollToBottom()
|
||||
stopAudioPlayer()
|
||||
if let cId {
|
||||
selectedChatItems = nil
|
||||
if let c = chatModel.getChat(cId) {
|
||||
chat = c
|
||||
}
|
||||
@@ -147,8 +159,10 @@ struct ChatView: View {
|
||||
.onChange(of: revealedChatItem) { _ in
|
||||
NotificationCenter.postReverseListNeedsLayout()
|
||||
}
|
||||
.onChange(of: im.reversedChatItems) { reversedChatItems in
|
||||
if reversedChatItems.count <= loadItemsPerPage && filtered(reversedChatItems).count < 10 {
|
||||
.onChange(of: im.isLoading) { isLoading in
|
||||
if !isLoading,
|
||||
im.reversedChatItems.count <= loadItemsPerPage,
|
||||
filtered(im.reversedChatItems).count < 10 {
|
||||
loadChatItems(chat.chatInfo)
|
||||
}
|
||||
}
|
||||
@@ -157,7 +171,6 @@ struct ChatView: View {
|
||||
VideoPlayerView.players.removeAll()
|
||||
stopAudioPlayer()
|
||||
if chatModel.chatId == cInfo.id && !presentationMode.wrappedValue.isPresented {
|
||||
chatModel.chatId = nil
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 0.35) {
|
||||
if chatModel.chatId == nil {
|
||||
chatModel.chatItemStatuses = [:]
|
||||
@@ -184,7 +197,7 @@ struct ChatView: View {
|
||||
} label: {
|
||||
ChatInfoToolbar(chat: chat)
|
||||
}
|
||||
.appSheet(isPresented: $showChatInfoSheet) {
|
||||
.appSheet(isPresented: $showChatInfoSheet, onDismiss: { theme = buildTheme() }) {
|
||||
ChatInfoView(
|
||||
chat: chat,
|
||||
contact: contact,
|
||||
@@ -217,6 +230,7 @@ struct ChatView: View {
|
||||
}
|
||||
}
|
||||
ToolbarItem(placement: .navigationBarTrailing) {
|
||||
let isLoading = im.isLoading && im.showLoadingProgress
|
||||
if selectedChatItems != nil {
|
||||
Button {
|
||||
withAnimation {
|
||||
@@ -239,19 +253,23 @@ struct ChatView: View {
|
||||
}
|
||||
}
|
||||
Menu {
|
||||
if callsPrefEnabled && chatModel.activeCall == nil {
|
||||
Button {
|
||||
CallController.shared.startCall(contact, .video)
|
||||
} label: {
|
||||
Label("Video call", systemImage: "video")
|
||||
if !isLoading {
|
||||
if callsPrefEnabled && chatModel.activeCall == nil {
|
||||
Button {
|
||||
CallController.shared.startCall(contact, .video)
|
||||
} label: {
|
||||
Label("Video call", systemImage: "video")
|
||||
}
|
||||
.disabled(!contact.ready || !contact.active)
|
||||
}
|
||||
.disabled(!contact.ready || !contact.active)
|
||||
searchButton()
|
||||
ToggleNtfsButton(chat: chat)
|
||||
.disabled(!contact.ready || !contact.active)
|
||||
}
|
||||
searchButton()
|
||||
ToggleNtfsButton(chat: chat)
|
||||
.disabled(!contact.ready || !contact.active)
|
||||
} label: {
|
||||
Image(systemName: "ellipsis")
|
||||
.tint(isLoading ? Color.clear : nil)
|
||||
.overlay { if isLoading { ProgressView() } }
|
||||
}
|
||||
}
|
||||
case let .group(groupInfo):
|
||||
@@ -276,10 +294,14 @@ struct ChatView: View {
|
||||
}
|
||||
}
|
||||
Menu {
|
||||
searchButton()
|
||||
ToggleNtfsButton(chat: chat)
|
||||
if !isLoading {
|
||||
searchButton()
|
||||
ToggleNtfsButton(chat: chat)
|
||||
}
|
||||
} label: {
|
||||
Image(systemName: "ellipsis")
|
||||
.tint(isLoading ? Color.clear : nil)
|
||||
.overlay { if isLoading { ProgressView() } }
|
||||
}
|
||||
}
|
||||
case .local:
|
||||
@@ -345,14 +367,11 @@ struct ChatView: View {
|
||||
searchText = ""
|
||||
searchMode = false
|
||||
searchFocussed = false
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 0.35) {
|
||||
loadChat(chat: chat)
|
||||
}
|
||||
Task { await loadChat(chat: chat) }
|
||||
}
|
||||
}
|
||||
.padding(.horizontal)
|
||||
.padding(.vertical, 8)
|
||||
.background(.thinMaterial)
|
||||
}
|
||||
|
||||
private func voiceWithoutFrame(_ ci: ChatItem) -> Bool {
|
||||
@@ -386,31 +405,33 @@ struct ChatView: View {
|
||||
: voiceNoFrame
|
||||
? (g.size.width - 32)
|
||||
: (g.size.width - 32) * 0.84
|
||||
return chatItemView(ci, maxWidth)
|
||||
.onAppear {
|
||||
floatingButtonModel.appeared(viewId: ci.viewId)
|
||||
}
|
||||
.onDisappear {
|
||||
floatingButtonModel.disappeared(viewId: ci.viewId)
|
||||
}
|
||||
.id(ci.id) // Required to trigger `onAppear` on iOS15
|
||||
return ChatItemWithMenu(
|
||||
chat: $chat,
|
||||
chatItem: ci,
|
||||
maxWidth: maxWidth,
|
||||
composeState: $composeState,
|
||||
selectedMember: $selectedMember,
|
||||
revealedChatItem: $revealedChatItem,
|
||||
selectedChatItems: $selectedChatItems
|
||||
)
|
||||
.id(ci.id) // Required to trigger `onAppear` on iOS15
|
||||
} loadPage: {
|
||||
loadChatItems(cInfo)
|
||||
}
|
||||
.onTapGesture { hideKeyboard() }
|
||||
.onChange(of: searchText) { _ in
|
||||
loadChat(chat: chat, search: searchText)
|
||||
}
|
||||
.onChange(of: chatModel.chatId) { chatId in
|
||||
if let chatId, let c = chatModel.getChat(chatId) {
|
||||
chat = c
|
||||
showChatInfoSheet = false
|
||||
loadChat(chat: c)
|
||||
.opacity(ItemsModel.shared.isLoading ? 0 : 1)
|
||||
.padding(.vertical, -InvertedTableView.inset)
|
||||
.onTapGesture { hideKeyboard() }
|
||||
.onChange(of: searchText) { _ in
|
||||
Task { await loadChat(chat: chat, search: searchText) }
|
||||
}
|
||||
.onChange(of: im.itemAdded) { added in
|
||||
if added {
|
||||
im.itemAdded = false
|
||||
if floatingButtonModel.isReallyNearBottom {
|
||||
scrollModel.scrollToBottom()
|
||||
}
|
||||
}
|
||||
.onChange(of: im.reversedChatItems) { _ in
|
||||
floatingButtonModel.chatItemsChanged()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -429,57 +450,43 @@ struct ChatView: View {
|
||||
}
|
||||
|
||||
class FloatingButtonModel: ObservableObject {
|
||||
private enum Event {
|
||||
case appeared(String)
|
||||
case disappeared(String)
|
||||
case chatItemsChanged
|
||||
}
|
||||
|
||||
@Published var unreadChatItemCounts: UnreadChatItemCounts
|
||||
|
||||
private let events = PassthroughSubject<Event, Never>()
|
||||
static let shared = FloatingButtonModel()
|
||||
@Published var unreadBelow: Int = 0
|
||||
@Published var isNearBottom: Bool = true
|
||||
var isReallyNearBottom: Bool { scrollOffset.value > 0 && scrollOffset.value < 500 }
|
||||
let visibleItems = PassthroughSubject<[String], Never>()
|
||||
let scrollOffset = CurrentValueSubject<Double, Never>(0)
|
||||
private var bag = Set<AnyCancellable>()
|
||||
|
||||
init() {
|
||||
unreadChatItemCounts = UnreadChatItemCounts(
|
||||
isNearBottom: true,
|
||||
unreadBelow: 0
|
||||
)
|
||||
events
|
||||
visibleItems
|
||||
.receive(on: DispatchQueue.global(qos: .background))
|
||||
.scan(Set<String>()) { itemsInView, event in
|
||||
return switch event {
|
||||
case let .appeared(viewId):
|
||||
itemsInView.union([viewId])
|
||||
case let .disappeared(viewId):
|
||||
itemsInView.subtracting([viewId])
|
||||
case .chatItemsChanged:
|
||||
itemsInView
|
||||
}
|
||||
.map { itemIds in
|
||||
if let viewId = itemIds.first,
|
||||
let index = ItemsModel.shared.reversedChatItems.firstIndex(where: { $0.viewId == viewId }) {
|
||||
ItemsModel.shared.reversedChatItems[..<index].reduce(into: 0) { unread, chatItem in
|
||||
if chatItem.isRcvNew { unread += 1 }
|
||||
}
|
||||
} else { 0 }
|
||||
}
|
||||
.map { ChatModel.shared.unreadChatItemCounts(itemsInView: $0) }
|
||||
.removeDuplicates()
|
||||
.throttle(for: .seconds(0.2), scheduler: DispatchQueue.main, latest: true)
|
||||
.assign(to: \.unreadChatItemCounts, on: self)
|
||||
.receive(on: DispatchQueue.main)
|
||||
.assign(to: \.unreadBelow, on: self)
|
||||
.store(in: &bag)
|
||||
}
|
||||
|
||||
func appeared(viewId: String) {
|
||||
events.send(.appeared(viewId))
|
||||
}
|
||||
|
||||
func disappeared(viewId: String) {
|
||||
events.send(.disappeared(viewId))
|
||||
}
|
||||
|
||||
func chatItemsChanged() {
|
||||
events.send(.chatItemsChanged)
|
||||
scrollOffset
|
||||
.map { $0 < 800 }
|
||||
.removeDuplicates()
|
||||
// Delay the state change until scroll to bottom animation is finished
|
||||
.delay(for: 0.35, scheduler: DispatchQueue.main)
|
||||
.assign(to: \.isNearBottom, on: self)
|
||||
.store(in: &bag)
|
||||
}
|
||||
}
|
||||
|
||||
private func floatingButtons(counts: UnreadChatItemCounts) -> some View {
|
||||
private func floatingButtons(unreadBelow: Int, isNearBottom: Bool) -> some View {
|
||||
VStack {
|
||||
let unreadAbove = chat.chatStats.unreadCount - counts.unreadBelow
|
||||
let unreadAbove = chat.chatStats.unreadCount - unreadBelow
|
||||
if unreadAbove > 0 {
|
||||
circleButton {
|
||||
unreadCountText(unreadAbove)
|
||||
@@ -500,16 +507,16 @@ struct ChatView: View {
|
||||
}
|
||||
}
|
||||
Spacer()
|
||||
if counts.unreadBelow > 0 {
|
||||
if unreadBelow > 0 {
|
||||
circleButton {
|
||||
unreadCountText(counts.unreadBelow)
|
||||
unreadCountText(unreadBelow)
|
||||
.font(.callout)
|
||||
.foregroundColor(theme.colors.primary)
|
||||
}
|
||||
.onTapGesture {
|
||||
scrollModel.scrollToBottom()
|
||||
}
|
||||
} else if !counts.isNearBottom {
|
||||
} else if !isNearBottom {
|
||||
circleButton {
|
||||
Image(systemName: "chevron.down")
|
||||
.foregroundColor(theme.colors.primary)
|
||||
@@ -539,8 +546,8 @@ struct ChatView: View {
|
||||
|
||||
private func endCallButton(_ call: Call) -> some View {
|
||||
Button {
|
||||
if let uuid = call.callkitUUID {
|
||||
CallController.shared.endCall(callUUID: uuid)
|
||||
if CallController.useCallKit(), let callUUID = call.callUUID {
|
||||
CallController.shared.endCall(callUUID: callUUID)
|
||||
} else {
|
||||
CallController.shared.endCall(call: call) {}
|
||||
}
|
||||
@@ -663,22 +670,11 @@ struct ChatView: View {
|
||||
VoiceItemState.chatView = [:]
|
||||
}
|
||||
|
||||
@ViewBuilder private func chatItemView(_ ci: ChatItem, _ maxWidth: CGFloat) -> some View {
|
||||
ChatItemWithMenu(
|
||||
chat: chat,
|
||||
chatItem: ci,
|
||||
maxWidth: maxWidth,
|
||||
composeState: $composeState,
|
||||
selectedMember: $selectedMember,
|
||||
revealedChatItem: $revealedChatItem,
|
||||
selectedChatItems: $selectedChatItems
|
||||
)
|
||||
}
|
||||
|
||||
private struct ChatItemWithMenu: View {
|
||||
@EnvironmentObject var m: ChatModel
|
||||
@EnvironmentObject var theme: AppTheme
|
||||
@ObservedObject var chat: Chat
|
||||
@Binding @ObservedObject var chat: Chat
|
||||
@ObservedObject var dummyModel: ChatItemDummyModel = .shared
|
||||
let chatItem: ChatItem
|
||||
let maxWidth: CGFloat
|
||||
@Binding var composeState: ComposeState
|
||||
@@ -692,38 +688,72 @@ struct ChatView: View {
|
||||
@State private var showChatItemInfoSheet: Bool = false
|
||||
@State private var chatItemInfo: ChatItemInfo?
|
||||
@State private var showForwardingSheet: Bool = false
|
||||
|
||||
@State private var msgWidth: CGFloat = 0
|
||||
|
||||
@Binding var selectedChatItems: Set<Int64>?
|
||||
|
||||
@State private var allowMenu: Bool = true
|
||||
|
||||
var revealed: Bool { chatItem == revealedChatItem }
|
||||
|
||||
typealias ItemSeparation = (timestamp: Bool, largeGap: Bool, date: Date?)
|
||||
|
||||
func getItemSeparation(_ chatItem: ChatItem, at i: Int?) -> ItemSeparation {
|
||||
let im = ItemsModel.shared
|
||||
if let i, i > 0 && im.reversedChatItems.count >= i {
|
||||
let nextItem = im.reversedChatItems[i - 1]
|
||||
let largeGap = !nextItem.chatDir.sameDirection(chatItem.chatDir) || nextItem.meta.itemTs.timeIntervalSince(chatItem.meta.itemTs) > 60
|
||||
return (
|
||||
timestamp: largeGap || formatTimestampText(chatItem.meta.itemTs) != formatTimestampText(nextItem.meta.itemTs),
|
||||
largeGap: largeGap,
|
||||
date: Calendar.current.isDate(chatItem.meta.itemTs, inSameDayAs: nextItem.meta.itemTs) ? nil : nextItem.meta.itemTs
|
||||
)
|
||||
} else {
|
||||
return (timestamp: true, largeGap: true, date: nil)
|
||||
}
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
let (currIndex, _) = m.getNextChatItem(chatItem)
|
||||
let currIndex = m.getChatItemIndex(chatItem)
|
||||
let ciCategory = chatItem.mergeCategory
|
||||
let (prevHidden, prevItem) = m.getPrevShownChatItem(currIndex, ciCategory)
|
||||
let range = itemsRange(currIndex, prevHidden)
|
||||
let timeSeparation = getItemSeparation(chatItem, at: currIndex)
|
||||
let im = ItemsModel.shared
|
||||
Group {
|
||||
if revealed, let range = range {
|
||||
let items = Array(zip(Array(range), im.reversedChatItems[range]))
|
||||
ForEach(items, id: \.1.viewId) { (i, ci) in
|
||||
let prev = i == prevHidden ? prevItem : im.reversedChatItems[i + 1]
|
||||
chatItemView(ci, nil, prev)
|
||||
.overlay {
|
||||
if let selected = selectedChatItems, ci.canBeDeletedForSelf {
|
||||
Color.clear
|
||||
.contentShape(Rectangle())
|
||||
.onTapGesture {
|
||||
let checked = selected.contains(ci.id)
|
||||
selectUnselectChatItem(select: !checked, ci)
|
||||
VStack(spacing: 0) {
|
||||
ForEach(items.reversed(), id: \.1.viewId) { (i: Int, ci: ChatItem) in
|
||||
let prev = i == prevHidden ? prevItem : im.reversedChatItems[i + 1]
|
||||
chatItemView(ci, nil, prev, getItemSeparation(ci, at: i))
|
||||
.overlay {
|
||||
if let selected = selectedChatItems, ci.canBeDeletedForSelf {
|
||||
Color.clear
|
||||
.contentShape(Rectangle())
|
||||
.onTapGesture {
|
||||
let checked = selected.contains(ci.id)
|
||||
selectUnselectChatItem(select: !checked, ci)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
chatItemView(chatItem, range, prevItem)
|
||||
VStack(spacing: 0) {
|
||||
chatItemView(chatItem, range, prevItem, timeSeparation)
|
||||
if let date = timeSeparation.date {
|
||||
Text(String.localizedStringWithFormat(
|
||||
NSLocalizedString("%@, %@", comment: "format for date separator in chat"),
|
||||
date.formatted(.dateTime.weekday(.abbreviated)),
|
||||
date.formatted(.dateTime.day().month(.abbreviated))
|
||||
))
|
||||
.font(.callout)
|
||||
.fontWeight(.medium)
|
||||
.foregroundStyle(.secondary)
|
||||
.padding(8)
|
||||
}
|
||||
}
|
||||
.overlay {
|
||||
if let selected = selectedChatItems, chatItem.canBeDeletedForSelf {
|
||||
Color.clear
|
||||
@@ -773,8 +803,54 @@ struct ChatView: View {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ViewBuilder func chatItemView(_ ci: ChatItem, _ range: ClosedRange<Int>?, _ prevItem: ChatItem?) -> some View {
|
||||
@available(iOS 16.0, *)
|
||||
struct MemberLayout: Layout {
|
||||
let spacing: Double
|
||||
let msgWidth: Double
|
||||
|
||||
private func sizes(subviews: Subviews, proposal: ProposedViewSize) -> (CGSize, CGSize) {
|
||||
assert(subviews.count == 2, "member layout must contain exactly two subviews")
|
||||
let roleSize = subviews[1].sizeThatFits(proposal)
|
||||
let memberSize = subviews[0].sizeThatFits(
|
||||
ProposedViewSize(
|
||||
width: (proposal.width ?? msgWidth) - roleSize.width,
|
||||
height: proposal.height
|
||||
)
|
||||
)
|
||||
return (memberSize, roleSize)
|
||||
}
|
||||
|
||||
func sizeThatFits(proposal: ProposedViewSize, subviews: Subviews, cache: inout Void) -> CGSize {
|
||||
let (memberSize, roleSize) = sizes(subviews: subviews, proposal: proposal)
|
||||
return CGSize(
|
||||
width: min(
|
||||
proposal.width ?? msgWidth,
|
||||
max(msgWidth, roleSize.width + spacing + memberSize.width)
|
||||
),
|
||||
height: max(memberSize.height, roleSize.height)
|
||||
)
|
||||
}
|
||||
|
||||
func placeSubviews(in bounds: CGRect, proposal: ProposedViewSize, subviews: Subviews, cache: inout Void) {
|
||||
let (memberSize, roleSize) = sizes(subviews: subviews, proposal: proposal)
|
||||
subviews[0].place(
|
||||
at: CGPoint(x: bounds.minX, y: bounds.midY - memberSize.height / 2),
|
||||
proposal: ProposedViewSize(memberSize)
|
||||
)
|
||||
subviews[1].place(
|
||||
at: CGPoint(
|
||||
x: bounds.minX + max(memberSize.width + spacing, msgWidth - roleSize.width),
|
||||
y: bounds.midY - roleSize.height / 2
|
||||
),
|
||||
proposal: ProposedViewSize(roleSize)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@ViewBuilder func chatItemView(_ ci: ChatItem, _ range: ClosedRange<Int>?, _ prevItem: ChatItem?, _ itemSeparation: ItemSeparation) -> some View {
|
||||
let bottomPadding: Double = itemSeparation.largeGap ? 10 : 2
|
||||
if case let .groupRcv(member) = ci.chatDir,
|
||||
case let .group(groupInfo) = chat.chatInfo {
|
||||
let (prevMember, memCount): (GroupMember?, Int) =
|
||||
@@ -786,28 +862,53 @@ struct ChatView: View {
|
||||
if prevItem == nil || showMemberImage(member, prevItem) || prevMember != nil {
|
||||
VStack(alignment: .leading, spacing: 4) {
|
||||
if ci.content.showMemberName {
|
||||
let t = if memCount == 1 && member.memberRole > .member {
|
||||
Text(member.memberRole.text + " ").fontWeight(.semibold) + Text(member.displayName)
|
||||
} else {
|
||||
Text(memberNames(member, prevMember, memCount))
|
||||
Group {
|
||||
if memCount == 1 && member.memberRole > .member {
|
||||
Group {
|
||||
if #available(iOS 16.0, *) {
|
||||
MemberLayout(spacing: 16, msgWidth: msgWidth) {
|
||||
Text(member.chatViewName)
|
||||
.lineLimit(1)
|
||||
Text(member.memberRole.text)
|
||||
.fontWeight(.semibold)
|
||||
.lineLimit(1)
|
||||
.padding(.trailing, 8)
|
||||
}
|
||||
} else {
|
||||
HStack(spacing: 16) {
|
||||
Text(member.chatViewName)
|
||||
.lineLimit(1)
|
||||
Text(member.memberRole.text)
|
||||
.fontWeight(.semibold)
|
||||
.lineLimit(1)
|
||||
.layoutPriority(1)
|
||||
}
|
||||
}
|
||||
}
|
||||
.frame(
|
||||
maxWidth: maxWidth,
|
||||
alignment: chatItem.chatDir.sent ? .trailing : .leading
|
||||
)
|
||||
} else {
|
||||
Text(memberNames(member, prevMember, memCount))
|
||||
.lineLimit(2)
|
||||
}
|
||||
}
|
||||
t
|
||||
.font(.caption)
|
||||
.foregroundStyle(.secondary)
|
||||
.lineLimit(2)
|
||||
.padding(.leading, memberImageSize + 14 + (selectedChatItems != nil && ci.canBeDeletedForSelf ? 12 + 24 : 0))
|
||||
.padding(.top, 7)
|
||||
.padding(.top, 3) // this is in addition to message sequence gap
|
||||
}
|
||||
HStack(alignment: .center, spacing: 0) {
|
||||
if selectedChatItems != nil && ci.canBeDeletedForSelf {
|
||||
SelectedChatItem(ciId: ci.id, selectedChatItems: $selectedChatItems)
|
||||
.padding(.trailing, 12)
|
||||
}
|
||||
HStack(alignment: .top, spacing: 8) {
|
||||
HStack(alignment: .top, spacing: 10) {
|
||||
MemberProfileImage(member, size: memberImageSize, backgroundColor: theme.colors.background)
|
||||
.onTapGesture {
|
||||
if m.membersLoaded {
|
||||
selectedMember = m.getGroupMember(member.groupMemberId)
|
||||
if let member = m.getGroupMember(member.groupMemberId) {
|
||||
selectedMember = member
|
||||
} else {
|
||||
Task {
|
||||
await m.loadGroupMembers(groupInfo) {
|
||||
@@ -816,14 +917,12 @@ struct ChatView: View {
|
||||
}
|
||||
}
|
||||
}
|
||||
.appSheet(item: $selectedMember) { member in
|
||||
GroupMemberInfoView(groupInfo: groupInfo, groupMember: member, navigation: true)
|
||||
}
|
||||
chatItemWithMenu(ci, range, maxWidth)
|
||||
chatItemWithMenu(ci, range, maxWidth, itemSeparation)
|
||||
.onPreferenceChange(DetermineWidth.Key.self) { msgWidth = $0 }
|
||||
}
|
||||
}
|
||||
}
|
||||
.padding(.bottom, 5)
|
||||
.padding(.bottom, bottomPadding)
|
||||
.padding(.trailing)
|
||||
.padding(.leading, 12)
|
||||
} else {
|
||||
@@ -832,11 +931,11 @@ struct ChatView: View {
|
||||
SelectedChatItem(ciId: ci.id, selectedChatItems: $selectedChatItems)
|
||||
.padding(.leading, 12)
|
||||
}
|
||||
chatItemWithMenu(ci, range, maxWidth)
|
||||
chatItemWithMenu(ci, range, maxWidth, itemSeparation)
|
||||
.padding(.trailing)
|
||||
.padding(.leading, memberImageSize + 8 + 12)
|
||||
.padding(.leading, 10 + memberImageSize + 12)
|
||||
}
|
||||
.padding(.bottom, 5)
|
||||
.padding(.bottom, bottomPadding)
|
||||
}
|
||||
} else {
|
||||
HStack(alignment: .center, spacing: 0) {
|
||||
@@ -849,10 +948,10 @@ struct ChatView: View {
|
||||
.padding(.leading)
|
||||
}
|
||||
}
|
||||
chatItemWithMenu(ci, range, maxWidth)
|
||||
chatItemWithMenu(ci, range, maxWidth, itemSeparation)
|
||||
.padding(.horizontal)
|
||||
}
|
||||
.padding(.bottom, 5)
|
||||
.padding(.bottom, bottomPadding)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -867,7 +966,7 @@ struct ChatView: View {
|
||||
}
|
||||
}
|
||||
|
||||
@ViewBuilder func chatItemWithMenu(_ ci: ChatItem, _ range: ClosedRange<Int>?, _ maxWidth: CGFloat) -> some View {
|
||||
@ViewBuilder func chatItemWithMenu(_ ci: ChatItem, _ range: ClosedRange<Int>?, _ maxWidth: CGFloat, _ itemSeparation: ItemSeparation) -> some View {
|
||||
let alignment: Alignment = ci.chatDir.sent ? .trailing : .leading
|
||||
VStack(alignment: alignment.horizontal, spacing: 3) {
|
||||
ChatItemView(
|
||||
@@ -877,7 +976,8 @@ struct ChatView: View {
|
||||
revealed: .constant(revealed),
|
||||
allowMenu: $allowMenu
|
||||
)
|
||||
.modifier(ChatItemClipped(ci))
|
||||
.environment(\.showTimestamp, itemSeparation.timestamp)
|
||||
.modifier(ChatItemClipped(ci, tailVisible: itemSeparation.largeGap))
|
||||
.contextMenu { menu(ci, range, live: composeState.liveMessage != nil) }
|
||||
.accessibilityLabel("")
|
||||
if ci.content.msgContent != nil && (ci.meta.itemDeleted == nil || revealed) && ci.reactions.count > 0 {
|
||||
|
||||
@@ -18,7 +18,7 @@ struct ComposeImageView: View {
|
||||
var body: some View {
|
||||
HStack(alignment: .center, spacing: 8) {
|
||||
let imgs: [UIImage] = images.compactMap { image in
|
||||
UIImage(base64Encoded: image)
|
||||
imageFromBase64(image)
|
||||
}
|
||||
if imgs.count == 0 {
|
||||
ProgressView()
|
||||
|
||||
@@ -40,7 +40,7 @@ struct ComposeLinkView: View {
|
||||
|
||||
private func linkPreviewView(_ linkPreview: LinkPreview) -> some View {
|
||||
HStack(alignment: .center, spacing: 8) {
|
||||
if let uiImage = UIImage(base64Encoded: linkPreview.image) {
|
||||
if let uiImage = imageFromBase64(linkPreview.image) {
|
||||
Image(uiImage: uiImage)
|
||||
.resizable()
|
||||
.aspectRatio(contentMode: .fit)
|
||||
@@ -55,7 +55,7 @@ struct ComposeLinkView: View {
|
||||
.foregroundColor(theme.colors.secondary)
|
||||
}
|
||||
.padding(.vertical, 5)
|
||||
.frame(maxWidth: .infinity, minHeight: 60, maxHeight: 60)
|
||||
.frame(maxWidth: .infinity, minHeight: 60)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -281,6 +281,7 @@ struct ComposeView: View {
|
||||
@State private var stopPlayback: Bool = false
|
||||
|
||||
@AppStorage(DEFAULT_PRIVACY_SAVE_LAST_DRAFT) private var saveLastDraft = true
|
||||
@AppStorage(DEFAULT_TOOLBAR_MATERIAL) private var toolbarMaterial = ToolbarMaterial.defaultMaterial
|
||||
|
||||
var body: some View {
|
||||
VStack(spacing: 0) {
|
||||
@@ -381,7 +382,11 @@ struct ComposeView: View {
|
||||
}
|
||||
}
|
||||
}
|
||||
.background(.thinMaterial)
|
||||
.background {
|
||||
Color.clear
|
||||
.overlay(ToolbarMaterial.material(toolbarMaterial))
|
||||
.ignoresSafeArea(.all, edges: .bottom)
|
||||
}
|
||||
.onChange(of: composeState.message) { msg in
|
||||
if composeState.linkPreviewAllowed {
|
||||
if msg.count > 0 {
|
||||
@@ -746,6 +751,7 @@ struct ComposeView: View {
|
||||
case .linkPreview:
|
||||
sent = await send(checkLinkPreview(), quoted: quoted, live: live, ttl: ttl)
|
||||
case let .mediaPreviews(mediaPreviews: media):
|
||||
// TODO batch send: batch media previews
|
||||
let last = media.count - 1
|
||||
if last >= 0 {
|
||||
for i in 0..<last {
|
||||
@@ -882,22 +888,26 @@ struct ComposeView: View {
|
||||
}
|
||||
|
||||
func send(_ mc: MsgContent, quoted: Int64?, file: CryptoFile? = nil, live: Bool = false, ttl: Int?) async -> ChatItem? {
|
||||
if let chatItem = chat.chatInfo.chatType == .local
|
||||
? await apiCreateChatItem(noteFolderId: chat.chatInfo.apiId, file: file, msg: mc)
|
||||
: await apiSendMessage(
|
||||
if let chatItems = chat.chatInfo.chatType == .local
|
||||
? await apiCreateChatItems(
|
||||
noteFolderId: chat.chatInfo.apiId,
|
||||
composedMessages: [ComposedMessage(fileSource: file, msgContent: mc)]
|
||||
)
|
||||
: await apiSendMessages(
|
||||
type: chat.chatInfo.chatType,
|
||||
id: chat.chatInfo.apiId,
|
||||
file: file,
|
||||
quotedItemId: quoted,
|
||||
msg: mc,
|
||||
live: live,
|
||||
ttl: ttl
|
||||
ttl: ttl,
|
||||
composedMessages: [ComposedMessage(fileSource: file, quotedItemId: quoted, msgContent: mc)]
|
||||
) {
|
||||
await MainActor.run {
|
||||
chatModel.removeLiveDummy(animated: false)
|
||||
chatModel.addChatItem(chat.chatInfo, chatItem)
|
||||
for chatItem in chatItems {
|
||||
chatModel.addChatItem(chat.chatInfo, chatItem)
|
||||
}
|
||||
}
|
||||
return chatItem
|
||||
// UI only supports sending one item at a time
|
||||
return chatItems.first
|
||||
}
|
||||
if let file = file {
|
||||
removeFile(file.filePath)
|
||||
@@ -906,18 +916,21 @@ struct ComposeView: View {
|
||||
}
|
||||
|
||||
func forwardItem(_ forwardedItem: ChatItem, _ fromChatInfo: ChatInfo, _ ttl: Int?) async -> ChatItem? {
|
||||
if let chatItem = await apiForwardChatItem(
|
||||
if let chatItems = await apiForwardChatItems(
|
||||
toChatType: chat.chatInfo.chatType,
|
||||
toChatId: chat.chatInfo.apiId,
|
||||
fromChatType: fromChatInfo.chatType,
|
||||
fromChatId: fromChatInfo.apiId,
|
||||
itemId: forwardedItem.id,
|
||||
itemIds: [forwardedItem.id],
|
||||
ttl: ttl
|
||||
) {
|
||||
await MainActor.run {
|
||||
chatModel.addChatItem(chat.chatInfo, chatItem)
|
||||
for chatItem in chatItems {
|
||||
chatModel.addChatItem(chat.chatInfo, chatItem)
|
||||
}
|
||||
}
|
||||
return chatItem
|
||||
// TODO batch send: forward multiple messages
|
||||
return chatItems.first
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -185,7 +185,6 @@ struct GroupChatInfoView: View {
|
||||
logger.error("GroupChatInfoView apiGetGroupLink: \(responseError(error))")
|
||||
}
|
||||
}
|
||||
.keyboardPadding()
|
||||
}
|
||||
|
||||
private func groupInfoHeader() -> some View {
|
||||
|
||||
@@ -321,24 +321,24 @@ struct GroupMemberInfoView: View {
|
||||
|
||||
func knownDirectChatButton(_ chat: Chat, width: CGFloat) -> some View {
|
||||
InfoViewButton(image: "message.fill", title: "message", width: width) {
|
||||
dismissAllSheets(animated: true)
|
||||
DispatchQueue.main.async {
|
||||
chatModel.chatId = chat.id
|
||||
ItemsModel.shared.loadOpenChat(chat.id) {
|
||||
dismissAllSheets(animated: true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func newDirectChatButton(_ contactId: Int64, width: CGFloat) -> some View {
|
||||
InfoViewButton(image: "message.fill", title: "message", width: width) {
|
||||
do {
|
||||
let chat = try apiGetChat(type: .direct, id: contactId)
|
||||
chatModel.addChat(chat)
|
||||
dismissAllSheets(animated: true)
|
||||
DispatchQueue.main.async {
|
||||
chatModel.chatId = chat.id
|
||||
Task {
|
||||
do {
|
||||
let chat = try await apiGetChat(type: .direct, id: contactId)
|
||||
chatModel.addChat(chat)
|
||||
ItemsModel.shared.loadOpenChat(chat.id) {
|
||||
dismissAllSheets(animated: true)
|
||||
}
|
||||
} catch let error {
|
||||
logger.error("openDirectChatButton apiGetChat error: \(responseError(error))")
|
||||
}
|
||||
} catch let error {
|
||||
logger.error("openDirectChatButton apiGetChat error: \(responseError(error))")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -352,9 +352,10 @@ struct GroupMemberInfoView: View {
|
||||
await MainActor.run {
|
||||
progressIndicator = false
|
||||
chatModel.addChat(Chat(chatInfo: .direct(contact: memberContact)))
|
||||
dismissAllSheets(animated: true)
|
||||
chatModel.chatId = memberContact.id
|
||||
chatModel.setContactNetworkStatus(memberContact, .connected)
|
||||
ItemsModel.shared.loadOpenChat(memberContact.id) {
|
||||
dismissAllSheets(animated: true)
|
||||
}
|
||||
NetworkModel.shared.setContactNetworkStatus(memberContact, .connected)
|
||||
}
|
||||
} catch let error {
|
||||
logger.error("createMemberContactButton apiCreateMemberContact error: \(responseError(error))")
|
||||
|
||||
@@ -8,16 +8,16 @@
|
||||
|
||||
import SwiftUI
|
||||
import Combine
|
||||
import SimpleXChat
|
||||
|
||||
/// A List, which displays it's items in reverse order - from bottom to top
|
||||
struct ReverseList<Item: Identifiable & Hashable & Sendable, Content: View>: UIViewControllerRepresentable {
|
||||
struct ReverseList<Content: View>: UIViewControllerRepresentable {
|
||||
let items: Array<ChatItem>
|
||||
|
||||
let items: Array<Item>
|
||||
|
||||
@Binding var scrollState: ReverseListScrollModel<Item>.State
|
||||
@Binding var scrollState: ReverseListScrollModel.State
|
||||
|
||||
/// Closure, that returns user interface for a given item
|
||||
let content: (Item) -> Content
|
||||
let content: (ChatItem) -> Content
|
||||
|
||||
let loadPage: () -> Void
|
||||
|
||||
@@ -26,7 +26,9 @@ struct ReverseList<Item: Identifiable & Hashable & Sendable, Content: View>: UIV
|
||||
}
|
||||
|
||||
func updateUIViewController(_ controller: Controller, context: Context) {
|
||||
controller.representer = self
|
||||
if case let .scrollingTo(destination) = scrollState, !items.isEmpty {
|
||||
controller.view.layer.removeAllAnimations()
|
||||
switch destination {
|
||||
case .nextPage:
|
||||
controller.scrollToNextPage()
|
||||
@@ -43,9 +45,10 @@ struct ReverseList<Item: Identifiable & Hashable & Sendable, Content: View>: UIV
|
||||
/// Controller, which hosts SwiftUI cells
|
||||
class Controller: UITableViewController {
|
||||
private enum Section { case main }
|
||||
private let representer: ReverseList
|
||||
private var dataSource: UITableViewDiffableDataSource<Section, Item>!
|
||||
var representer: ReverseList
|
||||
private var dataSource: UITableViewDiffableDataSource<Section, ChatItem>!
|
||||
private var itemCount: Int = 0
|
||||
private let updateFloatingButtons = PassthroughSubject<Void, Never>()
|
||||
private var bag = Set<AnyCancellable>()
|
||||
|
||||
init(representer: ReverseList) {
|
||||
@@ -53,6 +56,7 @@ struct ReverseList<Item: Identifiable & Hashable & Sendable, Content: View>: UIV
|
||||
super.init(style: .plain)
|
||||
|
||||
// 1. Style
|
||||
tableView = InvertedTableView()
|
||||
tableView.separatorStyle = .none
|
||||
tableView.transform = .verticalFlip
|
||||
tableView.backgroundColor = .clear
|
||||
@@ -71,7 +75,7 @@ struct ReverseList<Item: Identifiable & Hashable & Sendable, Content: View>: UIV
|
||||
}
|
||||
|
||||
// 3. Configure data source
|
||||
self.dataSource = UITableViewDiffableDataSource<Section, Item>(
|
||||
self.dataSource = UITableViewDiffableDataSource<Section, ChatItem>(
|
||||
tableView: tableView
|
||||
) { (tableView, indexPath, item) -> UITableViewCell? in
|
||||
if indexPath.item > self.itemCount - 8, self.itemCount > 8 {
|
||||
@@ -103,6 +107,10 @@ struct ReverseList<Item: Identifiable & Hashable & Sendable, Content: View>: UIV
|
||||
name: notificationName,
|
||||
object: nil
|
||||
)
|
||||
updateFloatingButtons
|
||||
.throttle(for: 0.2, scheduler: DispatchQueue.main, latest: true)
|
||||
.sink { self.updateVisibleItems() }
|
||||
.store(in: &bag)
|
||||
}
|
||||
|
||||
@available(*, unavailable)
|
||||
@@ -132,6 +140,11 @@ struct ReverseList<Item: Identifiable & Hashable & Sendable, Content: View>: UIV
|
||||
NotificationCenter.default.post(name: .chatViewWillBeginScrolling, object: nil)
|
||||
}
|
||||
|
||||
override func viewDidAppear(_ animated: Bool) {
|
||||
tableView.clipsToBounds = false
|
||||
parent?.viewIfLoaded?.clipsToBounds = false
|
||||
}
|
||||
|
||||
/// Scrolls up
|
||||
func scrollToNextPage() {
|
||||
tableView.setContentOffset(
|
||||
@@ -147,22 +160,27 @@ struct ReverseList<Item: Identifiable & Hashable & Sendable, Content: View>: UIV
|
||||
/// Scrolls to Item at index path
|
||||
/// - Parameter indexPath: Item to scroll to - will scroll to beginning of the list, if `nil`
|
||||
func scroll(to index: Int?, position: UITableView.ScrollPosition) {
|
||||
if let index {
|
||||
var animated = false
|
||||
if #available(iOS 16.0, *) {
|
||||
animated = true
|
||||
}
|
||||
var animated = false
|
||||
if #available(iOS 16.0, *) {
|
||||
animated = true
|
||||
}
|
||||
if let index, tableView.numberOfRows(inSection: 0) != 0 {
|
||||
tableView.scrollToRow(
|
||||
at: IndexPath(row: index, section: 0),
|
||||
at: position,
|
||||
animated: animated
|
||||
)
|
||||
Task { representer.scrollState = .atDestination }
|
||||
} else {
|
||||
tableView.setContentOffset(
|
||||
CGPoint(x: .zero, y: -InvertedTableView.inset),
|
||||
animated: animated
|
||||
)
|
||||
}
|
||||
Task { representer.scrollState = .atDestination }
|
||||
}
|
||||
|
||||
func update(items: Array<Item>) {
|
||||
var snapshot = NSDiffableDataSourceSnapshot<Section, Item>()
|
||||
func update(items: [ChatItem]) {
|
||||
var snapshot = NSDiffableDataSourceSnapshot<Section, ChatItem>()
|
||||
snapshot.appendSections([.main])
|
||||
snapshot.appendItems(items)
|
||||
dataSource.defaultRowAnimation = .none
|
||||
@@ -170,7 +188,40 @@ struct ReverseList<Item: Identifiable & Hashable & Sendable, Content: View>: UIV
|
||||
snapshot,
|
||||
animatingDifferences: itemCount != 0 && abs(items.count - itemCount) == 1
|
||||
)
|
||||
// Sets content offset on initial load
|
||||
if itemCount == 0 {
|
||||
tableView.setContentOffset(
|
||||
CGPoint(x: 0, y: -InvertedTableView.inset),
|
||||
animated: false
|
||||
)
|
||||
}
|
||||
itemCount = items.count
|
||||
updateFloatingButtons.send()
|
||||
}
|
||||
|
||||
override func scrollViewDidScroll(_ scrollView: UIScrollView) {
|
||||
updateFloatingButtons.send()
|
||||
}
|
||||
|
||||
private func updateVisibleItems() {
|
||||
let fbm = ChatView.FloatingButtonModel.shared
|
||||
fbm.scrollOffset.send(tableView.contentOffset.y + InvertedTableView.inset)
|
||||
fbm.visibleItems.send(
|
||||
(tableView.indexPathsForVisibleRows ?? [])
|
||||
.compactMap { indexPath -> String? in
|
||||
guard let relativeFrame = tableView.superview?.convert(
|
||||
tableView.rectForRow(at: indexPath),
|
||||
from: tableView
|
||||
) else { return nil }
|
||||
// Checks that the cell is visible accounting for the added insets
|
||||
let isVisible =
|
||||
relativeFrame.maxY > InvertedTableView.inset &&
|
||||
relativeFrame.minY < tableView.frame.height - InvertedTableView.inset
|
||||
return indexPath.item < representer.items.count && isVisible
|
||||
? representer.items[indexPath.item].viewId
|
||||
: nil
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -215,12 +266,12 @@ struct ReverseList<Item: Identifiable & Hashable & Sendable, Content: View>: UIV
|
||||
}
|
||||
|
||||
/// Manages ``ReverseList`` scrolling
|
||||
class ReverseListScrollModel<Item: Identifiable>: ObservableObject {
|
||||
class ReverseListScrollModel: ObservableObject {
|
||||
/// Represents Scroll State of ``ReverseList``
|
||||
enum State: Equatable {
|
||||
enum Destination: Equatable {
|
||||
case nextPage
|
||||
case item(Item.ID)
|
||||
case item(ChatItem.ID)
|
||||
case bottom
|
||||
}
|
||||
|
||||
@@ -238,7 +289,7 @@ class ReverseListScrollModel<Item: Identifiable>: ObservableObject {
|
||||
state = .scrollingTo(.bottom)
|
||||
}
|
||||
|
||||
func scrollToItem(id: Item.ID) {
|
||||
func scrollToItem(id: ChatItem.ID) {
|
||||
state = .scrollingTo(.item(id))
|
||||
}
|
||||
}
|
||||
@@ -272,3 +323,28 @@ func withConditionalAnimation<Result>(
|
||||
try body()
|
||||
}
|
||||
}
|
||||
|
||||
class InvertedTableView: UITableView {
|
||||
static let inset = CGFloat(100)
|
||||
|
||||
static let insets = UIEdgeInsets(
|
||||
top: inset,
|
||||
left: .zero,
|
||||
bottom: inset,
|
||||
right: .zero
|
||||
)
|
||||
|
||||
override var contentInsetAdjustmentBehavior: UIScrollView.ContentInsetAdjustmentBehavior {
|
||||
get { .never }
|
||||
set { }
|
||||
}
|
||||
|
||||
override var contentInset: UIEdgeInsets {
|
||||
get { Self.insets }
|
||||
set { }
|
||||
}
|
||||
|
||||
override var adjustedContentInset: UIEdgeInsets {
|
||||
Self.insets
|
||||
}
|
||||
}
|
||||
|
||||
@@ -104,19 +104,22 @@ struct SelectedItemsBottomToolbar: View {
|
||||
allButtonsDisabled = count == 0 || count > 20
|
||||
canModerate = possibleToModerate(chatInfo)
|
||||
if let selected = selectedItems {
|
||||
(deleteEnabled, deleteForEveryoneEnabled, moderateEnabled, _, selectedChatItems) = chatItems.reduce((true, true, true, true, [])) { (r, ci) in
|
||||
let me: Bool
|
||||
let onlyOwnGroupItems: Bool
|
||||
(deleteEnabled, deleteForEveryoneEnabled, me, onlyOwnGroupItems, selectedChatItems) = chatItems.reduce((true, true, true, true, [])) { (r, ci) in
|
||||
if selected.contains(ci.id) {
|
||||
var (de, dee, me, onlyOwnGroupItems, sel) = r
|
||||
de = de && ci.canBeDeletedForSelf
|
||||
dee = dee && ci.meta.deletable && !ci.localNote
|
||||
onlyOwnGroupItems = onlyOwnGroupItems && ci.chatDir == .groupSnd
|
||||
me = me && !onlyOwnGroupItems && ci.content.msgContent != nil && ci.memberToModerate(chatInfo) != nil
|
||||
me = me && ci.content.msgContent != nil && ci.memberToModerate(chatInfo) != nil
|
||||
sel.insert(ci.id) // we are collecting new selected items here to account for any changes in chat items list
|
||||
return (de, dee, me, onlyOwnGroupItems, sel)
|
||||
} else {
|
||||
return r
|
||||
}
|
||||
}
|
||||
moderateEnabled = me && !onlyOwnGroupItems
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -114,7 +114,7 @@ struct ChatListNavLink: View {
|
||||
}
|
||||
} else {
|
||||
NavLinkPlain(
|
||||
tag: chat.chatInfo.id,
|
||||
chatId: chat.chatInfo.id,
|
||||
selection: $chatModel.chatId,
|
||||
label: { ChatPreviewView(chat: chat, progressByTimeout: Binding.constant(false)) }
|
||||
)
|
||||
@@ -194,7 +194,7 @@ struct ChatListNavLink: View {
|
||||
}
|
||||
default:
|
||||
NavLinkPlain(
|
||||
tag: chat.chatInfo.id,
|
||||
chatId: chat.chatInfo.id,
|
||||
selection: $chatModel.chatId,
|
||||
label: { ChatPreviewView(chat: chat, progressByTimeout: Binding.constant(false)) },
|
||||
disabled: !groupInfo.ready
|
||||
@@ -221,7 +221,7 @@ struct ChatListNavLink: View {
|
||||
|
||||
@ViewBuilder private func noteFolderNavLink(_ noteFolder: NoteFolder) -> some View {
|
||||
NavLinkPlain(
|
||||
tag: chat.chatInfo.id,
|
||||
chatId: chat.chatInfo.id,
|
||||
selection: $chatModel.chatId,
|
||||
label: { ChatPreviewView(chat: chat, progressByTimeout: Binding.constant(false)) },
|
||||
disabled: !noteFolder.ready
|
||||
@@ -244,7 +244,7 @@ struct ChatListNavLink: View {
|
||||
await MainActor.run { inProgress = false }
|
||||
}
|
||||
} label: {
|
||||
SwipeLabel("Join", systemImage: chat.chatInfo.incognito ? "theatermasks" : "ipad.and.arrow.forward", inverted: oneHandUI)
|
||||
SwipeLabel(NSLocalizedString("Join", comment: "swipe action"), systemImage: chat.chatInfo.incognito ? "theatermasks" : "ipad.and.arrow.forward", inverted: oneHandUI)
|
||||
}
|
||||
.tint(chat.chatInfo.incognito ? .indigo : theme.colors.primary)
|
||||
}
|
||||
@@ -254,14 +254,14 @@ struct ChatListNavLink: View {
|
||||
Button {
|
||||
Task { await markChatRead(chat) }
|
||||
} label: {
|
||||
SwipeLabel("Read", systemImage: "checkmark", inverted: oneHandUI)
|
||||
SwipeLabel(NSLocalizedString("Read", comment: "swipe action"), systemImage: "checkmark", inverted: oneHandUI)
|
||||
}
|
||||
.tint(theme.colors.primary)
|
||||
} else {
|
||||
Button {
|
||||
Task { await markChatUnread(chat) }
|
||||
} label: {
|
||||
SwipeLabel("Unread", systemImage: "circlebadge.fill", inverted: oneHandUI)
|
||||
SwipeLabel(NSLocalizedString("Unread", comment: "swipe action"), systemImage: "circlebadge.fill", inverted: oneHandUI)
|
||||
}
|
||||
.tint(theme.colors.primary)
|
||||
}
|
||||
@@ -273,14 +273,14 @@ struct ChatListNavLink: View {
|
||||
Button {
|
||||
toggleChatFavorite(chat, favorite: false)
|
||||
} label: {
|
||||
SwipeLabel("Unfav.", systemImage: "star.slash.fill", inverted: oneHandUI)
|
||||
SwipeLabel(NSLocalizedString("Unfav.", comment: "swipe action"), systemImage: "star.slash.fill", inverted: oneHandUI)
|
||||
}
|
||||
.tint(.green)
|
||||
} else {
|
||||
Button {
|
||||
toggleChatFavorite(chat, favorite: true)
|
||||
} label: {
|
||||
SwipeLabel("Favorite", systemImage: "star.fill", inverted: oneHandUI)
|
||||
SwipeLabel(NSLocalizedString("Favorite", comment: "swipe action"), systemImage: "star.fill", inverted: oneHandUI)
|
||||
}
|
||||
.tint(.green)
|
||||
}
|
||||
@@ -291,9 +291,9 @@ struct ChatListNavLink: View {
|
||||
toggleNotifications(chat, enableNtfs: !chat.chatInfo.ntfsEnabled)
|
||||
} label: {
|
||||
if chat.chatInfo.ntfsEnabled {
|
||||
SwipeLabel("Mute", systemImage: "speaker.slash.fill", inverted: oneHandUI)
|
||||
SwipeLabel(NSLocalizedString("Mute", comment: "swipe action"), systemImage: "speaker.slash.fill", inverted: oneHandUI)
|
||||
} else {
|
||||
SwipeLabel("Unmute", systemImage: "speaker.wave.2.fill", inverted: oneHandUI)
|
||||
SwipeLabel(NSLocalizedString("Unmute", comment: "swipe action"), systemImage: "speaker.wave.2.fill", inverted: oneHandUI)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -302,7 +302,7 @@ struct ChatListNavLink: View {
|
||||
Button {
|
||||
AlertManager.shared.showAlert(clearChatAlert())
|
||||
} label: {
|
||||
SwipeLabel("Clear", systemImage: "gobackward", inverted: oneHandUI)
|
||||
SwipeLabel(NSLocalizedString("Clear", comment: "swipe action"), systemImage: "gobackward", inverted: oneHandUI)
|
||||
}
|
||||
.tint(Color.orange)
|
||||
}
|
||||
@@ -311,7 +311,7 @@ struct ChatListNavLink: View {
|
||||
Button {
|
||||
AlertManager.shared.showAlert(clearNoteFolderAlert())
|
||||
} label: {
|
||||
SwipeLabel("Clear", systemImage: "gobackward", inverted: oneHandUI)
|
||||
SwipeLabel(NSLocalizedString("Clear", comment: "swipe action"), systemImage: "gobackward", inverted: oneHandUI)
|
||||
}
|
||||
.tint(Color.orange)
|
||||
}
|
||||
@@ -320,7 +320,7 @@ struct ChatListNavLink: View {
|
||||
Button {
|
||||
AlertManager.shared.showAlert(leaveGroupAlert(groupInfo))
|
||||
} label: {
|
||||
SwipeLabel("Leave", systemImage: "rectangle.portrait.and.arrow.right.fill", inverted: oneHandUI)
|
||||
SwipeLabel(NSLocalizedString("Leave", comment: "swipe action"), systemImage: "rectangle.portrait.and.arrow.right.fill", inverted: oneHandUI)
|
||||
}
|
||||
.tint(Color.yellow)
|
||||
}
|
||||
@@ -339,22 +339,23 @@ struct ChatListNavLink: View {
|
||||
.swipeActions(edge: .trailing, allowsFullSwipe: true) {
|
||||
Button {
|
||||
Task { await acceptContactRequest(incognito: false, contactRequest: contactRequest) }
|
||||
} label: { SwipeLabel("Accept", systemImage: "checkmark", inverted: oneHandUI) }
|
||||
} label: { SwipeLabel(NSLocalizedString("Accept", comment: "swipe action"), systemImage: "checkmark", inverted: oneHandUI) }
|
||||
.tint(theme.colors.primary)
|
||||
Button {
|
||||
Task { await acceptContactRequest(incognito: true, contactRequest: contactRequest) }
|
||||
} label: {
|
||||
SwipeLabel("Accept incognito", systemImage: "theatermasks.fill", inverted: oneHandUI)
|
||||
SwipeLabel(NSLocalizedString("Accept incognito", comment: "swipe action"), systemImage: "theatermasks.fill", inverted: oneHandUI)
|
||||
}
|
||||
.tint(.indigo)
|
||||
Button {
|
||||
AlertManager.shared.showAlert(rejectContactRequestAlert(contactRequest))
|
||||
} label: {
|
||||
SwipeLabel("Reject", systemImage: "multiply.fill", inverted: oneHandUI)
|
||||
SwipeLabel(NSLocalizedString("Reject", comment: "swipe action"), systemImage: "multiply.fill", inverted: oneHandUI)
|
||||
}
|
||||
.tint(.red)
|
||||
}
|
||||
.frame(height: dynamicRowHeight)
|
||||
.contentShape(Rectangle())
|
||||
.onTapGesture { showContactRequestDialog = true }
|
||||
.confirmationDialog("Accept connection request?", isPresented: $showContactRequestDialog, titleVisibility: .visible) {
|
||||
Button("Accept") { Task { await acceptContactRequest(incognito: false, contactRequest: contactRequest) } }
|
||||
@@ -378,7 +379,7 @@ struct ChatListNavLink: View {
|
||||
Button {
|
||||
showContactConnectionInfo = true
|
||||
} label: {
|
||||
SwipeLabel("Name", systemImage: "pencil", inverted: oneHandUI)
|
||||
SwipeLabel(NSLocalizedString("Name", comment: "swipe action"), systemImage: "pencil", inverted: oneHandUI)
|
||||
}
|
||||
.tint(theme.colors.primary)
|
||||
}
|
||||
@@ -392,13 +393,14 @@ struct ChatListNavLink: View {
|
||||
}
|
||||
}
|
||||
}
|
||||
.contentShape(Rectangle())
|
||||
.onTapGesture {
|
||||
showContactConnectionInfo = true
|
||||
}
|
||||
}
|
||||
|
||||
private var deleteLabel: some View {
|
||||
SwipeLabel("Delete", systemImage: "trash.fill", inverted: oneHandUI)
|
||||
SwipeLabel(NSLocalizedString("Delete", comment: "swipe action"), systemImage: "trash.fill", inverted: oneHandUI)
|
||||
}
|
||||
|
||||
private func deleteGroupAlert(_ groupInfo: GroupInfo) -> Alert {
|
||||
@@ -472,9 +474,7 @@ struct ChatListNavLink: View {
|
||||
Task {
|
||||
let ok = await connectContactViaAddress(contact.contactId, incognito, showAlert: { AlertManager.shared.showAlert($0) })
|
||||
if ok {
|
||||
await MainActor.run {
|
||||
chatModel.chatId = contact.id
|
||||
}
|
||||
ItemsModel.shared.loadOpenChat(contact.id)
|
||||
AlertManager.shared.showAlert(connReqSentAlert(.contact))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,17 @@
|
||||
import SwiftUI
|
||||
import SimpleXChat
|
||||
|
||||
enum UserPickerSheet: Identifiable {
|
||||
case address
|
||||
case chatPreferences
|
||||
case chatProfiles
|
||||
case currentProfile
|
||||
case useFromDesktop
|
||||
case settings
|
||||
|
||||
var id: Self { self }
|
||||
}
|
||||
|
||||
struct ChatListView: View {
|
||||
@EnvironmentObject var chatModel: ChatModel
|
||||
@EnvironmentObject var theme: AppTheme
|
||||
@@ -18,12 +29,14 @@ struct ChatListView: View {
|
||||
@State private var searchText = ""
|
||||
@State private var searchShowingSimplexLink = false
|
||||
@State private var searchChatFilteredBySimplexLink: String? = nil
|
||||
@State private var userPickerVisible = false
|
||||
@State private var showConnectDesktop = false
|
||||
@State private var scrollToSearchBar = false
|
||||
@State private var activeUserPickerSheet: UserPickerSheet? = nil
|
||||
@State private var isUserPickerPresented: Bool = false
|
||||
|
||||
@AppStorage(DEFAULT_SHOW_UNREAD_AND_FAVORITES) private var showUnreadAndFavorites = false
|
||||
@AppStorage(GROUP_DEFAULT_ONE_HAND_UI, store: groupDefaults) private var oneHandUI = true
|
||||
@AppStorage(DEFAULT_ONE_HAND_UI_CARD_SHOWN) private var oneHandUICardShown = false
|
||||
@AppStorage(DEFAULT_TOOLBAR_MATERIAL) private var toolbarMaterial = ToolbarMaterial.defaultMaterial
|
||||
|
||||
var body: some View {
|
||||
if #available(iOS 16.0, *) {
|
||||
@@ -38,37 +51,63 @@ struct ChatListView: View {
|
||||
NavStackCompat(
|
||||
isActive: Binding(
|
||||
get: { chatModel.chatId != nil },
|
||||
set: { _ in }
|
||||
set: { active in
|
||||
if !active { chatModel.chatId = nil }
|
||||
}
|
||||
),
|
||||
destination: chatView
|
||||
) { chatListView }
|
||||
if userPickerVisible {
|
||||
Rectangle().fill(.white.opacity(0.001)).onTapGesture {
|
||||
withAnimation {
|
||||
userPickerVisible.toggle()
|
||||
}
|
||||
.sheet(isPresented: $isUserPickerPresented) {
|
||||
UserPicker(activeSheet: $activeUserPickerSheet)
|
||||
.sheet(item: $activeUserPickerSheet) { sheet in
|
||||
if let currentUser = chatModel.currentUser {
|
||||
switch sheet {
|
||||
case .address:
|
||||
NavigationView {
|
||||
UserAddressView(shareViaProfile: currentUser.addressShared)
|
||||
.navigationTitle("Public address")
|
||||
.navigationBarTitleDisplayMode(.large)
|
||||
.modifier(ThemedBackground(grouped: true))
|
||||
}
|
||||
case .chatProfiles:
|
||||
NavigationView {
|
||||
UserProfilesView()
|
||||
}
|
||||
case .currentProfile:
|
||||
NavigationView {
|
||||
UserProfile()
|
||||
.navigationTitle("Your current profile")
|
||||
.modifier(ThemedBackground())
|
||||
}
|
||||
case .chatPreferences:
|
||||
NavigationView {
|
||||
PreferencesView(profile: currentUser.profile, preferences: currentUser.fullPreferences, currentPreferences: currentUser.fullPreferences)
|
||||
.navigationTitle("Your preferences")
|
||||
.navigationBarTitleDisplayMode(.large)
|
||||
.modifier(ThemedBackground(grouped: true))
|
||||
}
|
||||
case .useFromDesktop:
|
||||
ConnectDesktopView(viaSettings: false)
|
||||
case .settings:
|
||||
SettingsView(showSettings: $showSettings)
|
||||
.navigationBarTitleDisplayMode(.large)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
UserPicker(
|
||||
showSettings: $showSettings,
|
||||
showConnectDesktop: $showConnectDesktop,
|
||||
userPickerVisible: $userPickerVisible
|
||||
)
|
||||
}
|
||||
.sheet(isPresented: $showConnectDesktop) {
|
||||
ConnectDesktopView()
|
||||
}
|
||||
}
|
||||
|
||||
private var chatListView: some View {
|
||||
withToolbar {
|
||||
let tm = ToolbarMaterial.material(toolbarMaterial)
|
||||
return withToolbar(tm) {
|
||||
chatList
|
||||
.background(theme.colors.background)
|
||||
.navigationBarTitleDisplayMode(.inline)
|
||||
.navigationBarHidden(searchMode || oneHandUI)
|
||||
}
|
||||
.scaleEffect(x: 1, y: oneHandUI ? -1 : 1, anchor: .center)
|
||||
.onDisappear() { withAnimation { userPickerVisible = false } }
|
||||
.onDisappear() { activeUserPickerSheet = nil }
|
||||
.refreshable {
|
||||
AlertManager.shared.showAlert(Alert(
|
||||
title: Text("Reconnect servers?"),
|
||||
@@ -86,24 +125,37 @@ struct ChatListView: View {
|
||||
))
|
||||
}
|
||||
.safeAreaInset(edge: .top) {
|
||||
if oneHandUI { Divider().background(Material.ultraThin) }
|
||||
if oneHandUI { Divider().background(tm) }
|
||||
}
|
||||
.safeAreaInset(edge: .bottom) {
|
||||
if oneHandUI {
|
||||
Divider().padding(.bottom, Self.hasHomeIndicator ? 0 : 8).background(tm)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ViewBuilder func withToolbar(content: () -> some View) -> some View {
|
||||
static var hasHomeIndicator: Bool = {
|
||||
if let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene,
|
||||
let window = windowScene.windows.first {
|
||||
window.safeAreaInsets.bottom > 0
|
||||
} else { false }
|
||||
}()
|
||||
|
||||
@ViewBuilder func withToolbar(_ material: Material, content: () -> some View) -> some View {
|
||||
if #available(iOS 16.0, *) {
|
||||
if oneHandUI {
|
||||
content()
|
||||
.toolbarBackground(.visible, for: .bottomBar)
|
||||
.toolbarBackground(.hidden, for: .bottomBar)
|
||||
.toolbar { bottomToolbar }
|
||||
} else {
|
||||
content()
|
||||
.toolbarBackground(.automatic, for: .navigationBar)
|
||||
.toolbarBackground(material)
|
||||
.toolbar { topToolbar }
|
||||
}
|
||||
} else {
|
||||
if oneHandUI {
|
||||
content().toolbar { bottomToolbar }
|
||||
content().toolbar { bottomToolbarGroup }
|
||||
} else {
|
||||
content().toolbar { topToolbar }
|
||||
}
|
||||
@@ -112,28 +164,33 @@ struct ChatListView: View {
|
||||
|
||||
@ToolbarContentBuilder var topToolbar: some ToolbarContent {
|
||||
ToolbarItem(placement: .topBarLeading) { leadingToolbarItem }
|
||||
ToolbarItem(placement: .principal) { principalToolbarItem }
|
||||
ToolbarItem(placement: .principal) { SubsStatusIndicator() }
|
||||
ToolbarItem(placement: .topBarTrailing) { trailingToolbarItem }
|
||||
}
|
||||
|
||||
@ToolbarContentBuilder var bottomToolbar: some ToolbarContent {
|
||||
let padding: Double = Self.hasHomeIndicator ? 0 : 14
|
||||
ToolbarItem(placement: .bottomBar) {
|
||||
let v = HStack {
|
||||
leadingToolbarItem
|
||||
principalToolbarItem
|
||||
trailingToolbarItem
|
||||
}
|
||||
if #available(iOS 16.0, *) {
|
||||
v
|
||||
} else {
|
||||
VStack(spacing: 0) {
|
||||
Divider()
|
||||
v
|
||||
.padding(.vertical)
|
||||
.frame(maxWidth: .infinity)
|
||||
.background(Material.ultraThin)
|
||||
}
|
||||
HStack {
|
||||
leadingToolbarItem.padding(.bottom, padding)
|
||||
Spacer()
|
||||
SubsStatusIndicator().padding(.bottom, padding)
|
||||
Spacer()
|
||||
trailingToolbarItem.padding(.bottom, padding)
|
||||
}
|
||||
.contentShape(Rectangle())
|
||||
.onTapGesture { scrollToSearchBar = true }
|
||||
}
|
||||
}
|
||||
|
||||
@ToolbarContentBuilder var bottomToolbarGroup: some ToolbarContent {
|
||||
let padding: Double = Self.hasHomeIndicator ? 0 : 14
|
||||
ToolbarItemGroup(placement: .bottomBar) {
|
||||
leadingToolbarItem.padding(.bottom, padding)
|
||||
Spacer()
|
||||
SubsStatusIndicator().padding(.bottom, padding)
|
||||
Spacer()
|
||||
trailingToolbarItem.padding(.bottom, padding)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -141,7 +198,7 @@ struct ChatListView: View {
|
||||
let user = chatModel.currentUser ?? User.sampleData
|
||||
ZStack(alignment: .topTrailing) {
|
||||
ProfileImage(imageStr: user.image, size: 32, color: Color(uiColor: .quaternaryLabel))
|
||||
.padding(.trailing, 4)
|
||||
.padding([.top, .trailing], 3)
|
||||
let allRead = chatModel.users
|
||||
.filter { u in !u.user.activeUser && !u.user.hidden }
|
||||
.allSatisfy { u in u.unreadCount == 0 }
|
||||
@@ -150,24 +207,10 @@ struct ChatListView: View {
|
||||
}
|
||||
}
|
||||
.onTapGesture {
|
||||
if chatModel.users.filter({ u in u.user.activeUser || !u.user.hidden }).count > 1 {
|
||||
withAnimation {
|
||||
userPickerVisible.toggle()
|
||||
}
|
||||
} else {
|
||||
showSettings = true
|
||||
}
|
||||
isUserPickerPresented = true
|
||||
}
|
||||
}
|
||||
|
||||
@ViewBuilder var principalToolbarItem: some View {
|
||||
HStack(spacing: 4) {
|
||||
Text("Chats").font(.headline)
|
||||
SubsStatusIndicator()
|
||||
}
|
||||
.frame(maxWidth: .infinity, alignment: .center)
|
||||
}
|
||||
|
||||
@ViewBuilder var trailingToolbarItem: some View {
|
||||
switch chatModel.chatRunning {
|
||||
case .some(true): NewChatMenuButton()
|
||||
@@ -179,50 +222,73 @@ struct ChatListView: View {
|
||||
@ViewBuilder private var chatList: some View {
|
||||
let cs = filteredChats()
|
||||
ZStack {
|
||||
List {
|
||||
if !chatModel.chats.isEmpty {
|
||||
ChatListSearchBar(
|
||||
searchMode: $searchMode,
|
||||
searchFocussed: $searchFocussed,
|
||||
searchText: $searchText,
|
||||
searchShowingSimplexLink: $searchShowingSimplexLink,
|
||||
searchChatFilteredBySimplexLink: $searchChatFilteredBySimplexLink
|
||||
)
|
||||
.scaleEffect(x: 1, y: oneHandUI ? -1 : 1, anchor: .center)
|
||||
.listRowSeparator(.hidden)
|
||||
.listRowBackground(Color.clear)
|
||||
.frame(maxWidth: .infinity)
|
||||
.padding(.top, oneHandUI ? 8 : 0)
|
||||
}
|
||||
if !oneHandUICardShown {
|
||||
OneHandUICard()
|
||||
ScrollViewReader { scrollProxy in
|
||||
List {
|
||||
if !chatModel.chats.isEmpty {
|
||||
ChatListSearchBar(
|
||||
searchMode: $searchMode,
|
||||
searchFocussed: $searchFocussed,
|
||||
searchText: $searchText,
|
||||
searchShowingSimplexLink: $searchShowingSimplexLink,
|
||||
searchChatFilteredBySimplexLink: $searchChatFilteredBySimplexLink
|
||||
)
|
||||
.scaleEffect(x: 1, y: oneHandUI ? -1 : 1, anchor: .center)
|
||||
.listRowSeparator(.hidden)
|
||||
.listRowBackground(Color.clear)
|
||||
.frame(maxWidth: .infinity)
|
||||
.padding(.top, oneHandUI ? 8 : 0)
|
||||
.id("searchBar")
|
||||
}
|
||||
if !oneHandUICardShown {
|
||||
OneHandUICard()
|
||||
.scaleEffect(x: 1, y: oneHandUI ? -1 : 1, anchor: .center)
|
||||
.listRowSeparator(.hidden)
|
||||
.listRowBackground(Color.clear)
|
||||
}
|
||||
if #available(iOS 16.0, *) {
|
||||
ForEach(cs, id: \.viewId) { chat in
|
||||
ChatListNavLink(chat: chat)
|
||||
.scaleEffect(x: 1, y: oneHandUI ? -1 : 1, anchor: .center)
|
||||
.padding(.trailing, -16)
|
||||
.disabled(chatModel.chatRunning != true || chatModel.deletedChats.contains(chat.chatInfo.id))
|
||||
.listRowBackground(Color.clear)
|
||||
}
|
||||
.offset(x: -8)
|
||||
} else {
|
||||
ForEach(cs, id: \.viewId) { chat in
|
||||
VStack(spacing: .zero) {
|
||||
Divider()
|
||||
.padding(.leading, 16)
|
||||
ChatListNavLink(chat: chat)
|
||||
.padding(.horizontal, 8)
|
||||
.padding(.vertical, 6)
|
||||
}
|
||||
.scaleEffect(x: 1, y: oneHandUI ? -1 : 1, anchor: .center)
|
||||
.listRowSeparator(.hidden)
|
||||
.listRowInsets(EdgeInsets())
|
||||
.background { theme.colors.background } // Hides default list selection colour
|
||||
.disabled(chatModel.chatRunning != true || chatModel.deletedChats.contains(chat.chatInfo.id))
|
||||
}
|
||||
}
|
||||
}
|
||||
ForEach(cs, id: \.viewId) { chat in
|
||||
ChatListNavLink(chat: chat)
|
||||
.scaleEffect(x: 1, y: oneHandUI ? -1 : 1, anchor: .center)
|
||||
.padding(.trailing, -16)
|
||||
.disabled(chatModel.chatRunning != true || chatModel.deletedChats.contains(chat.chatInfo.id))
|
||||
.listRowBackground(Color.clear)
|
||||
.listStyle(.plain)
|
||||
.onChange(of: chatModel.chatId) { currentChatId in
|
||||
if let chatId = chatModel.chatToTop, currentChatId != chatId {
|
||||
chatModel.chatToTop = nil
|
||||
chatModel.popChat(chatId)
|
||||
}
|
||||
stopAudioPlayer()
|
||||
}
|
||||
.offset(x: -8)
|
||||
}
|
||||
.listStyle(.plain)
|
||||
.onChange(of: chatModel.chatId) { chId in
|
||||
if chId == nil, let chatId = chatModel.chatToTop {
|
||||
chatModel.chatToTop = nil
|
||||
chatModel.popChat(chatId)
|
||||
.onChange(of: chatModel.currentUser?.userId) { _ in
|
||||
stopAudioPlayer()
|
||||
}
|
||||
.onChange(of: scrollToSearchBar) { scrollToSearchBar in
|
||||
if scrollToSearchBar {
|
||||
Task { self.scrollToSearchBar = false }
|
||||
withAnimation { scrollProxy.scrollTo("searchBar") }
|
||||
}
|
||||
}
|
||||
stopAudioPlayer()
|
||||
}
|
||||
.onChange(of: chatModel.currentUser?.userId) { _ in
|
||||
stopAudioPlayer()
|
||||
}
|
||||
// .onAppear {
|
||||
// oneHandUICardShown = false
|
||||
// }
|
||||
if cs.isEmpty && !chatModel.chats.isEmpty {
|
||||
Text("No filtered chats")
|
||||
.scaleEffect(x: 1, y: oneHandUI ? -1 : 1, anchor: .center)
|
||||
@@ -231,7 +297,7 @@ struct ChatListView: View {
|
||||
}
|
||||
}
|
||||
|
||||
private func unreadBadge(_ text: Text? = Text(" "), size: CGFloat = 18) -> some View {
|
||||
private func unreadBadge(size: CGFloat = 18) -> some View {
|
||||
Circle()
|
||||
.frame(width: size, height: size)
|
||||
.foregroundColor(theme.colors.primary)
|
||||
@@ -303,7 +369,7 @@ struct ChatListView: View {
|
||||
struct SubsStatusIndicator: View {
|
||||
@State private var subs: SMPServerSubs = SMPServerSubs.newSMPServerSubs
|
||||
@State private var hasSess: Bool = false
|
||||
@State private var timer: Timer? = nil
|
||||
@State private var task: Task<Void, Never>?
|
||||
@State private var showServersSummary = false
|
||||
|
||||
@AppStorage(DEFAULT_SHOW_SUBSCRIPTION_PERCENTAGE) private var showSubscriptionPercentage = false
|
||||
@@ -313,17 +379,19 @@ struct SubsStatusIndicator: View {
|
||||
showServersSummary = true
|
||||
} label: {
|
||||
HStack(spacing: 4) {
|
||||
Text("Chats").foregroundStyle(Color.primary).fixedSize().font(.headline)
|
||||
SubscriptionStatusIndicatorView(subs: subs, hasSess: hasSess)
|
||||
if showSubscriptionPercentage {
|
||||
SubscriptionStatusPercentageView(subs: subs, hasSess: hasSess)
|
||||
}
|
||||
}
|
||||
}
|
||||
.disabled(ChatModel.shared.chatRunning != true)
|
||||
.onAppear {
|
||||
startTimer()
|
||||
startTask()
|
||||
}
|
||||
.onDisappear {
|
||||
stopTimer()
|
||||
stopTask()
|
||||
}
|
||||
.appSheet(isPresented: $showServersSummary) {
|
||||
ServersSummaryView()
|
||||
@@ -331,25 +399,28 @@ struct SubsStatusIndicator: View {
|
||||
}
|
||||
}
|
||||
|
||||
private func startTimer() {
|
||||
timer = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) { _ in
|
||||
if AppChatState.shared.value == .active {
|
||||
getSubsTotal()
|
||||
private func startTask() {
|
||||
task = Task {
|
||||
while !Task.isCancelled {
|
||||
if AppChatState.shared.value == .active {
|
||||
do {
|
||||
let (subs, hasSess) = try await getAgentSubsTotal()
|
||||
await MainActor.run {
|
||||
self.subs = subs
|
||||
self.hasSess = hasSess
|
||||
}
|
||||
} catch let error {
|
||||
logger.error("getSubsTotal error: \(responseError(error))")
|
||||
}
|
||||
}
|
||||
try? await Task.sleep(nanoseconds: 1_000_000_000) // Sleep for 1 second
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func stopTimer() {
|
||||
timer?.invalidate()
|
||||
timer = nil
|
||||
}
|
||||
|
||||
private func getSubsTotal() {
|
||||
do {
|
||||
(subs, hasSess) = try getAgentSubsTotal()
|
||||
} catch let error {
|
||||
logger.error("getSubsTotal error: \(responseError(error))")
|
||||
}
|
||||
func stopTask() {
|
||||
task?.cancel()
|
||||
task = nil
|
||||
}
|
||||
}
|
||||
|
||||
@@ -475,21 +546,21 @@ func chatStoppedIcon() -> some View {
|
||||
struct ChatListView_Previews: PreviewProvider {
|
||||
static var previews: some View {
|
||||
let chatModel = ChatModel()
|
||||
chatModel.chats = [
|
||||
Chat(
|
||||
chatModel.updateChats([
|
||||
ChatData(
|
||||
chatInfo: ChatInfo.sampleData.direct,
|
||||
chatItems: [ChatItem.getSample(1, .directSnd, .now, "hello")]
|
||||
),
|
||||
Chat(
|
||||
ChatData(
|
||||
chatInfo: ChatInfo.sampleData.group,
|
||||
chatItems: [ChatItem.getSample(1, .directSnd, .now, "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.")]
|
||||
),
|
||||
Chat(
|
||||
ChatData(
|
||||
chatInfo: ChatInfo.sampleData.contactRequest,
|
||||
chatItems: []
|
||||
)
|
||||
|
||||
]
|
||||
])
|
||||
return Group {
|
||||
ChatListView(showSettings: Binding.constant(false))
|
||||
.environmentObject(chatModel)
|
||||
|
||||
@@ -302,7 +302,7 @@ struct ChatPreviewView: View {
|
||||
case let .link(_, preview):
|
||||
smallContentPreview(size: dynamicMediaSize) {
|
||||
ZStack(alignment: .topTrailing) {
|
||||
Image(uiImage: UIImage(base64Encoded: preview.image) ?? UIImage(systemName: "arrow.up.right")!)
|
||||
Image(uiImage: imageFromBase64(preview.image) ?? UIImage(systemName: "arrow.up.right")!)
|
||||
.resizable()
|
||||
.aspectRatio(contentMode: .fill)
|
||||
.frame(width: dynamicMediaSize, height: dynamicMediaSize)
|
||||
@@ -323,13 +323,13 @@ struct ChatPreviewView: View {
|
||||
}
|
||||
case let .image(_, image):
|
||||
smallContentPreview(size: dynamicMediaSize) {
|
||||
CIImageView(chatItem: ci, preview: UIImage(base64Encoded: image), maxWidth: dynamicMediaSize, smallView: true, showFullScreenImage: $showFullscreenGallery)
|
||||
.environmentObject(ReverseListScrollModel<ChatItem>())
|
||||
CIImageView(chatItem: ci, preview: imageFromBase64(image), maxWidth: dynamicMediaSize, smallView: true, showFullScreenImage: $showFullscreenGallery)
|
||||
.environmentObject(ReverseListScrollModel())
|
||||
}
|
||||
case let .video(_,image, duration):
|
||||
smallContentPreview(size: dynamicMediaSize) {
|
||||
CIVideoView(chatItem: ci, preview: UIImage(base64Encoded: image), duration: duration, maxWidth: dynamicMediaSize, videoWidth: nil, smallView: true, showFullscreenPlayer: $showFullscreenGallery)
|
||||
.environmentObject(ReverseListScrollModel<ChatItem>())
|
||||
CIVideoView(chatItem: ci, preview: imageFromBase64(image), duration: duration, maxWidth: dynamicMediaSize, videoWidth: nil, smallView: true, showFullscreenPlayer: $showFullscreenGallery)
|
||||
.environmentObject(ReverseListScrollModel())
|
||||
}
|
||||
case let .voice(_, duration):
|
||||
smallContentPreviewVoice(size: dynamicMediaSize) {
|
||||
@@ -376,17 +376,7 @@ struct ChatPreviewView: View {
|
||||
switch chat.chatInfo {
|
||||
case let .direct(contact):
|
||||
if contact.active && contact.activeConn != nil {
|
||||
switch (chatModel.contactNetworkStatus(contact)) {
|
||||
case .connected: incognitoIcon(chat.chatInfo.incognito, theme.colors.secondary, size: size)
|
||||
case .error:
|
||||
Image(systemName: "exclamationmark.circle")
|
||||
.resizable()
|
||||
.scaledToFit()
|
||||
.frame(width: dynamicChatInfoSize, height: dynamicChatInfoSize)
|
||||
.foregroundColor(theme.colors.secondary)
|
||||
default:
|
||||
ProgressView()
|
||||
}
|
||||
NetworkStatusView(contact: contact, size: size)
|
||||
} else {
|
||||
incognitoIcon(chat.chatInfo.incognito, theme.colors.secondary, size: size)
|
||||
}
|
||||
@@ -400,6 +390,30 @@ struct ChatPreviewView: View {
|
||||
incognitoIcon(chat.chatInfo.incognito, theme.colors.secondary, size: size)
|
||||
}
|
||||
}
|
||||
|
||||
struct NetworkStatusView: View {
|
||||
@Environment(\.dynamicTypeSize) private var userFont: DynamicTypeSize
|
||||
@EnvironmentObject var theme: AppTheme
|
||||
@ObservedObject var networkModel = NetworkModel.shared
|
||||
|
||||
let contact: Contact
|
||||
let size: CGFloat
|
||||
|
||||
var body: some View {
|
||||
let dynamicChatInfoSize = dynamicSize(userFont).chatInfoSize
|
||||
switch (networkModel.contactNetworkStatus(contact)) {
|
||||
case .connected: incognitoIcon(contact.contactConnIncognito, theme.colors.secondary, size: size)
|
||||
case .error:
|
||||
Image(systemName: "exclamationmark.circle")
|
||||
.resizable()
|
||||
.scaledToFit()
|
||||
.frame(width: dynamicChatInfoSize, height: dynamicChatInfoSize)
|
||||
.foregroundColor(theme.colors.secondary)
|
||||
default:
|
||||
ProgressView()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ViewBuilder func incognitoIcon(_ incognito: Bool, _ secondaryColor: Color, size: CGFloat) -> some View {
|
||||
|
||||
@@ -16,7 +16,6 @@ struct ContactConnectionView: View {
|
||||
@Environment(\.dynamicTypeSize) private var userFont: DynamicTypeSize
|
||||
@State private var localAlias = ""
|
||||
@FocusState private var aliasTextFieldFocused: Bool
|
||||
@State private var showContactConnectionInfo = false
|
||||
|
||||
var body: some View {
|
||||
if case let .contactConnection(conn) = chat.chatInfo {
|
||||
@@ -32,7 +31,6 @@ struct ContactConnectionView: View {
|
||||
.scaledToFill()
|
||||
.frame(width: 48, height: 48)
|
||||
.foregroundColor(Color(uiColor: .tertiarySystemGroupedBackground).asAnotherColorFromSecondaryVariant(theme))
|
||||
.onTapGesture { showContactConnectionInfo = true }
|
||||
}
|
||||
.frame(width: 63, height: 63)
|
||||
.padding(.leading, 4)
|
||||
@@ -72,9 +70,6 @@ struct ContactConnectionView: View {
|
||||
Spacer()
|
||||
}
|
||||
.frame(maxHeight: .infinity)
|
||||
.appSheet(isPresented: $showContactConnectionInfo) {
|
||||
ContactConnectionInfo(contactConnection: contactConnection)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,176 +8,254 @@ import SimpleXChat
|
||||
|
||||
struct UserPicker: View {
|
||||
@EnvironmentObject var m: ChatModel
|
||||
@Environment(\.scenePhase) var scenePhase
|
||||
@EnvironmentObject var theme: AppTheme
|
||||
@Binding var showSettings: Bool
|
||||
@Binding var showConnectDesktop: Bool
|
||||
@Binding var userPickerVisible: Bool
|
||||
@State var scrollViewContentSize: CGSize = .zero
|
||||
@State var disableScrolling: Bool = true
|
||||
private let menuButtonHeight: CGFloat = 68
|
||||
@State var chatViewNameWidth: CGFloat = 0
|
||||
|
||||
@Environment(\.dynamicTypeSize) private var userFont: DynamicTypeSize
|
||||
@Environment(\.scenePhase) private var scenePhase: ScenePhase
|
||||
@Environment(\.colorScheme) private var colorScheme: ColorScheme
|
||||
@Environment(\.dismiss) private var dismiss: DismissAction
|
||||
@Binding var activeSheet: UserPickerSheet?
|
||||
@State private var switchingProfile = false
|
||||
|
||||
var body: some View {
|
||||
VStack {
|
||||
Spacer().frame(height: 1)
|
||||
VStack(spacing: 0) {
|
||||
ScrollView {
|
||||
ScrollViewReader { sp in
|
||||
let users = m.users
|
||||
.filter({ u in u.user.activeUser || !u.user.hidden })
|
||||
.sorted { u, _ in u.user.activeUser }
|
||||
VStack(spacing: 0) {
|
||||
ForEach(users) { u in
|
||||
userView(u)
|
||||
Divider()
|
||||
if u.user.activeUser { Divider() }
|
||||
}
|
||||
}
|
||||
.overlay {
|
||||
GeometryReader { geo -> Color in
|
||||
DispatchQueue.main.async {
|
||||
scrollViewContentSize = geo.size
|
||||
let scenes = UIApplication.shared.connectedScenes
|
||||
if let windowScene = scenes.first as? UIWindowScene {
|
||||
let layoutFrame = windowScene.windows[0].safeAreaLayoutGuide.layoutFrame
|
||||
disableScrolling = scrollViewContentSize.height + menuButtonHeight + 10 < layoutFrame.height
|
||||
}
|
||||
}
|
||||
return Color.clear
|
||||
}
|
||||
}
|
||||
.onChange(of: userPickerVisible) { visible in
|
||||
if visible, let u = users.first {
|
||||
sp.scrollTo(u.id)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.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 {
|
||||
userPickerVisible.toggle()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.clipShape(RoundedRectangle(cornerRadius: 16))
|
||||
.background(
|
||||
Rectangle()
|
||||
.fill(theme.colors.surface)
|
||||
.cornerRadius(16)
|
||||
.shadow(color: .black.opacity(0.12), radius: 24, x: 0, y: 0)
|
||||
)
|
||||
.onPreferenceChange(DetermineWidth.Key.self) { chatViewNameWidth = $0 }
|
||||
.frame(maxWidth: chatViewNameWidth > 0 ? min(300, chatViewNameWidth + 130) : 300)
|
||||
.padding(8)
|
||||
.opacity(userPickerVisible ? 1.0 : 0.0)
|
||||
.onAppear {
|
||||
do {
|
||||
// This check prevents the call of listUsers after the app is suspended, and the database is closed.
|
||||
if case .active = scenePhase {
|
||||
m.users = try listUsers()
|
||||
}
|
||||
} catch let error {
|
||||
logger.error("Error loading users \(responseError(error))")
|
||||
if #available(iOS 16.0, *) {
|
||||
let v = viewBody.presentationDetents([.height(420)])
|
||||
if #available(iOS 16.4, *) {
|
||||
v.scrollBounceBehavior(.basedOnSize)
|
||||
} else {
|
||||
v
|
||||
}
|
||||
} else {
|
||||
viewBody
|
||||
}
|
||||
}
|
||||
|
||||
private var viewBody: some View {
|
||||
let otherUsers = m.users.filter { u in !u.user.hidden && u.user.userId != m.currentUser?.userId }
|
||||
return List {
|
||||
Section(header: Text("You").foregroundColor(theme.colors.secondary)) {
|
||||
if let user = m.currentUser {
|
||||
openSheetOnTap(label: {
|
||||
ZStack {
|
||||
let v = ProfilePreview(profileOf: user)
|
||||
.foregroundColor(.primary)
|
||||
.padding(.leading, -8)
|
||||
if #available(iOS 16.0, *) {
|
||||
v
|
||||
} else {
|
||||
v.padding(.vertical, 4)
|
||||
}
|
||||
}
|
||||
}) {
|
||||
activeSheet = .currentProfile
|
||||
}
|
||||
|
||||
private func userView(_ u: UserInfo) -> some View {
|
||||
let user = u.user
|
||||
return Button(action: {
|
||||
if user.activeUser {
|
||||
showSettings = true
|
||||
withAnimation {
|
||||
userPickerVisible.toggle()
|
||||
openSheetOnTap(title: m.userAddress == nil ? "Create public address" : "Your public address", icon: "qrcode") {
|
||||
activeSheet = .address
|
||||
}
|
||||
|
||||
openSheetOnTap(title: "Chat preferences", icon: "switch.2") {
|
||||
activeSheet = .chatPreferences
|
||||
}
|
||||
}
|
||||
} else {
|
||||
}
|
||||
|
||||
Section {
|
||||
if otherUsers.isEmpty {
|
||||
openSheetOnTap(title: "Your chat profiles", icon: "person.crop.rectangle.stack") {
|
||||
activeSheet = .chatProfiles
|
||||
}
|
||||
} else {
|
||||
let v = userPickerRow(otherUsers, size: 44)
|
||||
.padding(.leading, -8)
|
||||
if #available(iOS 16.0, *) {
|
||||
v
|
||||
} else {
|
||||
v.padding(.vertical, 4)
|
||||
}
|
||||
}
|
||||
|
||||
openSheetOnTap(title: "Use from desktop", icon: "desktopcomputer") {
|
||||
activeSheet = .useFromDesktop
|
||||
}
|
||||
|
||||
HStack {
|
||||
openSheetOnTap(title: "Settings", icon: "gearshape") {
|
||||
activeSheet = .settings
|
||||
}
|
||||
Label {} icon: {
|
||||
Image(systemName: colorScheme == .light ? "sun.max" : "moon.fill")
|
||||
.resizable()
|
||||
.symbolRenderingMode(.monochrome)
|
||||
.foregroundColor(theme.colors.secondary)
|
||||
.frame(maxWidth: 20, maxHeight: 20)
|
||||
}
|
||||
.padding(.leading, 16).padding(.vertical, 8).padding(.trailing, 16)
|
||||
.contentShape(Rectangle())
|
||||
.onTapGesture {
|
||||
if (colorScheme == .light) {
|
||||
ThemeManager.applyTheme(systemDarkThemeDefault.get())
|
||||
} else {
|
||||
ThemeManager.applyTheme(DefaultTheme.LIGHT.themeName)
|
||||
}
|
||||
}
|
||||
.onLongPressGesture {
|
||||
ThemeManager.applyTheme(DefaultTheme.SYSTEM_THEME_NAME)
|
||||
}
|
||||
.padding(.leading, -16).padding(.vertical, -8).padding(.trailing, -16)
|
||||
}
|
||||
.padding(.horizontal, -3)
|
||||
}
|
||||
}
|
||||
.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .topLeading)
|
||||
.onAppear {
|
||||
// This check prevents the call of listUsers after the app is suspended, and the database is closed.
|
||||
if case .active = scenePhase {
|
||||
Task {
|
||||
do {
|
||||
try await changeActiveUserAsync_(user.userId, viewPwd: nil)
|
||||
await MainActor.run { userPickerVisible = false }
|
||||
let users = try await listUsersAsync()
|
||||
await MainActor.run { m.users = users }
|
||||
} catch {
|
||||
await MainActor.run {
|
||||
AlertManager.shared.showAlertMsg(
|
||||
title: "Error switching profile!",
|
||||
message: "Error: \(responseError(error))"
|
||||
)
|
||||
}
|
||||
logger.error("Error loading users \(responseError(error))")
|
||||
}
|
||||
}
|
||||
}
|
||||
}, label: {
|
||||
HStack(spacing: 0) {
|
||||
ProfileImage(imageStr: user.image, size: 44, color: Color(uiColor: .tertiarySystemFill))
|
||||
.padding(.trailing, 12)
|
||||
Text(user.chatViewName)
|
||||
.fontWeight(user.activeUser ? .medium : .regular)
|
||||
.foregroundColor(theme.colors.onBackground)
|
||||
.overlay(DetermineWidth())
|
||||
Spacer()
|
||||
if user.activeUser {
|
||||
Image(systemName: "checkmark")
|
||||
} else if u.unreadCount > 0 {
|
||||
unreadCounter(u.unreadCount, color: user.showNtfs ? theme.colors.primary : theme.colors.secondary)
|
||||
} else if !user.showNtfs {
|
||||
Image(systemName: "speaker.slash")
|
||||
}
|
||||
.modifier(ThemedBackground(grouped: true))
|
||||
.disabled(switchingProfile)
|
||||
}
|
||||
|
||||
private func userPickerRow(_ users: [UserInfo], size: CGFloat) -> some View {
|
||||
HStack(spacing: 6) {
|
||||
let s = ScrollView(.horizontal) {
|
||||
HStack(spacing: 27) {
|
||||
// Image(systemName: "person.crop.rectangle.stack.fill")
|
||||
// .resizable()
|
||||
// .scaledToFit()
|
||||
// .frame(height: size)
|
||||
// .foregroundColor(Color(uiColor: .tertiarySystemGroupedBackground).asAnotherColorFromSecondaryVariant(theme))
|
||||
// .padding([.top, .trailing], 3)
|
||||
// Image(systemName: "theatermasks.fill")
|
||||
// .resizable()
|
||||
// .scaledToFit()
|
||||
// .frame(width: size, height: size)
|
||||
// .foregroundColor(.indigo)
|
||||
// .padding([.top, .trailing], 3)
|
||||
ForEach(users) { u in
|
||||
if !u.user.hidden && u.user.userId != m.currentUser?.userId {
|
||||
userView(u, size: size)
|
||||
}
|
||||
}
|
||||
}
|
||||
.padding(.leading, 2)
|
||||
.padding(.trailing, 22)
|
||||
}
|
||||
ZStack {
|
||||
if #available(iOS 16.0, *) {
|
||||
s.scrollIndicators(.hidden)
|
||||
} else {
|
||||
s
|
||||
}
|
||||
HStack(spacing: 0) {
|
||||
LinearGradient(
|
||||
colors: [.black, .clear],
|
||||
startPoint: .leading,
|
||||
endPoint: .trailing
|
||||
)
|
||||
.frame(width: 2)
|
||||
Color.clear
|
||||
LinearGradient(
|
||||
colors: [.clear, .black],
|
||||
startPoint: .leading,
|
||||
endPoint: .trailing
|
||||
)
|
||||
.frame(width: size)
|
||||
}
|
||||
.frame(height: size + 3)
|
||||
.blendMode(.destinationOut)
|
||||
.allowsHitTesting(false)
|
||||
}
|
||||
.compositingGroup()
|
||||
.padding(.top, -3) // to fit unread badge
|
||||
Spacer()
|
||||
Image(systemName: "chevron.right")
|
||||
.foregroundColor(theme.colors.secondary)
|
||||
.padding(.trailing, 4)
|
||||
.onTapGesture {
|
||||
activeSheet = .chatProfiles
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func userView(_ u: UserInfo, size: CGFloat) -> some View {
|
||||
ZStack(alignment: .topTrailing) {
|
||||
ProfileImage(imageStr: u.user.image, size: size, color: Color(uiColor: .tertiarySystemGroupedBackground))
|
||||
.padding([.top, .trailing], 3)
|
||||
if (u.unreadCount > 0) {
|
||||
unreadBadge(u)
|
||||
}
|
||||
}
|
||||
.frame(width: size)
|
||||
.onTapGesture {
|
||||
switchingProfile = true
|
||||
Task {
|
||||
do {
|
||||
try await changeActiveUserAsync_(u.user.userId, viewPwd: nil)
|
||||
await MainActor.run {
|
||||
switchingProfile = false
|
||||
dismiss()
|
||||
}
|
||||
} catch {
|
||||
await MainActor.run {
|
||||
switchingProfile = false
|
||||
AlertManager.shared.showAlertMsg(
|
||||
title: "Error switching profile!",
|
||||
message: "Error: \(responseError(error))"
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
.padding(.trailing)
|
||||
.padding([.leading, .vertical], 12)
|
||||
})
|
||||
.buttonStyle(PressedButtonStyle(defaultColor: theme.colors.surface, pressedColor: Color(uiColor: .secondarySystemFill)))
|
||||
}
|
||||
}
|
||||
|
||||
private func menuButton(_ title: LocalizedStringKey, icon: String, action: @escaping () -> Void) -> some View {
|
||||
Button(action: action) {
|
||||
HStack(spacing: 0) {
|
||||
Text(title)
|
||||
.overlay(DetermineWidth())
|
||||
Spacer()
|
||||
Image(systemName: icon)
|
||||
|
||||
private func openSheetOnTap(title: LocalizedStringKey, icon: String, action: @escaping () -> Void) -> some View {
|
||||
openSheetOnTap(label: {
|
||||
ZStack(alignment: .leading) {
|
||||
Image(systemName: icon).frame(maxWidth: 24, maxHeight: 24, alignment: .center)
|
||||
.symbolRenderingMode(.monochrome)
|
||||
.foregroundColor(theme.colors.secondary)
|
||||
Text(title)
|
||||
.foregroundColor(.primary)
|
||||
.padding(.leading, 36)
|
||||
}
|
||||
.padding(.horizontal)
|
||||
.padding(.vertical, 22)
|
||||
.frame(height: menuButtonHeight)
|
||||
}
|
||||
.buttonStyle(PressedButtonStyle(defaultColor: theme.colors.surface, pressedColor: Color(uiColor: .secondarySystemFill)))
|
||||
}, action: action)
|
||||
}
|
||||
|
||||
private func openSheetOnTap<V: View>(label: () -> V, action: @escaping () -> Void) -> some View {
|
||||
Button(action: action, label: label)
|
||||
.frame(maxWidth: .infinity, alignment: .leading)
|
||||
.contentShape(Rectangle())
|
||||
}
|
||||
|
||||
private func unreadBadge(_ u: UserInfo) -> some View {
|
||||
let size = dynamicSize(userFont).chatInfoSize
|
||||
return unreadCountText(u.unreadCount)
|
||||
.font(userFont <= .xxxLarge ? .caption : .caption2)
|
||||
.foregroundColor(.white)
|
||||
.padding(.horizontal, dynamicSize(userFont).unreadPadding)
|
||||
.frame(minWidth: size, minHeight: size)
|
||||
.background(u.user.showNtfs ? theme.colors.primary : theme.colors.secondary)
|
||||
.cornerRadius(dynamicSize(userFont).unreadCorner)
|
||||
}
|
||||
}
|
||||
|
||||
private func unreadCounter(_ unread: Int, color: Color) -> some View {
|
||||
unreadCountText(unread)
|
||||
.font(.caption)
|
||||
.foregroundColor(.white)
|
||||
.padding(.horizontal, 4)
|
||||
.frame(minWidth: 18, minHeight: 18)
|
||||
.background(color)
|
||||
.cornerRadius(10)
|
||||
}
|
||||
|
||||
struct UserPicker_Previews: PreviewProvider {
|
||||
static var previews: some View {
|
||||
@State var activeSheet: UserPickerSheet?
|
||||
|
||||
let m = ChatModel()
|
||||
m.users = [UserInfo.sampleData, UserInfo.sampleData]
|
||||
return UserPicker(
|
||||
showSettings: Binding.constant(false),
|
||||
showConnectDesktop: Binding.constant(false),
|
||||
userPickerVisible: Binding.constant(true)
|
||||
activeSheet: $activeSheet
|
||||
)
|
||||
.environmentObject(m)
|
||||
}
|
||||
|
||||
@@ -56,7 +56,7 @@ struct ContactListNavLink: View {
|
||||
func recentContactNavLink(_ contact: Contact) -> some View {
|
||||
Button {
|
||||
dismissAllSheets(animated: true) {
|
||||
ChatModel.shared.chatId = contact.id
|
||||
ItemsModel.shared.loadOpenChat(contact.id)
|
||||
}
|
||||
} label: {
|
||||
contactPreview(contact, titleColor: theme.colors.onBackground)
|
||||
@@ -82,11 +82,8 @@ struct ContactListNavLink: View {
|
||||
Button {
|
||||
Task {
|
||||
await MainActor.run {
|
||||
var updatedContact = contact
|
||||
updatedContact.chatDeleted = false
|
||||
ChatModel.shared.updateContact(updatedContact)
|
||||
dismissAllSheets(animated: true) {
|
||||
ChatModel.shared.chatId = contact.id
|
||||
ItemsModel.shared.loadOpenChat(contact.id)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -191,9 +188,7 @@ struct ContactListNavLink: View {
|
||||
Task {
|
||||
let ok = await connectContactViaAddress(contact.contactId, incognito, showAlert: { alert = SomeAlert(alert: $0, id: "ContactListNavLink connectContactViaAddress") })
|
||||
if ok {
|
||||
await MainActor.run {
|
||||
ChatModel.shared.chatId = contact.id
|
||||
}
|
||||
ItemsModel.shared.loadOpenChat(contact.id)
|
||||
DispatchQueue.main.async {
|
||||
dismissAllSheets(animated: true) {
|
||||
AlertManager.shared.showAlert(connReqSentAlert(.contact))
|
||||
|
||||
@@ -491,7 +491,7 @@ struct DatabaseView: View {
|
||||
appFilesCountAndSize = directoryFileCountAndSize(getAppFilesDirectory())
|
||||
do {
|
||||
let chats = try apiGetChats()
|
||||
m.updateChats(with: chats)
|
||||
m.updateChats(chats)
|
||||
} catch let error {
|
||||
logger.error("apiGetChats: cannot update chats \(responseError(error))")
|
||||
}
|
||||
|
||||
@@ -8,41 +8,21 @@
|
||||
|
||||
import SwiftUI
|
||||
|
||||
private struct SheetIsPresented<C>: ViewModifier where C: View {
|
||||
var isPresented: Binding<Bool>
|
||||
var onDismiss: (() -> Void)?
|
||||
var sheetContent: () -> C
|
||||
@Environment(\.scenePhase) var scenePhase
|
||||
|
||||
func body(content: Content) -> some View {
|
||||
content.sheet(isPresented: isPresented, onDismiss: onDismiss) {
|
||||
sheetContent().modifier(PrivacySensitive())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private struct SheetForItem<T, C>: ViewModifier where T: Identifiable, C: View {
|
||||
var item: Binding<T?>
|
||||
var onDismiss: (() -> Void)?
|
||||
var sheetContent: (T) -> C
|
||||
@Environment(\.scenePhase) var scenePhase
|
||||
|
||||
func body(content: Content) -> some View {
|
||||
content.sheet(item: item, onDismiss: onDismiss) { it in
|
||||
sheetContent(it).modifier(PrivacySensitive())
|
||||
}
|
||||
}
|
||||
class AppSheetState: ObservableObject {
|
||||
static let shared = AppSheetState()
|
||||
@Published var scenePhaseActive: Bool = false
|
||||
}
|
||||
|
||||
private struct PrivacySensitive: ViewModifier {
|
||||
@AppStorage(DEFAULT_PRIVACY_PROTECT_SCREEN) private var protectScreen = false
|
||||
@Environment(\.scenePhase) var scenePhase
|
||||
// Screen protection doesn't work for appSheet on iOS 16 if @Environment(\.scenePhase) is used instead of global state
|
||||
@ObservedObject var appSheetState: AppSheetState = AppSheetState.shared
|
||||
|
||||
func body(content: Content) -> some View {
|
||||
if case .active = scenePhase {
|
||||
if !protectScreen {
|
||||
content
|
||||
} else {
|
||||
content.privacySensitive(protectScreen).redacted(reason: .privacy)
|
||||
content.privacySensitive(!appSheetState.scenePhaseActive).redacted(reason: .privacy)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -53,7 +33,9 @@ extension View {
|
||||
onDismiss: (() -> Void)? = nil,
|
||||
content: @escaping () -> Content
|
||||
) -> some View where Content: View {
|
||||
modifier(SheetIsPresented(isPresented: isPresented, onDismiss: onDismiss, sheetContent: content))
|
||||
sheet(isPresented: isPresented, onDismiss: onDismiss) {
|
||||
content().modifier(PrivacySensitive())
|
||||
}
|
||||
}
|
||||
|
||||
func appSheet<T, Content>(
|
||||
@@ -61,6 +43,8 @@ extension View {
|
||||
onDismiss: (() -> Void)? = nil,
|
||||
content: @escaping (T) -> Content
|
||||
) -> some View where T: Identifiable, Content: View {
|
||||
modifier(SheetForItem(item: item, onDismiss: onDismiss, sheetContent: content))
|
||||
sheet(item: item, onDismiss: onDismiss) { it in
|
||||
content(it).modifier(PrivacySensitive())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,50 +14,60 @@ import SimpleXChat
|
||||
/// Supports [Dynamic Type](https://developer.apple.com/documentation/uikit/uifont/scaling_fonts_automatically)
|
||||
/// by retaining pill shape, even when ``ChatItem``'s height is less that twice its corner radius
|
||||
struct ChatItemClipped: ViewModifier {
|
||||
struct ClipShape: Shape {
|
||||
let maxCornerRadius: Double
|
||||
|
||||
func path(in rect: CGRect) -> Path {
|
||||
Path(
|
||||
roundedRect: rect,
|
||||
cornerRadius: min((rect.height / 2), maxCornerRadius),
|
||||
style: .circular
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@AppStorage(DEFAULT_CHAT_ITEM_ROUNDNESS) private var roundness = defaultChatItemRoundness
|
||||
@AppStorage(DEFAULT_CHAT_ITEM_TAIL) private var tailEnabled = true
|
||||
private let chatItem: (content: CIContent, chatDir: CIDirection)?
|
||||
private let tailVisible: Bool
|
||||
|
||||
init() {
|
||||
clipShape = ClipShape(
|
||||
maxCornerRadius: 18
|
||||
)
|
||||
self.chatItem = nil
|
||||
self.tailVisible = false
|
||||
}
|
||||
|
||||
init(_ ci: ChatItem, tailVisible: Bool) {
|
||||
self.chatItem = (ci.content, ci.chatDir)
|
||||
self.tailVisible = tailVisible
|
||||
}
|
||||
|
||||
init(_ chatItem: ChatItem) {
|
||||
clipShape = ClipShape(
|
||||
maxCornerRadius: {
|
||||
switch chatItem.content {
|
||||
case
|
||||
.sndMsgContent,
|
||||
private func shapeStyle() -> ChatItemShape.Style {
|
||||
if let ci = chatItem {
|
||||
switch ci.content {
|
||||
case
|
||||
.sndMsgContent,
|
||||
.rcvMsgContent,
|
||||
.rcvDecryptionError,
|
||||
.rcvGroupInvitation,
|
||||
.sndGroupInvitation,
|
||||
.sndDeleted,
|
||||
.sndDeleted,
|
||||
.rcvDeleted,
|
||||
.rcvIntegrityError,
|
||||
.sndModerated,
|
||||
.rcvModerated,
|
||||
.sndModerated,
|
||||
.rcvModerated,
|
||||
.rcvBlocked,
|
||||
.invalidJSON: 18
|
||||
default: 8
|
||||
.invalidJSON:
|
||||
let tail = if let mc = ci.content.msgContent, mc.isImageOrVideo && mc.text.isEmpty {
|
||||
false
|
||||
} else {
|
||||
tailVisible
|
||||
}
|
||||
}()
|
||||
)
|
||||
return tailEnabled
|
||||
? .bubble(
|
||||
padding: ci.chatDir.sent ? .trailing : .leading,
|
||||
tailVisible: tail
|
||||
)
|
||||
: .roundRect(radius: msgRectMaxRadius)
|
||||
case .rcvGroupInvitation, .sndGroupInvitation:
|
||||
return .roundRect(radius: msgRectMaxRadius)
|
||||
default: return .roundRect(radius: 8)
|
||||
}
|
||||
} else {
|
||||
return .roundRect(radius: msgRectMaxRadius)
|
||||
}
|
||||
}
|
||||
|
||||
private let clipShape: ClipShape
|
||||
|
||||
|
||||
func body(content: Content) -> some View {
|
||||
let clipShape = ChatItemShape(
|
||||
roundness: roundness,
|
||||
style: shapeStyle()
|
||||
)
|
||||
content
|
||||
.contentShape(.dragPreview, clipShape)
|
||||
.contentShape(.contextMenuPreview, clipShape)
|
||||
@@ -65,4 +75,106 @@ struct ChatItemClipped: ViewModifier {
|
||||
}
|
||||
}
|
||||
|
||||
struct ChatTailPadding: ViewModifier {
|
||||
func body(content: Content) -> some View {
|
||||
content.padding(.horizontal, -msgTailWidth)
|
||||
}
|
||||
}
|
||||
|
||||
private let msgRectMaxRadius: Double = 18
|
||||
private let msgBubbleMaxRadius: Double = msgRectMaxRadius * 1.2
|
||||
private let msgTailWidth: Double = 9
|
||||
private let msgTailMinHeight: Double = msgTailWidth * 1.254 // ~56deg
|
||||
private let msgTailMaxHeight: Double = msgTailWidth * 1.732 // 60deg
|
||||
|
||||
struct ChatItemShape: Shape {
|
||||
fileprivate enum Style {
|
||||
case bubble(padding: HorizontalEdge, tailVisible: Bool)
|
||||
case roundRect(radius: Double)
|
||||
}
|
||||
|
||||
fileprivate let roundness: Double
|
||||
fileprivate let style: Style
|
||||
|
||||
func path(in rect: CGRect) -> Path {
|
||||
switch style {
|
||||
case let .bubble(padding, tailVisible):
|
||||
let w = rect.width
|
||||
let h = rect.height
|
||||
let rxMax = min(msgBubbleMaxRadius, w / 2)
|
||||
let ryMax = min(msgBubbleMaxRadius, h / 2)
|
||||
let rx = roundness * rxMax
|
||||
let ry = roundness * ryMax
|
||||
let tailHeight = min(msgTailMinHeight + roundness * (msgTailMaxHeight - msgTailMinHeight), h / 2)
|
||||
var path = Path()
|
||||
// top side
|
||||
path.move(to: CGPoint(x: rx, y: 0))
|
||||
path.addLine(to: CGPoint(x: w - rx, y: 0))
|
||||
if roundness > 0 {
|
||||
// top-right corner
|
||||
path.addQuadCurve(to: CGPoint(x: w, y: ry), control: CGPoint(x: w, y: 0))
|
||||
}
|
||||
if rect.height > 2 * ry {
|
||||
// right side
|
||||
path.addLine(to: CGPoint(x: w, y: h - ry))
|
||||
}
|
||||
if roundness > 0 {
|
||||
// bottom-right corner
|
||||
path.addQuadCurve(to: CGPoint(x: w - rx, y: h), control: CGPoint(x: w, y: h))
|
||||
}
|
||||
// bottom side
|
||||
if tailVisible {
|
||||
path.addLine(to: CGPoint(x: -msgTailWidth, y: h))
|
||||
if roundness > 0 {
|
||||
// bottom-left tail
|
||||
// distance of control point from touch point, calculated via ratios
|
||||
let d = tailHeight - msgTailWidth * msgTailWidth / tailHeight
|
||||
// tail control point
|
||||
let tc = CGPoint(x: 0, y: h - tailHeight + d * sqrt(roundness))
|
||||
// bottom-left tail curve
|
||||
path.addQuadCurve(to: CGPoint(x: 0, y: h - tailHeight), control: tc)
|
||||
} else {
|
||||
path.addLine(to: CGPoint(x: 0, y: h - tailHeight))
|
||||
}
|
||||
if rect.height > ry + tailHeight {
|
||||
// left side
|
||||
path.addLine(to: CGPoint(x: 0, y: ry))
|
||||
}
|
||||
} else {
|
||||
path.addLine(to: CGPoint(x: rx, y: h))
|
||||
path.addQuadCurve(to: CGPoint(x: 0, y: h - ry), control: CGPoint(x: 0 , y: h))
|
||||
if rect.height > 2 * ry {
|
||||
// left side
|
||||
path.addLine(to: CGPoint(x: 0, y: ry))
|
||||
}
|
||||
}
|
||||
if roundness > 0 {
|
||||
// top-left corner
|
||||
path.addQuadCurve(to: CGPoint(x: rx, y: 0), control: CGPoint(x: 0, y: 0))
|
||||
}
|
||||
path.closeSubpath()
|
||||
return switch padding {
|
||||
case .leading: path
|
||||
case .trailing: path
|
||||
.scale(x: -1, y: 1, anchor: .center)
|
||||
.path(in: rect)
|
||||
}
|
||||
case let .roundRect(radius):
|
||||
return Path(roundedRect: rect, cornerRadius: radius * roundness)
|
||||
}
|
||||
}
|
||||
|
||||
var offset: Double? {
|
||||
switch style {
|
||||
case let .bubble(padding, isTailVisible):
|
||||
if isTailVisible {
|
||||
switch padding {
|
||||
case .leading: -msgTailWidth
|
||||
case .trailing: msgTailWidth
|
||||
}
|
||||
} else { 0 }
|
||||
case .roundRect: 0
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -11,13 +11,22 @@ import SwiftUI
|
||||
import SimpleXChat
|
||||
|
||||
struct ChatViewBackground: ViewModifier {
|
||||
@EnvironmentObject var theme: AppTheme
|
||||
@Environment(\.colorScheme) var colorScheme
|
||||
var image: Image
|
||||
var imageType: WallpaperType
|
||||
var background: Color
|
||||
var tint: Color
|
||||
|
||||
func body(content: Content) -> some View {
|
||||
// Workaround a problem (SwiftUI bug?) when wallpaper is not updated when user changes global theme in iOS settings from dark to light and vice versa
|
||||
if colorScheme == .light {
|
||||
back(content)
|
||||
} else {
|
||||
back(content)
|
||||
}
|
||||
}
|
||||
|
||||
func back(_ content: Content) -> some View {
|
||||
content.background(
|
||||
Canvas { context, size in
|
||||
var image = context.resolve(image)
|
||||
@@ -81,7 +90,7 @@ struct ChatViewBackground: ViewModifier {
|
||||
case WallpaperType.empty: ()
|
||||
}
|
||||
}
|
||||
)
|
||||
).ignoresSafeArea(.all)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -91,7 +100,7 @@ extension PresetWallpaper {
|
||||
scale
|
||||
} else if let type = ChatModel.shared.currentUser?.uiThemes?.preferredMode(base.mode == DefaultThemeMode.dark)?.wallpaper?.toAppWallpaper().type, type.sameType(WallpaperType.preset(filename, nil)) {
|
||||
type.scale
|
||||
} else if let scale = themeOverridesDefault.get().first(where: { $0.wallpaper != nil && $0.wallpaper!.preset == filename })?.wallpaper?.scale {
|
||||
} else if let scale = themeOverridesDefault.get().first(where: { $0.wallpaper != nil && $0.wallpaper!.preset == filename && $0.base == base })?.wallpaper?.scale {
|
||||
scale
|
||||
} else {
|
||||
Float(1.0)
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
//
|
||||
// KeyboardPadding.swift
|
||||
// SimpleX (iOS)
|
||||
//
|
||||
// Created by Evgeny on 10/07/2023.
|
||||
// Copyright © 2023 SimpleX Chat. All rights reserved.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
|
||||
extension View {
|
||||
@ViewBuilder func keyboardPadding() -> some View {
|
||||
if #available(iOS 17.0, *) {
|
||||
GeometryReader { g in
|
||||
self.padding(.bottom, max(0, ChatModel.shared.keyboardHeight - g.safeAreaInsets.bottom))
|
||||
}
|
||||
} else {
|
||||
self
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,16 +7,17 @@
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
import SimpleXChat
|
||||
|
||||
struct NavLinkPlain<V: Hashable, Label: View>: View {
|
||||
@State var tag: V
|
||||
@Binding var selection: V?
|
||||
struct NavLinkPlain<Label: View>: View {
|
||||
let chatId: ChatId
|
||||
@Binding var selection: ChatId?
|
||||
@ViewBuilder var label: () -> Label
|
||||
var disabled = false
|
||||
|
||||
var body: some View {
|
||||
ZStack {
|
||||
Button("") { DispatchQueue.main.async { selection = tag } }
|
||||
Button("") { ItemsModel.shared.loadOpenChat(chatId) }
|
||||
.disabled(disabled)
|
||||
label()
|
||||
}
|
||||
|
||||
@@ -17,7 +17,9 @@ struct NavStackCompat <C: View, D: View>: View {
|
||||
if #available(iOS 16, *) {
|
||||
NavigationStack(path: Binding(
|
||||
get: { isActive.wrappedValue ? [true] : [] },
|
||||
set: { _ in }
|
||||
set: { path in
|
||||
if path.isEmpty { isActive.wrappedValue = false }
|
||||
}
|
||||
)) {
|
||||
ZStack {
|
||||
NavigationLink(value: true) { EmptyView() }
|
||||
|
||||
@@ -20,7 +20,7 @@ struct ProfileImage: View {
|
||||
@AppStorage(DEFAULT_PROFILE_IMAGE_CORNER_RADIUS) private var radius = defaultProfileImageCorner
|
||||
|
||||
var body: some View {
|
||||
if let uiImage = UIImage(base64Encoded: imageStr) {
|
||||
if let uiImage = imageFromBase64(imageStr) {
|
||||
clipProfileImage(Image(uiImage: uiImage), size: size, radius: radius, blurred: blurred)
|
||||
} else {
|
||||
let c = color.asAnotherColorFromSecondaryVariant(theme)
|
||||
|
||||
@@ -20,3 +20,41 @@ func showShareSheet(items: [Any], completed: (() -> Void)? = nil) {
|
||||
presentedViewController.present(activityViewController, animated: true)
|
||||
}
|
||||
}
|
||||
|
||||
extension View {
|
||||
func shareSheet(item: Binding<ShareItem?>) -> some View {
|
||||
sheet(item: item) { item in
|
||||
Group {
|
||||
if #available(iOS 16.0, *) {
|
||||
ActivityView(item: item)
|
||||
.presentationDetents([.medium, .large])
|
||||
} else {
|
||||
ActivityView(item: item)
|
||||
}
|
||||
}.ignoresSafeArea()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct ShareItem: Identifiable {
|
||||
let content: any Hashable
|
||||
var id: Int { content.hashValue }
|
||||
}
|
||||
|
||||
private struct ActivityView: UIViewControllerRepresentable {
|
||||
let item: ShareItem
|
||||
|
||||
func makeUIViewController(
|
||||
context: UIViewControllerRepresentableContext<ActivityView>
|
||||
) -> UIActivityViewController {
|
||||
UIActivityViewController(
|
||||
activityItems: [item.content],
|
||||
applicationActivities: nil
|
||||
)
|
||||
}
|
||||
|
||||
func updateUIViewController(
|
||||
_ uiViewController: UIActivityViewController,
|
||||
context: UIViewControllerRepresentableContext<ActivityView>
|
||||
) { }
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@ struct SwipeLabel: View {
|
||||
super.init(frame: CGRect(x: 0, y: 0, width: 64, height: 32 + fontSize))
|
||||
imageView.image = UIImage(systemName: systemName)
|
||||
imageView.contentMode = .scaleAspectFit
|
||||
label.text = NSLocalizedString(text, comment: "swipe action")
|
||||
label.text = text
|
||||
label.textAlignment = .center
|
||||
label.font = UIFont.systemFont(ofSize: fontSize, weight: .medium)
|
||||
addSubview(imageView)
|
||||
|
||||
@@ -65,7 +65,7 @@ struct LocalAuthView: View {
|
||||
// Clear sensitive data on screen just in case app fails to hide its views while new database is created
|
||||
m.chatId = nil
|
||||
ItemsModel.shared.reversedChatItems = []
|
||||
m.chats = []
|
||||
m.updateChats([])
|
||||
m.users = []
|
||||
_ = kcAppPassword.set(password)
|
||||
_ = kcSelfDestructPassword.remove()
|
||||
|
||||
@@ -56,8 +56,6 @@ private enum MigrateFromDeviceViewAlert: Identifiable {
|
||||
struct MigrateFromDevice: View {
|
||||
@EnvironmentObject var m: ChatModel
|
||||
@EnvironmentObject var theme: AppTheme
|
||||
@Environment(\.dismiss) var dismiss: DismissAction
|
||||
@Binding var showSettings: Bool
|
||||
@Binding var showProgressOnSettings: Bool
|
||||
@State private var migrationState: MigrationFromState = .chatStopInProgress
|
||||
@State private var useKeychain = storeDBPassphraseGroupDefault.get()
|
||||
@@ -106,9 +104,6 @@ struct MigrateFromDevice: View {
|
||||
finishedView(chatDeletion)
|
||||
}
|
||||
}
|
||||
.modifier(BackButton(label: "Back", disabled: $backDisabled) {
|
||||
dismiss()
|
||||
})
|
||||
.onChange(of: migrationState) { state in
|
||||
backDisabled = switch migrationState {
|
||||
case .chatStopInProgress, .archiving, .linkShown, .finished: true
|
||||
@@ -590,7 +585,7 @@ struct MigrateFromDevice: View {
|
||||
} catch let error {
|
||||
fatalError("Error starting chat \(responseError(error))")
|
||||
}
|
||||
showSettings = false
|
||||
dismissAllSheets(animated: true)
|
||||
}
|
||||
} catch let error {
|
||||
alert = .error(title: "Error deleting database", error: responseError(error))
|
||||
@@ -613,9 +608,7 @@ struct MigrateFromDevice: View {
|
||||
}
|
||||
// Hide settings anyway if chatDbStatus is not ok, probably passphrase needs to be entered
|
||||
if dismiss || m.chatDbStatus != .ok {
|
||||
await MainActor.run {
|
||||
showSettings = false
|
||||
}
|
||||
dismissAllSheets(animated: true)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -767,6 +760,6 @@ private class MigrationChatReceiver {
|
||||
|
||||
struct MigrateFromDevice_Previews: PreviewProvider {
|
||||
static var previews: some View {
|
||||
MigrateFromDevice(showSettings: Binding.constant(true), showProgressOnSettings: Binding.constant(false))
|
||||
MigrateFromDevice(showProgressOnSettings: Binding.constant(false))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,7 +28,9 @@ struct AddContactLearnMore: View {
|
||||
Text("If you can't meet in person, show QR code in a video call, or share the link.")
|
||||
Text("Read more in [User Guide](https://simplex.chat/docs/guide/readme.html#connect-to-friends).")
|
||||
}
|
||||
.frame(maxWidth: .infinity, alignment: .leading)
|
||||
.listRowBackground(Color.clear)
|
||||
.listRowInsets(EdgeInsets(top: 0, leading: 0, bottom: 0, trailing: 0))
|
||||
}
|
||||
.modifier(ThemedBackground(grouped: true))
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ struct AddGroupView: View {
|
||||
) { _ in
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
|
||||
dismissAllSheets(animated: true) {
|
||||
m.chatId = groupInfo.id
|
||||
ItemsModel.shared.loadOpenChat(groupInfo.id)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -52,14 +52,14 @@ struct AddGroupView: View {
|
||||
) {
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
|
||||
dismissAllSheets(animated: true) {
|
||||
m.chatId = groupInfo.id
|
||||
ItemsModel.shared.loadOpenChat(groupInfo.id)
|
||||
}
|
||||
}
|
||||
}
|
||||
.navigationBarTitle("Group link")
|
||||
}
|
||||
} else {
|
||||
createGroupView().keyboardPadding()
|
||||
createGroupView()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -14,9 +14,10 @@ enum ContactType: Int {
|
||||
}
|
||||
|
||||
struct NewChatMenuButton: View {
|
||||
@EnvironmentObject var chatModel: ChatModel
|
||||
@State private var showNewChatSheet = false
|
||||
@State private var alert: SomeAlert? = nil
|
||||
@State private var globalAlert: SomeAlert? = nil
|
||||
@State private var pendingConnection: PendingContactConnection? = nil
|
||||
|
||||
var body: some View {
|
||||
Button {
|
||||
@@ -28,22 +29,14 @@ struct NewChatMenuButton: View {
|
||||
.frame(width: 24, height: 24)
|
||||
}
|
||||
.appSheet(isPresented: $showNewChatSheet) {
|
||||
NewChatSheet(alert: $alert)
|
||||
NewChatSheet(pendingConnection: $pendingConnection)
|
||||
.environment(\EnvironmentValues.refresh as! WritableKeyPath<EnvironmentValues, RefreshAction?>, nil)
|
||||
.alert(item: $alert) { a in
|
||||
return a.alert
|
||||
.onDisappear {
|
||||
alert = cleanupPendingConnection(chatModel: chatModel, contactConnection: pendingConnection)
|
||||
pendingConnection = nil
|
||||
}
|
||||
}
|
||||
// This is a workaround to show "Keep unused invitation" alert in both following cases:
|
||||
// - on going back from NewChatView to NewChatSheet,
|
||||
// - on dismissing NewChatMenuButton sheet while on NewChatView (skipping NewChatSheet)
|
||||
.onChange(of: alert?.id) { a in
|
||||
if !showNewChatSheet && alert != nil {
|
||||
globalAlert = alert
|
||||
alert = nil
|
||||
}
|
||||
}
|
||||
.alert(item: $globalAlert) { a in
|
||||
.alert(item: $alert) { a in
|
||||
return a.alert
|
||||
}
|
||||
}
|
||||
@@ -60,19 +53,44 @@ struct NewChatSheet: View {
|
||||
@State private var searchText = ""
|
||||
@State private var searchShowingSimplexLink = false
|
||||
@State private var searchChatFilteredBySimplexLink: String? = nil
|
||||
@Binding var alert: SomeAlert?
|
||||
|
||||
@State private var alert: SomeAlert?
|
||||
@Binding var pendingConnection: PendingContactConnection?
|
||||
|
||||
// Sheet height management
|
||||
@State private var isAddContactActive = false
|
||||
@State private var isScanPasteLinkActive = false
|
||||
@State private var isLargeSheet = false
|
||||
@State private var allowSmallSheet = true
|
||||
|
||||
@AppStorage(GROUP_DEFAULT_ONE_HAND_UI, store: groupDefaults) private var oneHandUI = true
|
||||
|
||||
var body: some View {
|
||||
NavigationView {
|
||||
viewBody()
|
||||
.navigationTitle("New Chat")
|
||||
let showArchive = !filterContactTypes(chats: chatModel.chats, contactTypes: [.chatDeleted]).isEmpty
|
||||
let v = NavigationView {
|
||||
viewBody(showArchive)
|
||||
.navigationTitle("New message")
|
||||
.navigationBarTitleDisplayMode(.large)
|
||||
.navigationBarHidden(searchMode)
|
||||
.modifier(ThemedBackground(grouped: true))
|
||||
.alert(item: $alert) { a in
|
||||
return a.alert
|
||||
}
|
||||
}
|
||||
if #available(iOS 16.0, *), oneHandUI {
|
||||
let sheetHeight: CGFloat = showArchive ? 575 : 500
|
||||
v.presentationDetents(
|
||||
allowSmallSheet ? [.height(sheetHeight), .large] : [.large],
|
||||
selection: Binding(
|
||||
get: { isLargeSheet || !allowSmallSheet ? .large : .height(sheetHeight) },
|
||||
set: { isLargeSheet = $0 == .large }
|
||||
)
|
||||
)
|
||||
} else {
|
||||
v
|
||||
}
|
||||
}
|
||||
|
||||
@ViewBuilder private func viewBody() -> some View {
|
||||
|
||||
@ViewBuilder private func viewBody(_ showArchive: Bool) -> some View {
|
||||
List {
|
||||
HStack {
|
||||
ContactsListSearchBar(
|
||||
@@ -90,21 +108,25 @@ struct NewChatSheet: View {
|
||||
|
||||
if (searchText.isEmpty) {
|
||||
Section {
|
||||
NavigationLink {
|
||||
NewChatView(selection: .invite, parentAlert: $alert)
|
||||
NavigationLink(isActive: $isAddContactActive) {
|
||||
NewChatView(selection: .invite, parentAlert: $alert, contactConnection: $pendingConnection)
|
||||
.navigationTitle("New chat")
|
||||
.modifier(ThemedBackground(grouped: true))
|
||||
.navigationBarTitleDisplayMode(.large)
|
||||
} label: {
|
||||
Label("Add contact", systemImage: "link.badge.plus")
|
||||
navigateOnTap(Label("Add contact", systemImage: "link.badge.plus")) {
|
||||
isAddContactActive = true
|
||||
}
|
||||
}
|
||||
NavigationLink {
|
||||
NewChatView(selection: .connect, showQRCodeScanner: true, parentAlert: $alert)
|
||||
NavigationLink(isActive: $isScanPasteLinkActive) {
|
||||
NewChatView(selection: .connect, showQRCodeScanner: true, parentAlert: $alert, contactConnection: $pendingConnection)
|
||||
.navigationTitle("New chat")
|
||||
.modifier(ThemedBackground(grouped: true))
|
||||
.navigationBarTitleDisplayMode(.large)
|
||||
} label: {
|
||||
Label("Scan / Paste link", systemImage: "qrcode")
|
||||
navigateOnTap(Label("Scan / Paste link", systemImage: "qrcode")) {
|
||||
isScanPasteLinkActive = true
|
||||
}
|
||||
}
|
||||
NavigationLink {
|
||||
AddGroupView()
|
||||
@@ -112,11 +134,11 @@ struct NewChatSheet: View {
|
||||
.modifier(ThemedBackground(grouped: true))
|
||||
.navigationBarTitleDisplayMode(.large)
|
||||
} label: {
|
||||
Label("Create group", systemImage: "person.2")
|
||||
Label("Create group", systemImage: "person.2.circle.fill")
|
||||
}
|
||||
}
|
||||
|
||||
if (!filterContactTypes(chats: chatModel.chats, contactTypes: [.chatDeleted]).isEmpty) {
|
||||
if (showArchive) {
|
||||
Section {
|
||||
NavigationLink {
|
||||
DeletedChats()
|
||||
@@ -140,9 +162,28 @@ struct NewChatSheet: View {
|
||||
}
|
||||
}
|
||||
|
||||
/// Extends label's tap area to match `.insetGrouped` list row insets
|
||||
private func navigateOnTap<L: View>(_ label: L, setActive: @escaping () -> Void) -> some View {
|
||||
label
|
||||
.frame(maxWidth: .infinity, alignment: .leading)
|
||||
.padding(.leading, 16).padding(.vertical, 8).padding(.trailing, 32)
|
||||
.contentShape(Rectangle())
|
||||
.onTapGesture {
|
||||
isLargeSheet = true
|
||||
DispatchQueue.main.async {
|
||||
allowSmallSheet = false
|
||||
setActive()
|
||||
}
|
||||
}
|
||||
.padding(.leading, -16).padding(.vertical, -8).padding(.trailing, -32)
|
||||
}
|
||||
|
||||
func newChatActionButton<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)
|
||||
Image(systemName: icon)
|
||||
.resizable()
|
||||
.scaledToFit()
|
||||
.frame(maxWidth: 24, maxHeight: 24, alignment: .center)
|
||||
.symbolRenderingMode(.monochrome)
|
||||
.foregroundColor(color)
|
||||
content().foregroundColor(theme.colors.onBackground).padding(.leading, indent)
|
||||
@@ -340,7 +381,7 @@ struct ContactsListSearchBar: View {
|
||||
}
|
||||
.padding(EdgeInsets(top: 7, leading: 7, bottom: 7, trailing: 7))
|
||||
.foregroundColor(theme.colors.secondary)
|
||||
.background(theme.colors.isLight ? theme.colors.background : theme.colors.secondaryVariant)
|
||||
.background(Color(uiColor: .secondarySystemGroupedBackground))
|
||||
.cornerRadius(10.0)
|
||||
|
||||
if searchFocussed {
|
||||
@@ -354,6 +395,7 @@ struct ContactsListSearchBar: View {
|
||||
toggleFilterButton()
|
||||
}
|
||||
}
|
||||
.padding(.top, 24)
|
||||
.onChange(of: searchFocussed) { sf in
|
||||
withAnimation { searchMode = sf }
|
||||
}
|
||||
@@ -447,8 +489,8 @@ struct DeletedChats: View {
|
||||
showDeletedChatIcon: false
|
||||
)
|
||||
}
|
||||
.navigationTitle("Deleted chats")
|
||||
.navigationBarTitleDisplayMode(.inline)
|
||||
.navigationTitle("Archived contacts")
|
||||
.navigationBarTitleDisplayMode(.large)
|
||||
.navigationBarHidden(searchMode)
|
||||
.modifier(ThemedBackground(grouped: true))
|
||||
|
||||
|
||||
@@ -45,18 +45,47 @@ enum NewChatOption: Identifiable {
|
||||
var id: Self { self }
|
||||
}
|
||||
|
||||
func cleanupPendingConnection(chatModel: ChatModel, contactConnection: PendingContactConnection?) -> SomeAlert? {
|
||||
var alert: SomeAlert? = nil
|
||||
|
||||
if !(chatModel.showingInvitation?.connChatUsed ?? true),
|
||||
let conn = contactConnection {
|
||||
alert = SomeAlert(
|
||||
alert: Alert(
|
||||
title: Text("Keep unused invitation?"),
|
||||
message: Text("You can view invitation link again in connection details."),
|
||||
primaryButton: .default(Text("Keep")) {},
|
||||
secondaryButton: .destructive(Text("Delete")) {
|
||||
Task {
|
||||
await deleteChat(Chat(
|
||||
chatInfo: .contactConnection(contactConnection: conn),
|
||||
chatItems: []
|
||||
))
|
||||
}
|
||||
}
|
||||
),
|
||||
id: "keepUnusedInvitation"
|
||||
)
|
||||
}
|
||||
|
||||
chatModel.showingInvitation = nil
|
||||
|
||||
return alert
|
||||
}
|
||||
|
||||
struct NewChatView: View {
|
||||
@EnvironmentObject var m: ChatModel
|
||||
@EnvironmentObject var theme: AppTheme
|
||||
@State var selection: NewChatOption
|
||||
@State var showQRCodeScanner = false
|
||||
@State private var invitationUsed: Bool = false
|
||||
@State private var contactConnection: PendingContactConnection? = nil
|
||||
@State private var connReqInvitation: String = ""
|
||||
@State private var creatingConnReq = false
|
||||
@State var choosingProfile = false
|
||||
@State private var pastedLink: String = ""
|
||||
@State private var alert: NewChatViewAlert?
|
||||
@Binding var parentAlert: SomeAlert?
|
||||
@Binding var contactConnection: PendingContactConnection?
|
||||
|
||||
var body: some View {
|
||||
VStack(alignment: .leading) {
|
||||
@@ -122,26 +151,10 @@ struct NewChatView: View {
|
||||
}
|
||||
}
|
||||
.onDisappear {
|
||||
if !(m.showingInvitation?.connChatUsed ?? true),
|
||||
let conn = contactConnection {
|
||||
parentAlert = SomeAlert(
|
||||
alert: Alert(
|
||||
title: Text("Keep unused invitation?"),
|
||||
message: Text("You can view invitation link again in connection details."),
|
||||
primaryButton: .default(Text("Keep")) {},
|
||||
secondaryButton: .destructive(Text("Delete")) {
|
||||
Task {
|
||||
await deleteChat(Chat(
|
||||
chatInfo: .contactConnection(contactConnection: conn),
|
||||
chatItems: []
|
||||
))
|
||||
}
|
||||
}
|
||||
),
|
||||
id: "keepUnusedInvitation"
|
||||
)
|
||||
if !choosingProfile {
|
||||
parentAlert = cleanupPendingConnection(chatModel: m, contactConnection: contactConnection)
|
||||
contactConnection = nil
|
||||
}
|
||||
m.showingInvitation = nil
|
||||
}
|
||||
.alert(item: $alert) { a in
|
||||
switch(a) {
|
||||
@@ -159,7 +172,8 @@ struct NewChatView: View {
|
||||
InviteView(
|
||||
invitationUsed: $invitationUsed,
|
||||
contactConnection: $contactConnection,
|
||||
connReqInvitation: connReqInvitation
|
||||
connReqInvitation: $connReqInvitation,
|
||||
choosingProfile: $choosingProfile
|
||||
)
|
||||
} else if creatingConnReq {
|
||||
creatingLinkProgressView()
|
||||
@@ -210,13 +224,24 @@ struct NewChatView: View {
|
||||
}
|
||||
}
|
||||
|
||||
private func incognitoProfileImage() -> some View {
|
||||
Image(systemName: "theatermasks.fill")
|
||||
.resizable()
|
||||
.scaledToFit()
|
||||
.frame(width: 30)
|
||||
.foregroundColor(.indigo)
|
||||
}
|
||||
|
||||
private struct InviteView: View {
|
||||
@EnvironmentObject var chatModel: ChatModel
|
||||
@EnvironmentObject var theme: AppTheme
|
||||
@Binding var invitationUsed: Bool
|
||||
@Binding var contactConnection: PendingContactConnection?
|
||||
var connReqInvitation: String
|
||||
@Binding var connReqInvitation: String
|
||||
@Binding var choosingProfile: Bool
|
||||
|
||||
@AppStorage(GROUP_DEFAULT_INCOGNITO, store: groupDefaults) private var incognitoDefault = false
|
||||
@State private var showSettings: Bool = false
|
||||
|
||||
var body: some View {
|
||||
List {
|
||||
@@ -226,28 +251,40 @@ private struct InviteView: View {
|
||||
.listRowInsets(EdgeInsets(top: 0, leading: 20, bottom: 0, trailing: 10))
|
||||
|
||||
qrCodeView()
|
||||
|
||||
Section {
|
||||
IncognitoToggle(incognitoEnabled: $incognitoDefault)
|
||||
} footer: {
|
||||
sharedProfileInfo(incognitoDefault)
|
||||
.foregroundColor(theme.colors.secondary)
|
||||
if let selectedProfile = chatModel.currentUser {
|
||||
Section {
|
||||
NavigationLink {
|
||||
ActiveProfilePicker(
|
||||
contactConnection: $contactConnection,
|
||||
connReqInvitation: $connReqInvitation,
|
||||
incognitoEnabled: $incognitoDefault,
|
||||
choosingProfile: $choosingProfile,
|
||||
selectedProfile: selectedProfile
|
||||
)
|
||||
} label: {
|
||||
HStack {
|
||||
if incognitoDefault {
|
||||
incognitoProfileImage()
|
||||
Text("Incognito")
|
||||
} else {
|
||||
ProfileImage(imageStr: chatModel.currentUser?.image, size: 30)
|
||||
Text(chatModel.currentUser?.chatViewName ?? "")
|
||||
}
|
||||
}
|
||||
}
|
||||
} header: {
|
||||
Text("Share profile").foregroundColor(theme.colors.secondary)
|
||||
} footer: {
|
||||
if incognitoDefault {
|
||||
Text("A new random profile will be shared.")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.onChange(of: incognitoDefault) { incognito in
|
||||
Task {
|
||||
do {
|
||||
if let contactConn = contactConnection,
|
||||
let conn = try await apiSetConnectionIncognito(connId: contactConn.pccConnId, incognito: incognito) {
|
||||
await MainActor.run {
|
||||
contactConnection = conn
|
||||
chatModel.updateContactConnection(conn)
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
logger.error("apiSetConnectionIncognito error: \(responseError(error))")
|
||||
}
|
||||
}
|
||||
setInvitationUsed()
|
||||
}
|
||||
.onChange(of: chatModel.currentUser) { u in
|
||||
setInvitationUsed()
|
||||
}
|
||||
}
|
||||
@@ -270,6 +307,7 @@ private struct InviteView: View {
|
||||
private func qrCodeView() -> some View {
|
||||
Section(header: Text("Or show this code").foregroundColor(theme.colors.secondary)) {
|
||||
SimpleXLinkQRCode(uri: connReqInvitation, onShare: setInvitationUsed)
|
||||
.id("simplex-qrcode-view-for-\(connReqInvitation)")
|
||||
.padding()
|
||||
.background(
|
||||
RoundedRectangle(cornerRadius: 12, style: .continuous)
|
||||
@@ -289,6 +327,257 @@ private struct InviteView: View {
|
||||
}
|
||||
}
|
||||
|
||||
private enum ProfileSwitchStatus {
|
||||
case switchingUser
|
||||
case switchingIncognito
|
||||
case idle
|
||||
}
|
||||
|
||||
private struct ActiveProfilePicker: View {
|
||||
@Environment(\.dismiss) var dismiss
|
||||
@EnvironmentObject var chatModel: ChatModel
|
||||
@EnvironmentObject var theme: AppTheme
|
||||
@Binding var contactConnection: PendingContactConnection?
|
||||
@Binding var connReqInvitation: String
|
||||
@Binding var incognitoEnabled: Bool
|
||||
@Binding var choosingProfile: Bool
|
||||
@State private var alert: SomeAlert?
|
||||
@State private var profileSwitchStatus: ProfileSwitchStatus = .idle
|
||||
@State private var switchingProfileByTimeout = false
|
||||
@State private var lastSwitchingProfileByTimeoutCall: Double?
|
||||
@State private var profiles: [User] = []
|
||||
@State private var searchTextOrPassword = ""
|
||||
@State private var showIncognitoSheet = false
|
||||
@State private var incognitoFirst: Bool = false
|
||||
@State var selectedProfile: User
|
||||
var trimmedSearchTextOrPassword: String { searchTextOrPassword.trimmingCharacters(in: .whitespaces)}
|
||||
|
||||
var body: some View {
|
||||
viewBody()
|
||||
.navigationTitle("Select chat profile")
|
||||
.searchable(text: $searchTextOrPassword, placement: .navigationBarDrawer(displayMode: .always))
|
||||
.autocorrectionDisabled(true)
|
||||
.navigationBarTitleDisplayMode(.large)
|
||||
.onAppear {
|
||||
profiles = chatModel.users
|
||||
.map { $0.user }
|
||||
.sorted { u, _ in u.activeUser }
|
||||
}
|
||||
.onChange(of: incognitoEnabled) { incognito in
|
||||
if profileSwitchStatus != .switchingIncognito {
|
||||
return
|
||||
}
|
||||
|
||||
Task {
|
||||
do {
|
||||
if let contactConn = contactConnection,
|
||||
let conn = try await apiSetConnectionIncognito(connId: contactConn.pccConnId, incognito: incognito) {
|
||||
await MainActor.run {
|
||||
contactConnection = conn
|
||||
chatModel.updateContactConnection(conn)
|
||||
profileSwitchStatus = .idle
|
||||
dismiss()
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
profileSwitchStatus = .idle
|
||||
incognitoEnabled = !incognito
|
||||
logger.error("apiSetConnectionIncognito error: \(responseError(error))")
|
||||
let err = getErrorAlert(error, "Error changing to incognito!")
|
||||
|
||||
alert = SomeAlert(
|
||||
alert: Alert(
|
||||
title: Text(err.title),
|
||||
message: Text(err.message ?? "Error: \(responseError(error))")
|
||||
),
|
||||
id: "setConnectionIncognitoError"
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
.onChange(of: profileSwitchStatus) { sp in
|
||||
if sp != .idle {
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
|
||||
switchingProfileByTimeout = profileSwitchStatus != .idle
|
||||
}
|
||||
} else {
|
||||
switchingProfileByTimeout = false
|
||||
}
|
||||
}
|
||||
.onChange(of: selectedProfile) { profile in
|
||||
if (profileSwitchStatus != .switchingUser) {
|
||||
return
|
||||
}
|
||||
Task {
|
||||
do {
|
||||
if let contactConn = contactConnection,
|
||||
let conn = try await apiChangeConnectionUser(connId: contactConn.pccConnId, userId: profile.userId) {
|
||||
|
||||
await MainActor.run {
|
||||
contactConnection = conn
|
||||
connReqInvitation = conn.connReqInv ?? ""
|
||||
incognitoEnabled = false
|
||||
chatModel.updateContactConnection(conn)
|
||||
}
|
||||
do {
|
||||
try await changeActiveUserAsync_(profile.userId, viewPwd: profile.hidden ? trimmedSearchTextOrPassword : nil )
|
||||
await MainActor.run {
|
||||
profileSwitchStatus = .idle
|
||||
dismiss()
|
||||
}
|
||||
} catch {
|
||||
await MainActor.run {
|
||||
profileSwitchStatus = .idle
|
||||
alert = SomeAlert(
|
||||
alert: Alert(
|
||||
title: Text("Error switching profile"),
|
||||
message: Text("Your connection was moved to \(profile.chatViewName) but an unexpected error occurred while redirecting you to the profile.")
|
||||
),
|
||||
id: "switchingProfileError"
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
await MainActor.run {
|
||||
profileSwitchStatus = .idle
|
||||
if let currentUser = chatModel.currentUser {
|
||||
selectedProfile = currentUser
|
||||
}
|
||||
let err = getErrorAlert(error, "Error changing connection profile")
|
||||
alert = SomeAlert(
|
||||
alert: Alert(
|
||||
title: Text(err.title),
|
||||
message: Text(err.message ?? "Error: \(responseError(error))")
|
||||
),
|
||||
id: "changeConnectionUserError"
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.alert(item: $alert) { a in
|
||||
a.alert
|
||||
}
|
||||
.onAppear {
|
||||
incognitoFirst = incognitoEnabled
|
||||
choosingProfile = true
|
||||
}
|
||||
.onDisappear {
|
||||
choosingProfile = false
|
||||
}
|
||||
.sheet(isPresented: $showIncognitoSheet) {
|
||||
IncognitoHelp()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ViewBuilder private func viewBody() -> some View {
|
||||
profilePicker()
|
||||
.allowsHitTesting(!switchingProfileByTimeout)
|
||||
.modifier(ThemedBackground(grouped: true))
|
||||
.overlay {
|
||||
if switchingProfileByTimeout {
|
||||
ProgressView()
|
||||
.scaleEffect(2)
|
||||
.frame(maxWidth: .infinity, maxHeight: .infinity)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func filteredProfiles() -> [User] {
|
||||
let s = trimmedSearchTextOrPassword
|
||||
let lower = s.localizedLowercase
|
||||
|
||||
return profiles.filter { u in
|
||||
if (u.activeUser || !u.hidden) && (s == "" || u.chatViewName.localizedLowercase.contains(lower)) {
|
||||
return true
|
||||
}
|
||||
return correctPassword(u, s)
|
||||
}
|
||||
}
|
||||
|
||||
@ViewBuilder private func profilerPickerUserOption(_ user: User) -> some View {
|
||||
Button {
|
||||
if selectedProfile == user && incognitoEnabled {
|
||||
incognitoEnabled = false
|
||||
profileSwitchStatus = .switchingIncognito
|
||||
} else if selectedProfile != user {
|
||||
selectedProfile = user
|
||||
profileSwitchStatus = .switchingUser
|
||||
}
|
||||
} label: {
|
||||
HStack {
|
||||
ProfileImage(imageStr: user.image, size: 30)
|
||||
.padding(.trailing, 2)
|
||||
Text(user.chatViewName)
|
||||
.foregroundColor(theme.colors.onBackground)
|
||||
.lineLimit(1)
|
||||
Spacer()
|
||||
if selectedProfile == user, !incognitoEnabled {
|
||||
Image(systemName: "checkmark")
|
||||
.resizable().scaledToFit().frame(width: 16)
|
||||
.foregroundColor(theme.colors.primary)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ViewBuilder private func profilePicker() -> some View {
|
||||
let incognitoOption = Button {
|
||||
if !incognitoEnabled {
|
||||
incognitoEnabled = true
|
||||
profileSwitchStatus = .switchingIncognito
|
||||
}
|
||||
} label : {
|
||||
HStack {
|
||||
incognitoProfileImage()
|
||||
Text("Incognito")
|
||||
.foregroundColor(theme.colors.onBackground)
|
||||
Image(systemName: "info.circle")
|
||||
.foregroundColor(theme.colors.primary)
|
||||
.font(.system(size: 14))
|
||||
.onTapGesture {
|
||||
showIncognitoSheet = true
|
||||
}
|
||||
Spacer()
|
||||
if incognitoEnabled {
|
||||
Image(systemName: "checkmark")
|
||||
.resizable().scaledToFit().frame(width: 16)
|
||||
.foregroundColor(theme.colors.primary)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
List {
|
||||
let filteredProfiles = filteredProfiles()
|
||||
let activeProfile = filteredProfiles.first { u in u.activeUser }
|
||||
|
||||
if let selectedProfile = activeProfile {
|
||||
let otherProfiles = filteredProfiles.filter { u in u.userId != activeProfile?.userId }
|
||||
|
||||
if incognitoFirst {
|
||||
incognitoOption
|
||||
profilerPickerUserOption(selectedProfile)
|
||||
} else {
|
||||
profilerPickerUserOption(selectedProfile)
|
||||
incognitoOption
|
||||
}
|
||||
|
||||
ForEach(otherProfiles) { p in
|
||||
profilerPickerUserOption(p)
|
||||
}
|
||||
} else {
|
||||
incognitoOption
|
||||
ForEach(filteredProfiles) { p in
|
||||
profilerPickerUserOption(p)
|
||||
}
|
||||
}
|
||||
}
|
||||
.opacity(switchingProfileByTimeout ? 0.4 : 1)
|
||||
}
|
||||
}
|
||||
|
||||
private struct ConnectView: View {
|
||||
@Environment(\.dismiss) var dismiss: DismissAction
|
||||
@EnvironmentObject var theme: AppTheme
|
||||
@@ -898,11 +1187,11 @@ func openKnownContact(_ contact: Contact, dismiss: Bool, showAlreadyExistsAlert:
|
||||
DispatchQueue.main.async {
|
||||
if dismiss {
|
||||
dismissAllSheets(animated: true) {
|
||||
m.chatId = c.id
|
||||
ItemsModel.shared.loadOpenChat(c.id)
|
||||
showAlreadyExistsAlert?()
|
||||
}
|
||||
} else {
|
||||
m.chatId = c.id
|
||||
ItemsModel.shared.loadOpenChat(c.id)
|
||||
showAlreadyExistsAlert?()
|
||||
}
|
||||
}
|
||||
@@ -917,11 +1206,11 @@ func openKnownGroup(_ groupInfo: GroupInfo, dismiss: Bool, showAlreadyExistsAler
|
||||
DispatchQueue.main.async {
|
||||
if dismiss {
|
||||
dismissAllSheets(animated: true) {
|
||||
m.chatId = g.id
|
||||
ItemsModel.shared.loadOpenChat(g.id)
|
||||
showAlreadyExistsAlert?()
|
||||
}
|
||||
} else {
|
||||
m.chatId = g.id
|
||||
ItemsModel.shared.loadOpenChat(g.id)
|
||||
showAlreadyExistsAlert?()
|
||||
}
|
||||
}
|
||||
@@ -975,10 +1264,12 @@ func connReqSentAlert(_ type: ConnReqType) -> Alert {
|
||||
struct NewChatView_Previews: PreviewProvider {
|
||||
static var previews: some View {
|
||||
@State var parentAlert: SomeAlert?
|
||||
@State var contactConnection: PendingContactConnection? = nil
|
||||
|
||||
NewChatView(
|
||||
selection: .invite,
|
||||
parentAlert: $parentAlert
|
||||
parentAlert: $parentAlert,
|
||||
contactConnection: $contactConnection
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -77,7 +77,6 @@ struct CreateProfile: View {
|
||||
focusDisplayName = true
|
||||
}
|
||||
}
|
||||
.keyboardPadding()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -128,7 +127,6 @@ struct CreateFirstProfile: View {
|
||||
}
|
||||
.padding()
|
||||
.frame(maxWidth: .infinity, alignment: .leading)
|
||||
.keyboardPadding()
|
||||
}
|
||||
|
||||
func onboardingButtons() -> some View {
|
||||
|
||||
@@ -15,9 +15,10 @@ private struct VersionDescription {
|
||||
}
|
||||
|
||||
private struct FeatureDescription {
|
||||
var icon: String
|
||||
var icon: String?
|
||||
var title: LocalizedStringKey
|
||||
var description: LocalizedStringKey
|
||||
var description: LocalizedStringKey?
|
||||
var subfeatures: [(icon: String, description: LocalizedStringKey)] = []
|
||||
}
|
||||
|
||||
private let versionDescriptions: [VersionDescription] = [
|
||||
@@ -432,34 +433,36 @@ private let versionDescriptions: [VersionDescription] = [
|
||||
version: "v6.0",
|
||||
post: URL(string: "https://simplex.chat/blog/20240814-simplex-chat-vision-funding-v6-private-routing-new-user-experience.html"),
|
||||
features: [
|
||||
FeatureDescription(
|
||||
icon: nil,
|
||||
title: "New chat experience 🎉",
|
||||
description: nil,
|
||||
subfeatures: [
|
||||
("link.badge.plus", "Connect to your friends faster."),
|
||||
("archivebox", "Archive contacts to chat later."),
|
||||
("trash", "Delete up to 20 messages at once."),
|
||||
("platter.filled.bottom.and.arrow.down.iphone", "Use the app with one hand."),
|
||||
("paintpalette", "Color chats with the new themes."),
|
||||
]
|
||||
),
|
||||
FeatureDescription(
|
||||
icon: nil,
|
||||
title: "New media options",
|
||||
description: nil,
|
||||
subfeatures: [
|
||||
("square.and.arrow.up", "Share from other apps."),
|
||||
("play.circle", "Play from the chat list."),
|
||||
("circle.filled.pattern.diagonalline.rectangle", "Blur for better privacy.")
|
||||
]
|
||||
),
|
||||
FeatureDescription(
|
||||
icon: "arrow.forward",
|
||||
title: "Private message routing 🚀",
|
||||
description: "It protects your IP address and connections."
|
||||
),
|
||||
FeatureDescription(
|
||||
icon: "person.text.rectangle",
|
||||
title: "Your contacts your way",
|
||||
description: "- Search contacts when starting chat.\n- Archive contacts to chat later."
|
||||
),
|
||||
FeatureDescription(
|
||||
icon: "platter.filled.bottom.iphone",
|
||||
title: "Reachable chat toolbar 👋",
|
||||
description: "Use the app with one hand."
|
||||
),
|
||||
FeatureDescription(
|
||||
icon: "link",
|
||||
title: "Connect to your friends faster",
|
||||
description: "Even when they are offline."
|
||||
),
|
||||
FeatureDescription(
|
||||
icon: "trash",
|
||||
title: "Moderate like a pro ✋",
|
||||
description: "Delete up to 20 messages at once."
|
||||
),
|
||||
FeatureDescription(
|
||||
icon: "network",
|
||||
title: "Control your network",
|
||||
title: "Better networking",
|
||||
description: "Connection and servers status."
|
||||
)
|
||||
]
|
||||
@@ -489,35 +492,37 @@ struct WhatsNewView: View {
|
||||
VStack {
|
||||
TabView(selection: $currentVersion) {
|
||||
ForEach(Array(versionDescriptions.enumerated()), id: \.0) { (i, v) in
|
||||
VStack(alignment: .leading, spacing: 16) {
|
||||
Text("New in \(v.version)")
|
||||
.font(.title)
|
||||
.foregroundColor(theme.colors.secondary)
|
||||
.frame(maxWidth: .infinity)
|
||||
.padding(.vertical)
|
||||
ForEach(v.features, id: \.icon) { f in
|
||||
featureDescription(f.icon, f.title, f.description)
|
||||
.padding(.bottom, 8)
|
||||
}
|
||||
if let post = v.post {
|
||||
Link(destination: post) {
|
||||
HStack {
|
||||
Text("Read more")
|
||||
Image(systemName: "arrow.up.right.circle")
|
||||
ScrollView {
|
||||
VStack(alignment: .leading, spacing: 16) {
|
||||
Text("New in \(v.version)")
|
||||
.font(.title)
|
||||
.foregroundColor(theme.colors.secondary)
|
||||
.frame(maxWidth: .infinity)
|
||||
.padding(.vertical)
|
||||
ForEach(v.features, id: \.title) { f in
|
||||
featureDescription(f)
|
||||
.padding(.bottom, 8)
|
||||
}
|
||||
if let post = v.post {
|
||||
Link(destination: post) {
|
||||
HStack {
|
||||
Text("Read more")
|
||||
Image(systemName: "arrow.up.right.circle")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if !viaSettings {
|
||||
Spacer()
|
||||
Button("Ok") {
|
||||
dismiss()
|
||||
if !viaSettings {
|
||||
Spacer()
|
||||
Button("Ok") {
|
||||
dismiss()
|
||||
}
|
||||
.font(.title3)
|
||||
.frame(maxWidth: .infinity, alignment: .center)
|
||||
Spacer()
|
||||
}
|
||||
.font(.title3)
|
||||
.frame(maxWidth: .infinity, alignment: .center)
|
||||
Spacer()
|
||||
}
|
||||
.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .topLeading)
|
||||
}
|
||||
.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .topLeading)
|
||||
.tag(i)
|
||||
}
|
||||
}
|
||||
@@ -531,18 +536,37 @@ struct WhatsNewView: View {
|
||||
}
|
||||
}
|
||||
|
||||
private func featureDescription(_ icon: String, _ title: LocalizedStringKey, _ description: LocalizedStringKey) -> some View {
|
||||
private func featureDescription(_ f: FeatureDescription) -> some View {
|
||||
VStack(alignment: .leading, spacing: 4) {
|
||||
HStack(alignment: .center, spacing: 4) {
|
||||
Image(systemName: icon)
|
||||
.symbolRenderingMode(.monochrome)
|
||||
.foregroundColor(theme.colors.secondary)
|
||||
.frame(minWidth: 30, alignment: .center)
|
||||
Text(title).font(.title3).bold()
|
||||
if let icon = f.icon {
|
||||
HStack(alignment: .center, spacing: 4) {
|
||||
Image(systemName: icon)
|
||||
.symbolRenderingMode(.monochrome)
|
||||
.foregroundColor(theme.colors.secondary)
|
||||
.frame(minWidth: 30, alignment: .center)
|
||||
Text(f.title).font(.title3).bold()
|
||||
}
|
||||
} else {
|
||||
Text(f.title).font(.title3).bold()
|
||||
}
|
||||
if let d = f.description {
|
||||
Text(d)
|
||||
.multilineTextAlignment(.leading)
|
||||
.lineLimit(10)
|
||||
}
|
||||
if f.subfeatures.count > 0 {
|
||||
ForEach(f.subfeatures, id: \.icon) { s in
|
||||
HStack(alignment: .center, spacing: 4) {
|
||||
Image(systemName: s.icon)
|
||||
.symbolRenderingMode(.monochrome)
|
||||
.foregroundColor(theme.colors.secondary)
|
||||
.frame(minWidth: 30, alignment: .center)
|
||||
Text(s.description)
|
||||
.multilineTextAlignment(.leading)
|
||||
.lineLimit(3)
|
||||
}
|
||||
}
|
||||
}
|
||||
Text(description)
|
||||
.multilineTextAlignment(.leading)
|
||||
.lineLimit(10)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -59,13 +59,6 @@ struct ConnectDesktopView: View {
|
||||
var body: some View {
|
||||
if viaSettings {
|
||||
viewBody
|
||||
.modifier(BackButton(label: "Back", disabled: Binding.constant(false)) {
|
||||
if m.activeRemoteCtrl {
|
||||
alert = .disconnectDesktop(action: .back)
|
||||
} else {
|
||||
dismiss()
|
||||
}
|
||||
})
|
||||
} else {
|
||||
NavigationView {
|
||||
viewBody
|
||||
|
||||
@@ -160,7 +160,7 @@ struct TerminalView_Previews: PreviewProvider {
|
||||
let chatModel = ChatModel()
|
||||
chatModel.terminalItems = [
|
||||
.resp(.now, ChatResponse.response(type: "contactSubscribed", json: "{}")),
|
||||
.resp(.now, ChatResponse.response(type: "newChatItem", json: "{}"))
|
||||
.resp(.now, ChatResponse.response(type: "newChatItems", json: "{}"))
|
||||
]
|
||||
return NavigationView {
|
||||
TerminalView()
|
||||
|
||||
@@ -33,7 +33,10 @@ struct AppearanceSettings: View {
|
||||
}()
|
||||
@State private var darkModeTheme: String = UserDefaults.standard.string(forKey: DEFAULT_SYSTEM_DARK_THEME) ?? DefaultTheme.DARK.themeName
|
||||
@AppStorage(DEFAULT_PROFILE_IMAGE_CORNER_RADIUS) private var profileImageCornerRadius = defaultProfileImageCorner
|
||||
@AppStorage(DEFAULT_CHAT_ITEM_ROUNDNESS) private var chatItemRoundness = defaultChatItemRoundness
|
||||
@AppStorage(DEFAULT_CHAT_ITEM_TAIL) private var chatItemTail = true
|
||||
@AppStorage(GROUP_DEFAULT_ONE_HAND_UI, store: groupDefaults) private var oneHandUI = true
|
||||
@AppStorage(DEFAULT_TOOLBAR_MATERIAL) private var toolbarMaterial = ToolbarMaterial.defaultMaterial
|
||||
|
||||
@State var themeUserDestination: (Int64, ThemeModeOverrides?)? = {
|
||||
if let currentUser = ChatModel.shared.currentUser, let uiThemes = currentUser.uiThemes, uiThemes.preferredMode(!CurrentColors.colors.isLight) != nil {
|
||||
@@ -65,6 +68,12 @@ struct AppearanceSettings: View {
|
||||
|
||||
Section("Chat list") {
|
||||
Toggle("Reachable chat toolbar", isOn: $oneHandUI)
|
||||
Picker("Toolbar opacity", selection: $toolbarMaterial) {
|
||||
ForEach(ToolbarMaterial.allCases, id: \.rawValue) { tm in
|
||||
Text(tm.text).tag(tm.rawValue)
|
||||
}
|
||||
}
|
||||
.frame(height: 36)
|
||||
}
|
||||
|
||||
Section {
|
||||
@@ -172,6 +181,14 @@ struct AppearanceSettings: View {
|
||||
}
|
||||
}
|
||||
|
||||
Section(header: Text("Message shape").foregroundColor(theme.colors.secondary)) {
|
||||
HStack {
|
||||
Text("Corner")
|
||||
Slider(value: $chatItemRoundness, in: 0...1, step: 0.05)
|
||||
}
|
||||
Toggle("Tail", isOn: $chatItemTail)
|
||||
}
|
||||
|
||||
Section(header: Text("Profile images").foregroundColor(theme.colors.secondary)) {
|
||||
HStack(spacing: 16) {
|
||||
if let img = m.currentUser?.image, img != "" {
|
||||
@@ -296,6 +313,43 @@ struct AppearanceSettings: View {
|
||||
}
|
||||
}
|
||||
|
||||
enum ToolbarMaterial: String, CaseIterable {
|
||||
case bar
|
||||
case ultraThin
|
||||
case thin
|
||||
case regular
|
||||
case thick
|
||||
case ultraThick
|
||||
|
||||
static func material(_ s: String) -> Material {
|
||||
ToolbarMaterial(rawValue: s)?.material ?? Material.bar
|
||||
}
|
||||
|
||||
static let defaultMaterial: String = ToolbarMaterial.regular.rawValue
|
||||
|
||||
var material: Material {
|
||||
switch self {
|
||||
case .bar: .bar
|
||||
case .ultraThin: .ultraThin
|
||||
case .thin: .thin
|
||||
case .regular: .regular
|
||||
case .thick: .thick
|
||||
case .ultraThick: .ultraThick
|
||||
}
|
||||
}
|
||||
|
||||
var text: String {
|
||||
switch self {
|
||||
case .bar: "System"
|
||||
case .ultraThin: "Ultra thin"
|
||||
case .thin: "Thin"
|
||||
case .regular: "Regular"
|
||||
case .thick: "Thick"
|
||||
case .ultraThick: "Ultra thick"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct ChatThemePreview: View {
|
||||
@EnvironmentObject var theme: AppTheme
|
||||
var base: DefaultTheme
|
||||
@@ -314,20 +368,21 @@ struct ChatThemePreview: View {
|
||||
let bob = ChatItem.getSample(2, CIDirection.directSnd, Date.now, NSLocalizedString("Good morning!", comment: "message preview"), quotedItem: CIQuote.getSample(alice.id, alice.meta.itemTs, alice.content.text, chatDir: alice.chatDir))
|
||||
HStack {
|
||||
ChatItemView(chat: Chat.sampleData, chatItem: alice, revealed: Binding.constant(false))
|
||||
.modifier(ChatItemClipped())
|
||||
.modifier(ChatItemClipped(alice, tailVisible: true))
|
||||
Spacer()
|
||||
}
|
||||
HStack {
|
||||
Spacer()
|
||||
ChatItemView(chat: Chat.sampleData, chatItem: bob, revealed: Binding.constant(false))
|
||||
.modifier(ChatItemClipped())
|
||||
.modifier(ChatItemClipped(bob, tailVisible: true))
|
||||
.frame(alignment: .trailing)
|
||||
}
|
||||
} else {
|
||||
Rectangle().fill(.clear)
|
||||
}
|
||||
}
|
||||
.padding(10)
|
||||
.padding(.vertical, 10)
|
||||
.padding(.horizontal, 16)
|
||||
.frame(maxWidth: .infinity)
|
||||
|
||||
if let wallpaperType, let wallpaperImage = wallpaperType.image, let backgroundColor, let tintColor {
|
||||
|
||||
@@ -13,6 +13,8 @@ struct DeveloperView: View {
|
||||
@EnvironmentObject var theme: AppTheme
|
||||
@AppStorage(DEFAULT_DEVELOPER_TOOLS) private var developerTools = false
|
||||
@AppStorage(GROUP_DEFAULT_CONFIRM_DB_UPGRADES, store: groupDefaults) private var confirmDatabaseUpgrades = false
|
||||
@State private var hintsUnchanged = hintDefaultsUnchanged()
|
||||
|
||||
@Environment(\.colorScheme) var colorScheme
|
||||
|
||||
var body: some View {
|
||||
@@ -33,6 +35,10 @@ struct DeveloperView: View {
|
||||
} label: {
|
||||
settingsRow("terminal", color: theme.colors.secondary) { Text("Chat console") }
|
||||
}
|
||||
settingsRow("lightbulb.max", color: theme.colors.secondary) {
|
||||
Button("Reset all hints", action: resetHintDefaults)
|
||||
.disabled(hintsUnchanged)
|
||||
}
|
||||
settingsRow("chevron.left.forwardslash.chevron.right", color: theme.colors.secondary) {
|
||||
Toggle("Show developer options", isOn: $developerTools)
|
||||
}
|
||||
@@ -55,6 +61,21 @@ struct DeveloperView: View {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func resetHintDefaults() {
|
||||
for def in hintDefaults {
|
||||
if let val = appDefaults[def] as? Bool {
|
||||
UserDefaults.standard.set(val, forKey: def)
|
||||
}
|
||||
}
|
||||
hintsUnchanged = true
|
||||
}
|
||||
}
|
||||
|
||||
private func hintDefaultsUnchanged() -> Bool {
|
||||
hintDefaults.allSatisfy { def in
|
||||
appDefaults[def] as? Bool == UserDefaults.standard.bool(forKey: def)
|
||||
}
|
||||
}
|
||||
|
||||
struct DeveloperView_Previews: PreviewProvider {
|
||||
|
||||
@@ -26,6 +26,7 @@ struct IncognitoHelp: View {
|
||||
Text("Read more in [User Guide](https://simplex.chat/docs/guide/chat-profiles.html#incognito-mode).")
|
||||
}
|
||||
.listRowBackground(Color.clear)
|
||||
.listRowInsets(EdgeInsets(top: 0, leading: 0, bottom: 0, trailing: 0))
|
||||
}
|
||||
.modifier(ThemedBackground())
|
||||
}
|
||||
|
||||
@@ -32,6 +32,18 @@ struct PreferencesView: View {
|
||||
.disabled(currentPreferences == preferences)
|
||||
}
|
||||
}
|
||||
.onDisappear {
|
||||
if currentPreferences != preferences {
|
||||
AlertManager.shared.showAlert(Alert(
|
||||
title: Text("Your chat preferences"),
|
||||
message: Text("Chat preferences were changed."),
|
||||
primaryButton: .default(Text("Save")) {
|
||||
savePreferences()
|
||||
},
|
||||
secondaryButton: .cancel()
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func featureSection(_ feature: ChatFeature, _ allowFeature: Binding<FeatureAllowed>) -> some View {
|
||||
|
||||
@@ -117,7 +117,7 @@ struct PrivacySettings: View {
|
||||
privacyAcceptImagesGroupDefault.set($0)
|
||||
}
|
||||
}
|
||||
settingsRow("circle.rectangle.filled.pattern.diagonalline", color: theme.colors.secondary) {
|
||||
settingsRow("circle.filled.pattern.diagonalline.rectangle", color: theme.colors.secondary) {
|
||||
Picker("Blur media", selection: $privacyMediaBlurRadius) {
|
||||
let values = [0, 12, 24, 48] + ([0, 12, 24, 48].contains(privacyMediaBlurRadius) ? [] : [privacyMediaBlurRadius])
|
||||
ForEach(values, id: \.self) { radius in
|
||||
@@ -470,7 +470,7 @@ struct SimplexLockView: View {
|
||||
}
|
||||
}
|
||||
.onChange(of: performLA) { performLAToggle in
|
||||
performLAGroupDefault.set(performLAToggle)
|
||||
appLocalAuthEnabledGroupDefault.set(performLAToggle)
|
||||
prefLANoticeShown = true
|
||||
if performLAToggleReset {
|
||||
performLAToggleReset = false
|
||||
|
||||
@@ -47,7 +47,10 @@ let DEFAULT_ACCENT_COLOR_GREEN = "accentColorGreen" // deprecated, only used for
|
||||
let DEFAULT_ACCENT_COLOR_BLUE = "accentColorBlue" // deprecated, only used for migration
|
||||
let DEFAULT_USER_INTERFACE_STYLE = "userInterfaceStyle" // deprecated, only used for migration
|
||||
let DEFAULT_PROFILE_IMAGE_CORNER_RADIUS = "profileImageCornerRadius"
|
||||
let DEFAULT_CHAT_ITEM_ROUNDNESS = "chatItemRoundness"
|
||||
let DEFAULT_CHAT_ITEM_TAIL = "chatItemTail"
|
||||
let DEFAULT_ONE_HAND_UI_CARD_SHOWN = "oneHandUICardShown"
|
||||
let DEFAULT_TOOLBAR_MATERIAL = "toolbarMaterial"
|
||||
let DEFAULT_CONNECT_VIA_LINK_TAB = "connectViaLinkTab"
|
||||
let DEFAULT_LIVE_MESSAGE_ALERT_SHOWN = "liveMessageAlertShown"
|
||||
let DEFAULT_SHOW_HIDDEN_PROFILES_NOTICE = "showHiddenProfilesNotice"
|
||||
@@ -74,6 +77,8 @@ let DEFAULT_THEME_OVERRIDES = "themeOverrides"
|
||||
|
||||
let ANDROID_DEFAULT_CALL_ON_LOCK_SCREEN = "androidCallOnLockScreen"
|
||||
|
||||
let defaultChatItemRoundness: Double = 0.75
|
||||
|
||||
let appDefaults: [String: Any] = [
|
||||
DEFAULT_SHOW_LA_NOTICE: false,
|
||||
DEFAULT_LA_NOTICE_SHOWN: false,
|
||||
@@ -97,7 +102,10 @@ let appDefaults: [String: Any] = [
|
||||
DEFAULT_DEVELOPER_TOOLS: false,
|
||||
DEFAULT_ENCRYPTION_STARTED: false,
|
||||
DEFAULT_PROFILE_IMAGE_CORNER_RADIUS: defaultProfileImageCorner,
|
||||
DEFAULT_CHAT_ITEM_ROUNDNESS: defaultChatItemRoundness,
|
||||
DEFAULT_CHAT_ITEM_TAIL: true,
|
||||
DEFAULT_ONE_HAND_UI_CARD_SHOWN: false,
|
||||
DEFAULT_TOOLBAR_MATERIAL: ToolbarMaterial.defaultMaterial,
|
||||
DEFAULT_CONNECT_VIA_LINK_TAB: ConnectViaLinkTab.scan.rawValue,
|
||||
DEFAULT_LIVE_MESSAGE_ALERT_SHOWN: false,
|
||||
DEFAULT_SHOW_HIDDEN_PROFILES_NOTICE: true,
|
||||
@@ -120,6 +128,18 @@ let appDefaults: [String: Any] = [
|
||||
DEFAULT_CURRENT_THEME_IDS: "{}"
|
||||
]
|
||||
|
||||
// only Bool defaults can be used here,
|
||||
// or hintDefaultsUnchanged and resetHintDefaults need to be changed
|
||||
let hintDefaults = [
|
||||
DEFAULT_LA_NOTICE_SHOWN,
|
||||
DEFAULT_ONE_HAND_UI_CARD_SHOWN,
|
||||
DEFAULT_LIVE_MESSAGE_ALERT_SHOWN,
|
||||
DEFAULT_SHOW_HIDDEN_PROFILES_NOTICE,
|
||||
DEFAULT_SHOW_MUTE_PROFILE_ALERT,
|
||||
DEFAULT_SHOW_DELETE_CONVERSATION_NOTICE,
|
||||
DEFAULT_SHOW_DELETE_CONTACT_NOTICE
|
||||
]
|
||||
|
||||
// not used anymore
|
||||
enum ConnectViaLinkTab: String {
|
||||
case scan
|
||||
@@ -174,7 +194,7 @@ let themeOverridesDefault: CodableDefault<[ThemeOverrides]> = CodableDefault(def
|
||||
|
||||
func setGroupDefaults() {
|
||||
privacyAcceptImagesGroupDefault.set(UserDefaults.standard.bool(forKey: DEFAULT_PRIVACY_ACCEPT_IMAGES))
|
||||
performLAGroupDefault.set(UserDefaults.standard.bool(forKey: DEFAULT_PERFORM_LA))
|
||||
appLocalAuthEnabledGroupDefault.set(UserDefaults.standard.bool(forKey: DEFAULT_PERFORM_LA))
|
||||
privacyLinkPreviewsGroupDefault.set(UserDefaults.standard.bool(forKey: DEFAULT_PRIVACY_LINK_PREVIEWS))
|
||||
profileImageCornerRadiusGroupDefault.set(UserDefaults.standard.double(forKey: DEFAULT_PROFILE_IMAGE_CORNER_RADIUS))
|
||||
}
|
||||
@@ -242,7 +262,9 @@ struct SettingsView: View {
|
||||
|
||||
var body: some View {
|
||||
ZStack {
|
||||
settingsView()
|
||||
NavigationView {
|
||||
settingsView()
|
||||
}
|
||||
if showProgress {
|
||||
progressView()
|
||||
}
|
||||
@@ -254,63 +276,7 @@ struct SettingsView: View {
|
||||
|
||||
@ViewBuilder func settingsView() -> some View {
|
||||
let user = chatModel.currentUser
|
||||
NavigationView {
|
||||
List {
|
||||
Section(header: Text("You").foregroundColor(theme.colors.secondary)) {
|
||||
if let user = user {
|
||||
NavigationLink {
|
||||
UserProfile()
|
||||
.navigationTitle("Your current profile")
|
||||
.modifier(ThemedBackground())
|
||||
} label: {
|
||||
ProfilePreview(profileOf: user)
|
||||
.padding(.leading, -8)
|
||||
}
|
||||
}
|
||||
|
||||
NavigationLink {
|
||||
UserProfilesView(showSettings: $showSettings)
|
||||
} label: {
|
||||
settingsRow("person.crop.rectangle.stack", color: theme.colors.secondary) { Text("Your chat profiles") }
|
||||
}
|
||||
|
||||
|
||||
if let user = user {
|
||||
NavigationLink {
|
||||
UserAddressView(shareViaProfile: user.addressShared)
|
||||
.navigationTitle("SimpleX address")
|
||||
.modifier(ThemedBackground(grouped: true))
|
||||
.navigationBarTitleDisplayMode(.large)
|
||||
} label: {
|
||||
settingsRow("qrcode", color: theme.colors.secondary) { Text("Your SimpleX address") }
|
||||
}
|
||||
|
||||
NavigationLink {
|
||||
PreferencesView(profile: user.profile, preferences: user.fullPreferences, currentPreferences: user.fullPreferences)
|
||||
.navigationTitle("Your preferences")
|
||||
.modifier(ThemedBackground(grouped: true))
|
||||
} label: {
|
||||
settingsRow("switch.2", color: theme.colors.secondary) { Text("Chat preferences") }
|
||||
}
|
||||
}
|
||||
|
||||
NavigationLink {
|
||||
ConnectDesktopView(viaSettings: true)
|
||||
} label: {
|
||||
settingsRow("desktopcomputer", color: theme.colors.secondary) { Text("Use from desktop") }
|
||||
}
|
||||
|
||||
NavigationLink {
|
||||
MigrateFromDevice(showSettings: $showSettings, showProgressOnSettings: $showProgress)
|
||||
.navigationTitle("Migrate device")
|
||||
.modifier(ThemedBackground(grouped: true))
|
||||
.navigationBarTitleDisplayMode(.large)
|
||||
} label: {
|
||||
settingsRow("tray.and.arrow.up", color: theme.colors.secondary) { Text("Migrate to another device") }
|
||||
}
|
||||
}
|
||||
.disabled(chatModel.chatRunning != true)
|
||||
|
||||
Section(header: Text("Settings").foregroundColor(theme.colors.secondary)) {
|
||||
NavigationLink {
|
||||
NotificationsView()
|
||||
@@ -361,10 +327,20 @@ struct SettingsView: View {
|
||||
}
|
||||
.disabled(chatModel.chatRunning != true)
|
||||
}
|
||||
|
||||
chatDatabaseRow()
|
||||
}
|
||||
|
||||
Section(header: Text("Chat database").foregroundColor(theme.colors.secondary)) {
|
||||
chatDatabaseRow()
|
||||
NavigationLink {
|
||||
MigrateFromDevice(showProgressOnSettings: $showProgress)
|
||||
.navigationTitle("Migrate device")
|
||||
.modifier(ThemedBackground(grouped: true))
|
||||
.navigationBarTitleDisplayMode(.large)
|
||||
} label: {
|
||||
settingsRow("tray.and.arrow.up", color: theme.colors.secondary) { Text("Migrate to another device") }
|
||||
}
|
||||
}
|
||||
|
||||
Section(header: Text("Help").foregroundColor(theme.colors.secondary)) {
|
||||
if let user = user {
|
||||
NavigationLink {
|
||||
@@ -442,11 +418,10 @@ struct SettingsView: View {
|
||||
}
|
||||
.navigationTitle("Your settings")
|
||||
.modifier(ThemedBackground(grouped: true))
|
||||
}
|
||||
.onDisappear {
|
||||
chatModel.showingTerminal = false
|
||||
chatModel.terminalItems = []
|
||||
}
|
||||
.onDisappear {
|
||||
chatModel.showingTerminal = false
|
||||
chatModel.terminalItems = []
|
||||
}
|
||||
}
|
||||
|
||||
private func chatDatabaseRow() -> some View {
|
||||
@@ -529,17 +504,18 @@ struct ProfilePreview: View {
|
||||
HStack {
|
||||
ProfileImage(imageStr: profileOf.image, size: 44, color: color)
|
||||
.padding(.trailing, 6)
|
||||
.padding(.vertical, 6)
|
||||
VStack(alignment: .leading) {
|
||||
Text(profileOf.displayName)
|
||||
.fontWeight(.bold)
|
||||
.font(.title2)
|
||||
if profileOf.fullName != "" && profileOf.fullName != profileOf.displayName {
|
||||
Text(profileOf.fullName)
|
||||
}
|
||||
}
|
||||
profileName().lineLimit(1)
|
||||
}
|
||||
}
|
||||
|
||||
private func profileName() -> Text {
|
||||
var t = Text(profileOf.displayName).fontWeight(.semibold).font(.title2)
|
||||
if profileOf.fullName != "" && profileOf.fullName != profileOf.displayName {
|
||||
t = t + Text(" (" + profileOf.fullName + ")")
|
||||
// .font(.callout)
|
||||
}
|
||||
return t
|
||||
}
|
||||
}
|
||||
|
||||
struct SettingsView_Previews: PreviewProvider {
|
||||
|
||||
@@ -14,7 +14,6 @@ struct UserAddressView: View {
|
||||
@Environment(\.dismiss) var dismiss: DismissAction
|
||||
@EnvironmentObject private var chatModel: ChatModel
|
||||
@EnvironmentObject var theme: AppTheme
|
||||
@State var viaCreateLinkView = false
|
||||
@State var shareViaProfile = false
|
||||
@State private var aas = AutoAcceptState()
|
||||
@State private var savedAAS = AutoAcceptState()
|
||||
@@ -22,8 +21,8 @@ struct UserAddressView: View {
|
||||
@State private var showMailView = false
|
||||
@State private var mailViewResult: Result<MFMailComposeResult, Error>? = nil
|
||||
@State private var alert: UserAddressAlert?
|
||||
@State private var showSaveDialogue = false
|
||||
@State private var progressIndicator = false
|
||||
@State private var shareItem: ShareItem?
|
||||
@FocusState private var keyboardVisible: Bool
|
||||
|
||||
private enum UserAddressAlert: Identifiable {
|
||||
@@ -44,26 +43,20 @@ struct UserAddressView: View {
|
||||
|
||||
var body: some View {
|
||||
ZStack {
|
||||
if viaCreateLinkView {
|
||||
userAddressScrollView()
|
||||
} else {
|
||||
userAddressScrollView()
|
||||
.modifier(BackButton(disabled: Binding.constant(false)) {
|
||||
if savedAAS == aas {
|
||||
dismiss()
|
||||
} else {
|
||||
keyboardVisible = false
|
||||
showSaveDialogue = true
|
||||
}
|
||||
})
|
||||
.confirmationDialog("Save settings?", isPresented: $showSaveDialogue) {
|
||||
Button("Save auto-accept settings") {
|
||||
saveAAS()
|
||||
dismiss()
|
||||
}
|
||||
Button("Exit without saving") { dismiss() }
|
||||
userAddressScrollView()
|
||||
.onDisappear {
|
||||
if savedAAS != aas {
|
||||
AlertManager.shared.showAlert(Alert(
|
||||
title: Text("Auto-accept settings"),
|
||||
message: Text("Settings were changed."),
|
||||
primaryButton: .default(Text("Save")) {
|
||||
saveAAS()
|
||||
},
|
||||
secondaryButton: .cancel()
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if progressIndicator {
|
||||
ZStack {
|
||||
if chatModel.userAddress != nil {
|
||||
@@ -76,6 +69,7 @@ struct UserAddressView: View {
|
||||
}
|
||||
}
|
||||
}
|
||||
.shareSheet(item: $shareItem)
|
||||
}
|
||||
|
||||
@Namespace private var bottomID
|
||||
@@ -238,7 +232,7 @@ struct UserAddressView: View {
|
||||
}
|
||||
}
|
||||
} label: {
|
||||
Label("Create SimpleX address", systemImage: "qrcode")
|
||||
Label("Create public address", systemImage: "qrcode")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -253,7 +247,7 @@ struct UserAddressView: View {
|
||||
|
||||
private func shareQRCodeButton(_ userAddress: UserContactLink) -> some View {
|
||||
Button {
|
||||
showShareSheet(items: [simplexChatLink(userAddress.connReqContact)])
|
||||
shareItem = ShareItem(content: simplexChatLink(userAddress.connReqContact))
|
||||
} label: {
|
||||
settingsRow("square.and.arrow.up", color: theme.colors.secondary) {
|
||||
Text("Share address")
|
||||
@@ -342,7 +336,7 @@ struct UserAddressView: View {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private struct AutoAcceptState: Equatable {
|
||||
var enable = false
|
||||
var incognito = false
|
||||
@@ -447,6 +441,8 @@ struct UserAddressView_Previews: PreviewProvider {
|
||||
static var previews: some View {
|
||||
let chatModel = ChatModel()
|
||||
chatModel.userAddress = UserContactLink(connReqContact: "https://simplex.chat/contact#/?v=1&smp=smp%3A%2F%2FPQUV2eL0t7OStZOoAsPEV2QYWt4-xilbakvGUGOItUo%3D%40smp6.simplex.im%2FK1rslx-m5bpXVIdMZg9NLUZ_8JBm8xTt%23MCowBQYDK2VuAyEALDeVe-sG8mRY22LsXlPgiwTNs9dbiLrNuA7f3ZMAJ2w%3D")
|
||||
|
||||
|
||||
return Group {
|
||||
UserAddressView()
|
||||
.environmentObject(chatModel)
|
||||
|
||||
@@ -9,7 +9,6 @@ import SimpleXChat
|
||||
struct UserProfilesView: View {
|
||||
@EnvironmentObject private var m: ChatModel
|
||||
@EnvironmentObject private var theme: AppTheme
|
||||
@Binding var showSettings: Bool
|
||||
@Environment(\.editMode) private var editMode
|
||||
@AppStorage(DEFAULT_SHOW_HIDDEN_PROFILES_NOTICE) private var showHiddenProfilesNotice = true
|
||||
@AppStorage(DEFAULT_SHOW_MUTE_PROFILE_ALERT) private var showMuteProfileAlert = true
|
||||
@@ -96,8 +95,7 @@ struct UserProfilesView: View {
|
||||
} label: {
|
||||
Label("Add profile", systemImage: "plus")
|
||||
}
|
||||
.frame(height: 44)
|
||||
.padding(.vertical, 4)
|
||||
.frame(height: 38)
|
||||
}
|
||||
} footer: {
|
||||
Text("Tap to activate profile.")
|
||||
@@ -285,7 +283,7 @@ struct UserProfilesView: View {
|
||||
await MainActor.run {
|
||||
onboardingStageDefault.set(.step1_SimpleXInfo)
|
||||
m.onboardingStage = .step1_SimpleXInfo
|
||||
showSettings = false
|
||||
dismissAllSheets()
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -308,14 +306,14 @@ struct UserProfilesView: View {
|
||||
Task {
|
||||
do {
|
||||
try await changeActiveUserAsync_(user.userId, viewPwd: userViewPassword(user))
|
||||
dismissAllSheets()
|
||||
} catch {
|
||||
await MainActor.run { alert = .activateUserError(error: responseError(error)) }
|
||||
}
|
||||
}
|
||||
} label: {
|
||||
HStack {
|
||||
ProfileImage(imageStr: user.image, size: 44)
|
||||
.padding(.vertical, 4)
|
||||
ProfileImage(imageStr: user.image, size: 38)
|
||||
.padding(.trailing, 12)
|
||||
Text(user.chatViewName)
|
||||
Spacer()
|
||||
@@ -406,8 +404,15 @@ public func chatPasswordHash(_ pwd: String, _ salt: String) -> String {
|
||||
return hash
|
||||
}
|
||||
|
||||
public func correctPassword(_ user: User, _ pwd: String) -> Bool {
|
||||
if let ph = user.viewPwdHash {
|
||||
return pwd != "" && chatPasswordHash(pwd, ph.salt) == ph.hash
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
struct UserProfilesView_Previews: PreviewProvider {
|
||||
static var previews: some View {
|
||||
UserProfilesView(showSettings: Binding.constant(true))
|
||||
UserProfilesView()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -137,6 +137,10 @@
|
||||
<target>%@ иска да се свърже!</target>
|
||||
<note>notification title</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="%@, %@" xml:space="preserve">
|
||||
<source>%1$@, %2$@</source>
|
||||
<note>format for date separator in chat</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="%@, %@ and %lld members" xml:space="preserve">
|
||||
<source>%@, %@ and %lld members</source>
|
||||
<target>%@, %@ и %lld членове</target>
|
||||
@@ -392,11 +396,6 @@
|
||||
<target>, </target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="- Search contacts when starting chat. - Archive contacts to chat later." xml:space="preserve">
|
||||
<source>- Search contacts when starting chat.
|
||||
- Archive contacts to chat later.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="- connect to [directory service](simplex:/contact#/?v=1-4&smp=smp%3A%2F%2Fu2dS9sG8nMNURyZwqASV4yROM28Er0luVTx5X1CsMrU%3D%40smp4.simplex.im%2FeXSPwqTkKyDO3px4fLf1wx3MvPdjdLW3%23%2F%3Fv%3D1-2%26dh%3DMCowBQYDK2VuAyEAaiv6MkMH44L2TcYrt_CsX3ZvM11WgbMEUn0hkIKTOho%253D%26srv%3Do5vmywmrnaxalvz6wi3zicyftgio6psuvyniis6gco6bp6ekl4cqj4id.onion) (BETA)! - delivery receipts (up to 20 members). - faster and more stable." xml:space="preserve">
|
||||
<source>- connect to [directory service](simplex:/contact#/?v=1-4&smp=smp%3A%2F%2Fu2dS9sG8nMNURyZwqASV4yROM28Er0luVTx5X1CsMrU%3D%40smp4.simplex.im%2FeXSPwqTkKyDO3px4fLf1wx3MvPdjdLW3%23%2F%3Fv%3D1-2%26dh%3DMCowBQYDK2VuAyEAaiv6MkMH44L2TcYrt_CsX3ZvM11WgbMEUn0hkIKTOho%253D%26srv%3Do5vmywmrnaxalvz6wi3zicyftgio6psuvyniis6gco6bp6ekl4cqj4id.onion) (BETA)!
|
||||
- delivery receipts (up to 20 members).
|
||||
@@ -565,7 +564,8 @@
|
||||
<source>Accept</source>
|
||||
<target>Приеми</target>
|
||||
<note>accept contact request via notification
|
||||
accept incoming call via notification</note>
|
||||
accept incoming call via notification
|
||||
swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Accept connection request?" xml:space="preserve">
|
||||
<source>Accept connection request?</source>
|
||||
@@ -580,7 +580,8 @@
|
||||
<trans-unit id="Accept incognito" xml:space="preserve">
|
||||
<source>Accept incognito</source>
|
||||
<target>Приеми инкогнито</target>
|
||||
<note>accept contact request via notification</note>
|
||||
<note>accept contact request via notification
|
||||
swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Acknowledged" xml:space="preserve">
|
||||
<source>Acknowledged</source>
|
||||
@@ -933,6 +934,10 @@
|
||||
<target>Архивиране и качване</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Archive contacts to chat later." xml:space="preserve">
|
||||
<source>Archive contacts to chat later.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Archived contacts" xml:space="preserve">
|
||||
<source>Archived contacts</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -1036,6 +1041,10 @@
|
||||
<target>По-добри съобщения</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Better networking" xml:space="preserve">
|
||||
<source>Better networking</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Black" xml:space="preserve">
|
||||
<source>Black</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -1075,6 +1084,10 @@
|
||||
<target>Блокиран от админ</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Blur for better privacy." xml:space="preserve">
|
||||
<source>Blur for better privacy.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Blur media" xml:space="preserve">
|
||||
<source>Blur media</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -1287,6 +1300,10 @@
|
||||
<target>Чатът е спрян. Ако вече сте използвали тази база данни на друго устройство, трябва да я прехвърлите обратно, преди да стартирате чата отново.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Chat list" xml:space="preserve">
|
||||
<source>Chat list</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Chat migrated!" xml:space="preserve">
|
||||
<source>Chat migrated!</source>
|
||||
<target>Чатът е мигриран!</target>
|
||||
@@ -1346,7 +1363,7 @@
|
||||
<trans-unit id="Clear" xml:space="preserve">
|
||||
<source>Clear</source>
|
||||
<target>Изчисти</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
<note>swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Clear conversation" xml:space="preserve">
|
||||
<source>Clear conversation</source>
|
||||
@@ -1368,6 +1385,10 @@
|
||||
<target>Изчисти проверката</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Color chats with the new themes." xml:space="preserve">
|
||||
<source>Color chats with the new themes.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Color mode" xml:space="preserve">
|
||||
<source>Color mode</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -1463,8 +1484,8 @@
|
||||
<target>Свързване с настолно устройство</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Connect to your friends faster" xml:space="preserve">
|
||||
<source>Connect to your friends faster</source>
|
||||
<trans-unit id="Connect to your friends faster." xml:space="preserve">
|
||||
<source>Connect to your friends faster.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Connect to yourself?" xml:space="preserve">
|
||||
@@ -1650,10 +1671,6 @@ This is your own one-time link!</source>
|
||||
<target>Продължи</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Control your network" xml:space="preserve">
|
||||
<source>Control your network</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Conversation deleted!" xml:space="preserve">
|
||||
<source>Conversation deleted!</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -1672,6 +1689,10 @@ This is your own one-time link!</source>
|
||||
<target>Версия на ядрото: v%@</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Corner" xml:space="preserve">
|
||||
<source>Corner</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Correct name to %@?" xml:space="preserve">
|
||||
<source>Correct name to %@?</source>
|
||||
<target>Поправи име на %@?</target>
|
||||
@@ -1923,7 +1944,8 @@ This is your own one-time link!</source>
|
||||
<trans-unit id="Delete" xml:space="preserve">
|
||||
<source>Delete</source>
|
||||
<target>Изтрий</target>
|
||||
<note>chat item action</note>
|
||||
<note>chat item action
|
||||
swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Delete %lld messages of members?" xml:space="preserve">
|
||||
<source>Delete %lld messages of members?</source>
|
||||
@@ -2125,10 +2147,6 @@ This is your own one-time link!</source>
|
||||
<target>Изтрито на: %@</target>
|
||||
<note>copied message info</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Deleted chats" xml:space="preserve">
|
||||
<source>Deleted chats</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Deletion errors" xml:space="preserve">
|
||||
<source>Deletion errors</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -2635,6 +2653,10 @@ This is your own one-time link!</source>
|
||||
<target>Грешка при промяна на адреса</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Error changing connection profile" xml:space="preserve">
|
||||
<source>Error changing connection profile</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Error changing role" xml:space="preserve">
|
||||
<source>Error changing role</source>
|
||||
<target>Грешка при промяна на ролята</target>
|
||||
@@ -2645,6 +2667,10 @@ This is your own one-time link!</source>
|
||||
<target>Грешка при промяна на настройката</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Error changing to incognito!" xml:space="preserve">
|
||||
<source>Error changing to incognito!</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Error connecting to forwarding server %@. Please try later." xml:space="preserve">
|
||||
<source>Error connecting to forwarding server %@. Please try later.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -2860,6 +2886,10 @@ This is your own one-time link!</source>
|
||||
<target>Грешка при спиране на чата</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Error switching profile" xml:space="preserve">
|
||||
<source>Error switching profile</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Error switching profile!" xml:space="preserve">
|
||||
<source>Error switching profile!</source>
|
||||
<target>Грешка при смяна на профил!</target>
|
||||
@@ -2930,10 +2960,6 @@ This is your own one-time link!</source>
|
||||
<target>Дори когато е деактивиран в разговора.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Even when they are offline." xml:space="preserve">
|
||||
<source>Even when they are offline.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Exit without saving" xml:space="preserve">
|
||||
<source>Exit without saving</source>
|
||||
<target>Изход без запазване</target>
|
||||
@@ -2991,7 +3017,7 @@ This is your own one-time link!</source>
|
||||
<trans-unit id="Favorite" xml:space="preserve">
|
||||
<source>Favorite</source>
|
||||
<target>Любим</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
<note>swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="File error" xml:space="preserve">
|
||||
<source>File error</source>
|
||||
@@ -3750,7 +3776,7 @@ Error: %2$@</source>
|
||||
<trans-unit id="Join" xml:space="preserve">
|
||||
<source>Join</source>
|
||||
<target>Присъединяване</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
<note>swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Join group" xml:space="preserve">
|
||||
<source>Join group</source>
|
||||
@@ -3841,7 +3867,7 @@ This is your link for group %@!</source>
|
||||
<trans-unit id="Leave" xml:space="preserve">
|
||||
<source>Leave</source>
|
||||
<target>Напусни</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
<note>swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Leave group" xml:space="preserve">
|
||||
<source>Leave group</source>
|
||||
@@ -4063,6 +4089,10 @@ This is your link for group %@!</source>
|
||||
<source>Message servers</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message shape" xml:space="preserve">
|
||||
<source>Message shape</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message source remains private." xml:space="preserve">
|
||||
<source>Message source remains private.</source>
|
||||
<target>Източникът на съобщението остава скрит.</target>
|
||||
@@ -4184,10 +4214,6 @@ This is your link for group %@!</source>
|
||||
<target>Модерирай</target>
|
||||
<note>chat item action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Moderate like a pro ✋" xml:space="preserve">
|
||||
<source>Moderate like a pro ✋</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Moderated at" xml:space="preserve">
|
||||
<source>Moderated at</source>
|
||||
<target>Модерирано в</target>
|
||||
@@ -4221,7 +4247,7 @@ This is your link for group %@!</source>
|
||||
<trans-unit id="Mute" xml:space="preserve">
|
||||
<source>Mute</source>
|
||||
<target>Без звук</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
<note>swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Muted when inactive!" xml:space="preserve">
|
||||
<source>Muted when inactive!</source>
|
||||
@@ -4231,7 +4257,7 @@ This is your link for group %@!</source>
|
||||
<trans-unit id="Name" xml:space="preserve">
|
||||
<source>Name</source>
|
||||
<target>Име</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
<note>swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Network & servers" xml:space="preserve">
|
||||
<source>Network & servers</source>
|
||||
@@ -4262,10 +4288,6 @@ This is your link for group %@!</source>
|
||||
<target>Състояние на мрежата</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="New Chat" xml:space="preserve">
|
||||
<source>New Chat</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="New Passcode" xml:space="preserve">
|
||||
<source>New Passcode</source>
|
||||
<target>Нов kод за достъп</target>
|
||||
@@ -4276,6 +4298,10 @@ This is your link for group %@!</source>
|
||||
<target>Нов чат</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="New chat experience 🎉" xml:space="preserve">
|
||||
<source>New chat experience 🎉</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="New contact request" xml:space="preserve">
|
||||
<source>New contact request</source>
|
||||
<target>Нова заявка за контакт</target>
|
||||
@@ -4306,6 +4332,10 @@ This is your link for group %@!</source>
|
||||
<target>Ново в %@</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="New media options" xml:space="preserve">
|
||||
<source>New media options</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="New member role" xml:space="preserve">
|
||||
<source>New member role</source>
|
||||
<target>Нова членска роля</target>
|
||||
@@ -4442,10 +4472,6 @@ This is your link for group %@!</source>
|
||||
<target>Стар архив на база данни</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="One-hand UI" xml:space="preserve">
|
||||
<source>One-hand UI</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="One-time invitation link" xml:space="preserve">
|
||||
<source>One-time invitation link</source>
|
||||
<target>Линк за еднократна покана</target>
|
||||
@@ -4711,6 +4737,10 @@ Requires compatible VPN.</source>
|
||||
<target>Обаждания "картина в картина"</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Play from the chat list." xml:space="preserve">
|
||||
<source>Play from the chat list.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Please ask your contact to enable calls." xml:space="preserve">
|
||||
<source>Please ask your contact to enable calls.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -5003,8 +5033,8 @@ Enable in *Network & servers* settings.</source>
|
||||
<target>Оценете приложението</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Reachable chat toolbar 👋" xml:space="preserve">
|
||||
<source>Reachable chat toolbar 👋</source>
|
||||
<trans-unit id="Reachable chat toolbar" xml:space="preserve">
|
||||
<source>Reachable chat toolbar</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="React…" xml:space="preserve">
|
||||
@@ -5015,7 +5045,7 @@ Enable in *Network & servers* settings.</source>
|
||||
<trans-unit id="Read" xml:space="preserve">
|
||||
<source>Read</source>
|
||||
<target>Прочетено</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
<note>swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Read more" xml:space="preserve">
|
||||
<source>Read more</source>
|
||||
@@ -5166,7 +5196,8 @@ Enable in *Network & servers* settings.</source>
|
||||
<trans-unit id="Reject" xml:space="preserve">
|
||||
<source>Reject</source>
|
||||
<target>Отхвърляне</target>
|
||||
<note>reject incoming call via notification</note>
|
||||
<note>reject incoming call via notification
|
||||
swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Reject (sender NOT notified)" xml:space="preserve">
|
||||
<source>Reject (sender NOT notified)</source>
|
||||
@@ -5267,6 +5298,10 @@ Enable in *Network & servers* settings.</source>
|
||||
<target>Нулиране</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Reset all hints" xml:space="preserve">
|
||||
<source>Reset all hints</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Reset all statistics" xml:space="preserve">
|
||||
<source>Reset all statistics</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -5551,6 +5586,10 @@ Enable in *Network & servers* settings.</source>
|
||||
<target>Избери</target>
|
||||
<note>chat item action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Select chat profile" xml:space="preserve">
|
||||
<source>Select chat profile</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Selected %lld" xml:space="preserve">
|
||||
<source>Selected %lld</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -5891,11 +5930,19 @@ Enable in *Network & servers* settings.</source>
|
||||
<target>Сподели адреса с контактите?</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Share from other apps." xml:space="preserve">
|
||||
<source>Share from other apps.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Share link" xml:space="preserve">
|
||||
<source>Share link</source>
|
||||
<target>Сподели линк</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Share profile" xml:space="preserve">
|
||||
<source>Share profile</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Share this 1-time invite link" xml:space="preserve">
|
||||
<source>Share this 1-time invite link</source>
|
||||
<target>Сподели този еднократен линк за връзка</target>
|
||||
@@ -6220,6 +6267,10 @@ Enable in *Network & servers* settings.</source>
|
||||
<target>TCP_KEEPINTVL</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Tail" xml:space="preserve">
|
||||
<source>Tail</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Take picture" xml:space="preserve">
|
||||
<source>Take picture</source>
|
||||
<target>Направи снимка</target>
|
||||
@@ -6551,11 +6602,19 @@ You will be prompted to complete authentication before this feature is enabled.<
|
||||
<target>За да проверите криптирането от край до край с вашия контакт, сравнете (или сканирайте) кода на вашите устройства.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Toggle chat list:" xml:space="preserve">
|
||||
<source>Toggle chat list:</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Toggle incognito when connecting." xml:space="preserve">
|
||||
<source>Toggle incognito when connecting.</source>
|
||||
<target>Избор на инкогнито при свързване.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Toolbar opacity" xml:space="preserve">
|
||||
<source>Toolbar opacity</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Total" xml:space="preserve">
|
||||
<source>Total</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -6632,7 +6691,7 @@ You will be prompted to complete authentication before this feature is enabled.<
|
||||
<trans-unit id="Unfav." xml:space="preserve">
|
||||
<source>Unfav.</source>
|
||||
<target>Премахни от любимите</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
<note>swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Unhide" xml:space="preserve">
|
||||
<source>Unhide</source>
|
||||
@@ -6708,12 +6767,12 @@ To connect, please ask your contact to create another connection link and check
|
||||
<trans-unit id="Unmute" xml:space="preserve">
|
||||
<source>Unmute</source>
|
||||
<target>Уведомявай</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
<note>swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Unread" xml:space="preserve">
|
||||
<source>Unread</source>
|
||||
<target>Непрочетено</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
<note>swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Up to 100 last messages are sent to new members." xml:space="preserve">
|
||||
<source>Up to 100 last messages are sent to new members.</source>
|
||||
@@ -7191,6 +7250,10 @@ Repeat join request?</source>
|
||||
<target>Можете да приемате обаждания от заключен екран, без идентификация на устройство и приложението.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="You can change it in Appearance settings." xml:space="preserve">
|
||||
<source>You can change it in Appearance settings.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="You can create it later" xml:space="preserve">
|
||||
<source>You can create it later</source>
|
||||
<target>Можете да го създадете по-късно</target>
|
||||
@@ -7453,6 +7516,10 @@ Repeat connection request?</source>
|
||||
<target>Вашите чат профили</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Your connection was moved to %@ but an unexpected error occurred while redirecting you to the profile." xml:space="preserve">
|
||||
<source>Your connection was moved to %@ but an unexpected error occurred while redirecting you to the profile.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Your contact sent a file that is larger than currently supported maximum size (%@)." xml:space="preserve">
|
||||
<source>Your contact sent a file that is larger than currently supported maximum size (%@).</source>
|
||||
<target>Вашият контакт изпрати файл, който е по-голям от поддържания в момента максимален размер (%@).</target>
|
||||
@@ -7468,10 +7535,6 @@ Repeat connection request?</source>
|
||||
<target>Вашите контакти ще останат свързани.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Your contacts your way" xml:space="preserve">
|
||||
<source>Your contacts your way</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Your current chat database will be DELETED and REPLACED with the imported one." xml:space="preserve">
|
||||
<source>Your current chat database will be DELETED and REPLACED with the imported one.</source>
|
||||
<target>Вашата текуща чат база данни ще бъде ИЗТРИТА и ЗАМЕНЕНА с импортираната.</target>
|
||||
|
||||
@@ -135,6 +135,10 @@
|
||||
<target>%@ se chce připojit!</target>
|
||||
<note>notification title</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="%@, %@" xml:space="preserve">
|
||||
<source>%1$@, %2$@</source>
|
||||
<note>format for date separator in chat</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="%@, %@ and %lld members" xml:space="preserve">
|
||||
<source>%@, %@ and %lld members</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -378,11 +382,6 @@
|
||||
<target>, </target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="- Search contacts when starting chat. - Archive contacts to chat later." xml:space="preserve">
|
||||
<source>- Search contacts when starting chat.
|
||||
- Archive contacts to chat later.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="- connect to [directory service](simplex:/contact#/?v=1-4&smp=smp%3A%2F%2Fu2dS9sG8nMNURyZwqASV4yROM28Er0luVTx5X1CsMrU%3D%40smp4.simplex.im%2FeXSPwqTkKyDO3px4fLf1wx3MvPdjdLW3%23%2F%3Fv%3D1-2%26dh%3DMCowBQYDK2VuAyEAaiv6MkMH44L2TcYrt_CsX3ZvM11WgbMEUn0hkIKTOho%253D%26srv%3Do5vmywmrnaxalvz6wi3zicyftgio6psuvyniis6gco6bp6ekl4cqj4id.onion) (BETA)! - delivery receipts (up to 20 members). - faster and more stable." xml:space="preserve">
|
||||
<source>- connect to [directory service](simplex:/contact#/?v=1-4&smp=smp%3A%2F%2Fu2dS9sG8nMNURyZwqASV4yROM28Er0luVTx5X1CsMrU%3D%40smp4.simplex.im%2FeXSPwqTkKyDO3px4fLf1wx3MvPdjdLW3%23%2F%3Fv%3D1-2%26dh%3DMCowBQYDK2VuAyEAaiv6MkMH44L2TcYrt_CsX3ZvM11WgbMEUn0hkIKTOho%253D%26srv%3Do5vmywmrnaxalvz6wi3zicyftgio6psuvyniis6gco6bp6ekl4cqj4id.onion) (BETA)!
|
||||
- delivery receipts (up to 20 members).
|
||||
@@ -547,7 +546,8 @@
|
||||
<source>Accept</source>
|
||||
<target>Přijmout</target>
|
||||
<note>accept contact request via notification
|
||||
accept incoming call via notification</note>
|
||||
accept incoming call via notification
|
||||
swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Accept connection request?" xml:space="preserve">
|
||||
<source>Accept connection request?</source>
|
||||
@@ -562,7 +562,8 @@
|
||||
<trans-unit id="Accept incognito" xml:space="preserve">
|
||||
<source>Accept incognito</source>
|
||||
<target>Přijmout inkognito</target>
|
||||
<note>accept contact request via notification</note>
|
||||
<note>accept contact request via notification
|
||||
swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Acknowledged" xml:space="preserve">
|
||||
<source>Acknowledged</source>
|
||||
@@ -904,6 +905,10 @@
|
||||
<source>Archive and upload</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Archive contacts to chat later." xml:space="preserve">
|
||||
<source>Archive contacts to chat later.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Archived contacts" xml:space="preserve">
|
||||
<source>Archived contacts</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -1004,6 +1009,10 @@
|
||||
<target>Lepší zprávy</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Better networking" xml:space="preserve">
|
||||
<source>Better networking</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Black" xml:space="preserve">
|
||||
<source>Black</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -1036,6 +1045,10 @@
|
||||
<source>Blocked by admin</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Blur for better privacy." xml:space="preserve">
|
||||
<source>Blur for better privacy.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Blur media" xml:space="preserve">
|
||||
<source>Blur media</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -1244,6 +1257,10 @@
|
||||
<source>Chat is stopped. If you already used this database on another device, you should transfer it back before starting chat.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Chat list" xml:space="preserve">
|
||||
<source>Chat list</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Chat migrated!" xml:space="preserve">
|
||||
<source>Chat migrated!</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -1301,7 +1318,7 @@
|
||||
<trans-unit id="Clear" xml:space="preserve">
|
||||
<source>Clear</source>
|
||||
<target>Vyčistit</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
<note>swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Clear conversation" xml:space="preserve">
|
||||
<source>Clear conversation</source>
|
||||
@@ -1322,6 +1339,10 @@
|
||||
<target>Zrušte ověření</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Color chats with the new themes." xml:space="preserve">
|
||||
<source>Color chats with the new themes.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Color mode" xml:space="preserve">
|
||||
<source>Color mode</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -1412,8 +1433,8 @@
|
||||
<source>Connect to desktop</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Connect to your friends faster" xml:space="preserve">
|
||||
<source>Connect to your friends faster</source>
|
||||
<trans-unit id="Connect to your friends faster." xml:space="preserve">
|
||||
<source>Connect to your friends faster.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Connect to yourself?" xml:space="preserve">
|
||||
@@ -1588,10 +1609,6 @@ This is your own one-time link!</source>
|
||||
<target>Pokračovat</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Control your network" xml:space="preserve">
|
||||
<source>Control your network</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Conversation deleted!" xml:space="preserve">
|
||||
<source>Conversation deleted!</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -1610,6 +1627,10 @@ This is your own one-time link!</source>
|
||||
<target>Verze jádra: v%@</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Corner" xml:space="preserve">
|
||||
<source>Corner</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Correct name to %@?" xml:space="preserve">
|
||||
<source>Correct name to %@?</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -1853,7 +1874,8 @@ This is your own one-time link!</source>
|
||||
<trans-unit id="Delete" xml:space="preserve">
|
||||
<source>Delete</source>
|
||||
<target>Smazat</target>
|
||||
<note>chat item action</note>
|
||||
<note>chat item action
|
||||
swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Delete %lld messages of members?" xml:space="preserve">
|
||||
<source>Delete %lld messages of members?</source>
|
||||
@@ -2052,10 +2074,6 @@ This is your own one-time link!</source>
|
||||
<target>Smazáno v: %@</target>
|
||||
<note>copied message info</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Deleted chats" xml:space="preserve">
|
||||
<source>Deleted chats</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Deletion errors" xml:space="preserve">
|
||||
<source>Deletion errors</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -2542,6 +2560,10 @@ This is your own one-time link!</source>
|
||||
<target>Chuba změny adresy</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Error changing connection profile" xml:space="preserve">
|
||||
<source>Error changing connection profile</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Error changing role" xml:space="preserve">
|
||||
<source>Error changing role</source>
|
||||
<target>Chyba při změně role</target>
|
||||
@@ -2552,6 +2574,10 @@ This is your own one-time link!</source>
|
||||
<target>Chyba změny nastavení</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Error changing to incognito!" xml:space="preserve">
|
||||
<source>Error changing to incognito!</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Error connecting to forwarding server %@. Please try later." xml:space="preserve">
|
||||
<source>Error connecting to forwarding server %@. Please try later.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -2762,6 +2788,10 @@ This is your own one-time link!</source>
|
||||
<target>Chyba při zastavení chatu</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Error switching profile" xml:space="preserve">
|
||||
<source>Error switching profile</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Error switching profile!" xml:space="preserve">
|
||||
<source>Error switching profile!</source>
|
||||
<target>Chyba při přepínání profilu!</target>
|
||||
@@ -2830,10 +2860,6 @@ This is your own one-time link!</source>
|
||||
<target>I při vypnutí v konverzaci.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Even when they are offline." xml:space="preserve">
|
||||
<source>Even when they are offline.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Exit without saving" xml:space="preserve">
|
||||
<source>Exit without saving</source>
|
||||
<target>Ukončit bez uložení</target>
|
||||
@@ -2888,7 +2914,7 @@ This is your own one-time link!</source>
|
||||
<trans-unit id="Favorite" xml:space="preserve">
|
||||
<source>Favorite</source>
|
||||
<target>Oblíbené</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
<note>swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="File error" xml:space="preserve">
|
||||
<source>File error</source>
|
||||
@@ -3620,7 +3646,7 @@ Error: %2$@</source>
|
||||
<trans-unit id="Join" xml:space="preserve">
|
||||
<source>Join</source>
|
||||
<target>Připojte se na</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
<note>swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Join group" xml:space="preserve">
|
||||
<source>Join group</source>
|
||||
@@ -3703,7 +3729,7 @@ This is your link for group %@!</source>
|
||||
<trans-unit id="Leave" xml:space="preserve">
|
||||
<source>Leave</source>
|
||||
<target>Opustit</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
<note>swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Leave group" xml:space="preserve">
|
||||
<source>Leave group</source>
|
||||
@@ -3922,6 +3948,10 @@ This is your link for group %@!</source>
|
||||
<source>Message servers</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message shape" xml:space="preserve">
|
||||
<source>Message shape</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message source remains private." xml:space="preserve">
|
||||
<source>Message source remains private.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -4031,10 +4061,6 @@ This is your link for group %@!</source>
|
||||
<target>Moderovat</target>
|
||||
<note>chat item action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Moderate like a pro ✋" xml:space="preserve">
|
||||
<source>Moderate like a pro ✋</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Moderated at" xml:space="preserve">
|
||||
<source>Moderated at</source>
|
||||
<target>Upraveno v</target>
|
||||
@@ -4067,7 +4093,7 @@ This is your link for group %@!</source>
|
||||
<trans-unit id="Mute" xml:space="preserve">
|
||||
<source>Mute</source>
|
||||
<target>Ztlumit</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
<note>swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Muted when inactive!" xml:space="preserve">
|
||||
<source>Muted when inactive!</source>
|
||||
@@ -4077,7 +4103,7 @@ This is your link for group %@!</source>
|
||||
<trans-unit id="Name" xml:space="preserve">
|
||||
<source>Name</source>
|
||||
<target>Jméno</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
<note>swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Network & servers" xml:space="preserve">
|
||||
<source>Network & servers</source>
|
||||
@@ -4106,10 +4132,6 @@ This is your link for group %@!</source>
|
||||
<target>Stav sítě</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="New Chat" xml:space="preserve">
|
||||
<source>New Chat</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="New Passcode" xml:space="preserve">
|
||||
<source>New Passcode</source>
|
||||
<target>Nové heslo</target>
|
||||
@@ -4119,6 +4141,10 @@ This is your link for group %@!</source>
|
||||
<source>New chat</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="New chat experience 🎉" xml:space="preserve">
|
||||
<source>New chat experience 🎉</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="New contact request" xml:space="preserve">
|
||||
<source>New contact request</source>
|
||||
<target>Žádost o nový kontakt</target>
|
||||
@@ -4149,6 +4175,10 @@ This is your link for group %@!</source>
|
||||
<target>Nový V %@</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="New media options" xml:space="preserve">
|
||||
<source>New media options</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="New member role" xml:space="preserve">
|
||||
<source>New member role</source>
|
||||
<target>Nová role člena</target>
|
||||
@@ -4282,10 +4312,6 @@ This is your link for group %@!</source>
|
||||
<target>Archiv staré databáze</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="One-hand UI" xml:space="preserve">
|
||||
<source>One-hand UI</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="One-time invitation link" xml:space="preserve">
|
||||
<source>One-time invitation link</source>
|
||||
<target>Jednorázový zvací odkaz</target>
|
||||
@@ -4538,6 +4564,10 @@ Vyžaduje povolení sítě VPN.</target>
|
||||
<source>Picture-in-picture calls</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Play from the chat list." xml:space="preserve">
|
||||
<source>Play from the chat list.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Please ask your contact to enable calls." xml:space="preserve">
|
||||
<source>Please ask your contact to enable calls.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -4820,8 +4850,8 @@ Enable in *Network & servers* settings.</source>
|
||||
<target>Ohodnoťte aplikaci</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Reachable chat toolbar 👋" xml:space="preserve">
|
||||
<source>Reachable chat toolbar 👋</source>
|
||||
<trans-unit id="Reachable chat toolbar" xml:space="preserve">
|
||||
<source>Reachable chat toolbar</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="React…" xml:space="preserve">
|
||||
@@ -4832,7 +4862,7 @@ Enable in *Network & servers* settings.</source>
|
||||
<trans-unit id="Read" xml:space="preserve">
|
||||
<source>Read</source>
|
||||
<target>Číst</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
<note>swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Read more" xml:space="preserve">
|
||||
<source>Read more</source>
|
||||
@@ -4980,7 +5010,8 @@ Enable in *Network & servers* settings.</source>
|
||||
<trans-unit id="Reject" xml:space="preserve">
|
||||
<source>Reject</source>
|
||||
<target>Odmítnout</target>
|
||||
<note>reject incoming call via notification</note>
|
||||
<note>reject incoming call via notification
|
||||
swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Reject (sender NOT notified)" xml:space="preserve">
|
||||
<source>Reject (sender NOT notified)</source>
|
||||
@@ -5076,6 +5107,10 @@ Enable in *Network & servers* settings.</source>
|
||||
<target>Obnovit</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Reset all hints" xml:space="preserve">
|
||||
<source>Reset all hints</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Reset all statistics" xml:space="preserve">
|
||||
<source>Reset all statistics</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -5352,6 +5387,10 @@ Enable in *Network & servers* settings.</source>
|
||||
<target>Vybrat</target>
|
||||
<note>chat item action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Select chat profile" xml:space="preserve">
|
||||
<source>Select chat profile</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Selected %lld" xml:space="preserve">
|
||||
<source>Selected %lld</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -5688,11 +5727,19 @@ Enable in *Network & servers* settings.</source>
|
||||
<target>Sdílet adresu s kontakty?</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Share from other apps." xml:space="preserve">
|
||||
<source>Share from other apps.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Share link" xml:space="preserve">
|
||||
<source>Share link</source>
|
||||
<target>Sdílet odkaz</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Share profile" xml:space="preserve">
|
||||
<source>Share profile</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Share this 1-time invite link" xml:space="preserve">
|
||||
<source>Share this 1-time invite link</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -6009,6 +6056,10 @@ Enable in *Network & servers* settings.</source>
|
||||
<target>TCP_KEEPINTVL</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Tail" xml:space="preserve">
|
||||
<source>Tail</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Take picture" xml:space="preserve">
|
||||
<source>Take picture</source>
|
||||
<target>Vyfotit</target>
|
||||
@@ -6328,11 +6379,19 @@ Před zapnutím této funkce budete vyzváni k dokončení ověření.</target>
|
||||
<target>Chcete-li ověřit koncové šifrování u svého kontaktu, porovnejte (nebo naskenujte) kód na svých zařízeních.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Toggle chat list:" xml:space="preserve">
|
||||
<source>Toggle chat list:</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Toggle incognito when connecting." xml:space="preserve">
|
||||
<source>Toggle incognito when connecting.</source>
|
||||
<target>Změnit inkognito režim při připojení.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Toolbar opacity" xml:space="preserve">
|
||||
<source>Toolbar opacity</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Total" xml:space="preserve">
|
||||
<source>Total</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -6403,7 +6462,7 @@ Před zapnutím této funkce budete vyzváni k dokončení ověření.</target>
|
||||
<trans-unit id="Unfav." xml:space="preserve">
|
||||
<source>Unfav.</source>
|
||||
<target>Odobl.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
<note>swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Unhide" xml:space="preserve">
|
||||
<source>Unhide</source>
|
||||
@@ -6477,12 +6536,12 @@ Chcete-li se připojit, požádejte svůj kontakt o vytvoření dalšího odkazu
|
||||
<trans-unit id="Unmute" xml:space="preserve">
|
||||
<source>Unmute</source>
|
||||
<target>Zrušit ztlumení</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
<note>swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Unread" xml:space="preserve">
|
||||
<source>Unread</source>
|
||||
<target>Nepřečtený</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
<note>swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Up to 100 last messages are sent to new members." xml:space="preserve">
|
||||
<source>Up to 100 last messages are sent to new members.</source>
|
||||
@@ -6928,6 +6987,10 @@ Repeat join request?</source>
|
||||
<target>Můžete přijímat hovory z obrazovky zámku, bez ověření zařízení a aplikace.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="You can change it in Appearance settings." xml:space="preserve">
|
||||
<source>You can change it in Appearance settings.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="You can create it later" xml:space="preserve">
|
||||
<source>You can create it later</source>
|
||||
<target>Můžete vytvořit později</target>
|
||||
@@ -7182,6 +7245,10 @@ Repeat connection request?</source>
|
||||
<target>Vaše chat profily</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Your connection was moved to %@ but an unexpected error occurred while redirecting you to the profile." xml:space="preserve">
|
||||
<source>Your connection was moved to %@ but an unexpected error occurred while redirecting you to the profile.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Your contact sent a file that is larger than currently supported maximum size (%@)." xml:space="preserve">
|
||||
<source>Your contact sent a file that is larger than currently supported maximum size (%@).</source>
|
||||
<target>Kontakt odeslal soubor, který je větší než aktuálně podporovaná maximální velikost (%@).</target>
|
||||
@@ -7197,10 +7264,6 @@ Repeat connection request?</source>
|
||||
<target>Vaše kontakty zůstanou připojeny.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Your contacts your way" xml:space="preserve">
|
||||
<source>Your contacts your way</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Your current chat database will be DELETED and REPLACED with the imported one." xml:space="preserve">
|
||||
<source>Your current chat database will be DELETED and REPLACED with the imported one.</source>
|
||||
<target>Vaše aktuální chat databáze bude ODSTRANĚNA a NAHRAZENA importovanou.</target>
|
||||
|
||||
@@ -137,6 +137,10 @@
|
||||
<target>%@ will sich mit Ihnen verbinden!</target>
|
||||
<note>notification title</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="%@, %@" xml:space="preserve">
|
||||
<source>%1$@, %2$@</source>
|
||||
<note>format for date separator in chat</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="%@, %@ and %lld members" xml:space="preserve">
|
||||
<source>%@, %@ and %lld members</source>
|
||||
<target>%@, %@ und %lld Mitglieder</target>
|
||||
@@ -392,11 +396,6 @@
|
||||
<target>, </target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="- Search contacts when starting chat. - Archive contacts to chat later." xml:space="preserve">
|
||||
<source>- Search contacts when starting chat.
|
||||
- Archive contacts to chat later.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="- connect to [directory service](simplex:/contact#/?v=1-4&smp=smp%3A%2F%2Fu2dS9sG8nMNURyZwqASV4yROM28Er0luVTx5X1CsMrU%3D%40smp4.simplex.im%2FeXSPwqTkKyDO3px4fLf1wx3MvPdjdLW3%23%2F%3Fv%3D1-2%26dh%3DMCowBQYDK2VuAyEAaiv6MkMH44L2TcYrt_CsX3ZvM11WgbMEUn0hkIKTOho%253D%26srv%3Do5vmywmrnaxalvz6wi3zicyftgio6psuvyniis6gco6bp6ekl4cqj4id.onion) (BETA)! - delivery receipts (up to 20 members). - faster and more stable." xml:space="preserve">
|
||||
<source>- connect to [directory service](simplex:/contact#/?v=1-4&smp=smp%3A%2F%2Fu2dS9sG8nMNURyZwqASV4yROM28Er0luVTx5X1CsMrU%3D%40smp4.simplex.im%2FeXSPwqTkKyDO3px4fLf1wx3MvPdjdLW3%23%2F%3Fv%3D1-2%26dh%3DMCowBQYDK2VuAyEAaiv6MkMH44L2TcYrt_CsX3ZvM11WgbMEUn0hkIKTOho%253D%26srv%3Do5vmywmrnaxalvz6wi3zicyftgio6psuvyniis6gco6bp6ekl4cqj4id.onion) (BETA)!
|
||||
- delivery receipts (up to 20 members).
|
||||
@@ -529,17 +528,17 @@
|
||||
</trans-unit>
|
||||
<trans-unit id="Abort" xml:space="preserve">
|
||||
<source>Abort</source>
|
||||
<target>Abbrechen</target>
|
||||
<target>Beenden</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Abort changing address" xml:space="preserve">
|
||||
<source>Abort changing address</source>
|
||||
<target>Wechsel der Empfängeradresse abbrechen</target>
|
||||
<target>Wechsel der Empfängeradresse beenden</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Abort changing address?" xml:space="preserve">
|
||||
<source>Abort changing address?</source>
|
||||
<target>Wechsel der Empfängeradresse abbrechen?</target>
|
||||
<target>Wechsel der Empfängeradresse beenden?</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="About SimpleX" xml:space="preserve">
|
||||
@@ -566,7 +565,8 @@
|
||||
<source>Accept</source>
|
||||
<target>Annehmen</target>
|
||||
<note>accept contact request via notification
|
||||
accept incoming call via notification</note>
|
||||
accept incoming call via notification
|
||||
swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Accept connection request?" xml:space="preserve">
|
||||
<source>Accept connection request?</source>
|
||||
@@ -581,7 +581,8 @@
|
||||
<trans-unit id="Accept incognito" xml:space="preserve">
|
||||
<source>Accept incognito</source>
|
||||
<target>Inkognito akzeptieren</target>
|
||||
<note>accept contact request via notification</note>
|
||||
<note>accept contact request via notification
|
||||
swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Acknowledged" xml:space="preserve">
|
||||
<source>Acknowledged</source>
|
||||
@@ -660,7 +661,7 @@
|
||||
</trans-unit>
|
||||
<trans-unit id="Address change will be aborted. Old receiving address will be used." xml:space="preserve">
|
||||
<source>Address change will be aborted. Old receiving address will be used.</source>
|
||||
<target>Der Wechsel der Empfängeradresse wird abgebrochen. Die bisherige Adresse wird weiter verwendet.</target>
|
||||
<target>Der Wechsel der Empfängeradresse wird beendet. Die bisherige Adresse wird weiter verwendet.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Admins can block a member for all." xml:space="preserve">
|
||||
@@ -755,6 +756,7 @@
|
||||
</trans-unit>
|
||||
<trans-unit id="Allow calls?" xml:space="preserve">
|
||||
<source>Allow calls?</source>
|
||||
<target>Anrufe erlauben?</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Allow disappearing messages only if your contact allows it to you." xml:space="preserve">
|
||||
@@ -947,8 +949,14 @@
|
||||
<target>Archivieren und Hochladen</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Archive contacts to chat later." xml:space="preserve">
|
||||
<source>Archive contacts to chat later.</source>
|
||||
<target>Kontakte für spätere Chats archivieren.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Archived contacts" xml:space="preserve">
|
||||
<source>Archived contacts</source>
|
||||
<target>Archivierte Kontakte</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Archiving database" xml:space="preserve">
|
||||
@@ -1051,6 +1059,11 @@
|
||||
<target>Verbesserungen bei Nachrichten</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Better networking" xml:space="preserve">
|
||||
<source>Better networking</source>
|
||||
<target>Kontrollieren Sie Ihr Netzwerk</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Black" xml:space="preserve">
|
||||
<source>Black</source>
|
||||
<target>Schwarz</target>
|
||||
@@ -1091,6 +1104,11 @@
|
||||
<target>wurde vom Administrator blockiert</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Blur for better privacy." xml:space="preserve">
|
||||
<source>Blur for better privacy.</source>
|
||||
<target>Für bessere Privatsphäre verpixeln.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Blur media" xml:space="preserve">
|
||||
<source>Blur media</source>
|
||||
<target>Medium unscharf machen</target>
|
||||
@@ -1143,6 +1161,7 @@
|
||||
</trans-unit>
|
||||
<trans-unit id="Calls prohibited!" xml:space="preserve">
|
||||
<source>Calls prohibited!</source>
|
||||
<target>Anrufe nicht zugelassen!</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Camera not available" xml:space="preserve">
|
||||
@@ -1152,10 +1171,12 @@
|
||||
</trans-unit>
|
||||
<trans-unit id="Can't call contact" xml:space="preserve">
|
||||
<source>Can't call contact</source>
|
||||
<target>Kontakt kann nicht angerufen werden</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Can't call member" xml:space="preserve">
|
||||
<source>Can't call member</source>
|
||||
<target>Mitglied kann nicht angerufen werden</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Can't invite contact!" xml:space="preserve">
|
||||
@@ -1170,6 +1191,7 @@
|
||||
</trans-unit>
|
||||
<trans-unit id="Can't message member" xml:space="preserve">
|
||||
<source>Can't message member</source>
|
||||
<target>Mitglied kann nicht benachrichtigt werden</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Cancel" xml:space="preserve">
|
||||
@@ -1308,6 +1330,11 @@
|
||||
<target>Der Chat ist angehalten. Wenn Sie diese Datenbank bereits auf einem anderen Gerät genutzt haben, sollten Sie diese vor dem Starten des Chats wieder zurückspielen.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Chat list" xml:space="preserve">
|
||||
<source>Chat list</source>
|
||||
<target>Chat-Liste</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Chat migrated!" xml:space="preserve">
|
||||
<source>Chat migrated!</source>
|
||||
<target>Chat wurde migriert!</target>
|
||||
@@ -1371,7 +1398,7 @@
|
||||
<trans-unit id="Clear" xml:space="preserve">
|
||||
<source>Clear</source>
|
||||
<target>Löschen</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
<note>swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Clear conversation" xml:space="preserve">
|
||||
<source>Clear conversation</source>
|
||||
@@ -1393,6 +1420,11 @@
|
||||
<target>Überprüfung zurücknehmen</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Color chats with the new themes." xml:space="preserve">
|
||||
<source>Color chats with the new themes.</source>
|
||||
<target>Farbige Chats mit neuen Designs.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Color mode" xml:space="preserve">
|
||||
<source>Color mode</source>
|
||||
<target>Farbvariante</target>
|
||||
@@ -1435,6 +1467,7 @@
|
||||
</trans-unit>
|
||||
<trans-unit id="Confirm contact deletion?" xml:space="preserve">
|
||||
<source>Confirm contact deletion?</source>
|
||||
<target>Löschen des Kontakts bestätigen?</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Confirm database upgrades" xml:space="preserve">
|
||||
@@ -1492,8 +1525,9 @@
|
||||
<target>Mit dem Desktop verbinden</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Connect to your friends faster" xml:space="preserve">
|
||||
<source>Connect to your friends faster</source>
|
||||
<trans-unit id="Connect to your friends faster." xml:space="preserve">
|
||||
<source>Connect to your friends faster.</source>
|
||||
<target>Schneller mit Ihren Freunden verbinden.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Connect to yourself?" xml:space="preserve">
|
||||
@@ -1572,6 +1606,7 @@ Das ist Ihr eigener Einmal-Link!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Connecting to contact, please wait or check later!" xml:space="preserve">
|
||||
<source>Connecting to contact, please wait or check later!</source>
|
||||
<target>Verbinde mit Kontakt, bitte warten oder später erneut überprüfen!</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Connecting to desktop" xml:space="preserve">
|
||||
@@ -1586,6 +1621,7 @@ Das ist Ihr eigener Einmal-Link!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Connection and servers status." xml:space="preserve">
|
||||
<source>Connection and servers status.</source>
|
||||
<target>Verbindungs- und Server-Status.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Connection error" xml:space="preserve">
|
||||
@@ -1640,6 +1676,7 @@ Das ist Ihr eigener Einmal-Link!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Contact deleted!" xml:space="preserve">
|
||||
<source>Contact deleted!</source>
|
||||
<target>Kontakt gelöscht!</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Contact hidden:" xml:space="preserve">
|
||||
@@ -1654,6 +1691,7 @@ Das ist Ihr eigener Einmal-Link!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Contact is deleted." xml:space="preserve">
|
||||
<source>Contact is deleted.</source>
|
||||
<target>Kontakt wurde gelöscht.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Contact name" xml:space="preserve">
|
||||
@@ -1668,6 +1706,7 @@ Das ist Ihr eigener Einmal-Link!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Contact will be deleted - this cannot be undone!" xml:space="preserve">
|
||||
<source>Contact will be deleted - this cannot be undone!</source>
|
||||
<target>Kontakt wird gelöscht. Dies kann nicht rückgängig gemacht werden!</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Contacts" xml:space="preserve">
|
||||
@@ -1685,12 +1724,9 @@ Das ist Ihr eigener Einmal-Link!</target>
|
||||
<target>Weiter</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Control your network" xml:space="preserve">
|
||||
<source>Control your network</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Conversation deleted!" xml:space="preserve">
|
||||
<source>Conversation deleted!</source>
|
||||
<target>Unterhaltung gelöscht!</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Copy" xml:space="preserve">
|
||||
@@ -1708,6 +1744,10 @@ Das ist Ihr eigener Einmal-Link!</target>
|
||||
<target>Core Version: v%@</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Corner" xml:space="preserve">
|
||||
<source>Corner</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Correct name to %@?" xml:space="preserve">
|
||||
<source>Correct name to %@?</source>
|
||||
<target>Richtiger Name für %@?</target>
|
||||
@@ -1964,7 +2004,8 @@ Das ist Ihr eigener Einmal-Link!</target>
|
||||
<trans-unit id="Delete" xml:space="preserve">
|
||||
<source>Delete</source>
|
||||
<target>Löschen</target>
|
||||
<note>chat item action</note>
|
||||
<note>chat item action
|
||||
swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Delete %lld messages of members?" xml:space="preserve">
|
||||
<source>Delete %lld messages of members?</source>
|
||||
@@ -2033,6 +2074,7 @@ Das ist Ihr eigener Einmal-Link!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Delete contact?" xml:space="preserve">
|
||||
<source>Delete contact?</source>
|
||||
<target>Kontakt löschen?</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Delete database" xml:space="preserve">
|
||||
@@ -2142,6 +2184,7 @@ Das ist Ihr eigener Einmal-Link!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Delete up to 20 messages at once." xml:space="preserve">
|
||||
<source>Delete up to 20 messages at once.</source>
|
||||
<target>Löschen Sie bis zu 20 Nachrichten auf einmal.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Delete user profile?" xml:space="preserve">
|
||||
@@ -2151,6 +2194,7 @@ Das ist Ihr eigener Einmal-Link!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Delete without notification" xml:space="preserve">
|
||||
<source>Delete without notification</source>
|
||||
<target>Ohne Benachrichtigung löschen</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Deleted" xml:space="preserve">
|
||||
@@ -2168,10 +2212,6 @@ Das ist Ihr eigener Einmal-Link!</target>
|
||||
<target>Gelöscht um: %@</target>
|
||||
<note>copied message info</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Deleted chats" xml:space="preserve">
|
||||
<source>Deleted chats</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Deletion errors" xml:space="preserve">
|
||||
<source>Deletion errors</source>
|
||||
<target>Fehler beim Löschen</target>
|
||||
@@ -2244,6 +2284,7 @@ Das ist Ihr eigener Einmal-Link!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Developer options" xml:space="preserve">
|
||||
<source>Developer options</source>
|
||||
<target>Optionen für Entwickler</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Developer tools" xml:space="preserve">
|
||||
@@ -2668,7 +2709,7 @@ Das ist Ihr eigener Einmal-Link!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Error aborting address change" xml:space="preserve">
|
||||
<source>Error aborting address change</source>
|
||||
<target>Fehler beim Abbrechen des Adresswechsels</target>
|
||||
<target>Fehler beim Beenden des Adresswechsels</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Error accepting contact request" xml:space="preserve">
|
||||
@@ -2691,6 +2732,10 @@ Das ist Ihr eigener Einmal-Link!</target>
|
||||
<target>Fehler beim Wechseln der Empfängeradresse</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Error changing connection profile" xml:space="preserve">
|
||||
<source>Error changing connection profile</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Error changing role" xml:space="preserve">
|
||||
<source>Error changing role</source>
|
||||
<target>Fehler beim Ändern der Rolle</target>
|
||||
@@ -2701,6 +2746,10 @@ Das ist Ihr eigener Einmal-Link!</target>
|
||||
<target>Fehler beim Ändern der Einstellung</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Error changing to incognito!" xml:space="preserve">
|
||||
<source>Error changing to incognito!</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Error connecting to forwarding server %@. Please try later." xml:space="preserve">
|
||||
<source>Error connecting to forwarding server %@. Please try later.</source>
|
||||
<target>Fehler beim Verbinden mit dem Weiterleitungsserver %@. Bitte versuchen Sie es später erneut.</target>
|
||||
@@ -2921,6 +2970,10 @@ Das ist Ihr eigener Einmal-Link!</target>
|
||||
<target>Fehler beim Beenden des Chats</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Error switching profile" xml:space="preserve">
|
||||
<source>Error switching profile</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Error switching profile!" xml:space="preserve">
|
||||
<source>Error switching profile!</source>
|
||||
<target>Fehler beim Umschalten des Profils!</target>
|
||||
@@ -2992,10 +3045,6 @@ Das ist Ihr eigener Einmal-Link!</target>
|
||||
<target>Auch wenn sie im Chat deaktiviert sind.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Even when they are offline." xml:space="preserve">
|
||||
<source>Even when they are offline.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Exit without saving" xml:space="preserve">
|
||||
<source>Exit without saving</source>
|
||||
<target>Beenden ohne Speichern</target>
|
||||
@@ -3054,7 +3103,7 @@ Das ist Ihr eigener Einmal-Link!</target>
|
||||
<trans-unit id="Favorite" xml:space="preserve">
|
||||
<source>Favorite</source>
|
||||
<target>Favorit</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
<note>swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="File error" xml:space="preserve">
|
||||
<source>File error</source>
|
||||
@@ -3810,6 +3859,7 @@ Fehler: %2$@</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="It protects your IP address and connections." xml:space="preserve">
|
||||
<source>It protects your IP address and connections.</source>
|
||||
<target>Ihre IP-Adresse und Verbindungen werden geschützt.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</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">
|
||||
@@ -3830,7 +3880,7 @@ Fehler: %2$@</target>
|
||||
<trans-unit id="Join" xml:space="preserve">
|
||||
<source>Join</source>
|
||||
<target>Beitreten</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
<note>swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Join group" xml:space="preserve">
|
||||
<source>Join group</source>
|
||||
@@ -3876,6 +3926,7 @@ Das ist Ihr Link für die Gruppe %@!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Keep conversation" xml:space="preserve">
|
||||
<source>Keep conversation</source>
|
||||
<target>Unterhaltung behalten</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">
|
||||
@@ -3921,7 +3972,7 @@ Das ist Ihr Link für die Gruppe %@!</target>
|
||||
<trans-unit id="Leave" xml:space="preserve">
|
||||
<source>Leave</source>
|
||||
<target>Verlassen</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
<note>swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Leave group" xml:space="preserve">
|
||||
<source>Leave group</source>
|
||||
@@ -4153,6 +4204,10 @@ Das ist Ihr Link für die Gruppe %@!</target>
|
||||
<target>Nachrichten-Server</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message shape" xml:space="preserve">
|
||||
<source>Message shape</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message source remains private." xml:space="preserve">
|
||||
<source>Message source remains private.</source>
|
||||
<target>Die Nachrichtenquelle bleibt privat.</target>
|
||||
@@ -4278,10 +4333,6 @@ Das ist Ihr Link für die Gruppe %@!</target>
|
||||
<target>Moderieren</target>
|
||||
<note>chat item action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Moderate like a pro ✋" xml:space="preserve">
|
||||
<source>Moderate like a pro ✋</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Moderated at" xml:space="preserve">
|
||||
<source>Moderated at</source>
|
||||
<target>Moderiert um</target>
|
||||
@@ -4315,7 +4366,7 @@ Das ist Ihr Link für die Gruppe %@!</target>
|
||||
<trans-unit id="Mute" xml:space="preserve">
|
||||
<source>Mute</source>
|
||||
<target>Stummschalten</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
<note>swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Muted when inactive!" xml:space="preserve">
|
||||
<source>Muted when inactive!</source>
|
||||
@@ -4325,7 +4376,7 @@ Das ist Ihr Link für die Gruppe %@!</target>
|
||||
<trans-unit id="Name" xml:space="preserve">
|
||||
<source>Name</source>
|
||||
<target>Name</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
<note>swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Network & servers" xml:space="preserve">
|
||||
<source>Network & servers</source>
|
||||
@@ -4357,10 +4408,6 @@ Das ist Ihr Link für die Gruppe %@!</target>
|
||||
<target>Netzwerkstatus</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="New Chat" xml:space="preserve">
|
||||
<source>New Chat</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="New Passcode" xml:space="preserve">
|
||||
<source>New Passcode</source>
|
||||
<target>Neuer Zugangscode</target>
|
||||
@@ -4371,6 +4418,11 @@ Das ist Ihr Link für die Gruppe %@!</target>
|
||||
<target>Neuer Chat</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="New chat experience 🎉" xml:space="preserve">
|
||||
<source>New chat experience 🎉</source>
|
||||
<target>Neue Chat-Erfahrung 🎉</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="New contact request" xml:space="preserve">
|
||||
<source>New contact request</source>
|
||||
<target>Neue Kontaktanfrage</target>
|
||||
@@ -4401,6 +4453,11 @@ Das ist Ihr Link für die Gruppe %@!</target>
|
||||
<target>Neu in %@</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="New media options" xml:space="preserve">
|
||||
<source>New media options</source>
|
||||
<target>Neue Medien-Optionen</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="New member role" xml:space="preserve">
|
||||
<source>New member role</source>
|
||||
<target>Neue Mitgliedsrolle</target>
|
||||
@@ -4540,10 +4597,6 @@ Das ist Ihr Link für die Gruppe %@!</target>
|
||||
<target>Altes Datenbankarchiv</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="One-hand UI" xml:space="preserve">
|
||||
<source>One-hand UI</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="One-time invitation link" xml:space="preserve">
|
||||
<source>One-time invitation link</source>
|
||||
<target>Einmal-Einladungslink</target>
|
||||
@@ -4575,6 +4628,7 @@ Dies erfordert die Aktivierung eines VPNs.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Only delete conversation" xml:space="preserve">
|
||||
<source>Only delete conversation</source>
|
||||
<target>Nur die Unterhaltung löschen</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Only group owners can change group preferences." xml:space="preserve">
|
||||
@@ -4812,8 +4866,14 @@ Dies erfordert die Aktivierung eines VPNs.</target>
|
||||
<target>Bild-in-Bild-Anrufe</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Play from the chat list." xml:space="preserve">
|
||||
<source>Play from the chat list.</source>
|
||||
<target>Direkt aus der Chat-Liste abspielen.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Please ask your contact to enable calls." xml:space="preserve">
|
||||
<source>Please ask your contact to enable calls.</source>
|
||||
<target>Bitten Sie Ihren Kontakt darum, Anrufe zu aktivieren.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Please ask your contact to enable sending voice messages." xml:space="preserve">
|
||||
@@ -5117,8 +5177,9 @@ Aktivieren Sie es in den *Netzwerk & Server* Einstellungen.</target>
|
||||
<target>Bewerten Sie die App</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Reachable chat toolbar 👋" xml:space="preserve">
|
||||
<source>Reachable chat toolbar 👋</source>
|
||||
<trans-unit id="Reachable chat toolbar" xml:space="preserve">
|
||||
<source>Reachable chat toolbar</source>
|
||||
<target>Erreichbare Chat-Symbolleiste</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="React…" xml:space="preserve">
|
||||
@@ -5129,7 +5190,7 @@ Aktivieren Sie es in den *Netzwerk & Server* Einstellungen.</target>
|
||||
<trans-unit id="Read" xml:space="preserve">
|
||||
<source>Read</source>
|
||||
<target>Gelesen</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
<note>swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Read more" xml:space="preserve">
|
||||
<source>Read more</source>
|
||||
@@ -5289,7 +5350,8 @@ Aktivieren Sie es in den *Netzwerk & Server* Einstellungen.</target>
|
||||
<trans-unit id="Reject" xml:space="preserve">
|
||||
<source>Reject</source>
|
||||
<target>Ablehnen</target>
|
||||
<note>reject incoming call via notification</note>
|
||||
<note>reject incoming call via notification
|
||||
swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Reject (sender NOT notified)" xml:space="preserve">
|
||||
<source>Reject (sender NOT notified)</source>
|
||||
@@ -5391,6 +5453,11 @@ Aktivieren Sie es in den *Netzwerk & Server* Einstellungen.</target>
|
||||
<target>Zurücksetzen</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Reset all hints" xml:space="preserve">
|
||||
<source>Reset all hints</source>
|
||||
<target>Alle Hinweise zurücksetzen</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Reset all statistics" xml:space="preserve">
|
||||
<source>Reset all statistics</source>
|
||||
<target>Alle Statistiken zurücksetzen</target>
|
||||
@@ -5686,6 +5753,10 @@ Aktivieren Sie es in den *Netzwerk & Server* Einstellungen.</target>
|
||||
<target>Auswählen</target>
|
||||
<note>chat item action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Select chat profile" xml:space="preserve">
|
||||
<source>Select chat profile</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Selected %lld" xml:space="preserve">
|
||||
<source>Selected %lld</source>
|
||||
<target>%lld ausgewählt</target>
|
||||
@@ -5758,6 +5829,7 @@ Aktivieren Sie es in den *Netzwerk & Server* Einstellungen.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Send message to enable calls." xml:space="preserve">
|
||||
<source>Send message to enable calls.</source>
|
||||
<target>Nachricht senden, um Anrufe zu aktivieren.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Send messages directly when IP address is protected and your or destination server does not support private routing." xml:space="preserve">
|
||||
@@ -6045,11 +6117,20 @@ Aktivieren Sie es in den *Netzwerk & Server* Einstellungen.</target>
|
||||
<target>Die Adresse mit Kontakten teilen?</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Share from other apps." xml:space="preserve">
|
||||
<source>Share from other apps.</source>
|
||||
<target>Aus anderen Apps heraus teilen.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Share link" xml:space="preserve">
|
||||
<source>Share link</source>
|
||||
<target>Link teilen</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Share profile" xml:space="preserve">
|
||||
<source>Share profile</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Share this 1-time invite link" xml:space="preserve">
|
||||
<source>Share this 1-time invite link</source>
|
||||
<target>Teilen Sie diesen Einmal-Einladungslink</target>
|
||||
@@ -6390,6 +6471,10 @@ Aktivieren Sie es in den *Netzwerk & Server* Einstellungen.</target>
|
||||
<target>TCP_KEEPINTVL</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Tail" xml:space="preserve">
|
||||
<source>Tail</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Take picture" xml:space="preserve">
|
||||
<source>Take picture</source>
|
||||
<target>Machen Sie ein Foto</target>
|
||||
@@ -6729,11 +6814,21 @@ Sie werden aufgefordert, die Authentifizierung abzuschließen, bevor diese Funkt
|
||||
<target>Um die Ende-zu-Ende-Verschlüsselung mit Ihrem Kontakt zu überprüfen, müssen Sie den Sicherheitscode in Ihren Apps vergleichen oder scannen.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Toggle chat list:" xml:space="preserve">
|
||||
<source>Toggle chat list:</source>
|
||||
<target>Chat-Liste umschalten:</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Toggle incognito when connecting." xml:space="preserve">
|
||||
<source>Toggle incognito when connecting.</source>
|
||||
<target>Inkognito beim Verbinden einschalten.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Toolbar opacity" xml:space="preserve">
|
||||
<source>Toolbar opacity</source>
|
||||
<target>Deckkraft der Symbolleiste</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Total" xml:space="preserve">
|
||||
<source>Total</source>
|
||||
<target>Summe aller Abonnements</target>
|
||||
@@ -6812,7 +6907,7 @@ Sie werden aufgefordert, die Authentifizierung abzuschließen, bevor diese Funkt
|
||||
<trans-unit id="Unfav." xml:space="preserve">
|
||||
<source>Unfav.</source>
|
||||
<target>Fav. entf.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
<note>swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Unhide" xml:space="preserve">
|
||||
<source>Unhide</source>
|
||||
@@ -6889,12 +6984,12 @@ Bitten Sie Ihren Kontakt darum einen weiteren Verbindungs-Link zu erzeugen, um s
|
||||
<trans-unit id="Unmute" xml:space="preserve">
|
||||
<source>Unmute</source>
|
||||
<target>Stummschaltung aufheben</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
<note>swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Unread" xml:space="preserve">
|
||||
<source>Unread</source>
|
||||
<target>Ungelesen</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
<note>swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Up to 100 last messages are sent to new members." xml:space="preserve">
|
||||
<source>Up to 100 last messages are sent to new members.</source>
|
||||
@@ -7028,6 +7123,7 @@ Bitten Sie Ihren Kontakt darum einen weiteren Verbindungs-Link zu erzeugen, um s
|
||||
</trans-unit>
|
||||
<trans-unit id="Use the app with one hand." xml:space="preserve">
|
||||
<source>Use the app with one hand.</source>
|
||||
<target>Die App mit einer Hand nutzen.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="User profile" xml:space="preserve">
|
||||
@@ -7387,6 +7483,11 @@ Verbindungsanfrage wiederholen?</target>
|
||||
<target>Sie können Anrufe ohne Geräte- und App-Authentifizierung vom Sperrbildschirm aus annehmen.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="You can change it in Appearance settings." xml:space="preserve">
|
||||
<source>You can change it in Appearance settings.</source>
|
||||
<target>Kann von Ihnen in den Erscheinungsbild-Einstellungen geändert werden.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="You can create it later" xml:space="preserve">
|
||||
<source>You can create it later</source>
|
||||
<target>Sie können dies später erstellen</target>
|
||||
@@ -7424,6 +7525,7 @@ Verbindungsanfrage wiederholen?</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="You can send messages to %@ from Archived contacts." xml:space="preserve">
|
||||
<source>You can send messages to %@ from Archived contacts.</source>
|
||||
<target>Sie können aus den archivierten Kontakten heraus Nachrichten an %@ versenden.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="You can set lock screen notification preview via settings." xml:space="preserve">
|
||||
@@ -7453,6 +7555,7 @@ Verbindungsanfrage wiederholen?</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="You can still view conversation with %@ in the list of chats." xml:space="preserve">
|
||||
<source>You can still view conversation with %@ in the list of chats.</source>
|
||||
<target>Sie können in der Chatliste weiterhin die Unterhaltung mit %@ einsehen.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="You can turn on SimpleX Lock via Settings." xml:space="preserve">
|
||||
@@ -7534,6 +7637,7 @@ Verbindungsanfrage wiederholen?</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="You need to allow your contact to call to be able to call them." xml:space="preserve">
|
||||
<source>You need to allow your contact to call to be able to call them.</source>
|
||||
<target>Sie müssen Ihrem Kontakt Anrufe zu Ihnen erlauben, bevor Sie ihn selbst anrufen können.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="You need to allow your contact to send voice messages to be able to send them." xml:space="preserve">
|
||||
@@ -7651,6 +7755,10 @@ Verbindungsanfrage wiederholen?</target>
|
||||
<target>Ihre Chat-Profile</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Your connection was moved to %@ but an unexpected error occurred while redirecting you to the profile." xml:space="preserve">
|
||||
<source>Your connection was moved to %@ but an unexpected error occurred while redirecting you to the profile.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Your contact sent a file that is larger than currently supported maximum size (%@)." xml:space="preserve">
|
||||
<source>Your contact sent a file that is larger than currently supported maximum size (%@).</source>
|
||||
<target>Ihr Kontakt hat eine Datei gesendet, die größer ist als die derzeit unterstützte maximale Größe (%@).</target>
|
||||
@@ -7666,10 +7774,6 @@ Verbindungsanfrage wiederholen?</target>
|
||||
<target>Ihre Kontakte bleiben weiterhin verbunden.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Your contacts your way" xml:space="preserve">
|
||||
<source>Your contacts your way</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Your current chat database will be DELETED and REPLACED with the imported one." xml:space="preserve">
|
||||
<source>Your current chat database will be DELETED and REPLACED with the imported one.</source>
|
||||
<target>Ihre aktuelle Chat-Datenbank wird GELÖSCHT und durch die Importierte ERSETZT.</target>
|
||||
@@ -7849,6 +7953,7 @@ SimpleX-Server können Ihr Profil nicht einsehen.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="call" xml:space="preserve">
|
||||
<source>call</source>
|
||||
<target>Anrufen</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="call error" xml:space="preserve">
|
||||
@@ -8223,6 +8328,7 @@ SimpleX-Server können Ihr Profil nicht einsehen.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="invite" xml:space="preserve">
|
||||
<source>invite</source>
|
||||
<target>Einladen</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="invited" xml:space="preserve">
|
||||
@@ -8282,6 +8388,7 @@ SimpleX-Server können Ihr Profil nicht einsehen.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="message" xml:space="preserve">
|
||||
<source>message</source>
|
||||
<target>Nachricht</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="message received" xml:space="preserve">
|
||||
@@ -8316,6 +8423,7 @@ SimpleX-Server können Ihr Profil nicht einsehen.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="mute" xml:space="preserve">
|
||||
<source>mute</source>
|
||||
<target>Stummschalten</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="never" xml:space="preserve">
|
||||
@@ -8452,6 +8560,7 @@ SimpleX-Server können Ihr Profil nicht einsehen.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="search" xml:space="preserve">
|
||||
<source>search</source>
|
||||
<target>Suchen</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="sec" xml:space="preserve">
|
||||
@@ -8540,6 +8649,7 @@ Zuletzt empfangene Nachricht: %2$@</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="unmute" xml:space="preserve">
|
||||
<source>unmute</source>
|
||||
<target>Stummschaltung aufheben</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="unprotected" xml:space="preserve">
|
||||
@@ -8589,6 +8699,7 @@ Zuletzt empfangene Nachricht: %2$@</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="video" xml:space="preserve">
|
||||
<source>video</source>
|
||||
<target>Video</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="video call (not e2e encrypted)" xml:space="preserve">
|
||||
@@ -8971,7 +9082,7 @@ Zuletzt empfangene Nachricht: %2$@</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="You can allow sharing in Privacy & Security / SimpleX Lock settings." xml:space="preserve">
|
||||
<source>You can allow sharing in Privacy & Security / SimpleX Lock settings.</source>
|
||||
<target>Du kannst das Teilen in den Einstellungen zu Datenschutz & Sicherheit bzw. SimpleX-Sperre erlauben.</target>
|
||||
<target>Du kannst das Teilen in den Einstellungen zu Datenschutz & Sicherheit - SimpleX-Sperre erlauben.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
</body>
|
||||
|
||||
@@ -137,6 +137,11 @@
|
||||
<target>%@ wants to connect!</target>
|
||||
<note>notification title</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="%@, %@" xml:space="preserve">
|
||||
<source>%1$@, %2$@</source>
|
||||
<target>%1$@, %2$@</target>
|
||||
<note>format for date separator in chat</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="%@, %@ and %lld members" xml:space="preserve">
|
||||
<source>%@, %@ and %lld members</source>
|
||||
<target>%@, %@ and %lld members</target>
|
||||
@@ -392,13 +397,6 @@
|
||||
<target>, </target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="- Search contacts when starting chat. - Archive contacts to chat later." xml:space="preserve">
|
||||
<source>- Search contacts when starting chat.
|
||||
- Archive contacts to chat later.</source>
|
||||
<target>- Search contacts when starting chat.
|
||||
- Archive contacts to chat later.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="- connect to [directory service](simplex:/contact#/?v=1-4&smp=smp%3A%2F%2Fu2dS9sG8nMNURyZwqASV4yROM28Er0luVTx5X1CsMrU%3D%40smp4.simplex.im%2FeXSPwqTkKyDO3px4fLf1wx3MvPdjdLW3%23%2F%3Fv%3D1-2%26dh%3DMCowBQYDK2VuAyEAaiv6MkMH44L2TcYrt_CsX3ZvM11WgbMEUn0hkIKTOho%253D%26srv%3Do5vmywmrnaxalvz6wi3zicyftgio6psuvyniis6gco6bp6ekl4cqj4id.onion) (BETA)! - delivery receipts (up to 20 members). - faster and more stable." xml:space="preserve">
|
||||
<source>- connect to [directory service](simplex:/contact#/?v=1-4&smp=smp%3A%2F%2Fu2dS9sG8nMNURyZwqASV4yROM28Er0luVTx5X1CsMrU%3D%40smp4.simplex.im%2FeXSPwqTkKyDO3px4fLf1wx3MvPdjdLW3%23%2F%3Fv%3D1-2%26dh%3DMCowBQYDK2VuAyEAaiv6MkMH44L2TcYrt_CsX3ZvM11WgbMEUn0hkIKTOho%253D%26srv%3Do5vmywmrnaxalvz6wi3zicyftgio6psuvyniis6gco6bp6ekl4cqj4id.onion) (BETA)!
|
||||
- delivery receipts (up to 20 members).
|
||||
@@ -568,7 +566,8 @@
|
||||
<source>Accept</source>
|
||||
<target>Accept</target>
|
||||
<note>accept contact request via notification
|
||||
accept incoming call via notification</note>
|
||||
accept incoming call via notification
|
||||
swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Accept connection request?" xml:space="preserve">
|
||||
<source>Accept connection request?</source>
|
||||
@@ -583,7 +582,8 @@
|
||||
<trans-unit id="Accept incognito" xml:space="preserve">
|
||||
<source>Accept incognito</source>
|
||||
<target>Accept incognito</target>
|
||||
<note>accept contact request via notification</note>
|
||||
<note>accept contact request via notification
|
||||
swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Acknowledged" xml:space="preserve">
|
||||
<source>Acknowledged</source>
|
||||
@@ -950,6 +950,11 @@
|
||||
<target>Archive and upload</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Archive contacts to chat later." xml:space="preserve">
|
||||
<source>Archive contacts to chat later.</source>
|
||||
<target>Archive contacts to chat later.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Archived contacts" xml:space="preserve">
|
||||
<source>Archived contacts</source>
|
||||
<target>Archived contacts</target>
|
||||
@@ -1055,6 +1060,11 @@
|
||||
<target>Better messages</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Better networking" xml:space="preserve">
|
||||
<source>Better networking</source>
|
||||
<target>Better networking</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Black" xml:space="preserve">
|
||||
<source>Black</source>
|
||||
<target>Black</target>
|
||||
@@ -1095,6 +1105,11 @@
|
||||
<target>Blocked by admin</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Blur for better privacy." xml:space="preserve">
|
||||
<source>Blur for better privacy.</source>
|
||||
<target>Blur for better privacy.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Blur media" xml:space="preserve">
|
||||
<source>Blur media</source>
|
||||
<target>Blur media</target>
|
||||
@@ -1316,6 +1331,11 @@
|
||||
<target>Chat is stopped. If you already used this database on another device, you should transfer it back before starting chat.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Chat list" xml:space="preserve">
|
||||
<source>Chat list</source>
|
||||
<target>Chat list</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Chat migrated!" xml:space="preserve">
|
||||
<source>Chat migrated!</source>
|
||||
<target>Chat migrated!</target>
|
||||
@@ -1379,7 +1399,7 @@
|
||||
<trans-unit id="Clear" xml:space="preserve">
|
||||
<source>Clear</source>
|
||||
<target>Clear</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
<note>swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Clear conversation" xml:space="preserve">
|
||||
<source>Clear conversation</source>
|
||||
@@ -1401,6 +1421,11 @@
|
||||
<target>Clear verification</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Color chats with the new themes." xml:space="preserve">
|
||||
<source>Color chats with the new themes.</source>
|
||||
<target>Color chats with the new themes.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Color mode" xml:space="preserve">
|
||||
<source>Color mode</source>
|
||||
<target>Color mode</target>
|
||||
@@ -1501,9 +1526,9 @@
|
||||
<target>Connect to desktop</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Connect to your friends faster" xml:space="preserve">
|
||||
<source>Connect to your friends faster</source>
|
||||
<target>Connect to your friends faster</target>
|
||||
<trans-unit id="Connect to your friends faster." xml:space="preserve">
|
||||
<source>Connect to your friends faster.</source>
|
||||
<target>Connect to your friends faster.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Connect to yourself?" xml:space="preserve">
|
||||
@@ -1700,11 +1725,6 @@ This is your own one-time link!</target>
|
||||
<target>Continue</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Control your network" xml:space="preserve">
|
||||
<source>Control your network</source>
|
||||
<target>Control your network</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Conversation deleted!" xml:space="preserve">
|
||||
<source>Conversation deleted!</source>
|
||||
<target>Conversation deleted!</target>
|
||||
@@ -1725,6 +1745,11 @@ This is your own one-time link!</target>
|
||||
<target>Core version: v%@</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Corner" xml:space="preserve">
|
||||
<source>Corner</source>
|
||||
<target>Corner</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Correct name to %@?" xml:space="preserve">
|
||||
<source>Correct name to %@?</source>
|
||||
<target>Correct name to %@?</target>
|
||||
@@ -1981,7 +2006,8 @@ This is your own one-time link!</target>
|
||||
<trans-unit id="Delete" xml:space="preserve">
|
||||
<source>Delete</source>
|
||||
<target>Delete</target>
|
||||
<note>chat item action</note>
|
||||
<note>chat item action
|
||||
swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Delete %lld messages of members?" xml:space="preserve">
|
||||
<source>Delete %lld messages of members?</source>
|
||||
@@ -2188,11 +2214,6 @@ This is your own one-time link!</target>
|
||||
<target>Deleted at: %@</target>
|
||||
<note>copied message info</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Deleted chats" xml:space="preserve">
|
||||
<source>Deleted chats</source>
|
||||
<target>Deleted chats</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Deletion errors" xml:space="preserve">
|
||||
<source>Deletion errors</source>
|
||||
<target>Deletion errors</target>
|
||||
@@ -2713,6 +2734,11 @@ This is your own one-time link!</target>
|
||||
<target>Error changing address</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Error changing connection profile" xml:space="preserve">
|
||||
<source>Error changing connection profile</source>
|
||||
<target>Error changing connection profile</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Error changing role" xml:space="preserve">
|
||||
<source>Error changing role</source>
|
||||
<target>Error changing role</target>
|
||||
@@ -2723,6 +2749,11 @@ This is your own one-time link!</target>
|
||||
<target>Error changing setting</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Error changing to incognito!" xml:space="preserve">
|
||||
<source>Error changing to incognito!</source>
|
||||
<target>Error changing to incognito!</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Error connecting to forwarding server %@. Please try later." xml:space="preserve">
|
||||
<source>Error connecting to forwarding server %@. Please try later.</source>
|
||||
<target>Error connecting to forwarding server %@. Please try later.</target>
|
||||
@@ -2943,6 +2974,11 @@ This is your own one-time link!</target>
|
||||
<target>Error stopping chat</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Error switching profile" xml:space="preserve">
|
||||
<source>Error switching profile</source>
|
||||
<target>Error switching profile</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Error switching profile!" xml:space="preserve">
|
||||
<source>Error switching profile!</source>
|
||||
<target>Error switching profile!</target>
|
||||
@@ -3014,11 +3050,6 @@ This is your own one-time link!</target>
|
||||
<target>Even when disabled in the conversation.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Even when they are offline." xml:space="preserve">
|
||||
<source>Even when they are offline.</source>
|
||||
<target>Even when they are offline.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Exit without saving" xml:space="preserve">
|
||||
<source>Exit without saving</source>
|
||||
<target>Exit without saving</target>
|
||||
@@ -3077,7 +3108,7 @@ This is your own one-time link!</target>
|
||||
<trans-unit id="Favorite" xml:space="preserve">
|
||||
<source>Favorite</source>
|
||||
<target>Favorite</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
<note>swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="File error" xml:space="preserve">
|
||||
<source>File error</source>
|
||||
@@ -3854,7 +3885,7 @@ Error: %2$@</target>
|
||||
<trans-unit id="Join" xml:space="preserve">
|
||||
<source>Join</source>
|
||||
<target>Join</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
<note>swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Join group" xml:space="preserve">
|
||||
<source>Join group</source>
|
||||
@@ -3946,7 +3977,7 @@ This is your link for group %@!</target>
|
||||
<trans-unit id="Leave" xml:space="preserve">
|
||||
<source>Leave</source>
|
||||
<target>Leave</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
<note>swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Leave group" xml:space="preserve">
|
||||
<source>Leave group</source>
|
||||
@@ -4178,6 +4209,11 @@ This is your link for group %@!</target>
|
||||
<target>Message servers</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message shape" xml:space="preserve">
|
||||
<source>Message shape</source>
|
||||
<target>Message shape</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message source remains private." xml:space="preserve">
|
||||
<source>Message source remains private.</source>
|
||||
<target>Message source remains private.</target>
|
||||
@@ -4303,11 +4339,6 @@ This is your link for group %@!</target>
|
||||
<target>Moderate</target>
|
||||
<note>chat item action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Moderate like a pro ✋" xml:space="preserve">
|
||||
<source>Moderate like a pro ✋</source>
|
||||
<target>Moderate like a pro ✋</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Moderated at" xml:space="preserve">
|
||||
<source>Moderated at</source>
|
||||
<target>Moderated at</target>
|
||||
@@ -4341,7 +4372,7 @@ This is your link for group %@!</target>
|
||||
<trans-unit id="Mute" xml:space="preserve">
|
||||
<source>Mute</source>
|
||||
<target>Mute</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
<note>swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Muted when inactive!" xml:space="preserve">
|
||||
<source>Muted when inactive!</source>
|
||||
@@ -4351,7 +4382,7 @@ This is your link for group %@!</target>
|
||||
<trans-unit id="Name" xml:space="preserve">
|
||||
<source>Name</source>
|
||||
<target>Name</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
<note>swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Network & servers" xml:space="preserve">
|
||||
<source>Network & servers</source>
|
||||
@@ -4383,11 +4414,6 @@ This is your link for group %@!</target>
|
||||
<target>Network status</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="New Chat" xml:space="preserve">
|
||||
<source>New Chat</source>
|
||||
<target>New Chat</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="New Passcode" xml:space="preserve">
|
||||
<source>New Passcode</source>
|
||||
<target>New Passcode</target>
|
||||
@@ -4398,6 +4424,11 @@ This is your link for group %@!</target>
|
||||
<target>New chat</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="New chat experience 🎉" xml:space="preserve">
|
||||
<source>New chat experience 🎉</source>
|
||||
<target>New chat experience 🎉</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="New contact request" xml:space="preserve">
|
||||
<source>New contact request</source>
|
||||
<target>New contact request</target>
|
||||
@@ -4428,6 +4459,11 @@ This is your link for group %@!</target>
|
||||
<target>New in %@</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="New media options" xml:space="preserve">
|
||||
<source>New media options</source>
|
||||
<target>New media options</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="New member role" xml:space="preserve">
|
||||
<source>New member role</source>
|
||||
<target>New member role</target>
|
||||
@@ -4567,11 +4603,6 @@ This is your link for group %@!</target>
|
||||
<target>Old database archive</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="One-hand UI" xml:space="preserve">
|
||||
<source>One-hand UI</source>
|
||||
<target>One-hand UI</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="One-time invitation link" xml:space="preserve">
|
||||
<source>One-time invitation link</source>
|
||||
<target>One-time invitation link</target>
|
||||
@@ -4841,6 +4872,11 @@ Requires compatible VPN.</target>
|
||||
<target>Picture-in-picture calls</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Play from the chat list." xml:space="preserve">
|
||||
<source>Play from the chat list.</source>
|
||||
<target>Play from the chat list.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Please ask your contact to enable calls." xml:space="preserve">
|
||||
<source>Please ask your contact to enable calls.</source>
|
||||
<target>Please ask your contact to enable calls.</target>
|
||||
@@ -5147,9 +5183,9 @@ Enable in *Network & servers* settings.</target>
|
||||
<target>Rate the app</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Reachable chat toolbar 👋" xml:space="preserve">
|
||||
<source>Reachable chat toolbar 👋</source>
|
||||
<target>Reachable chat toolbar 👋</target>
|
||||
<trans-unit id="Reachable chat toolbar" xml:space="preserve">
|
||||
<source>Reachable chat toolbar</source>
|
||||
<target>Reachable chat toolbar</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="React…" xml:space="preserve">
|
||||
@@ -5160,7 +5196,7 @@ Enable in *Network & servers* settings.</target>
|
||||
<trans-unit id="Read" xml:space="preserve">
|
||||
<source>Read</source>
|
||||
<target>Read</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
<note>swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Read more" xml:space="preserve">
|
||||
<source>Read more</source>
|
||||
@@ -5320,7 +5356,8 @@ Enable in *Network & servers* settings.</target>
|
||||
<trans-unit id="Reject" xml:space="preserve">
|
||||
<source>Reject</source>
|
||||
<target>Reject</target>
|
||||
<note>reject incoming call via notification</note>
|
||||
<note>reject incoming call via notification
|
||||
swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Reject (sender NOT notified)" xml:space="preserve">
|
||||
<source>Reject (sender NOT notified)</source>
|
||||
@@ -5422,6 +5459,11 @@ Enable in *Network & servers* settings.</target>
|
||||
<target>Reset</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Reset all hints" xml:space="preserve">
|
||||
<source>Reset all hints</source>
|
||||
<target>Reset all hints</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Reset all statistics" xml:space="preserve">
|
||||
<source>Reset all statistics</source>
|
||||
<target>Reset all statistics</target>
|
||||
@@ -5717,6 +5759,11 @@ Enable in *Network & servers* settings.</target>
|
||||
<target>Select</target>
|
||||
<note>chat item action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Select chat profile" xml:space="preserve">
|
||||
<source>Select chat profile</source>
|
||||
<target>Select chat profile</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Selected %lld" xml:space="preserve">
|
||||
<source>Selected %lld</source>
|
||||
<target>Selected %lld</target>
|
||||
@@ -6077,11 +6124,21 @@ Enable in *Network & servers* settings.</target>
|
||||
<target>Share address with contacts?</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Share from other apps." xml:space="preserve">
|
||||
<source>Share from other apps.</source>
|
||||
<target>Share from other apps.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Share link" xml:space="preserve">
|
||||
<source>Share link</source>
|
||||
<target>Share link</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Share profile" xml:space="preserve">
|
||||
<source>Share profile</source>
|
||||
<target>Share profile</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Share this 1-time invite link" xml:space="preserve">
|
||||
<source>Share this 1-time invite link</source>
|
||||
<target>Share this 1-time invite link</target>
|
||||
@@ -6422,6 +6479,11 @@ Enable in *Network & servers* settings.</target>
|
||||
<target>TCP_KEEPINTVL</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Tail" xml:space="preserve">
|
||||
<source>Tail</source>
|
||||
<target>Tail</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Take picture" xml:space="preserve">
|
||||
<source>Take picture</source>
|
||||
<target>Take picture</target>
|
||||
@@ -6761,11 +6823,21 @@ You will be prompted to complete authentication before this feature is enabled.<
|
||||
<target>To verify end-to-end encryption with your contact compare (or scan) the code on your devices.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Toggle chat list:" xml:space="preserve">
|
||||
<source>Toggle chat list:</source>
|
||||
<target>Toggle chat list:</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Toggle incognito when connecting." xml:space="preserve">
|
||||
<source>Toggle incognito when connecting.</source>
|
||||
<target>Toggle incognito when connecting.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Toolbar opacity" xml:space="preserve">
|
||||
<source>Toolbar opacity</source>
|
||||
<target>Toolbar opacity</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Total" xml:space="preserve">
|
||||
<source>Total</source>
|
||||
<target>Total</target>
|
||||
@@ -6844,7 +6916,7 @@ You will be prompted to complete authentication before this feature is enabled.<
|
||||
<trans-unit id="Unfav." xml:space="preserve">
|
||||
<source>Unfav.</source>
|
||||
<target>Unfav.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
<note>swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Unhide" xml:space="preserve">
|
||||
<source>Unhide</source>
|
||||
@@ -6921,12 +6993,12 @@ To connect, please ask your contact to create another connection link and check
|
||||
<trans-unit id="Unmute" xml:space="preserve">
|
||||
<source>Unmute</source>
|
||||
<target>Unmute</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
<note>swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Unread" xml:space="preserve">
|
||||
<source>Unread</source>
|
||||
<target>Unread</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
<note>swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Up to 100 last messages are sent to new members." xml:space="preserve">
|
||||
<source>Up to 100 last messages are sent to new members.</source>
|
||||
@@ -7420,6 +7492,11 @@ Repeat join request?</target>
|
||||
<target>You can accept calls from lock screen, without device and app authentication.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="You can change it in Appearance settings." xml:space="preserve">
|
||||
<source>You can change it in Appearance settings.</source>
|
||||
<target>You can change it in Appearance settings.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="You can create it later" xml:space="preserve">
|
||||
<source>You can create it later</source>
|
||||
<target>You can create it later</target>
|
||||
@@ -7687,6 +7764,11 @@ Repeat connection request?</target>
|
||||
<target>Your chat profiles</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Your connection was moved to %@ but an unexpected error occurred while redirecting you to the profile." xml:space="preserve">
|
||||
<source>Your connection was moved to %@ but an unexpected error occurred while redirecting you to the profile.</source>
|
||||
<target>Your connection was moved to %@ but an unexpected error occurred while redirecting you to the profile.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Your contact sent a file that is larger than currently supported maximum size (%@)." xml:space="preserve">
|
||||
<source>Your contact sent a file that is larger than currently supported maximum size (%@).</source>
|
||||
<target>Your contact sent a file that is larger than currently supported maximum size (%@).</target>
|
||||
@@ -7702,11 +7784,6 @@ Repeat connection request?</target>
|
||||
<target>Your contacts will remain connected.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Your contacts your way" xml:space="preserve">
|
||||
<source>Your contacts your way</source>
|
||||
<target>Your contacts your way</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Your current chat database will be DELETED and REPLACED with the imported one." xml:space="preserve">
|
||||
<source>Your current chat database will be DELETED and REPLACED with the imported one.</source>
|
||||
<target>Your current chat database will be DELETED and REPLACED with the imported one.</target>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -133,6 +133,10 @@
|
||||
<target>%@ haluaa muodostaa yhteyden!</target>
|
||||
<note>notification title</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="%@, %@" xml:space="preserve">
|
||||
<source>%1$@, %2$@</source>
|
||||
<note>format for date separator in chat</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="%@, %@ and %lld members" xml:space="preserve">
|
||||
<source>%@, %@ and %lld members</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -376,11 +380,6 @@
|
||||
<target>, </target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="- Search contacts when starting chat. - Archive contacts to chat later." xml:space="preserve">
|
||||
<source>- Search contacts when starting chat.
|
||||
- Archive contacts to chat later.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="- connect to [directory service](simplex:/contact#/?v=1-4&smp=smp%3A%2F%2Fu2dS9sG8nMNURyZwqASV4yROM28Er0luVTx5X1CsMrU%3D%40smp4.simplex.im%2FeXSPwqTkKyDO3px4fLf1wx3MvPdjdLW3%23%2F%3Fv%3D1-2%26dh%3DMCowBQYDK2VuAyEAaiv6MkMH44L2TcYrt_CsX3ZvM11WgbMEUn0hkIKTOho%253D%26srv%3Do5vmywmrnaxalvz6wi3zicyftgio6psuvyniis6gco6bp6ekl4cqj4id.onion) (BETA)! - delivery receipts (up to 20 members). - faster and more stable." xml:space="preserve">
|
||||
<source>- connect to [directory service](simplex:/contact#/?v=1-4&smp=smp%3A%2F%2Fu2dS9sG8nMNURyZwqASV4yROM28Er0luVTx5X1CsMrU%3D%40smp4.simplex.im%2FeXSPwqTkKyDO3px4fLf1wx3MvPdjdLW3%23%2F%3Fv%3D1-2%26dh%3DMCowBQYDK2VuAyEAaiv6MkMH44L2TcYrt_CsX3ZvM11WgbMEUn0hkIKTOho%253D%26srv%3Do5vmywmrnaxalvz6wi3zicyftgio6psuvyniis6gco6bp6ekl4cqj4id.onion) (BETA)!
|
||||
- delivery receipts (up to 20 members).
|
||||
@@ -542,7 +541,8 @@
|
||||
<source>Accept</source>
|
||||
<target>Hyväksy</target>
|
||||
<note>accept contact request via notification
|
||||
accept incoming call via notification</note>
|
||||
accept incoming call via notification
|
||||
swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Accept connection request?" xml:space="preserve">
|
||||
<source>Accept connection request?</source>
|
||||
@@ -557,7 +557,8 @@
|
||||
<trans-unit id="Accept incognito" xml:space="preserve">
|
||||
<source>Accept incognito</source>
|
||||
<target>Hyväksy tuntematon</target>
|
||||
<note>accept contact request via notification</note>
|
||||
<note>accept contact request via notification
|
||||
swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Acknowledged" xml:space="preserve">
|
||||
<source>Acknowledged</source>
|
||||
@@ -898,6 +899,10 @@
|
||||
<source>Archive and upload</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Archive contacts to chat later." xml:space="preserve">
|
||||
<source>Archive contacts to chat later.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Archived contacts" xml:space="preserve">
|
||||
<source>Archived contacts</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -998,6 +1003,10 @@
|
||||
<target>Parempia viestejä</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Better networking" xml:space="preserve">
|
||||
<source>Better networking</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Black" xml:space="preserve">
|
||||
<source>Black</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -1030,6 +1039,10 @@
|
||||
<source>Blocked by admin</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Blur for better privacy." xml:space="preserve">
|
||||
<source>Blur for better privacy.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Blur media" xml:space="preserve">
|
||||
<source>Blur media</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -1237,6 +1250,10 @@
|
||||
<source>Chat is stopped. If you already used this database on another device, you should transfer it back before starting chat.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Chat list" xml:space="preserve">
|
||||
<source>Chat list</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Chat migrated!" xml:space="preserve">
|
||||
<source>Chat migrated!</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -1294,7 +1311,7 @@
|
||||
<trans-unit id="Clear" xml:space="preserve">
|
||||
<source>Clear</source>
|
||||
<target>Tyhjennä</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
<note>swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Clear conversation" xml:space="preserve">
|
||||
<source>Clear conversation</source>
|
||||
@@ -1315,6 +1332,10 @@
|
||||
<target>Tyhjennä vahvistus</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Color chats with the new themes." xml:space="preserve">
|
||||
<source>Color chats with the new themes.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Color mode" xml:space="preserve">
|
||||
<source>Color mode</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -1405,8 +1426,8 @@
|
||||
<source>Connect to desktop</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Connect to your friends faster" xml:space="preserve">
|
||||
<source>Connect to your friends faster</source>
|
||||
<trans-unit id="Connect to your friends faster." xml:space="preserve">
|
||||
<source>Connect to your friends faster.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Connect to yourself?" xml:space="preserve">
|
||||
@@ -1581,10 +1602,6 @@ This is your own one-time link!</source>
|
||||
<target>Jatka</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Control your network" xml:space="preserve">
|
||||
<source>Control your network</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Conversation deleted!" xml:space="preserve">
|
||||
<source>Conversation deleted!</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -1603,6 +1620,10 @@ This is your own one-time link!</source>
|
||||
<target>Ydinversio: v%@</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Corner" xml:space="preserve">
|
||||
<source>Corner</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Correct name to %@?" xml:space="preserve">
|
||||
<source>Correct name to %@?</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -1846,7 +1867,8 @@ This is your own one-time link!</source>
|
||||
<trans-unit id="Delete" xml:space="preserve">
|
||||
<source>Delete</source>
|
||||
<target>Poista</target>
|
||||
<note>chat item action</note>
|
||||
<note>chat item action
|
||||
swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Delete %lld messages of members?" xml:space="preserve">
|
||||
<source>Delete %lld messages of members?</source>
|
||||
@@ -2045,10 +2067,6 @@ This is your own one-time link!</source>
|
||||
<target>Poistettu klo: %@</target>
|
||||
<note>copied message info</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Deleted chats" xml:space="preserve">
|
||||
<source>Deleted chats</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Deletion errors" xml:space="preserve">
|
||||
<source>Deletion errors</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -2534,6 +2552,10 @@ This is your own one-time link!</source>
|
||||
<target>Virhe osoitteenvaihdossa</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Error changing connection profile" xml:space="preserve">
|
||||
<source>Error changing connection profile</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Error changing role" xml:space="preserve">
|
||||
<source>Error changing role</source>
|
||||
<target>Virhe roolin vaihdossa</target>
|
||||
@@ -2544,6 +2566,10 @@ This is your own one-time link!</source>
|
||||
<target>Virhe asetuksen muuttamisessa</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Error changing to incognito!" xml:space="preserve">
|
||||
<source>Error changing to incognito!</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Error connecting to forwarding server %@. Please try later." xml:space="preserve">
|
||||
<source>Error connecting to forwarding server %@. Please try later.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -2752,6 +2778,10 @@ This is your own one-time link!</source>
|
||||
<target>Virhe keskustelun lopettamisessa</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Error switching profile" xml:space="preserve">
|
||||
<source>Error switching profile</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Error switching profile!" xml:space="preserve">
|
||||
<source>Error switching profile!</source>
|
||||
<target>Virhe profiilin vaihdossa!</target>
|
||||
@@ -2820,10 +2850,6 @@ This is your own one-time link!</source>
|
||||
<target>Jopa kun ei käytössä keskustelussa.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Even when they are offline." xml:space="preserve">
|
||||
<source>Even when they are offline.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Exit without saving" xml:space="preserve">
|
||||
<source>Exit without saving</source>
|
||||
<target>Poistu tallentamatta</target>
|
||||
@@ -2878,7 +2904,7 @@ This is your own one-time link!</source>
|
||||
<trans-unit id="Favorite" xml:space="preserve">
|
||||
<source>Favorite</source>
|
||||
<target>Suosikki</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
<note>swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="File error" xml:space="preserve">
|
||||
<source>File error</source>
|
||||
@@ -3610,7 +3636,7 @@ Error: %2$@</source>
|
||||
<trans-unit id="Join" xml:space="preserve">
|
||||
<source>Join</source>
|
||||
<target>Liity</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
<note>swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Join group" xml:space="preserve">
|
||||
<source>Join group</source>
|
||||
@@ -3693,7 +3719,7 @@ This is your link for group %@!</source>
|
||||
<trans-unit id="Leave" xml:space="preserve">
|
||||
<source>Leave</source>
|
||||
<target>Poistu</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
<note>swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Leave group" xml:space="preserve">
|
||||
<source>Leave group</source>
|
||||
@@ -3912,6 +3938,10 @@ This is your link for group %@!</source>
|
||||
<source>Message servers</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message shape" xml:space="preserve">
|
||||
<source>Message shape</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message source remains private." xml:space="preserve">
|
||||
<source>Message source remains private.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -4021,10 +4051,6 @@ This is your link for group %@!</source>
|
||||
<target>Moderoi</target>
|
||||
<note>chat item action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Moderate like a pro ✋" xml:space="preserve">
|
||||
<source>Moderate like a pro ✋</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Moderated at" xml:space="preserve">
|
||||
<source>Moderated at</source>
|
||||
<target>Moderoitu klo</target>
|
||||
@@ -4057,7 +4083,7 @@ This is your link for group %@!</source>
|
||||
<trans-unit id="Mute" xml:space="preserve">
|
||||
<source>Mute</source>
|
||||
<target>Mykistä</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
<note>swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Muted when inactive!" xml:space="preserve">
|
||||
<source>Muted when inactive!</source>
|
||||
@@ -4067,7 +4093,7 @@ This is your link for group %@!</source>
|
||||
<trans-unit id="Name" xml:space="preserve">
|
||||
<source>Name</source>
|
||||
<target>Nimi</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
<note>swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Network & servers" xml:space="preserve">
|
||||
<source>Network & servers</source>
|
||||
@@ -4096,10 +4122,6 @@ This is your link for group %@!</source>
|
||||
<target>Verkon tila</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="New Chat" xml:space="preserve">
|
||||
<source>New Chat</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="New Passcode" xml:space="preserve">
|
||||
<source>New Passcode</source>
|
||||
<target>Uusi pääsykoodi</target>
|
||||
@@ -4109,6 +4131,10 @@ This is your link for group %@!</source>
|
||||
<source>New chat</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="New chat experience 🎉" xml:space="preserve">
|
||||
<source>New chat experience 🎉</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="New contact request" xml:space="preserve">
|
||||
<source>New contact request</source>
|
||||
<target>Uusi kontaktipyyntö</target>
|
||||
@@ -4138,6 +4164,10 @@ This is your link for group %@!</source>
|
||||
<target>Uutta %@</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="New media options" xml:space="preserve">
|
||||
<source>New media options</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="New member role" xml:space="preserve">
|
||||
<source>New member role</source>
|
||||
<target>Uusi jäsenrooli</target>
|
||||
@@ -4271,10 +4301,6 @@ This is your link for group %@!</source>
|
||||
<target>Vanha tietokanta-arkisto</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="One-hand UI" xml:space="preserve">
|
||||
<source>One-hand UI</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="One-time invitation link" xml:space="preserve">
|
||||
<source>One-time invitation link</source>
|
||||
<target>Kertakutsulinkki</target>
|
||||
@@ -4526,6 +4552,10 @@ Edellyttää VPN:n sallimista.</target>
|
||||
<source>Picture-in-picture calls</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Play from the chat list." xml:space="preserve">
|
||||
<source>Play from the chat list.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Please ask your contact to enable calls." xml:space="preserve">
|
||||
<source>Please ask your contact to enable calls.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -4808,8 +4838,8 @@ Enable in *Network & servers* settings.</source>
|
||||
<target>Arvioi sovellus</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Reachable chat toolbar 👋" xml:space="preserve">
|
||||
<source>Reachable chat toolbar 👋</source>
|
||||
<trans-unit id="Reachable chat toolbar" xml:space="preserve">
|
||||
<source>Reachable chat toolbar</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="React…" xml:space="preserve">
|
||||
@@ -4820,7 +4850,7 @@ Enable in *Network & servers* settings.</source>
|
||||
<trans-unit id="Read" xml:space="preserve">
|
||||
<source>Read</source>
|
||||
<target>Lue</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
<note>swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Read more" xml:space="preserve">
|
||||
<source>Read more</source>
|
||||
@@ -4968,7 +4998,8 @@ Enable in *Network & servers* settings.</source>
|
||||
<trans-unit id="Reject" xml:space="preserve">
|
||||
<source>Reject</source>
|
||||
<target>Hylkää</target>
|
||||
<note>reject incoming call via notification</note>
|
||||
<note>reject incoming call via notification
|
||||
swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Reject (sender NOT notified)" xml:space="preserve">
|
||||
<source>Reject (sender NOT notified)</source>
|
||||
@@ -5064,6 +5095,10 @@ Enable in *Network & servers* settings.</source>
|
||||
<target>Oletustilaan</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Reset all hints" xml:space="preserve">
|
||||
<source>Reset all hints</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Reset all statistics" xml:space="preserve">
|
||||
<source>Reset all statistics</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -5340,6 +5375,10 @@ Enable in *Network & servers* settings.</source>
|
||||
<target>Valitse</target>
|
||||
<note>chat item action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Select chat profile" xml:space="preserve">
|
||||
<source>Select chat profile</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Selected %lld" xml:space="preserve">
|
||||
<source>Selected %lld</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -5675,11 +5714,19 @@ Enable in *Network & servers* settings.</source>
|
||||
<target>Jaa osoite kontakteille?</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Share from other apps." xml:space="preserve">
|
||||
<source>Share from other apps.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Share link" xml:space="preserve">
|
||||
<source>Share link</source>
|
||||
<target>Jaa linkki</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Share profile" xml:space="preserve">
|
||||
<source>Share profile</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Share this 1-time invite link" xml:space="preserve">
|
||||
<source>Share this 1-time invite link</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -5995,6 +6042,10 @@ Enable in *Network & servers* settings.</source>
|
||||
<target>TCP_KEEPINTVL</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Tail" xml:space="preserve">
|
||||
<source>Tail</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Take picture" xml:space="preserve">
|
||||
<source>Take picture</source>
|
||||
<target>Ota kuva</target>
|
||||
@@ -6314,10 +6365,18 @@ Sinua kehotetaan suorittamaan todennus loppuun, ennen kuin tämä ominaisuus ote
|
||||
<target>Voit tarkistaa päästä päähän -salauksen kontaktisi kanssa vertaamalla (tai skannaamalla) laitteidenne koodia.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Toggle chat list:" xml:space="preserve">
|
||||
<source>Toggle chat list:</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Toggle incognito when connecting." xml:space="preserve">
|
||||
<source>Toggle incognito when connecting.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Toolbar opacity" xml:space="preserve">
|
||||
<source>Toolbar opacity</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Total" xml:space="preserve">
|
||||
<source>Total</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -6388,7 +6447,7 @@ Sinua kehotetaan suorittamaan todennus loppuun, ennen kuin tämä ominaisuus ote
|
||||
<trans-unit id="Unfav." xml:space="preserve">
|
||||
<source>Unfav.</source>
|
||||
<target>Epäsuotuisa.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
<note>swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Unhide" xml:space="preserve">
|
||||
<source>Unhide</source>
|
||||
@@ -6462,12 +6521,12 @@ Jos haluat muodostaa yhteyden, pyydä kontaktiasi luomaan toinen yhteyslinkki ja
|
||||
<trans-unit id="Unmute" xml:space="preserve">
|
||||
<source>Unmute</source>
|
||||
<target>Poista mykistys</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
<note>swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Unread" xml:space="preserve">
|
||||
<source>Unread</source>
|
||||
<target>Lukematon</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
<note>swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Up to 100 last messages are sent to new members." xml:space="preserve">
|
||||
<source>Up to 100 last messages are sent to new members.</source>
|
||||
@@ -6913,6 +6972,10 @@ Repeat join request?</source>
|
||||
<target>Voit vastaanottaa puheluita lukitusnäytöltä ilman laitteen ja sovelluksen todennusta.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="You can change it in Appearance settings." xml:space="preserve">
|
||||
<source>You can change it in Appearance settings.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="You can create it later" xml:space="preserve">
|
||||
<source>You can create it later</source>
|
||||
<target>Voit luoda sen myöhemmin</target>
|
||||
@@ -7167,6 +7230,10 @@ Repeat connection request?</source>
|
||||
<target>Keskusteluprofiilisi</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Your connection was moved to %@ but an unexpected error occurred while redirecting you to the profile." xml:space="preserve">
|
||||
<source>Your connection was moved to %@ but an unexpected error occurred while redirecting you to the profile.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Your contact sent a file that is larger than currently supported maximum size (%@)." xml:space="preserve">
|
||||
<source>Your contact sent a file that is larger than currently supported maximum size (%@).</source>
|
||||
<target>Yhteyshenkilösi lähetti tiedoston, joka on suurempi kuin tällä hetkellä tuettu enimmäiskoko (%@).</target>
|
||||
@@ -7182,10 +7249,6 @@ Repeat connection request?</source>
|
||||
<target>Kontaktisi pysyvät yhdistettyinä.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Your contacts your way" xml:space="preserve">
|
||||
<source>Your contacts your way</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Your current chat database will be DELETED and REPLACED with the imported one." xml:space="preserve">
|
||||
<source>Your current chat database will be DELETED and REPLACED with the imported one.</source>
|
||||
<target>Nykyinen keskustelut-tietokantasi poistetaan ja korvataan tuodulla tietokannalla.</target>
|
||||
|
||||
@@ -137,6 +137,10 @@
|
||||
<target>%@ veut se connecter !</target>
|
||||
<note>notification title</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="%@, %@" xml:space="preserve">
|
||||
<source>%1$@, %2$@</source>
|
||||
<note>format for date separator in chat</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="%@, %@ and %lld members" xml:space="preserve">
|
||||
<source>%@, %@ and %lld members</source>
|
||||
<target>%@, %@ et %lld membres</target>
|
||||
@@ -392,11 +396,6 @@
|
||||
<target>, </target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="- Search contacts when starting chat. - Archive contacts to chat later." xml:space="preserve">
|
||||
<source>- Search contacts when starting chat.
|
||||
- Archive contacts to chat later.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="- connect to [directory service](simplex:/contact#/?v=1-4&smp=smp%3A%2F%2Fu2dS9sG8nMNURyZwqASV4yROM28Er0luVTx5X1CsMrU%3D%40smp4.simplex.im%2FeXSPwqTkKyDO3px4fLf1wx3MvPdjdLW3%23%2F%3Fv%3D1-2%26dh%3DMCowBQYDK2VuAyEAaiv6MkMH44L2TcYrt_CsX3ZvM11WgbMEUn0hkIKTOho%253D%26srv%3Do5vmywmrnaxalvz6wi3zicyftgio6psuvyniis6gco6bp6ekl4cqj4id.onion) (BETA)! - delivery receipts (up to 20 members). - faster and more stable." xml:space="preserve">
|
||||
<source>- connect to [directory service](simplex:/contact#/?v=1-4&smp=smp%3A%2F%2Fu2dS9sG8nMNURyZwqASV4yROM28Er0luVTx5X1CsMrU%3D%40smp4.simplex.im%2FeXSPwqTkKyDO3px4fLf1wx3MvPdjdLW3%23%2F%3Fv%3D1-2%26dh%3DMCowBQYDK2VuAyEAaiv6MkMH44L2TcYrt_CsX3ZvM11WgbMEUn0hkIKTOho%253D%26srv%3Do5vmywmrnaxalvz6wi3zicyftgio6psuvyniis6gco6bp6ekl4cqj4id.onion) (BETA)!
|
||||
- delivery receipts (up to 20 members).
|
||||
@@ -529,7 +528,7 @@
|
||||
</trans-unit>
|
||||
<trans-unit id="Abort" xml:space="preserve">
|
||||
<source>Abort</source>
|
||||
<target>Annuler</target>
|
||||
<target>Abandonner</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Abort changing address" xml:space="preserve">
|
||||
@@ -566,7 +565,8 @@
|
||||
<source>Accept</source>
|
||||
<target>Accepter</target>
|
||||
<note>accept contact request via notification
|
||||
accept incoming call via notification</note>
|
||||
accept incoming call via notification
|
||||
swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Accept connection request?" xml:space="preserve">
|
||||
<source>Accept connection request?</source>
|
||||
@@ -581,7 +581,8 @@
|
||||
<trans-unit id="Accept incognito" xml:space="preserve">
|
||||
<source>Accept incognito</source>
|
||||
<target>Accepter en incognito</target>
|
||||
<note>accept contact request via notification</note>
|
||||
<note>accept contact request via notification
|
||||
swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Acknowledged" xml:space="preserve">
|
||||
<source>Acknowledged</source>
|
||||
@@ -755,6 +756,7 @@
|
||||
</trans-unit>
|
||||
<trans-unit id="Allow calls?" xml:space="preserve">
|
||||
<source>Allow calls?</source>
|
||||
<target>Autoriser les appels ?</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Allow disappearing messages only if your contact allows it to you." xml:space="preserve">
|
||||
@@ -944,11 +946,17 @@
|
||||
</trans-unit>
|
||||
<trans-unit id="Archive and upload" xml:space="preserve">
|
||||
<source>Archive and upload</source>
|
||||
<target>Archiver et transférer</target>
|
||||
<target>Archiver et téléverser</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Archive contacts to chat later." xml:space="preserve">
|
||||
<source>Archive contacts to chat later.</source>
|
||||
<target>Archiver les contacts pour discuter plus tard.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Archived contacts" xml:space="preserve">
|
||||
<source>Archived contacts</source>
|
||||
<target>Contacts archivés</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Archiving database" xml:space="preserve">
|
||||
@@ -1051,6 +1059,11 @@
|
||||
<target>Meilleurs messages</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Better networking" xml:space="preserve">
|
||||
<source>Better networking</source>
|
||||
<target>Meilleure gestion de réseau</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Black" xml:space="preserve">
|
||||
<source>Black</source>
|
||||
<target>Noir</target>
|
||||
@@ -1091,6 +1104,11 @@
|
||||
<target>Bloqué par l'administrateur</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Blur for better privacy." xml:space="preserve">
|
||||
<source>Blur for better privacy.</source>
|
||||
<target>Rendez les images floues et protégez-les contre les regards indiscrets.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Blur media" xml:space="preserve">
|
||||
<source>Blur media</source>
|
||||
<target>Flouter les médias</target>
|
||||
@@ -1143,6 +1161,7 @@
|
||||
</trans-unit>
|
||||
<trans-unit id="Calls prohibited!" xml:space="preserve">
|
||||
<source>Calls prohibited!</source>
|
||||
<target>Les appels ne sont pas autorisés !</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Camera not available" xml:space="preserve">
|
||||
@@ -1152,10 +1171,12 @@
|
||||
</trans-unit>
|
||||
<trans-unit id="Can't call contact" xml:space="preserve">
|
||||
<source>Can't call contact</source>
|
||||
<target>Impossible d'appeler le contact</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Can't call member" xml:space="preserve">
|
||||
<source>Can't call member</source>
|
||||
<target>Impossible d'appeler le membre</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Can't invite contact!" xml:space="preserve">
|
||||
@@ -1170,6 +1191,7 @@
|
||||
</trans-unit>
|
||||
<trans-unit id="Can't message member" xml:space="preserve">
|
||||
<source>Can't message member</source>
|
||||
<target>Impossible d'envoyer un message à ce membre</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Cancel" xml:space="preserve">
|
||||
@@ -1285,6 +1307,7 @@
|
||||
</trans-unit>
|
||||
<trans-unit id="Chat database exported" xml:space="preserve">
|
||||
<source>Chat database exported</source>
|
||||
<target>Exportation de la base de données des discussions</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Chat database imported" xml:space="preserve">
|
||||
@@ -1307,6 +1330,11 @@
|
||||
<target>Le chat est arrêté. Si vous avez déjà utilisé cette base de données sur un autre appareil, vous devez la transférer à nouveau avant de démarrer le chat.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Chat list" xml:space="preserve">
|
||||
<source>Chat list</source>
|
||||
<target>Liste de discussion</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Chat migrated!" xml:space="preserve">
|
||||
<source>Chat migrated!</source>
|
||||
<target>Messagerie transférée !</target>
|
||||
@@ -1370,7 +1398,7 @@
|
||||
<trans-unit id="Clear" xml:space="preserve">
|
||||
<source>Clear</source>
|
||||
<target>Effacer</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
<note>swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Clear conversation" xml:space="preserve">
|
||||
<source>Clear conversation</source>
|
||||
@@ -1392,6 +1420,11 @@
|
||||
<target>Retirer la vérification</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Color chats with the new themes." xml:space="preserve">
|
||||
<source>Color chats with the new themes.</source>
|
||||
<target>Colorez vos discussions avec les nouveaux thèmes.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Color mode" xml:space="preserve">
|
||||
<source>Color mode</source>
|
||||
<target>Mode de couleur</target>
|
||||
@@ -1409,7 +1442,7 @@
|
||||
</trans-unit>
|
||||
<trans-unit id="Completed" xml:space="preserve">
|
||||
<source>Completed</source>
|
||||
<target>Complété</target>
|
||||
<target>Complétées</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Configure ICE servers" xml:space="preserve">
|
||||
@@ -1434,6 +1467,7 @@
|
||||
</trans-unit>
|
||||
<trans-unit id="Confirm contact deletion?" xml:space="preserve">
|
||||
<source>Confirm contact deletion?</source>
|
||||
<target>Confirmer la suppression du contact ?</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Confirm database upgrades" xml:space="preserve">
|
||||
@@ -1491,8 +1525,9 @@
|
||||
<target>Connexion au bureau</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Connect to your friends faster" xml:space="preserve">
|
||||
<source>Connect to your friends faster</source>
|
||||
<trans-unit id="Connect to your friends faster." xml:space="preserve">
|
||||
<source>Connect to your friends faster.</source>
|
||||
<target>Connectez-vous à vos amis plus rapidement.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Connect to yourself?" xml:space="preserve">
|
||||
@@ -1571,6 +1606,7 @@ Il s'agit de votre propre lien unique !</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Connecting to contact, please wait or check later!" xml:space="preserve">
|
||||
<source>Connecting to contact, please wait or check later!</source>
|
||||
<target>Connexion au contact, veuillez patienter ou vérifier plus tard !</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Connecting to desktop" xml:space="preserve">
|
||||
@@ -1585,6 +1621,7 @@ Il s'agit de votre propre lien unique !</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Connection and servers status." xml:space="preserve">
|
||||
<source>Connection and servers status.</source>
|
||||
<target>État de la connexion et des serveurs.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Connection error" xml:space="preserve">
|
||||
@@ -1639,6 +1676,7 @@ Il s'agit de votre propre lien unique !</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Contact deleted!" xml:space="preserve">
|
||||
<source>Contact deleted!</source>
|
||||
<target>Contact supprimé !</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Contact hidden:" xml:space="preserve">
|
||||
@@ -1653,6 +1691,7 @@ Il s'agit de votre propre lien unique !</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Contact is deleted." xml:space="preserve">
|
||||
<source>Contact is deleted.</source>
|
||||
<target>Le contact est supprimé.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Contact name" xml:space="preserve">
|
||||
@@ -1667,6 +1706,7 @@ Il s'agit de votre propre lien unique !</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Contact will be deleted - this cannot be undone!" xml:space="preserve">
|
||||
<source>Contact will be deleted - this cannot be undone!</source>
|
||||
<target>Le contact sera supprimé - il n'est pas possible de revenir en arrière !</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Contacts" xml:space="preserve">
|
||||
@@ -1684,12 +1724,9 @@ Il s'agit de votre propre lien unique !</target>
|
||||
<target>Continuer</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Control your network" xml:space="preserve">
|
||||
<source>Control your network</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Conversation deleted!" xml:space="preserve">
|
||||
<source>Conversation deleted!</source>
|
||||
<target>Conversation supprimée !</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Copy" xml:space="preserve">
|
||||
@@ -1707,6 +1744,10 @@ Il s'agit de votre propre lien unique !</target>
|
||||
<target>Version du cœur : v%@</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Corner" xml:space="preserve">
|
||||
<source>Corner</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Correct name to %@?" xml:space="preserve">
|
||||
<source>Correct name to %@?</source>
|
||||
<target>Corriger le nom pour %@ ?</target>
|
||||
@@ -1779,7 +1820,7 @@ Il s'agit de votre propre lien unique !</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Created" xml:space="preserve">
|
||||
<source>Created</source>
|
||||
<target>Créé</target>
|
||||
<target>Créées</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Created at" xml:space="preserve">
|
||||
@@ -1963,7 +2004,8 @@ Il s'agit de votre propre lien unique !</target>
|
||||
<trans-unit id="Delete" xml:space="preserve">
|
||||
<source>Delete</source>
|
||||
<target>Supprimer</target>
|
||||
<note>chat item action</note>
|
||||
<note>chat item action
|
||||
swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Delete %lld messages of members?" xml:space="preserve">
|
||||
<source>Delete %lld messages of members?</source>
|
||||
@@ -2032,6 +2074,7 @@ Il s'agit de votre propre lien unique !</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Delete contact?" xml:space="preserve">
|
||||
<source>Delete contact?</source>
|
||||
<target>Supprimer le contact ?</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Delete database" xml:space="preserve">
|
||||
@@ -2141,6 +2184,7 @@ Il s'agit de votre propre lien unique !</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Delete up to 20 messages at once." xml:space="preserve">
|
||||
<source>Delete up to 20 messages at once.</source>
|
||||
<target>Supprimez jusqu'à 20 messages à la fois.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Delete user profile?" xml:space="preserve">
|
||||
@@ -2150,11 +2194,12 @@ Il s'agit de votre propre lien unique !</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Delete without notification" xml:space="preserve">
|
||||
<source>Delete without notification</source>
|
||||
<target>Supprimer sans notification</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Deleted" xml:space="preserve">
|
||||
<source>Deleted</source>
|
||||
<target>Supprimé</target>
|
||||
<target>Supprimées</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Deleted at" xml:space="preserve">
|
||||
@@ -2167,10 +2212,6 @@ Il s'agit de votre propre lien unique !</target>
|
||||
<target>Supprimé à : %@</target>
|
||||
<note>copied message info</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Deleted chats" xml:space="preserve">
|
||||
<source>Deleted chats</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Deletion errors" xml:space="preserve">
|
||||
<source>Deletion errors</source>
|
||||
<target>Erreurs de suppression</target>
|
||||
@@ -2243,6 +2284,7 @@ Il s'agit de votre propre lien unique !</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Developer options" xml:space="preserve">
|
||||
<source>Developer options</source>
|
||||
<target>Options pour les développeurs</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Developer tools" xml:space="preserve">
|
||||
@@ -2690,6 +2732,10 @@ Il s'agit de votre propre lien unique !</target>
|
||||
<target>Erreur de changement d'adresse</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Error changing connection profile" xml:space="preserve">
|
||||
<source>Error changing connection profile</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Error changing role" xml:space="preserve">
|
||||
<source>Error changing role</source>
|
||||
<target>Erreur lors du changement de rôle</target>
|
||||
@@ -2700,6 +2746,10 @@ Il s'agit de votre propre lien unique !</target>
|
||||
<target>Erreur de changement de paramètre</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Error changing to incognito!" xml:space="preserve">
|
||||
<source>Error changing to incognito!</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Error connecting to forwarding server %@. Please try later." xml:space="preserve">
|
||||
<source>Error connecting to forwarding server %@. Please try later.</source>
|
||||
<target>Erreur de connexion au serveur de redirection %@. Veuillez réessayer plus tard.</target>
|
||||
@@ -2920,6 +2970,10 @@ Il s'agit de votre propre lien unique !</target>
|
||||
<target>Erreur lors de l'arrêt du chat</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Error switching profile" xml:space="preserve">
|
||||
<source>Error switching profile</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Error switching profile!" xml:space="preserve">
|
||||
<source>Error switching profile!</source>
|
||||
<target>Erreur lors du changement de profil !</target>
|
||||
@@ -2991,10 +3045,6 @@ Il s'agit de votre propre lien unique !</target>
|
||||
<target>Même s'il est désactivé dans la conversation.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Even when they are offline." xml:space="preserve">
|
||||
<source>Even when they are offline.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Exit without saving" xml:space="preserve">
|
||||
<source>Exit without saving</source>
|
||||
<target>Quitter sans enregistrer</target>
|
||||
@@ -3053,7 +3103,7 @@ Il s'agit de votre propre lien unique !</target>
|
||||
<trans-unit id="Favorite" xml:space="preserve">
|
||||
<source>Favorite</source>
|
||||
<target>Favoris</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
<note>swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="File error" xml:space="preserve">
|
||||
<source>File error</source>
|
||||
@@ -3809,6 +3859,7 @@ Erreur : %2$@</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="It protects your IP address and connections." xml:space="preserve">
|
||||
<source>It protects your IP address and connections.</source>
|
||||
<target>Il protège votre adresse IP et vos connexions.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</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">
|
||||
@@ -3829,7 +3880,7 @@ Erreur : %2$@</target>
|
||||
<trans-unit id="Join" xml:space="preserve">
|
||||
<source>Join</source>
|
||||
<target>Rejoindre</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
<note>swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Join group" xml:space="preserve">
|
||||
<source>Join group</source>
|
||||
@@ -3875,6 +3926,7 @@ Voici votre lien pour le groupe %@ !</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Keep conversation" xml:space="preserve">
|
||||
<source>Keep conversation</source>
|
||||
<target>Garder la conversation</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">
|
||||
@@ -3920,7 +3972,7 @@ Voici votre lien pour le groupe %@ !</target>
|
||||
<trans-unit id="Leave" xml:space="preserve">
|
||||
<source>Leave</source>
|
||||
<target>Quitter</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
<note>swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Leave group" xml:space="preserve">
|
||||
<source>Leave group</source>
|
||||
@@ -4054,6 +4106,7 @@ Voici votre lien pour le groupe %@ !</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Media & file servers" xml:space="preserve">
|
||||
<source>Media & file servers</source>
|
||||
<target>Serveurs de fichiers et de médias</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Medium" xml:space="preserve">
|
||||
@@ -4148,6 +4201,11 @@ Voici votre lien pour le groupe %@ !</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message servers" xml:space="preserve">
|
||||
<source>Message servers</source>
|
||||
<target>Serveurs de messages</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message shape" xml:space="preserve">
|
||||
<source>Message shape</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message source remains private." xml:space="preserve">
|
||||
@@ -4275,10 +4333,6 @@ Voici votre lien pour le groupe %@ !</target>
|
||||
<target>Modérer</target>
|
||||
<note>chat item action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Moderate like a pro ✋" xml:space="preserve">
|
||||
<source>Moderate like a pro ✋</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Moderated at" xml:space="preserve">
|
||||
<source>Moderated at</source>
|
||||
<target>Modéré à</target>
|
||||
@@ -4312,7 +4366,7 @@ Voici votre lien pour le groupe %@ !</target>
|
||||
<trans-unit id="Mute" xml:space="preserve">
|
||||
<source>Mute</source>
|
||||
<target>Muet</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
<note>swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Muted when inactive!" xml:space="preserve">
|
||||
<source>Muted when inactive!</source>
|
||||
@@ -4322,7 +4376,7 @@ Voici votre lien pour le groupe %@ !</target>
|
||||
<trans-unit id="Name" xml:space="preserve">
|
||||
<source>Name</source>
|
||||
<target>Nom</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
<note>swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Network & servers" xml:space="preserve">
|
||||
<source>Network & servers</source>
|
||||
@@ -4354,10 +4408,6 @@ Voici votre lien pour le groupe %@ !</target>
|
||||
<target>État du réseau</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="New Chat" xml:space="preserve">
|
||||
<source>New Chat</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="New Passcode" xml:space="preserve">
|
||||
<source>New Passcode</source>
|
||||
<target>Nouveau code d'accès</target>
|
||||
@@ -4368,6 +4418,11 @@ Voici votre lien pour le groupe %@ !</target>
|
||||
<target>Nouveau chat</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="New chat experience 🎉" xml:space="preserve">
|
||||
<source>New chat experience 🎉</source>
|
||||
<target>Nouvelle expérience de discussion 🎉</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="New contact request" xml:space="preserve">
|
||||
<source>New contact request</source>
|
||||
<target>Nouvelle demande de contact</target>
|
||||
@@ -4398,6 +4453,11 @@ Voici votre lien pour le groupe %@ !</target>
|
||||
<target>Nouveautés de la %@</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="New media options" xml:space="preserve">
|
||||
<source>New media options</source>
|
||||
<target>Nouvelles options de médias</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="New member role" xml:space="preserve">
|
||||
<source>New member role</source>
|
||||
<target>Nouveau rôle</target>
|
||||
@@ -4537,10 +4597,6 @@ Voici votre lien pour le groupe %@ !</target>
|
||||
<target>Archives de l'ancienne base de données</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="One-hand UI" xml:space="preserve">
|
||||
<source>One-hand UI</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="One-time invitation link" xml:space="preserve">
|
||||
<source>One-time invitation link</source>
|
||||
<target>Lien d'invitation unique</target>
|
||||
@@ -4572,6 +4628,7 @@ Nécessite l'activation d'un VPN.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Only delete conversation" xml:space="preserve">
|
||||
<source>Only delete conversation</source>
|
||||
<target>Ne supprimer que la conversation</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Only group owners can change group preferences." xml:space="preserve">
|
||||
@@ -4809,8 +4866,14 @@ Nécessite l'activation d'un VPN.</target>
|
||||
<target>Appels picture-in-picture</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Play from the chat list." xml:space="preserve">
|
||||
<source>Play from the chat list.</source>
|
||||
<target>Aperçu depuis la liste de conversation.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Please ask your contact to enable calls." xml:space="preserve">
|
||||
<source>Please ask your contact to enable calls.</source>
|
||||
<target>Veuillez demander à votre contact d'autoriser les appels.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Please ask your contact to enable sending voice messages." xml:space="preserve">
|
||||
@@ -5114,8 +5177,9 @@ Activez-le dans les paramètres *Réseau et serveurs*.</target>
|
||||
<target>Évaluer l'app</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Reachable chat toolbar 👋" xml:space="preserve">
|
||||
<source>Reachable chat toolbar 👋</source>
|
||||
<trans-unit id="Reachable chat toolbar" xml:space="preserve">
|
||||
<source>Reachable chat toolbar</source>
|
||||
<target>Barre d'outils accessible</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="React…" xml:space="preserve">
|
||||
@@ -5126,7 +5190,7 @@ Activez-le dans les paramètres *Réseau et serveurs*.</target>
|
||||
<trans-unit id="Read" xml:space="preserve">
|
||||
<source>Read</source>
|
||||
<target>Lire</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
<note>swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Read more" xml:space="preserve">
|
||||
<source>Read more</source>
|
||||
@@ -5286,7 +5350,8 @@ Activez-le dans les paramètres *Réseau et serveurs*.</target>
|
||||
<trans-unit id="Reject" xml:space="preserve">
|
||||
<source>Reject</source>
|
||||
<target>Rejeter</target>
|
||||
<note>reject incoming call via notification</note>
|
||||
<note>reject incoming call via notification
|
||||
swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Reject (sender NOT notified)" xml:space="preserve">
|
||||
<source>Reject (sender NOT notified)</source>
|
||||
@@ -5388,6 +5453,11 @@ Activez-le dans les paramètres *Réseau et serveurs*.</target>
|
||||
<target>Réinitialisation</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Reset all hints" xml:space="preserve">
|
||||
<source>Reset all hints</source>
|
||||
<target>Rétablir tous les conseils</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Reset all statistics" xml:space="preserve">
|
||||
<source>Reset all statistics</source>
|
||||
<target>Réinitialiser toutes les statistiques</target>
|
||||
@@ -5520,6 +5590,7 @@ Activez-le dans les paramètres *Réseau et serveurs*.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Save and reconnect" xml:space="preserve">
|
||||
<source>Save and reconnect</source>
|
||||
<target>Sauvegarder et se reconnecter</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Save and update group profile" xml:space="preserve">
|
||||
@@ -5664,7 +5735,7 @@ Activez-le dans les paramètres *Réseau et serveurs*.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Secured" xml:space="preserve">
|
||||
<source>Secured</source>
|
||||
<target>Sécurisé</target>
|
||||
<target>Sécurisées</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Security assessment" xml:space="preserve">
|
||||
@@ -5682,6 +5753,10 @@ Activez-le dans les paramètres *Réseau et serveurs*.</target>
|
||||
<target>Choisir</target>
|
||||
<note>chat item action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Select chat profile" xml:space="preserve">
|
||||
<source>Select chat profile</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Selected %lld" xml:space="preserve">
|
||||
<source>Selected %lld</source>
|
||||
<target>%lld sélectionné(s)</target>
|
||||
@@ -5744,7 +5819,7 @@ Activez-le dans les paramètres *Réseau et serveurs*.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Send link previews" xml:space="preserve">
|
||||
<source>Send link previews</source>
|
||||
<target>Envoi d'aperçus de liens</target>
|
||||
<target>Aperçu des liens</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Send live message" xml:space="preserve">
|
||||
@@ -5754,6 +5829,7 @@ Activez-le dans les paramètres *Réseau et serveurs*.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Send message to enable calls." xml:space="preserve">
|
||||
<source>Send message to enable calls.</source>
|
||||
<target>Envoyer un message pour activer les appels.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Send messages directly when IP address is protected and your or destination server does not support private routing." xml:space="preserve">
|
||||
@@ -5918,7 +5994,7 @@ Activez-le dans les paramètres *Réseau et serveurs*.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Server requires authorization to upload, check password" xml:space="preserve">
|
||||
<source>Server requires authorization to upload, check password</source>
|
||||
<target>Le serveur requiert une autorisation pour uploader, vérifiez le mot de passe</target>
|
||||
<target>Le serveur requiert une autorisation pour téléverser, vérifiez le mot de passe</target>
|
||||
<note>server test error</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Server test failed!" xml:space="preserve">
|
||||
@@ -6041,11 +6117,20 @@ Activez-le dans les paramètres *Réseau et serveurs*.</target>
|
||||
<target>Partager l'adresse avec vos contacts ?</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Share from other apps." xml:space="preserve">
|
||||
<source>Share from other apps.</source>
|
||||
<target>Partager depuis d'autres applications.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Share link" xml:space="preserve">
|
||||
<source>Share link</source>
|
||||
<target>Partager le lien</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Share profile" xml:space="preserve">
|
||||
<source>Share profile</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Share this 1-time invite link" xml:space="preserve">
|
||||
<source>Share this 1-time invite link</source>
|
||||
<target>Partager ce lien d'invitation unique</target>
|
||||
@@ -6078,7 +6163,7 @@ Activez-le dans les paramètres *Réseau et serveurs*.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Show last messages" xml:space="preserve">
|
||||
<source>Show last messages</source>
|
||||
<target>Voir les derniers messages</target>
|
||||
<target>Aperçu des derniers messages</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Show message status" xml:space="preserve">
|
||||
@@ -6093,7 +6178,7 @@ Activez-le dans les paramètres *Réseau et serveurs*.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Show preview" xml:space="preserve">
|
||||
<source>Show preview</source>
|
||||
<target>Afficher l'aperçu</target>
|
||||
<target>Aperçu affiché</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Show → on messages sent via private routing." xml:space="preserve">
|
||||
@@ -6213,6 +6298,7 @@ Activez-le dans les paramètres *Réseau et serveurs*.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Some file(s) were not exported:" xml:space="preserve">
|
||||
<source>Some file(s) were not exported:</source>
|
||||
<target>Certains fichiers n'ont pas été exportés :</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Some non-fatal errors occurred during import - you may see Chat console for more details." xml:space="preserve">
|
||||
@@ -6222,6 +6308,7 @@ Activez-le dans les paramètres *Réseau et serveurs*.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Some non-fatal errors occurred during import:" xml:space="preserve">
|
||||
<source>Some non-fatal errors occurred during import:</source>
|
||||
<target>L'importation a entraîné des erreurs non fatales :</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Somebody" xml:space="preserve">
|
||||
@@ -6331,7 +6418,7 @@ Activez-le dans les paramètres *Réseau et serveurs*.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Subscribed" xml:space="preserve">
|
||||
<source>Subscribed</source>
|
||||
<target>Inscrit</target>
|
||||
<target>Inscriptions</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Subscription errors" xml:space="preserve">
|
||||
@@ -6361,6 +6448,7 @@ Activez-le dans les paramètres *Réseau et serveurs*.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="TCP connection" xml:space="preserve">
|
||||
<source>TCP connection</source>
|
||||
<target>Connexion TCP</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="TCP connection timeout" xml:space="preserve">
|
||||
@@ -6383,6 +6471,10 @@ Activez-le dans les paramètres *Réseau et serveurs*.</target>
|
||||
<target>TCP_KEEPINTVL</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Tail" xml:space="preserve">
|
||||
<source>Tail</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Take picture" xml:space="preserve">
|
||||
<source>Take picture</source>
|
||||
<target>Prendre une photo</target>
|
||||
@@ -6722,11 +6814,21 @@ Vous serez invité à confirmer l'authentification avant que cette fonction ne s
|
||||
<target>Pour vérifier le chiffrement de bout en bout avec votre contact, comparez (ou scannez) le code sur vos appareils.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Toggle chat list:" xml:space="preserve">
|
||||
<source>Toggle chat list:</source>
|
||||
<target>Afficher la liste des conversations :</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Toggle incognito when connecting." xml:space="preserve">
|
||||
<source>Toggle incognito when connecting.</source>
|
||||
<target>Basculer en mode incognito lors de la connexion.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Toolbar opacity" xml:space="preserve">
|
||||
<source>Toolbar opacity</source>
|
||||
<target>Opacité de la barre d'outils</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Total" xml:space="preserve">
|
||||
<source>Total</source>
|
||||
<target>Total</target>
|
||||
@@ -6805,7 +6907,7 @@ Vous serez invité à confirmer l'authentification avant que cette fonction ne s
|
||||
<trans-unit id="Unfav." xml:space="preserve">
|
||||
<source>Unfav.</source>
|
||||
<target>Unfav.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
<note>swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Unhide" xml:space="preserve">
|
||||
<source>Unhide</source>
|
||||
@@ -6882,12 +6984,12 @@ Pour vous connecter, veuillez demander à votre contact de créer un autre lien
|
||||
<trans-unit id="Unmute" xml:space="preserve">
|
||||
<source>Unmute</source>
|
||||
<target>Démute</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
<note>swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Unread" xml:space="preserve">
|
||||
<source>Unread</source>
|
||||
<target>Non lu</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
<note>swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Up to 100 last messages are sent to new members." xml:space="preserve">
|
||||
<source>Up to 100 last messages are sent to new members.</source>
|
||||
@@ -6911,6 +7013,7 @@ Pour vous connecter, veuillez demander à votre contact de créer un autre lien
|
||||
</trans-unit>
|
||||
<trans-unit id="Update settings?" xml:space="preserve">
|
||||
<source>Update settings?</source>
|
||||
<target>Mettre à jour les paramètres ?</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Updating settings will re-connect the client to all servers." xml:space="preserve">
|
||||
@@ -6935,7 +7038,7 @@ Pour vous connecter, veuillez demander à votre contact de créer un autre lien
|
||||
</trans-unit>
|
||||
<trans-unit id="Upload file" xml:space="preserve">
|
||||
<source>Upload file</source>
|
||||
<target>Transférer le fichier</target>
|
||||
<target>Téléverser le fichier</target>
|
||||
<note>server test step</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Uploaded" xml:space="preserve">
|
||||
@@ -7020,6 +7123,7 @@ Pour vous connecter, veuillez demander à votre contact de créer un autre lien
|
||||
</trans-unit>
|
||||
<trans-unit id="Use the app with one hand." xml:space="preserve">
|
||||
<source>Use the app with one hand.</source>
|
||||
<target>Utiliser l'application d'une main.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="User profile" xml:space="preserve">
|
||||
@@ -7089,7 +7193,7 @@ Pour vous connecter, veuillez demander à votre contact de créer un autre lien
|
||||
</trans-unit>
|
||||
<trans-unit id="Video will be received when your contact completes uploading it." xml:space="preserve">
|
||||
<source>Video will be received when your contact completes uploading it.</source>
|
||||
<target>La vidéo ne sera reçue que lorsque votre contact aura fini de la transférer.</target>
|
||||
<target>La vidéo ne sera reçue que lorsque votre contact aura fini la mettre en ligne.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Video will be received when your contact is online, please wait or check later!" xml:space="preserve">
|
||||
@@ -7379,6 +7483,11 @@ Répéter la demande d'adhésion ?</target>
|
||||
<target>Vous pouvez accepter des appels à partir de l'écran de verrouillage, sans authentification de l'appareil ou de l'application.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="You can change it in Appearance settings." xml:space="preserve">
|
||||
<source>You can change it in Appearance settings.</source>
|
||||
<target>Vous pouvez choisir de le modifier dans les paramètres d'apparence.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="You can create it later" xml:space="preserve">
|
||||
<source>You can create it later</source>
|
||||
<target>Vous pouvez la créer plus tard</target>
|
||||
@@ -7416,6 +7525,7 @@ Répéter la demande d'adhésion ?</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="You can send messages to %@ from Archived contacts." xml:space="preserve">
|
||||
<source>You can send messages to %@ from Archived contacts.</source>
|
||||
<target>Vous pouvez envoyer des messages à %@ à partir des contacts archivés.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="You can set lock screen notification preview via settings." xml:space="preserve">
|
||||
@@ -7445,6 +7555,7 @@ Répéter la demande d'adhésion ?</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="You can still view conversation with %@ in the list of chats." xml:space="preserve">
|
||||
<source>You can still view conversation with %@ in the list of chats.</source>
|
||||
<target>Vous pouvez toujours voir la conversation avec %@ dans la liste des discussions.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="You can turn on SimpleX Lock via Settings." xml:space="preserve">
|
||||
@@ -7511,10 +7622,12 @@ Répéter la demande de connexion ?</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="You may migrate the exported database." xml:space="preserve">
|
||||
<source>You may migrate the exported database.</source>
|
||||
<target>Vous pouvez migrer la base de données exportée.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="You may save the exported archive." xml:space="preserve">
|
||||
<source>You may save the exported archive.</source>
|
||||
<target>Vous pouvez enregistrer l'archive exportée.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="You must use the most recent version of your chat database on one device ONLY, otherwise you may stop receiving the messages from some contacts." xml:space="preserve">
|
||||
@@ -7524,6 +7637,7 @@ Répéter la demande de connexion ?</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="You need to allow your contact to call to be able to call them." xml:space="preserve">
|
||||
<source>You need to allow your contact to call to be able to call them.</source>
|
||||
<target>Vous devez autoriser votre contact à appeler pour pouvoir l'appeler.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="You need to allow your contact to send voice messages to be able to send them." xml:space="preserve">
|
||||
@@ -7641,6 +7755,10 @@ Répéter la demande de connexion ?</target>
|
||||
<target>Vos profils de chat</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Your connection was moved to %@ but an unexpected error occurred while redirecting you to the profile." xml:space="preserve">
|
||||
<source>Your connection was moved to %@ but an unexpected error occurred while redirecting you to the profile.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Your contact sent a file that is larger than currently supported maximum size (%@)." xml:space="preserve">
|
||||
<source>Your contact sent a file that is larger than currently supported maximum size (%@).</source>
|
||||
<target>Votre contact a envoyé un fichier plus grand que la taille maximale supportée actuellement(%@).</target>
|
||||
@@ -7656,10 +7774,6 @@ Répéter la demande de connexion ?</target>
|
||||
<target>Vos contacts resteront connectés.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Your contacts your way" xml:space="preserve">
|
||||
<source>Your contacts your way</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Your current chat database will be DELETED and REPLACED with the imported one." xml:space="preserve">
|
||||
<source>Your current chat database will be DELETED and REPLACED with the imported one.</source>
|
||||
<target>Votre base de données de chat actuelle va être SUPPRIMEE et REMPLACEE par celle importée.</target>
|
||||
@@ -7839,6 +7953,7 @@ Les serveurs SimpleX ne peuvent pas voir votre profil.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="call" xml:space="preserve">
|
||||
<source>call</source>
|
||||
<target>appeler</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="call error" xml:space="preserve">
|
||||
@@ -8213,6 +8328,7 @@ Les serveurs SimpleX ne peuvent pas voir votre profil.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="invite" xml:space="preserve">
|
||||
<source>invite</source>
|
||||
<target>inviter</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="invited" xml:space="preserve">
|
||||
@@ -8272,6 +8388,7 @@ Les serveurs SimpleX ne peuvent pas voir votre profil.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="message" xml:space="preserve">
|
||||
<source>message</source>
|
||||
<target>message</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="message received" xml:space="preserve">
|
||||
@@ -8306,6 +8423,7 @@ Les serveurs SimpleX ne peuvent pas voir votre profil.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="mute" xml:space="preserve">
|
||||
<source>mute</source>
|
||||
<target>muet</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="never" xml:space="preserve">
|
||||
@@ -8442,6 +8560,7 @@ Les serveurs SimpleX ne peuvent pas voir votre profil.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="search" xml:space="preserve">
|
||||
<source>search</source>
|
||||
<target>rechercher</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="sec" xml:space="preserve">
|
||||
@@ -8530,6 +8649,7 @@ dernier message reçu : %2$@</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="unmute" xml:space="preserve">
|
||||
<source>unmute</source>
|
||||
<target>démuter</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="unprotected" xml:space="preserve">
|
||||
@@ -8579,6 +8699,7 @@ dernier message reçu : %2$@</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="video" xml:space="preserve">
|
||||
<source>video</source>
|
||||
<target>vidéo</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="video call (not e2e encrypted)" xml:space="preserve">
|
||||
@@ -8921,10 +9042,12 @@ dernier message reçu : %2$@</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Sending a message takes longer than expected." xml:space="preserve">
|
||||
<source>Sending a message takes longer than expected.</source>
|
||||
<target>L'envoi d'un message prend plus de temps que prévu.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Sending message…" xml:space="preserve">
|
||||
<source>Sending message…</source>
|
||||
<target>Envoi du message…</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Share" xml:space="preserve">
|
||||
@@ -8934,6 +9057,7 @@ dernier message reçu : %2$@</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Slow network?" xml:space="preserve">
|
||||
<source>Slow network?</source>
|
||||
<target>Réseau lent ?</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Unknown database error: %@" xml:space="preserve">
|
||||
@@ -8948,6 +9072,7 @@ dernier message reçu : %2$@</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Wait" xml:space="preserve">
|
||||
<source>Wait</source>
|
||||
<target>Attendez</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Wrong database passphrase" xml:space="preserve">
|
||||
|
||||
@@ -137,6 +137,10 @@
|
||||
<target>%@ kapcsolódni szeretne!</target>
|
||||
<note>notification title</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="%@, %@" xml:space="preserve">
|
||||
<source>%1$@, %2$@</source>
|
||||
<note>format for date separator in chat</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="%@, %@ and %lld members" xml:space="preserve">
|
||||
<source>%@, %@ and %lld members</source>
|
||||
<target>%@, %@ és további %lld tag</target>
|
||||
@@ -219,12 +223,12 @@
|
||||
</trans-unit>
|
||||
<trans-unit id="%lld messages blocked" xml:space="preserve">
|
||||
<source>%lld messages blocked</source>
|
||||
<target>%lld üzenet blokkolva</target>
|
||||
<target>%lld üzenet letiltva</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="%lld messages blocked by admin" xml:space="preserve">
|
||||
<source>%lld messages blocked by admin</source>
|
||||
<target>%lld üzenet blokkolva az admin által</target>
|
||||
<target>%lld üzenet letiltva az admin által</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="%lld messages marked deleted" xml:space="preserve">
|
||||
@@ -392,11 +396,6 @@
|
||||
<target>, </target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="- Search contacts when starting chat. - Archive contacts to chat later." xml:space="preserve">
|
||||
<source>- Search contacts when starting chat.
|
||||
- Archive contacts to chat later.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="- connect to [directory service](simplex:/contact#/?v=1-4&smp=smp%3A%2F%2Fu2dS9sG8nMNURyZwqASV4yROM28Er0luVTx5X1CsMrU%3D%40smp4.simplex.im%2FeXSPwqTkKyDO3px4fLf1wx3MvPdjdLW3%23%2F%3Fv%3D1-2%26dh%3DMCowBQYDK2VuAyEAaiv6MkMH44L2TcYrt_CsX3ZvM11WgbMEUn0hkIKTOho%253D%26srv%3Do5vmywmrnaxalvz6wi3zicyftgio6psuvyniis6gco6bp6ekl4cqj4id.onion) (BETA)! - delivery receipts (up to 20 members). - faster and more stable." xml:space="preserve">
|
||||
<source>- connect to [directory service](simplex:/contact#/?v=1-4&smp=smp%3A%2F%2Fu2dS9sG8nMNURyZwqASV4yROM28Er0luVTx5X1CsMrU%3D%40smp4.simplex.im%2FeXSPwqTkKyDO3px4fLf1wx3MvPdjdLW3%23%2F%3Fv%3D1-2%26dh%3DMCowBQYDK2VuAyEAaiv6MkMH44L2TcYrt_CsX3ZvM11WgbMEUn0hkIKTOho%253D%26srv%3Do5vmywmrnaxalvz6wi3zicyftgio6psuvyniis6gco6bp6ekl4cqj4id.onion) (BETA)!
|
||||
- delivery receipts (up to 20 members).
|
||||
@@ -566,7 +565,8 @@
|
||||
<source>Accept</source>
|
||||
<target>Elfogadás</target>
|
||||
<note>accept contact request via notification
|
||||
accept incoming call via notification</note>
|
||||
accept incoming call via notification
|
||||
swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Accept connection request?" xml:space="preserve">
|
||||
<source>Accept connection request?</source>
|
||||
@@ -581,7 +581,8 @@
|
||||
<trans-unit id="Accept incognito" xml:space="preserve">
|
||||
<source>Accept incognito</source>
|
||||
<target>Fogadás inkognítóban</target>
|
||||
<note>accept contact request via notification</note>
|
||||
<note>accept contact request via notification
|
||||
swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Acknowledged" xml:space="preserve">
|
||||
<source>Acknowledged</source>
|
||||
@@ -755,6 +756,7 @@
|
||||
</trans-unit>
|
||||
<trans-unit id="Allow calls?" xml:space="preserve">
|
||||
<source>Allow calls?</source>
|
||||
<target>Hívások engedélyezése?</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Allow disappearing messages only if your contact allows it to you." xml:space="preserve">
|
||||
@@ -947,8 +949,14 @@
|
||||
<target>Archiválás és feltöltés</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Archive contacts to chat later." xml:space="preserve">
|
||||
<source>Archive contacts to chat later.</source>
|
||||
<target>Ismerősök archiválása a későbbi csevegéshez.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Archived contacts" xml:space="preserve">
|
||||
<source>Archived contacts</source>
|
||||
<target>Archivált ismerősök</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Archiving database" xml:space="preserve">
|
||||
@@ -1038,7 +1046,7 @@
|
||||
</trans-unit>
|
||||
<trans-unit id="Bad message hash" xml:space="preserve">
|
||||
<source>Bad message hash</source>
|
||||
<target>Téves üzenet hash</target>
|
||||
<target>Hibás az üzenet ellenőrzőösszege</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Better groups" xml:space="preserve">
|
||||
@@ -1051,6 +1059,11 @@
|
||||
<target>Jobb üzenetek</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Better networking" xml:space="preserve">
|
||||
<source>Better networking</source>
|
||||
<target>Jobb hálózatkezelés</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Black" xml:space="preserve">
|
||||
<source>Black</source>
|
||||
<target>Fekete</target>
|
||||
@@ -1058,7 +1071,7 @@
|
||||
</trans-unit>
|
||||
<trans-unit id="Block" xml:space="preserve">
|
||||
<source>Block</source>
|
||||
<target>Blokkolás</target>
|
||||
<target>Letiltás</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Block for all" xml:space="preserve">
|
||||
@@ -1068,12 +1081,12 @@
|
||||
</trans-unit>
|
||||
<trans-unit id="Block group members" xml:space="preserve">
|
||||
<source>Block group members</source>
|
||||
<target>Csoporttagok blokkolása</target>
|
||||
<target>Csoporttagok letiltása</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Block member" xml:space="preserve">
|
||||
<source>Block member</source>
|
||||
<target>Tag blokkolása</target>
|
||||
<target>Tag letiltása</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Block member for all?" xml:space="preserve">
|
||||
@@ -1083,7 +1096,7 @@
|
||||
</trans-unit>
|
||||
<trans-unit id="Block member?" xml:space="preserve">
|
||||
<source>Block member?</source>
|
||||
<target>Tag blokkolása?</target>
|
||||
<target>Tag letiltása?</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Blocked by admin" xml:space="preserve">
|
||||
@@ -1091,6 +1104,11 @@
|
||||
<target>Letiltva az admin által</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Blur for better privacy." xml:space="preserve">
|
||||
<source>Blur for better privacy.</source>
|
||||
<target>Elhomályosítás a jobb adatvédelemért.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Blur media" xml:space="preserve">
|
||||
<source>Blur media</source>
|
||||
<target>Média elhomályosítása</target>
|
||||
@@ -1143,6 +1161,7 @@
|
||||
</trans-unit>
|
||||
<trans-unit id="Calls prohibited!" xml:space="preserve">
|
||||
<source>Calls prohibited!</source>
|
||||
<target>A hívások le vannak tiltva!</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Camera not available" xml:space="preserve">
|
||||
@@ -1152,10 +1171,12 @@
|
||||
</trans-unit>
|
||||
<trans-unit id="Can't call contact" xml:space="preserve">
|
||||
<source>Can't call contact</source>
|
||||
<target>Nem lehet felhívni az ismerőst</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Can't call member" xml:space="preserve">
|
||||
<source>Can't call member</source>
|
||||
<target>Nem lehet felhívni a tagot</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Can't invite contact!" xml:space="preserve">
|
||||
@@ -1170,6 +1191,7 @@
|
||||
</trans-unit>
|
||||
<trans-unit id="Can't message member" xml:space="preserve">
|
||||
<source>Can't message member</source>
|
||||
<target>Nem lehet üzenetet küldeni a tagnak</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Cancel" xml:space="preserve">
|
||||
@@ -1308,6 +1330,11 @@
|
||||
<target>A csevegés leállt. Ha már használta ezt az adatbázist egy másik eszközön, úgy visszaállítás szükséges a csevegés megkezdése előtt.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Chat list" xml:space="preserve">
|
||||
<source>Chat list</source>
|
||||
<target>Csevegőlista</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Chat migrated!" xml:space="preserve">
|
||||
<source>Chat migrated!</source>
|
||||
<target>A csevegés átköltöztetve!</target>
|
||||
@@ -1371,7 +1398,7 @@
|
||||
<trans-unit id="Clear" xml:space="preserve">
|
||||
<source>Clear</source>
|
||||
<target>Kiürítés</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
<note>swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Clear conversation" xml:space="preserve">
|
||||
<source>Clear conversation</source>
|
||||
@@ -1393,6 +1420,11 @@
|
||||
<target>Hitelesítés törlése</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Color chats with the new themes." xml:space="preserve">
|
||||
<source>Color chats with the new themes.</source>
|
||||
<target>Csevegések színezése új témákkal.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Color mode" xml:space="preserve">
|
||||
<source>Color mode</source>
|
||||
<target>Színmód</target>
|
||||
@@ -1435,6 +1467,7 @@
|
||||
</trans-unit>
|
||||
<trans-unit id="Confirm contact deletion?" xml:space="preserve">
|
||||
<source>Confirm contact deletion?</source>
|
||||
<target>Biztosan törli az ismerőst?</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Confirm database upgrades" xml:space="preserve">
|
||||
@@ -1492,8 +1525,9 @@
|
||||
<target>Kapcsolódás számítógéphez</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Connect to your friends faster" xml:space="preserve">
|
||||
<source>Connect to your friends faster</source>
|
||||
<trans-unit id="Connect to your friends faster." xml:space="preserve">
|
||||
<source>Connect to your friends faster.</source>
|
||||
<target>Kapcsolódjon gyorsabban az ismerőseihez.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Connect to yourself?" xml:space="preserve">
|
||||
@@ -1572,6 +1606,7 @@ Ez az egyszer használatos hivatkozása!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Connecting to contact, please wait or check later!" xml:space="preserve">
|
||||
<source>Connecting to contact, please wait or check later!</source>
|
||||
<target>Kapcsolódás az ismerőshöz, várjon vagy ellenőrizze később!</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Connecting to desktop" xml:space="preserve">
|
||||
@@ -1586,6 +1621,7 @@ Ez az egyszer használatos hivatkozása!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Connection and servers status." xml:space="preserve">
|
||||
<source>Connection and servers status.</source>
|
||||
<target>Kapcsolatok- és kiszolgálók állapotának megjelenítése.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Connection error" xml:space="preserve">
|
||||
@@ -1640,6 +1676,7 @@ Ez az egyszer használatos hivatkozása!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Contact deleted!" xml:space="preserve">
|
||||
<source>Contact deleted!</source>
|
||||
<target>Ismerős törölve!</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Contact hidden:" xml:space="preserve">
|
||||
@@ -1654,6 +1691,7 @@ Ez az egyszer használatos hivatkozása!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Contact is deleted." xml:space="preserve">
|
||||
<source>Contact is deleted.</source>
|
||||
<target>Törölt ismerős.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Contact name" xml:space="preserve">
|
||||
@@ -1668,6 +1706,7 @@ Ez az egyszer használatos hivatkozása!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Contact will be deleted - this cannot be undone!" xml:space="preserve">
|
||||
<source>Contact will be deleted - this cannot be undone!</source>
|
||||
<target>Az ismerős törlésre fog kerülni - ez a művelet nem vonható vissza!</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Contacts" xml:space="preserve">
|
||||
@@ -1685,12 +1724,9 @@ Ez az egyszer használatos hivatkozása!</target>
|
||||
<target>Folytatás</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Control your network" xml:space="preserve">
|
||||
<source>Control your network</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Conversation deleted!" xml:space="preserve">
|
||||
<source>Conversation deleted!</source>
|
||||
<target>Beszélgetés törölve!</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Copy" xml:space="preserve">
|
||||
@@ -1708,6 +1744,10 @@ Ez az egyszer használatos hivatkozása!</target>
|
||||
<target>Alapverziószám: v%@</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Corner" xml:space="preserve">
|
||||
<source>Corner</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Correct name to %@?" xml:space="preserve">
|
||||
<source>Correct name to %@?</source>
|
||||
<target>Név javítása erre: %@?</target>
|
||||
@@ -1964,7 +2004,8 @@ Ez az egyszer használatos hivatkozása!</target>
|
||||
<trans-unit id="Delete" xml:space="preserve">
|
||||
<source>Delete</source>
|
||||
<target>Törlés</target>
|
||||
<note>chat item action</note>
|
||||
<note>chat item action
|
||||
swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Delete %lld messages of members?" xml:space="preserve">
|
||||
<source>Delete %lld messages of members?</source>
|
||||
@@ -2033,6 +2074,7 @@ Ez az egyszer használatos hivatkozása!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Delete contact?" xml:space="preserve">
|
||||
<source>Delete contact?</source>
|
||||
<target>Ismerős törlése?</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Delete database" xml:space="preserve">
|
||||
@@ -2097,7 +2139,7 @@ Ez az egyszer használatos hivatkozása!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Delete member message?" xml:space="preserve">
|
||||
<source>Delete member message?</source>
|
||||
<target>Csoporttag üzenet törlése?</target>
|
||||
<target>Csoporttag üzenetének törlése?</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Delete message?" xml:space="preserve">
|
||||
@@ -2142,6 +2184,7 @@ Ez az egyszer használatos hivatkozása!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Delete up to 20 messages at once." xml:space="preserve">
|
||||
<source>Delete up to 20 messages at once.</source>
|
||||
<target>Legfeljebb 20 üzenet törlése egyszerre.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Delete user profile?" xml:space="preserve">
|
||||
@@ -2151,6 +2194,7 @@ Ez az egyszer használatos hivatkozása!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Delete without notification" xml:space="preserve">
|
||||
<source>Delete without notification</source>
|
||||
<target>Törlés értesítés nélkül</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Deleted" xml:space="preserve">
|
||||
@@ -2168,10 +2212,6 @@ Ez az egyszer használatos hivatkozása!</target>
|
||||
<target>Törölve ekkor: %@</target>
|
||||
<note>copied message info</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Deleted chats" xml:space="preserve">
|
||||
<source>Deleted chats</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Deletion errors" xml:space="preserve">
|
||||
<source>Deletion errors</source>
|
||||
<target>Törlési hibák</target>
|
||||
@@ -2189,7 +2229,7 @@ Ez az egyszer használatos hivatkozása!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Delivery receipts!" xml:space="preserve">
|
||||
<source>Delivery receipts!</source>
|
||||
<target>Kézbesítési igazolások!</target>
|
||||
<target>Üzenet kézbesítési jelentések!</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Description" xml:space="preserve">
|
||||
@@ -2244,6 +2284,7 @@ Ez az egyszer használatos hivatkozása!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Developer options" xml:space="preserve">
|
||||
<source>Developer options</source>
|
||||
<target>Fejlesztői beállítások</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Developer tools" xml:space="preserve">
|
||||
@@ -2648,12 +2689,12 @@ Ez az egyszer használatos hivatkozása!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Enter welcome message…" xml:space="preserve">
|
||||
<source>Enter welcome message…</source>
|
||||
<target>Üdvözlő üzenetet megadása…</target>
|
||||
<target>Üdvözlő üzenet megadása…</target>
|
||||
<note>placeholder</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Enter welcome message… (optional)" xml:space="preserve">
|
||||
<source>Enter welcome message… (optional)</source>
|
||||
<target>Üdvözlő üzenetet megadása… (opcionális)</target>
|
||||
<target>Üdvözlő üzenet megadása… (opcionális)</target>
|
||||
<note>placeholder</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Enter your name…" xml:space="preserve">
|
||||
@@ -2691,6 +2732,10 @@ Ez az egyszer használatos hivatkozása!</target>
|
||||
<target>Hiba a cím megváltoztatásakor</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Error changing connection profile" xml:space="preserve">
|
||||
<source>Error changing connection profile</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Error changing role" xml:space="preserve">
|
||||
<source>Error changing role</source>
|
||||
<target>Hiba a szerepkör megváltoztatásakor</target>
|
||||
@@ -2701,6 +2746,10 @@ Ez az egyszer használatos hivatkozása!</target>
|
||||
<target>Hiba a beállítás megváltoztatásakor</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Error changing to incognito!" xml:space="preserve">
|
||||
<source>Error changing to incognito!</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Error connecting to forwarding server %@. Please try later." xml:space="preserve">
|
||||
<source>Error connecting to forwarding server %@. Please try later.</source>
|
||||
<target>Hiba a(z) %@ továbbító kiszolgálóhoz való kapcsolódáskor. Próbálja meg később.</target>
|
||||
@@ -2921,6 +2970,10 @@ Ez az egyszer használatos hivatkozása!</target>
|
||||
<target>Hiba a csevegés megállításakor</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Error switching profile" xml:space="preserve">
|
||||
<source>Error switching profile</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Error switching profile!" xml:space="preserve">
|
||||
<source>Error switching profile!</source>
|
||||
<target>Hiba a profil váltásakor!</target>
|
||||
@@ -2928,7 +2981,7 @@ Ez az egyszer használatos hivatkozása!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Error synchronizing connection" xml:space="preserve">
|
||||
<source>Error synchronizing connection</source>
|
||||
<target>Hiba a kapcsolat szinkronizálása során</target>
|
||||
<target>Hiba a kapcsolat szinkronizálása közben</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Error updating group link" xml:space="preserve">
|
||||
@@ -2992,10 +3045,6 @@ Ez az egyszer használatos hivatkozása!</target>
|
||||
<target>Akkor is, ha le van tiltva a beszélgetésben.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Even when they are offline." xml:space="preserve">
|
||||
<source>Even when they are offline.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Exit without saving" xml:space="preserve">
|
||||
<source>Exit without saving</source>
|
||||
<target>Kilépés mentés nélkül</target>
|
||||
@@ -3054,7 +3103,7 @@ Ez az egyszer használatos hivatkozása!</target>
|
||||
<trans-unit id="Favorite" xml:space="preserve">
|
||||
<source>Favorite</source>
|
||||
<target>Kedvenc</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
<note>swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="File error" xml:space="preserve">
|
||||
<source>File error</source>
|
||||
@@ -3512,7 +3561,7 @@ Hiba: %2$@</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="If you can't meet in person, show QR code in a video call, or share the link." xml:space="preserve">
|
||||
<source>If you can't meet in person, show QR code in a video call, or share the link.</source>
|
||||
<target>Ha nem tud személyesen találkozni, mutassa meg a QR-kódot egy videohívás során, vagy ossza meg a hivatkozást.</target>
|
||||
<target>Ha nem tud személyesen találkozni, mutassa meg a QR-kódot egy videohívás közben, vagy ossza meg a hivatkozást.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="If you enter this passcode when opening the app, all app data will be irreversibly removed!" xml:space="preserve">
|
||||
@@ -3810,6 +3859,7 @@ Hiba: %2$@</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="It protects your IP address and connections." xml:space="preserve">
|
||||
<source>It protects your IP address and connections.</source>
|
||||
<target>Védi az IP-címét és a kapcsolatokat.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</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">
|
||||
@@ -3830,7 +3880,7 @@ Hiba: %2$@</target>
|
||||
<trans-unit id="Join" xml:space="preserve">
|
||||
<source>Join</source>
|
||||
<target>Csatlakozás</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
<note>swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Join group" xml:space="preserve">
|
||||
<source>Join group</source>
|
||||
@@ -3876,6 +3926,7 @@ Ez az ön hivatkozása a(z) %@ csoporthoz!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Keep conversation" xml:space="preserve">
|
||||
<source>Keep conversation</source>
|
||||
<target>Beszélgetés megtartása</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">
|
||||
@@ -3921,7 +3972,7 @@ Ez az ön hivatkozása a(z) %@ csoporthoz!</target>
|
||||
<trans-unit id="Leave" xml:space="preserve">
|
||||
<source>Leave</source>
|
||||
<target>Elhagyás</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
<note>swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Leave group" xml:space="preserve">
|
||||
<source>Leave group</source>
|
||||
@@ -4100,7 +4151,7 @@ Ez az ön hivatkozása a(z) %@ csoporthoz!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message delivery receipts!" xml:space="preserve">
|
||||
<source>Message delivery receipts!</source>
|
||||
<target>Üzenetkézbesítési bizonylatok!</target>
|
||||
<target>Üzenet kézbesítési jelentések!</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message delivery warning" xml:space="preserve">
|
||||
@@ -4145,7 +4196,7 @@ Ez az ön hivatkozása a(z) %@ csoporthoz!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message reception" xml:space="preserve">
|
||||
<source>Message reception</source>
|
||||
<target>Üzenetjelentés</target>
|
||||
<target>Üzenet kézbesítési jelentés</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message servers" xml:space="preserve">
|
||||
@@ -4153,6 +4204,10 @@ Ez az ön hivatkozása a(z) %@ csoporthoz!</target>
|
||||
<target>Üzenetkiszolgálók</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message shape" xml:space="preserve">
|
||||
<source>Message shape</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message source remains private." xml:space="preserve">
|
||||
<source>Message source remains private.</source>
|
||||
<target>Az üzenet forrása titokban marad.</target>
|
||||
@@ -4278,10 +4333,6 @@ Ez az ön hivatkozása a(z) %@ csoporthoz!</target>
|
||||
<target>Moderálás</target>
|
||||
<note>chat item action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Moderate like a pro ✋" xml:space="preserve">
|
||||
<source>Moderate like a pro ✋</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Moderated at" xml:space="preserve">
|
||||
<source>Moderated at</source>
|
||||
<target>Moderálva lett ekkor:</target>
|
||||
@@ -4314,8 +4365,8 @@ Ez az ön hivatkozása a(z) %@ csoporthoz!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Mute" xml:space="preserve">
|
||||
<source>Mute</source>
|
||||
<target>Elnémítás</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
<target>Némítás</target>
|
||||
<note>swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Muted when inactive!" xml:space="preserve">
|
||||
<source>Muted when inactive!</source>
|
||||
@@ -4325,7 +4376,7 @@ Ez az ön hivatkozása a(z) %@ csoporthoz!</target>
|
||||
<trans-unit id="Name" xml:space="preserve">
|
||||
<source>Name</source>
|
||||
<target>Név</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
<note>swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Network & servers" xml:space="preserve">
|
||||
<source>Network & servers</source>
|
||||
@@ -4357,10 +4408,6 @@ Ez az ön hivatkozása a(z) %@ csoporthoz!</target>
|
||||
<target>Hálózat állapota</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="New Chat" xml:space="preserve">
|
||||
<source>New Chat</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="New Passcode" xml:space="preserve">
|
||||
<source>New Passcode</source>
|
||||
<target>Új jelkód</target>
|
||||
@@ -4371,6 +4418,11 @@ Ez az ön hivatkozása a(z) %@ csoporthoz!</target>
|
||||
<target>Új beszélgetés</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="New chat experience 🎉" xml:space="preserve">
|
||||
<source>New chat experience 🎉</source>
|
||||
<target>Új csevegési élmény 🎉</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="New contact request" xml:space="preserve">
|
||||
<source>New contact request</source>
|
||||
<target>Új kapcsolattartási kérelem</target>
|
||||
@@ -4401,6 +4453,11 @@ Ez az ön hivatkozása a(z) %@ csoporthoz!</target>
|
||||
<target>Újdonságok a(z) %@ verzióban</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="New media options" xml:space="preserve">
|
||||
<source>New media options</source>
|
||||
<target>Új médiabeállítások</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="New member role" xml:space="preserve">
|
||||
<source>New member role</source>
|
||||
<target>Új tag szerepköre</target>
|
||||
@@ -4540,10 +4597,6 @@ Ez az ön hivatkozása a(z) %@ csoporthoz!</target>
|
||||
<target>Régi adatbázis archívum</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="One-hand UI" xml:space="preserve">
|
||||
<source>One-hand UI</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="One-time invitation link" xml:space="preserve">
|
||||
<source>One-time invitation link</source>
|
||||
<target>Egyszer használatos meghívó hivatkozás</target>
|
||||
@@ -4575,6 +4628,7 @@ VPN engedélyezése szükséges.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Only delete conversation" xml:space="preserve">
|
||||
<source>Only delete conversation</source>
|
||||
<target>Csak a beszélgetés törlése</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Only group owners can change group preferences." xml:space="preserve">
|
||||
@@ -4812,8 +4866,14 @@ VPN engedélyezése szükséges.</target>
|
||||
<target>Kép a képben hívások</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Play from the chat list." xml:space="preserve">
|
||||
<source>Play from the chat list.</source>
|
||||
<target>Lejátszás a csevegési listából.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Please ask your contact to enable calls." xml:space="preserve">
|
||||
<source>Please ask your contact to enable calls.</source>
|
||||
<target>Kérje meg az ismerősét, hogy engedélyezze a hívásokat.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Please ask your contact to enable sending voice messages." xml:space="preserve">
|
||||
@@ -5069,7 +5129,7 @@ Hiba: %@</target>
|
||||
<source>Protect your IP address from the messaging relays chosen by your contacts.
|
||||
Enable in *Network & servers* settings.</source>
|
||||
<target>Védje IP-címét az ismerősei által kiválasztott üzenetküldő átjátszókkal szemben.
|
||||
Engedélyezze a beállításokban a *Hálózat és kiszolgálók* menüpontban.</target>
|
||||
Engedélyezze a Beállítások / Hálózat és kiszolgálók menüben.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Protect your chat profiles with a password!" xml:space="preserve">
|
||||
@@ -5117,8 +5177,9 @@ Engedélyezze a beállításokban a *Hálózat és kiszolgálók* menüpontban.<
|
||||
<target>Értékelje az alkalmazást</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Reachable chat toolbar 👋" xml:space="preserve">
|
||||
<source>Reachable chat toolbar 👋</source>
|
||||
<trans-unit id="Reachable chat toolbar" xml:space="preserve">
|
||||
<source>Reachable chat toolbar</source>
|
||||
<target>Könnyen elérhető eszköztár</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="React…" xml:space="preserve">
|
||||
@@ -5129,7 +5190,7 @@ Engedélyezze a beállításokban a *Hálózat és kiszolgálók* menüpontban.<
|
||||
<trans-unit id="Read" xml:space="preserve">
|
||||
<source>Read</source>
|
||||
<target>Olvasd el</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
<note>swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Read more" xml:space="preserve">
|
||||
<source>Read more</source>
|
||||
@@ -5289,7 +5350,8 @@ Engedélyezze a beállításokban a *Hálózat és kiszolgálók* menüpontban.<
|
||||
<trans-unit id="Reject" xml:space="preserve">
|
||||
<source>Reject</source>
|
||||
<target>Elutasítás</target>
|
||||
<note>reject incoming call via notification</note>
|
||||
<note>reject incoming call via notification
|
||||
swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Reject (sender NOT notified)" xml:space="preserve">
|
||||
<source>Reject (sender NOT notified)</source>
|
||||
@@ -5391,6 +5453,11 @@ Engedélyezze a beállításokban a *Hálózat és kiszolgálók* menüpontban.<
|
||||
<target>Alaphelyzetbe állítás</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Reset all hints" xml:space="preserve">
|
||||
<source>Reset all hints</source>
|
||||
<target>Tippek visszaállítása</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Reset all statistics" xml:space="preserve">
|
||||
<source>Reset all statistics</source>
|
||||
<target>Minden statisztika visszaállítása</target>
|
||||
@@ -5686,6 +5753,10 @@ Engedélyezze a beállításokban a *Hálózat és kiszolgálók* menüpontban.<
|
||||
<target>Választás</target>
|
||||
<note>chat item action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Select chat profile" xml:space="preserve">
|
||||
<source>Select chat profile</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Selected %lld" xml:space="preserve">
|
||||
<source>Selected %lld</source>
|
||||
<target>%lld kiválasztva</target>
|
||||
@@ -5758,6 +5829,7 @@ Engedélyezze a beállításokban a *Hálózat és kiszolgálók* menüpontban.<
|
||||
</trans-unit>
|
||||
<trans-unit id="Send message to enable calls." xml:space="preserve">
|
||||
<source>Send message to enable calls.</source>
|
||||
<target>Üzenet küldése a hívások engedélyezéséhez.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Send messages directly when IP address is protected and your or destination server does not support private routing." xml:space="preserve">
|
||||
@@ -5927,7 +5999,7 @@ Engedélyezze a beállításokban a *Hálózat és kiszolgálók* menüpontban.<
|
||||
</trans-unit>
|
||||
<trans-unit id="Server test failed!" xml:space="preserve">
|
||||
<source>Server test failed!</source>
|
||||
<target>Sikertelen kiszolgáló-teszt!</target>
|
||||
<target>Sikertelen kiszolgáló teszt!</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Server type" xml:space="preserve">
|
||||
@@ -6045,11 +6117,20 @@ Engedélyezze a beállításokban a *Hálózat és kiszolgálók* menüpontban.<
|
||||
<target>Megosztja a címet az ismerőseivel?</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Share from other apps." xml:space="preserve">
|
||||
<source>Share from other apps.</source>
|
||||
<target>Megosztás más alkalmazásokból.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Share link" xml:space="preserve">
|
||||
<source>Share link</source>
|
||||
<target>Hivatkozás megosztása</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Share profile" xml:space="preserve">
|
||||
<source>Share profile</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Share this 1-time invite link" xml:space="preserve">
|
||||
<source>Share this 1-time invite link</source>
|
||||
<target>Egyszer használatos meghívó hivatkozás megosztása</target>
|
||||
@@ -6222,12 +6303,12 @@ Engedélyezze a beállításokban a *Hálózat és kiszolgálók* menüpontban.<
|
||||
</trans-unit>
|
||||
<trans-unit id="Some non-fatal errors occurred during import - you may see Chat console for more details." xml:space="preserve">
|
||||
<source>Some non-fatal errors occurred during import - you may see Chat console for more details.</source>
|
||||
<target>Néhány nem végzetes hiba történt az importálás során – további részletekért a csevegési konzolban olvashat.</target>
|
||||
<target>Néhány nem végzetes hiba történt az importálás közben – további részletekért a csevegési konzolban olvashat.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Some non-fatal errors occurred during import:" xml:space="preserve">
|
||||
<source>Some non-fatal errors occurred during import:</source>
|
||||
<target>Néhány nem végzetes hiba történt az importálás során:</target>
|
||||
<target>Néhány nem végzetes hiba történt az importálás közben:</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Somebody" xml:space="preserve">
|
||||
@@ -6390,6 +6471,10 @@ Engedélyezze a beállításokban a *Hálózat és kiszolgálók* menüpontban.<
|
||||
<target>TCP_KEEPINTVL</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Tail" xml:space="preserve">
|
||||
<source>Tail</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Take picture" xml:space="preserve">
|
||||
<source>Take picture</source>
|
||||
<target>Kép készítése</target>
|
||||
@@ -6514,7 +6599,7 @@ Ez valamilyen hiba, vagy sérült kapcsolat esetén fordulhat elő.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="The created archive is available via app Settings / Database / Old database archive." xml:space="preserve">
|
||||
<source>The created archive is available via app Settings / Database / Old database archive.</source>
|
||||
<target>A létrehozott archívum a Beállítások / Adatbázis / Régi adatbázis-archívum menüpontban érhető el.</target>
|
||||
<target>A létrehozott archívum a Beállítások / Adatbázis / Régi adatbázis-archívum menüben érhető el.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="The encryption is working and the new encryption agreement is not required. It may result in connection errors!" xml:space="preserve">
|
||||
@@ -6524,7 +6609,7 @@ Ez valamilyen hiba, vagy sérült kapcsolat esetén fordulhat elő.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="The hash of the previous message is different." xml:space="preserve">
|
||||
<source>The hash of the previous message is different.</source>
|
||||
<target>Az előző üzenet hash-e más.</target>
|
||||
<target>Az előző üzenet ellenőrzőösszege különbözik.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="The message will be deleted for all members." xml:space="preserve">
|
||||
@@ -6554,7 +6639,7 @@ Ez valamilyen hiba, vagy sérült kapcsolat esetén fordulhat elő.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="The old database was not removed during the migration, it can be deleted." xml:space="preserve">
|
||||
<source>The old database was not removed during the migration, it can be deleted.</source>
|
||||
<target>A régi adatbázis nem került eltávolításra az átköltöztetés során, így törölhető.</target>
|
||||
<target>A régi adatbázis nem került eltávolításra az átköltöztetés közben, így törölhető.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="The profile is only shared with your contacts." xml:space="preserve">
|
||||
@@ -6729,11 +6814,21 @@ A funkció bekapcsolása előtt a rendszer felszólítja a képernyőzár beáll
|
||||
<target>A végpontok közötti titkosítás ellenőrzéséhez hasonlítsa össze (vagy olvassa be a QR-kódot) az ismerőse eszközén lévő kóddal.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Toggle chat list:" xml:space="preserve">
|
||||
<source>Toggle chat list:</source>
|
||||
<target>Csevegőlista átváltása:</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Toggle incognito when connecting." xml:space="preserve">
|
||||
<source>Toggle incognito when connecting.</source>
|
||||
<target>Inkognitó mód kapcsolódáskor.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Toolbar opacity" xml:space="preserve">
|
||||
<source>Toolbar opacity</source>
|
||||
<target>Eszköztár átlátszatlansága</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Total" xml:space="preserve">
|
||||
<source>Total</source>
|
||||
<target>Összesen</target>
|
||||
@@ -6812,7 +6907,7 @@ A funkció bekapcsolása előtt a rendszer felszólítja a képernyőzár beáll
|
||||
<trans-unit id="Unfav." xml:space="preserve">
|
||||
<source>Unfav.</source>
|
||||
<target>Nem kedvelt.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
<note>swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Unhide" xml:space="preserve">
|
||||
<source>Unhide</source>
|
||||
@@ -6889,12 +6984,12 @@ A kapcsolódáshoz kérje meg ismerősét, hogy hozzon létre egy másik kapcsol
|
||||
<trans-unit id="Unmute" xml:space="preserve">
|
||||
<source>Unmute</source>
|
||||
<target>Némítás feloldása</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
<note>swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Unread" xml:space="preserve">
|
||||
<source>Unread</source>
|
||||
<target>Olvasatlan</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
<note>swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Up to 100 last messages are sent to new members." xml:space="preserve">
|
||||
<source>Up to 100 last messages are sent to new members.</source>
|
||||
@@ -7028,6 +7123,7 @@ A kapcsolódáshoz kérje meg ismerősét, hogy hozzon létre egy másik kapcsol
|
||||
</trans-unit>
|
||||
<trans-unit id="Use the app with one hand." xml:space="preserve">
|
||||
<source>Use the app with one hand.</source>
|
||||
<target>Használja az alkalmazást egy kézzel.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="User profile" xml:space="preserve">
|
||||
@@ -7387,6 +7483,11 @@ Csatlakozási kérés megismétlése?</target>
|
||||
<target>Hívásokat fogadhat a lezárási képernyőről, eszköz- és alkalmazáshitelesítés nélkül.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="You can change it in Appearance settings." xml:space="preserve">
|
||||
<source>You can change it in Appearance settings.</source>
|
||||
<target>Ezt a „Megjelenés” menüben módosíthatja.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="You can create it later" xml:space="preserve">
|
||||
<source>You can create it later</source>
|
||||
<target>Létrehozás később</target>
|
||||
@@ -7399,7 +7500,7 @@ Csatlakozási kérés megismétlése?</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="You can enable them later via app Privacy & Security settings." xml:space="preserve">
|
||||
<source>You can enable them later via app Privacy & Security settings.</source>
|
||||
<target>Később engedélyezheti őket az alkalmazás Adatvédelem és biztonság menüpontban.</target>
|
||||
<target>Később engedélyezheti őket az alkalmazás „Adatvédelem és biztonság” menüben.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="You can give another try." xml:space="preserve">
|
||||
@@ -7424,6 +7525,7 @@ Csatlakozási kérés megismétlése?</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="You can send messages to %@ from Archived contacts." xml:space="preserve">
|
||||
<source>You can send messages to %@ from Archived contacts.</source>
|
||||
<target>Az „Archivált ismerősökből” továbbra is küldhet üzeneteket neki: %@.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="You can set lock screen notification preview via settings." xml:space="preserve">
|
||||
@@ -7448,11 +7550,12 @@ Csatlakozási kérés megismétlése?</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="You can start chat via app Settings / Database or by restarting the app" xml:space="preserve">
|
||||
<source>You can start chat via app Settings / Database or by restarting the app</source>
|
||||
<target>A csevegést az alkalmazás Beállítások / Adatbázis menü segítségével vagy az alkalmazás újraindításával indíthatja el</target>
|
||||
<target>A csevegést az alkalmazás Beállítások / Adatbázis menüben vagy az alkalmazás újraindításával indíthatja el</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="You can still view conversation with %@ in the list of chats." xml:space="preserve">
|
||||
<source>You can still view conversation with %@ in the list of chats.</source>
|
||||
<target>A(z) %@ nevű ismerősével folytatott beszélgetéseit továbbra is megtekintheti a csevegések listájában.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="You can turn on SimpleX Lock via Settings." xml:space="preserve">
|
||||
@@ -7534,6 +7637,7 @@ Kapcsolódási kérés megismétlése?</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="You need to allow your contact to call to be able to call them." xml:space="preserve">
|
||||
<source>You need to allow your contact to call to be able to call them.</source>
|
||||
<target>Engedélyeznie kell a hívásokat az ismerőse számára, hogy fel tudják hívni egymást.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="You need to allow your contact to send voice messages to be able to send them." xml:space="preserve">
|
||||
@@ -7651,6 +7755,10 @@ Kapcsolódási kérés megismétlése?</target>
|
||||
<target>Csevegési profilok</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Your connection was moved to %@ but an unexpected error occurred while redirecting you to the profile." xml:space="preserve">
|
||||
<source>Your connection was moved to %@ but an unexpected error occurred while redirecting you to the profile.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Your contact sent a file that is larger than currently supported maximum size (%@)." xml:space="preserve">
|
||||
<source>Your contact sent a file that is larger than currently supported maximum size (%@).</source>
|
||||
<target>Ismerőse olyan fájlt küldött, amely meghaladja a jelenleg támogatott maximális méretet (%@).</target>
|
||||
@@ -7666,10 +7774,6 @@ Kapcsolódási kérés megismétlése?</target>
|
||||
<target>Az ismerősei továbbra is kapcsolódva maradnak.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Your contacts your way" xml:space="preserve">
|
||||
<source>Your contacts your way</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Your current chat database will be DELETED and REPLACED with the imported one." xml:space="preserve">
|
||||
<source>Your current chat database will be DELETED and REPLACED with the imported one.</source>
|
||||
<target>A jelenlegi csevegési adatbázis TÖRLŐDNI FOG, és a HELYÉRE az importált adatbázis kerül.</target>
|
||||
@@ -7824,17 +7928,17 @@ A SimpleX kiszolgálók nem látjhatják profilját.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="bad message hash" xml:space="preserve">
|
||||
<source>bad message hash</source>
|
||||
<target>téves üzenet hash</target>
|
||||
<target>hibás az üzenet ellenőrzőösszege</target>
|
||||
<note>integrity error chat item</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="blocked" xml:space="preserve">
|
||||
<source>blocked</source>
|
||||
<target>blokkolva</target>
|
||||
<target>letiltva</target>
|
||||
<note>marked deleted chat item preview text</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="blocked %@" xml:space="preserve">
|
||||
<source>blocked %@</source>
|
||||
<target>letiltotta őt: %@</target>
|
||||
<target>letiltotta %@-t</target>
|
||||
<note>rcv group event chat item</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="blocked by admin" xml:space="preserve">
|
||||
@@ -7849,6 +7953,7 @@ A SimpleX kiszolgálók nem látjhatják profilját.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="call" xml:space="preserve">
|
||||
<source>call</source>
|
||||
<target>hívás</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="call error" xml:space="preserve">
|
||||
@@ -8223,6 +8328,7 @@ A SimpleX kiszolgálók nem látjhatják profilját.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="invite" xml:space="preserve">
|
||||
<source>invite</source>
|
||||
<target>meghívás</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="invited" xml:space="preserve">
|
||||
@@ -8282,6 +8388,7 @@ A SimpleX kiszolgálók nem látjhatják profilját.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="message" xml:space="preserve">
|
||||
<source>message</source>
|
||||
<target>üzenet</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="message received" xml:space="preserve">
|
||||
@@ -8316,6 +8423,7 @@ A SimpleX kiszolgálók nem látjhatják profilját.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="mute" xml:space="preserve">
|
||||
<source>mute</source>
|
||||
<target>némítás</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="never" xml:space="preserve">
|
||||
@@ -8422,7 +8530,7 @@ A SimpleX kiszolgálók nem látjhatják profilját.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="removed %@" xml:space="preserve">
|
||||
<source>removed %@</source>
|
||||
<target>%@ eltávolítva</target>
|
||||
<target>eltávolította őt: %@</target>
|
||||
<note>rcv group event chat item</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="removed contact address" xml:space="preserve">
|
||||
@@ -8452,6 +8560,7 @@ A SimpleX kiszolgálók nem látjhatják profilját.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="search" xml:space="preserve">
|
||||
<source>search</source>
|
||||
<target>keresés</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="sec" xml:space="preserve">
|
||||
@@ -8520,7 +8629,7 @@ utoljára fogadott üzenet: %2$@</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="unblocked %@" xml:space="preserve">
|
||||
<source>unblocked %@</source>
|
||||
<target>%@ feloldva</target>
|
||||
<target>feloldotta %@ letiltását</target>
|
||||
<note>rcv group event chat item</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="unknown" xml:space="preserve">
|
||||
@@ -8540,6 +8649,7 @@ utoljára fogadott üzenet: %2$@</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="unmute" xml:space="preserve">
|
||||
<source>unmute</source>
|
||||
<target>némítás feloldása</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="unprotected" xml:space="preserve">
|
||||
@@ -8589,6 +8699,7 @@ utoljára fogadott üzenet: %2$@</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="video" xml:space="preserve">
|
||||
<source>video</source>
|
||||
<target>videó</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="video call (not e2e encrypted)" xml:space="preserve">
|
||||
@@ -8643,7 +8754,7 @@ utoljára fogadott üzenet: %2$@</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="you blocked %@" xml:space="preserve">
|
||||
<source>you blocked %@</source>
|
||||
<target>blokkolta őt: %@</target>
|
||||
<target>ön letiltotta %@-t</target>
|
||||
<note>snd group event chat item</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="you changed address" xml:space="preserve">
|
||||
@@ -8688,7 +8799,7 @@ utoljára fogadott üzenet: %2$@</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="you unblocked %@" xml:space="preserve">
|
||||
<source>you unblocked %@</source>
|
||||
<target>feloldotta %@ blokkolását</target>
|
||||
<target>ön feloldotta %@ letiltását</target>
|
||||
<note>snd group event chat item</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="you: " xml:space="preserve">
|
||||
@@ -8971,7 +9082,7 @@ utoljára fogadott üzenet: %2$@</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="You can allow sharing in Privacy & Security / SimpleX Lock settings." xml:space="preserve">
|
||||
<source>You can allow sharing in Privacy & Security / SimpleX Lock settings.</source>
|
||||
<target>A megosztást az Adatvédelem és biztonság / SimpleX zár menüpontban engedélyezheti.</target>
|
||||
<target>A megosztást az Adatvédelem és biztonság / SimpleX zár menüben engedélyezheti.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
</body>
|
||||
|
||||
@@ -137,6 +137,10 @@
|
||||
<target>%@ si vuole connettere!</target>
|
||||
<note>notification title</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="%@, %@" xml:space="preserve">
|
||||
<source>%1$@, %2$@</source>
|
||||
<note>format for date separator in chat</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="%@, %@ and %lld members" xml:space="preserve">
|
||||
<source>%@, %@ and %lld members</source>
|
||||
<target>%@, %@ e %lld membri</target>
|
||||
@@ -392,11 +396,6 @@
|
||||
<target>, </target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="- Search contacts when starting chat. - Archive contacts to chat later." xml:space="preserve">
|
||||
<source>- Search contacts when starting chat.
|
||||
- Archive contacts to chat later.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="- connect to [directory service](simplex:/contact#/?v=1-4&smp=smp%3A%2F%2Fu2dS9sG8nMNURyZwqASV4yROM28Er0luVTx5X1CsMrU%3D%40smp4.simplex.im%2FeXSPwqTkKyDO3px4fLf1wx3MvPdjdLW3%23%2F%3Fv%3D1-2%26dh%3DMCowBQYDK2VuAyEAaiv6MkMH44L2TcYrt_CsX3ZvM11WgbMEUn0hkIKTOho%253D%26srv%3Do5vmywmrnaxalvz6wi3zicyftgio6psuvyniis6gco6bp6ekl4cqj4id.onion) (BETA)! - delivery receipts (up to 20 members). - faster and more stable." xml:space="preserve">
|
||||
<source>- connect to [directory service](simplex:/contact#/?v=1-4&smp=smp%3A%2F%2Fu2dS9sG8nMNURyZwqASV4yROM28Er0luVTx5X1CsMrU%3D%40smp4.simplex.im%2FeXSPwqTkKyDO3px4fLf1wx3MvPdjdLW3%23%2F%3Fv%3D1-2%26dh%3DMCowBQYDK2VuAyEAaiv6MkMH44L2TcYrt_CsX3ZvM11WgbMEUn0hkIKTOho%253D%26srv%3Do5vmywmrnaxalvz6wi3zicyftgio6psuvyniis6gco6bp6ekl4cqj4id.onion) (BETA)!
|
||||
- delivery receipts (up to 20 members).
|
||||
@@ -566,7 +565,8 @@
|
||||
<source>Accept</source>
|
||||
<target>Accetta</target>
|
||||
<note>accept contact request via notification
|
||||
accept incoming call via notification</note>
|
||||
accept incoming call via notification
|
||||
swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Accept connection request?" xml:space="preserve">
|
||||
<source>Accept connection request?</source>
|
||||
@@ -581,7 +581,8 @@
|
||||
<trans-unit id="Accept incognito" xml:space="preserve">
|
||||
<source>Accept incognito</source>
|
||||
<target>Accetta in incognito</target>
|
||||
<note>accept contact request via notification</note>
|
||||
<note>accept contact request via notification
|
||||
swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Acknowledged" xml:space="preserve">
|
||||
<source>Acknowledged</source>
|
||||
@@ -755,6 +756,7 @@
|
||||
</trans-unit>
|
||||
<trans-unit id="Allow calls?" xml:space="preserve">
|
||||
<source>Allow calls?</source>
|
||||
<target>Consentire le chiamate?</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Allow disappearing messages only if your contact allows it to you." xml:space="preserve">
|
||||
@@ -947,8 +949,14 @@
|
||||
<target>Archivia e carica</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Archive contacts to chat later." xml:space="preserve">
|
||||
<source>Archive contacts to chat later.</source>
|
||||
<target>Archivia contatti per chattare più tardi.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Archived contacts" xml:space="preserve">
|
||||
<source>Archived contacts</source>
|
||||
<target>Contatti archiviati</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Archiving database" xml:space="preserve">
|
||||
@@ -1051,6 +1059,11 @@
|
||||
<target>Messaggi migliorati</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Better networking" xml:space="preserve">
|
||||
<source>Better networking</source>
|
||||
<target>Rete migliorata</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Black" xml:space="preserve">
|
||||
<source>Black</source>
|
||||
<target>Nero</target>
|
||||
@@ -1091,6 +1104,11 @@
|
||||
<target>Bloccato dall'amministratore</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Blur for better privacy." xml:space="preserve">
|
||||
<source>Blur for better privacy.</source>
|
||||
<target>Sfoca per una privacy maggiore.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Blur media" xml:space="preserve">
|
||||
<source>Blur media</source>
|
||||
<target>Sfocatura file multimediali</target>
|
||||
@@ -1143,6 +1161,7 @@
|
||||
</trans-unit>
|
||||
<trans-unit id="Calls prohibited!" xml:space="preserve">
|
||||
<source>Calls prohibited!</source>
|
||||
<target>Chiamate proibite!</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Camera not available" xml:space="preserve">
|
||||
@@ -1152,10 +1171,12 @@
|
||||
</trans-unit>
|
||||
<trans-unit id="Can't call contact" xml:space="preserve">
|
||||
<source>Can't call contact</source>
|
||||
<target>Impossibile chiamare il contatto</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Can't call member" xml:space="preserve">
|
||||
<source>Can't call member</source>
|
||||
<target>Impossibile chiamare il membro</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Can't invite contact!" xml:space="preserve">
|
||||
@@ -1170,6 +1191,7 @@
|
||||
</trans-unit>
|
||||
<trans-unit id="Can't message member" xml:space="preserve">
|
||||
<source>Can't message member</source>
|
||||
<target>Impossibile inviare un messaggio al membro</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Cancel" xml:space="preserve">
|
||||
@@ -1308,6 +1330,11 @@
|
||||
<target>La chat è ferma. Se hai già usato questo database su un altro dispositivo, dovresti trasferirlo prima di avviare la chat.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Chat list" xml:space="preserve">
|
||||
<source>Chat list</source>
|
||||
<target>Elenco delle chat</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Chat migrated!" xml:space="preserve">
|
||||
<source>Chat migrated!</source>
|
||||
<target>Chat migrata!</target>
|
||||
@@ -1371,7 +1398,7 @@
|
||||
<trans-unit id="Clear" xml:space="preserve">
|
||||
<source>Clear</source>
|
||||
<target>Svuota</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
<note>swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Clear conversation" xml:space="preserve">
|
||||
<source>Clear conversation</source>
|
||||
@@ -1393,6 +1420,11 @@
|
||||
<target>Annulla la verifica</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Color chats with the new themes." xml:space="preserve">
|
||||
<source>Color chats with the new themes.</source>
|
||||
<target>Colora le chat con i nuovi temi.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Color mode" xml:space="preserve">
|
||||
<source>Color mode</source>
|
||||
<target>Modalità di colore</target>
|
||||
@@ -1435,6 +1467,7 @@
|
||||
</trans-unit>
|
||||
<trans-unit id="Confirm contact deletion?" xml:space="preserve">
|
||||
<source>Confirm contact deletion?</source>
|
||||
<target>Confermare l'eliminazione del contatto?</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Confirm database upgrades" xml:space="preserve">
|
||||
@@ -1492,8 +1525,9 @@
|
||||
<target>Connetti al desktop</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Connect to your friends faster" xml:space="preserve">
|
||||
<source>Connect to your friends faster</source>
|
||||
<trans-unit id="Connect to your friends faster." xml:space="preserve">
|
||||
<source>Connect to your friends faster.</source>
|
||||
<target>Connettiti più velocemente ai tuoi amici.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Connect to yourself?" xml:space="preserve">
|
||||
@@ -1572,6 +1606,7 @@ Questo è il tuo link una tantum!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Connecting to contact, please wait or check later!" xml:space="preserve">
|
||||
<source>Connecting to contact, please wait or check later!</source>
|
||||
<target>In collegamento con il contatto, attendi o controlla più tardi!</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Connecting to desktop" xml:space="preserve">
|
||||
@@ -1586,6 +1621,7 @@ Questo è il tuo link una tantum!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Connection and servers status." xml:space="preserve">
|
||||
<source>Connection and servers status.</source>
|
||||
<target>Stato della connessione e dei server.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Connection error" xml:space="preserve">
|
||||
@@ -1640,6 +1676,7 @@ Questo è il tuo link una tantum!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Contact deleted!" xml:space="preserve">
|
||||
<source>Contact deleted!</source>
|
||||
<target>Contatto eliminato!</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Contact hidden:" xml:space="preserve">
|
||||
@@ -1654,6 +1691,7 @@ Questo è il tuo link una tantum!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Contact is deleted." xml:space="preserve">
|
||||
<source>Contact is deleted.</source>
|
||||
<target>Il contatto è stato eliminato.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Contact name" xml:space="preserve">
|
||||
@@ -1668,6 +1706,7 @@ Questo è il tuo link una tantum!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Contact will be deleted - this cannot be undone!" xml:space="preserve">
|
||||
<source>Contact will be deleted - this cannot be undone!</source>
|
||||
<target>Il contatto verrà eliminato - non è reversibile!</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Contacts" xml:space="preserve">
|
||||
@@ -1685,12 +1724,9 @@ Questo è il tuo link una tantum!</target>
|
||||
<target>Continua</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Control your network" xml:space="preserve">
|
||||
<source>Control your network</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Conversation deleted!" xml:space="preserve">
|
||||
<source>Conversation deleted!</source>
|
||||
<target>Conversazione eliminata!</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Copy" xml:space="preserve">
|
||||
@@ -1708,6 +1744,10 @@ Questo è il tuo link una tantum!</target>
|
||||
<target>Versione core: v%@</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Corner" xml:space="preserve">
|
||||
<source>Corner</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Correct name to %@?" xml:space="preserve">
|
||||
<source>Correct name to %@?</source>
|
||||
<target>Correggere il nome a %@?</target>
|
||||
@@ -1964,7 +2004,8 @@ Questo è il tuo link una tantum!</target>
|
||||
<trans-unit id="Delete" xml:space="preserve">
|
||||
<source>Delete</source>
|
||||
<target>Elimina</target>
|
||||
<note>chat item action</note>
|
||||
<note>chat item action
|
||||
swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Delete %lld messages of members?" xml:space="preserve">
|
||||
<source>Delete %lld messages of members?</source>
|
||||
@@ -2033,6 +2074,7 @@ Questo è il tuo link una tantum!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Delete contact?" xml:space="preserve">
|
||||
<source>Delete contact?</source>
|
||||
<target>Eliminare il contatto?</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Delete database" xml:space="preserve">
|
||||
@@ -2142,6 +2184,7 @@ Questo è il tuo link una tantum!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Delete up to 20 messages at once." xml:space="preserve">
|
||||
<source>Delete up to 20 messages at once.</source>
|
||||
<target>Elimina fino a 20 messaggi contemporaneamente.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Delete user profile?" xml:space="preserve">
|
||||
@@ -2151,6 +2194,7 @@ Questo è il tuo link una tantum!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Delete without notification" xml:space="preserve">
|
||||
<source>Delete without notification</source>
|
||||
<target>Elimina senza avvisare</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Deleted" xml:space="preserve">
|
||||
@@ -2168,10 +2212,6 @@ Questo è il tuo link una tantum!</target>
|
||||
<target>Eliminato il: %@</target>
|
||||
<note>copied message info</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Deleted chats" xml:space="preserve">
|
||||
<source>Deleted chats</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Deletion errors" xml:space="preserve">
|
||||
<source>Deletion errors</source>
|
||||
<target>Errori di eliminazione</target>
|
||||
@@ -2244,6 +2284,7 @@ Questo è il tuo link una tantum!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Developer options" xml:space="preserve">
|
||||
<source>Developer options</source>
|
||||
<target>Opzioni sviluppatore</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Developer tools" xml:space="preserve">
|
||||
@@ -2691,6 +2732,10 @@ Questo è il tuo link una tantum!</target>
|
||||
<target>Errore nella modifica dell'indirizzo</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Error changing connection profile" xml:space="preserve">
|
||||
<source>Error changing connection profile</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Error changing role" xml:space="preserve">
|
||||
<source>Error changing role</source>
|
||||
<target>Errore nel cambio di ruolo</target>
|
||||
@@ -2701,6 +2746,10 @@ Questo è il tuo link una tantum!</target>
|
||||
<target>Errore nella modifica dell'impostazione</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Error changing to incognito!" xml:space="preserve">
|
||||
<source>Error changing to incognito!</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Error connecting to forwarding server %@. Please try later." xml:space="preserve">
|
||||
<source>Error connecting to forwarding server %@. Please try later.</source>
|
||||
<target>Errore di connessione al server di inoltro %@. Riprova più tardi.</target>
|
||||
@@ -2921,6 +2970,10 @@ Questo è il tuo link una tantum!</target>
|
||||
<target>Errore nell'interruzione della chat</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Error switching profile" xml:space="preserve">
|
||||
<source>Error switching profile</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Error switching profile!" xml:space="preserve">
|
||||
<source>Error switching profile!</source>
|
||||
<target>Errore nel cambio di profilo!</target>
|
||||
@@ -2992,10 +3045,6 @@ Questo è il tuo link una tantum!</target>
|
||||
<target>Anche quando disattivato nella conversazione.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Even when they are offline." xml:space="preserve">
|
||||
<source>Even when they are offline.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Exit without saving" xml:space="preserve">
|
||||
<source>Exit without saving</source>
|
||||
<target>Esci senza salvare</target>
|
||||
@@ -3054,7 +3103,7 @@ Questo è il tuo link una tantum!</target>
|
||||
<trans-unit id="Favorite" xml:space="preserve">
|
||||
<source>Favorite</source>
|
||||
<target>Preferito</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
<note>swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="File error" xml:space="preserve">
|
||||
<source>File error</source>
|
||||
@@ -3810,6 +3859,7 @@ Errore: %2$@</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="It protects your IP address and connections." xml:space="preserve">
|
||||
<source>It protects your IP address and connections.</source>
|
||||
<target>Protegge il tuo indirizzo IP e le connessioni.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</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">
|
||||
@@ -3830,7 +3880,7 @@ Errore: %2$@</target>
|
||||
<trans-unit id="Join" xml:space="preserve">
|
||||
<source>Join</source>
|
||||
<target>Entra</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
<note>swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Join group" xml:space="preserve">
|
||||
<source>Join group</source>
|
||||
@@ -3876,6 +3926,7 @@ Questo è il tuo link per il gruppo %@!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Keep conversation" xml:space="preserve">
|
||||
<source>Keep conversation</source>
|
||||
<target>Tieni la conversazione</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">
|
||||
@@ -3921,7 +3972,7 @@ Questo è il tuo link per il gruppo %@!</target>
|
||||
<trans-unit id="Leave" xml:space="preserve">
|
||||
<source>Leave</source>
|
||||
<target>Esci</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
<note>swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Leave group" xml:space="preserve">
|
||||
<source>Leave group</source>
|
||||
@@ -4153,6 +4204,10 @@ Questo è il tuo link per il gruppo %@!</target>
|
||||
<target>Server dei messaggi</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message shape" xml:space="preserve">
|
||||
<source>Message shape</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message source remains private." xml:space="preserve">
|
||||
<source>Message source remains private.</source>
|
||||
<target>La fonte del messaggio resta privata.</target>
|
||||
@@ -4278,10 +4333,6 @@ Questo è il tuo link per il gruppo %@!</target>
|
||||
<target>Modera</target>
|
||||
<note>chat item action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Moderate like a pro ✋" xml:space="preserve">
|
||||
<source>Moderate like a pro ✋</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Moderated at" xml:space="preserve">
|
||||
<source>Moderated at</source>
|
||||
<target>Moderato il</target>
|
||||
@@ -4315,7 +4366,7 @@ Questo è il tuo link per il gruppo %@!</target>
|
||||
<trans-unit id="Mute" xml:space="preserve">
|
||||
<source>Mute</source>
|
||||
<target>Silenzia</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
<note>swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Muted when inactive!" xml:space="preserve">
|
||||
<source>Muted when inactive!</source>
|
||||
@@ -4325,7 +4376,7 @@ Questo è il tuo link per il gruppo %@!</target>
|
||||
<trans-unit id="Name" xml:space="preserve">
|
||||
<source>Name</source>
|
||||
<target>Nome</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
<note>swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Network & servers" xml:space="preserve">
|
||||
<source>Network & servers</source>
|
||||
@@ -4357,10 +4408,6 @@ Questo è il tuo link per il gruppo %@!</target>
|
||||
<target>Stato della rete</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="New Chat" xml:space="preserve">
|
||||
<source>New Chat</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="New Passcode" xml:space="preserve">
|
||||
<source>New Passcode</source>
|
||||
<target>Nuovo codice di accesso</target>
|
||||
@@ -4371,6 +4418,11 @@ Questo è il tuo link per il gruppo %@!</target>
|
||||
<target>Nuova chat</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="New chat experience 🎉" xml:space="preserve">
|
||||
<source>New chat experience 🎉</source>
|
||||
<target>Una nuova esperienza di chat 🎉</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="New contact request" xml:space="preserve">
|
||||
<source>New contact request</source>
|
||||
<target>Nuova richiesta di contatto</target>
|
||||
@@ -4401,6 +4453,11 @@ Questo è il tuo link per il gruppo %@!</target>
|
||||
<target>Novità nella %@</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="New media options" xml:space="preserve">
|
||||
<source>New media options</source>
|
||||
<target>Nuove opzioni multimediali</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="New member role" xml:space="preserve">
|
||||
<source>New member role</source>
|
||||
<target>Nuovo ruolo del membro</target>
|
||||
@@ -4540,10 +4597,6 @@ Questo è il tuo link per il gruppo %@!</target>
|
||||
<target>Vecchio archivio del database</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="One-hand UI" xml:space="preserve">
|
||||
<source>One-hand UI</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="One-time invitation link" xml:space="preserve">
|
||||
<source>One-time invitation link</source>
|
||||
<target>Link di invito una tantum</target>
|
||||
@@ -4575,6 +4628,7 @@ Richiede l'attivazione della VPN.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Only delete conversation" xml:space="preserve">
|
||||
<source>Only delete conversation</source>
|
||||
<target>Elimina solo la conversazione</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Only group owners can change group preferences." xml:space="preserve">
|
||||
@@ -4812,8 +4866,14 @@ Richiede l'attivazione della VPN.</target>
|
||||
<target>Chiamate picture-in-picture</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Play from the chat list." xml:space="preserve">
|
||||
<source>Play from the chat list.</source>
|
||||
<target>Riproduci dall'elenco delle chat.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Please ask your contact to enable calls." xml:space="preserve">
|
||||
<source>Please ask your contact to enable calls.</source>
|
||||
<target>Chiedi al contatto di attivare le chiamate.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Please ask your contact to enable sending voice messages." xml:space="preserve">
|
||||
@@ -5117,8 +5177,9 @@ Attivalo nelle impostazioni *Rete e server*.</target>
|
||||
<target>Valuta l'app</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Reachable chat toolbar 👋" xml:space="preserve">
|
||||
<source>Reachable chat toolbar 👋</source>
|
||||
<trans-unit id="Reachable chat toolbar" xml:space="preserve">
|
||||
<source>Reachable chat toolbar</source>
|
||||
<target>Barra degli strumenti di chat accessibile</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="React…" xml:space="preserve">
|
||||
@@ -5129,7 +5190,7 @@ Attivalo nelle impostazioni *Rete e server*.</target>
|
||||
<trans-unit id="Read" xml:space="preserve">
|
||||
<source>Read</source>
|
||||
<target>Leggi</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
<note>swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Read more" xml:space="preserve">
|
||||
<source>Read more</source>
|
||||
@@ -5289,7 +5350,8 @@ Attivalo nelle impostazioni *Rete e server*.</target>
|
||||
<trans-unit id="Reject" xml:space="preserve">
|
||||
<source>Reject</source>
|
||||
<target>Rifiuta</target>
|
||||
<note>reject incoming call via notification</note>
|
||||
<note>reject incoming call via notification
|
||||
swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Reject (sender NOT notified)" xml:space="preserve">
|
||||
<source>Reject (sender NOT notified)</source>
|
||||
@@ -5391,6 +5453,11 @@ Attivalo nelle impostazioni *Rete e server*.</target>
|
||||
<target>Ripristina</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Reset all hints" xml:space="preserve">
|
||||
<source>Reset all hints</source>
|
||||
<target>Ripristina tutti i suggerimenti</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Reset all statistics" xml:space="preserve">
|
||||
<source>Reset all statistics</source>
|
||||
<target>Azzera tutte le statistiche</target>
|
||||
@@ -5686,6 +5753,10 @@ Attivalo nelle impostazioni *Rete e server*.</target>
|
||||
<target>Seleziona</target>
|
||||
<note>chat item action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Select chat profile" xml:space="preserve">
|
||||
<source>Select chat profile</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Selected %lld" xml:space="preserve">
|
||||
<source>Selected %lld</source>
|
||||
<target>%lld selezionato</target>
|
||||
@@ -5758,6 +5829,7 @@ Attivalo nelle impostazioni *Rete e server*.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Send message to enable calls." xml:space="preserve">
|
||||
<source>Send message to enable calls.</source>
|
||||
<target>Invia un messaggio per attivare le chiamate.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Send messages directly when IP address is protected and your or destination server does not support private routing." xml:space="preserve">
|
||||
@@ -6045,11 +6117,20 @@ Attivalo nelle impostazioni *Rete e server*.</target>
|
||||
<target>Condividere l'indirizzo con i contatti?</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Share from other apps." xml:space="preserve">
|
||||
<source>Share from other apps.</source>
|
||||
<target>Condividi da altre app.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Share link" xml:space="preserve">
|
||||
<source>Share link</source>
|
||||
<target>Condividi link</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Share profile" xml:space="preserve">
|
||||
<source>Share profile</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Share this 1-time invite link" xml:space="preserve">
|
||||
<source>Share this 1-time invite link</source>
|
||||
<target>Condividi questo link di invito una tantum</target>
|
||||
@@ -6390,6 +6471,10 @@ Attivalo nelle impostazioni *Rete e server*.</target>
|
||||
<target>TCP_KEEPINTVL</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Tail" xml:space="preserve">
|
||||
<source>Tail</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Take picture" xml:space="preserve">
|
||||
<source>Take picture</source>
|
||||
<target>Scatta foto</target>
|
||||
@@ -6729,11 +6814,21 @@ Ti verrà chiesto di completare l'autenticazione prima di attivare questa funzio
|
||||
<target>Per verificare la crittografia end-to-end con il tuo contatto, confrontate (o scansionate) il codice sui vostri dispositivi.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Toggle chat list:" xml:space="preserve">
|
||||
<source>Toggle chat list:</source>
|
||||
<target>Cambia l'elenco delle chat:</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Toggle incognito when connecting." xml:space="preserve">
|
||||
<source>Toggle incognito when connecting.</source>
|
||||
<target>Attiva/disattiva l'incognito quando ti colleghi.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Toolbar opacity" xml:space="preserve">
|
||||
<source>Toolbar opacity</source>
|
||||
<target>Opacità barra degli strumenti</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Total" xml:space="preserve">
|
||||
<source>Total</source>
|
||||
<target>Totale</target>
|
||||
@@ -6812,7 +6907,7 @@ Ti verrà chiesto di completare l'autenticazione prima di attivare questa funzio
|
||||
<trans-unit id="Unfav." xml:space="preserve">
|
||||
<source>Unfav.</source>
|
||||
<target>Non pref.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
<note>swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Unhide" xml:space="preserve">
|
||||
<source>Unhide</source>
|
||||
@@ -6889,12 +6984,12 @@ Per connetterti, chiedi al tuo contatto di creare un altro link di connessione e
|
||||
<trans-unit id="Unmute" xml:space="preserve">
|
||||
<source>Unmute</source>
|
||||
<target>Riattiva notifiche</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
<note>swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Unread" xml:space="preserve">
|
||||
<source>Unread</source>
|
||||
<target>Non letto</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
<note>swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Up to 100 last messages are sent to new members." xml:space="preserve">
|
||||
<source>Up to 100 last messages are sent to new members.</source>
|
||||
@@ -7028,6 +7123,7 @@ Per connetterti, chiedi al tuo contatto di creare un altro link di connessione e
|
||||
</trans-unit>
|
||||
<trans-unit id="Use the app with one hand." xml:space="preserve">
|
||||
<source>Use the app with one hand.</source>
|
||||
<target>Usa l'app con una mano sola.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="User profile" xml:space="preserve">
|
||||
@@ -7387,6 +7483,11 @@ Ripetere la richiesta di ingresso?</target>
|
||||
<target>Puoi accettare chiamate dalla schermata di blocco, senza l'autenticazione del dispositivo e dell'app.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="You can change it in Appearance settings." xml:space="preserve">
|
||||
<source>You can change it in Appearance settings.</source>
|
||||
<target>Puoi cambiarlo nelle impostazioni dell'aspetto.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="You can create it later" xml:space="preserve">
|
||||
<source>You can create it later</source>
|
||||
<target>Puoi crearlo più tardi</target>
|
||||
@@ -7424,6 +7525,7 @@ Ripetere la richiesta di ingresso?</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="You can send messages to %@ from Archived contacts." xml:space="preserve">
|
||||
<source>You can send messages to %@ from Archived contacts.</source>
|
||||
<target>Puoi inviare messaggi a %@ dai contatti archiviati.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="You can set lock screen notification preview via settings." xml:space="preserve">
|
||||
@@ -7453,6 +7555,7 @@ Ripetere la richiesta di ingresso?</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="You can still view conversation with %@ in the list of chats." xml:space="preserve">
|
||||
<source>You can still view conversation with %@ in the list of chats.</source>
|
||||
<target>Puoi ancora vedere la conversazione con %@ nell'elenco delle chat.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="You can turn on SimpleX Lock via Settings." xml:space="preserve">
|
||||
@@ -7534,6 +7637,7 @@ Ripetere la richiesta di connessione?</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="You need to allow your contact to call to be able to call them." xml:space="preserve">
|
||||
<source>You need to allow your contact to call to be able to call them.</source>
|
||||
<target>Devi consentire le chiamate al tuo contatto per poterlo chiamare.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="You need to allow your contact to send voice messages to be able to send them." xml:space="preserve">
|
||||
@@ -7651,6 +7755,10 @@ Ripetere la richiesta di connessione?</target>
|
||||
<target>I tuoi profili di chat</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Your connection was moved to %@ but an unexpected error occurred while redirecting you to the profile." xml:space="preserve">
|
||||
<source>Your connection was moved to %@ but an unexpected error occurred while redirecting you to the profile.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Your contact sent a file that is larger than currently supported maximum size (%@)." xml:space="preserve">
|
||||
<source>Your contact sent a file that is larger than currently supported maximum size (%@).</source>
|
||||
<target>Il tuo contatto ha inviato un file più grande della dimensione massima attualmente supportata (%@).</target>
|
||||
@@ -7666,10 +7774,6 @@ Ripetere la richiesta di connessione?</target>
|
||||
<target>I tuoi contatti resteranno connessi.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Your contacts your way" xml:space="preserve">
|
||||
<source>Your contacts your way</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Your current chat database will be DELETED and REPLACED with the imported one." xml:space="preserve">
|
||||
<source>Your current chat database will be DELETED and REPLACED with the imported one.</source>
|
||||
<target>Il tuo attuale database della chat verrà ELIMINATO e SOSTITUITO con quello importato.</target>
|
||||
@@ -7849,6 +7953,7 @@ I server di SimpleX non possono vedere il tuo profilo.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="call" xml:space="preserve">
|
||||
<source>call</source>
|
||||
<target>chiama</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="call error" xml:space="preserve">
|
||||
@@ -8223,6 +8328,7 @@ I server di SimpleX non possono vedere il tuo profilo.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="invite" xml:space="preserve">
|
||||
<source>invite</source>
|
||||
<target>invita</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="invited" xml:space="preserve">
|
||||
@@ -8282,6 +8388,7 @@ I server di SimpleX non possono vedere il tuo profilo.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="message" xml:space="preserve">
|
||||
<source>message</source>
|
||||
<target>messaggio</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="message received" xml:space="preserve">
|
||||
@@ -8316,6 +8423,7 @@ I server di SimpleX non possono vedere il tuo profilo.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="mute" xml:space="preserve">
|
||||
<source>mute</source>
|
||||
<target>silenzia</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="never" xml:space="preserve">
|
||||
@@ -8452,6 +8560,7 @@ I server di SimpleX non possono vedere il tuo profilo.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="search" xml:space="preserve">
|
||||
<source>search</source>
|
||||
<target>cerca</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="sec" xml:space="preserve">
|
||||
@@ -8540,6 +8649,7 @@ ultimo msg ricevuto: %2$@</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="unmute" xml:space="preserve">
|
||||
<source>unmute</source>
|
||||
<target>riattiva notifiche</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="unprotected" xml:space="preserve">
|
||||
@@ -8589,6 +8699,7 @@ ultimo msg ricevuto: %2$@</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="video" xml:space="preserve">
|
||||
<source>video</source>
|
||||
<target>video</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="video call (not e2e encrypted)" xml:space="preserve">
|
||||
|
||||
@@ -137,6 +137,10 @@
|
||||
<target>%@ が接続を希望しています!</target>
|
||||
<note>notification title</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="%@, %@" xml:space="preserve">
|
||||
<source>%1$@, %2$@</source>
|
||||
<note>format for date separator in chat</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="%@, %@ and %lld members" xml:space="preserve">
|
||||
<source>%@, %@ and %lld members</source>
|
||||
<target>%@や%@など%lld人のメンバー</target>
|
||||
@@ -392,11 +396,6 @@
|
||||
<target>, </target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="- Search contacts when starting chat. - Archive contacts to chat later." xml:space="preserve">
|
||||
<source>- Search contacts when starting chat.
|
||||
- Archive contacts to chat later.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="- connect to [directory service](simplex:/contact#/?v=1-4&smp=smp%3A%2F%2Fu2dS9sG8nMNURyZwqASV4yROM28Er0luVTx5X1CsMrU%3D%40smp4.simplex.im%2FeXSPwqTkKyDO3px4fLf1wx3MvPdjdLW3%23%2F%3Fv%3D1-2%26dh%3DMCowBQYDK2VuAyEAaiv6MkMH44L2TcYrt_CsX3ZvM11WgbMEUn0hkIKTOho%253D%26srv%3Do5vmywmrnaxalvz6wi3zicyftgio6psuvyniis6gco6bp6ekl4cqj4id.onion) (BETA)! - delivery receipts (up to 20 members). - faster and more stable." xml:space="preserve">
|
||||
<source>- connect to [directory service](simplex:/contact#/?v=1-4&smp=smp%3A%2F%2Fu2dS9sG8nMNURyZwqASV4yROM28Er0luVTx5X1CsMrU%3D%40smp4.simplex.im%2FeXSPwqTkKyDO3px4fLf1wx3MvPdjdLW3%23%2F%3Fv%3D1-2%26dh%3DMCowBQYDK2VuAyEAaiv6MkMH44L2TcYrt_CsX3ZvM11WgbMEUn0hkIKTOho%253D%26srv%3Do5vmywmrnaxalvz6wi3zicyftgio6psuvyniis6gco6bp6ekl4cqj4id.onion) (BETA)!
|
||||
- delivery receipts (up to 20 members).
|
||||
@@ -559,7 +558,8 @@
|
||||
<source>Accept</source>
|
||||
<target>承諾</target>
|
||||
<note>accept contact request via notification
|
||||
accept incoming call via notification</note>
|
||||
accept incoming call via notification
|
||||
swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Accept connection request?" xml:space="preserve">
|
||||
<source>Accept connection request?</source>
|
||||
@@ -574,7 +574,8 @@
|
||||
<trans-unit id="Accept incognito" xml:space="preserve">
|
||||
<source>Accept incognito</source>
|
||||
<target>シークレットモードで承諾</target>
|
||||
<note>accept contact request via notification</note>
|
||||
<note>accept contact request via notification
|
||||
swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Acknowledged" xml:space="preserve">
|
||||
<source>Acknowledged</source>
|
||||
@@ -921,6 +922,10 @@
|
||||
<source>Archive and upload</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Archive contacts to chat later." xml:space="preserve">
|
||||
<source>Archive contacts to chat later.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Archived contacts" xml:space="preserve">
|
||||
<source>Archived contacts</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -1021,6 +1026,10 @@
|
||||
<target>より良いメッセージ</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Better networking" xml:space="preserve">
|
||||
<source>Better networking</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Black" xml:space="preserve">
|
||||
<source>Black</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -1053,6 +1062,10 @@
|
||||
<source>Blocked by admin</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Blur for better privacy." xml:space="preserve">
|
||||
<source>Blur for better privacy.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Blur media" xml:space="preserve">
|
||||
<source>Blur media</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -1261,6 +1274,10 @@
|
||||
<source>Chat is stopped. If you already used this database on another device, you should transfer it back before starting chat.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Chat list" xml:space="preserve">
|
||||
<source>Chat list</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Chat migrated!" xml:space="preserve">
|
||||
<source>Chat migrated!</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -1318,7 +1335,7 @@
|
||||
<trans-unit id="Clear" xml:space="preserve">
|
||||
<source>Clear</source>
|
||||
<target>消す</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
<note>swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Clear conversation" xml:space="preserve">
|
||||
<source>Clear conversation</source>
|
||||
@@ -1339,6 +1356,10 @@
|
||||
<target>検証を消す</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Color chats with the new themes." xml:space="preserve">
|
||||
<source>Color chats with the new themes.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Color mode" xml:space="preserve">
|
||||
<source>Color mode</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -1429,8 +1450,8 @@
|
||||
<source>Connect to desktop</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Connect to your friends faster" xml:space="preserve">
|
||||
<source>Connect to your friends faster</source>
|
||||
<trans-unit id="Connect to your friends faster." xml:space="preserve">
|
||||
<source>Connect to your friends faster.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Connect to yourself?" xml:space="preserve">
|
||||
@@ -1605,10 +1626,6 @@ This is your own one-time link!</source>
|
||||
<target>続ける</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Control your network" xml:space="preserve">
|
||||
<source>Control your network</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Conversation deleted!" xml:space="preserve">
|
||||
<source>Conversation deleted!</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -1627,6 +1644,10 @@ This is your own one-time link!</source>
|
||||
<target>コアのバージョン: v%@</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Corner" xml:space="preserve">
|
||||
<source>Corner</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Correct name to %@?" xml:space="preserve">
|
||||
<source>Correct name to %@?</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -1870,7 +1891,8 @@ This is your own one-time link!</source>
|
||||
<trans-unit id="Delete" xml:space="preserve">
|
||||
<source>Delete</source>
|
||||
<target>削除</target>
|
||||
<note>chat item action</note>
|
||||
<note>chat item action
|
||||
swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Delete %lld messages of members?" xml:space="preserve">
|
||||
<source>Delete %lld messages of members?</source>
|
||||
@@ -2069,10 +2091,6 @@ This is your own one-time link!</source>
|
||||
<target>削除完了: %@</target>
|
||||
<note>copied message info</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Deleted chats" xml:space="preserve">
|
||||
<source>Deleted chats</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Deletion errors" xml:space="preserve">
|
||||
<source>Deletion errors</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -2559,6 +2577,10 @@ This is your own one-time link!</source>
|
||||
<target>アドレス変更にエラー発生</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Error changing connection profile" xml:space="preserve">
|
||||
<source>Error changing connection profile</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Error changing role" xml:space="preserve">
|
||||
<source>Error changing role</source>
|
||||
<target>役割変更にエラー発生</target>
|
||||
@@ -2569,6 +2591,10 @@ This is your own one-time link!</source>
|
||||
<target>設定変更にエラー発生</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Error changing to incognito!" xml:space="preserve">
|
||||
<source>Error changing to incognito!</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Error connecting to forwarding server %@. Please try later." xml:space="preserve">
|
||||
<source>Error connecting to forwarding server %@. Please try later.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -2777,6 +2803,10 @@ This is your own one-time link!</source>
|
||||
<target>チャット停止にエラー発生</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Error switching profile" xml:space="preserve">
|
||||
<source>Error switching profile</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Error switching profile!" xml:space="preserve">
|
||||
<source>Error switching profile!</source>
|
||||
<target>プロフィール切り替えにエラー発生!</target>
|
||||
@@ -2845,10 +2875,6 @@ This is your own one-time link!</source>
|
||||
<target>会話中に無効になっている場合でも。</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Even when they are offline." xml:space="preserve">
|
||||
<source>Even when they are offline.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Exit without saving" xml:space="preserve">
|
||||
<source>Exit without saving</source>
|
||||
<target>保存せずに閉じる</target>
|
||||
@@ -2903,7 +2929,7 @@ This is your own one-time link!</source>
|
||||
<trans-unit id="Favorite" xml:space="preserve">
|
||||
<source>Favorite</source>
|
||||
<target>お気に入り</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
<note>swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="File error" xml:space="preserve">
|
||||
<source>File error</source>
|
||||
@@ -3635,7 +3661,7 @@ Error: %2$@</source>
|
||||
<trans-unit id="Join" xml:space="preserve">
|
||||
<source>Join</source>
|
||||
<target>参加</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
<note>swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Join group" xml:space="preserve">
|
||||
<source>Join group</source>
|
||||
@@ -3718,7 +3744,7 @@ This is your link for group %@!</source>
|
||||
<trans-unit id="Leave" xml:space="preserve">
|
||||
<source>Leave</source>
|
||||
<target>脱退</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
<note>swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Leave group" xml:space="preserve">
|
||||
<source>Leave group</source>
|
||||
@@ -3936,6 +3962,10 @@ This is your link for group %@!</source>
|
||||
<source>Message servers</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message shape" xml:space="preserve">
|
||||
<source>Message shape</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message source remains private." xml:space="preserve">
|
||||
<source>Message source remains private.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -4045,10 +4075,6 @@ This is your link for group %@!</source>
|
||||
<target>モデレート</target>
|
||||
<note>chat item action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Moderate like a pro ✋" xml:space="preserve">
|
||||
<source>Moderate like a pro ✋</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Moderated at" xml:space="preserve">
|
||||
<source>Moderated at</source>
|
||||
<target>モデレーターによって介入済み</target>
|
||||
@@ -4081,7 +4107,7 @@ This is your link for group %@!</source>
|
||||
<trans-unit id="Mute" xml:space="preserve">
|
||||
<source>Mute</source>
|
||||
<target>ミュート</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
<note>swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Muted when inactive!" xml:space="preserve">
|
||||
<source>Muted when inactive!</source>
|
||||
@@ -4091,7 +4117,7 @@ This is your link for group %@!</source>
|
||||
<trans-unit id="Name" xml:space="preserve">
|
||||
<source>Name</source>
|
||||
<target>名前</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
<note>swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Network & servers" xml:space="preserve">
|
||||
<source>Network & servers</source>
|
||||
@@ -4120,10 +4146,6 @@ This is your link for group %@!</source>
|
||||
<target>ネットワーク状況</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="New Chat" xml:space="preserve">
|
||||
<source>New Chat</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="New Passcode" xml:space="preserve">
|
||||
<source>New Passcode</source>
|
||||
<target>新しいパスコード</target>
|
||||
@@ -4133,6 +4155,10 @@ This is your link for group %@!</source>
|
||||
<source>New chat</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="New chat experience 🎉" xml:space="preserve">
|
||||
<source>New chat experience 🎉</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="New contact request" xml:space="preserve">
|
||||
<source>New contact request</source>
|
||||
<target>新しい繋がりのリクエスト</target>
|
||||
@@ -4163,6 +4189,10 @@ This is your link for group %@!</source>
|
||||
<target>%@ の新機能</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="New media options" xml:space="preserve">
|
||||
<source>New media options</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="New member role" xml:space="preserve">
|
||||
<source>New member role</source>
|
||||
<target>新しいメンバーの役割</target>
|
||||
@@ -4296,10 +4326,6 @@ This is your link for group %@!</source>
|
||||
<target>過去のデータベースアーカイブ</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="One-hand UI" xml:space="preserve">
|
||||
<source>One-hand UI</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="One-time invitation link" xml:space="preserve">
|
||||
<source>One-time invitation link</source>
|
||||
<target>使い捨ての招待リンク</target>
|
||||
@@ -4552,6 +4578,10 @@ VPN を有効にする必要があります。</target>
|
||||
<source>Picture-in-picture calls</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Play from the chat list." xml:space="preserve">
|
||||
<source>Play from the chat list.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Please ask your contact to enable calls." xml:space="preserve">
|
||||
<source>Please ask your contact to enable calls.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -4834,8 +4864,8 @@ Enable in *Network & servers* settings.</source>
|
||||
<target>アプリを評価</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Reachable chat toolbar 👋" xml:space="preserve">
|
||||
<source>Reachable chat toolbar 👋</source>
|
||||
<trans-unit id="Reachable chat toolbar" xml:space="preserve">
|
||||
<source>Reachable chat toolbar</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="React…" xml:space="preserve">
|
||||
@@ -4846,7 +4876,7 @@ Enable in *Network & servers* settings.</source>
|
||||
<trans-unit id="Read" xml:space="preserve">
|
||||
<source>Read</source>
|
||||
<target>読む</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
<note>swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Read more" xml:space="preserve">
|
||||
<source>Read more</source>
|
||||
@@ -4993,7 +5023,8 @@ Enable in *Network & servers* settings.</source>
|
||||
<trans-unit id="Reject" xml:space="preserve">
|
||||
<source>Reject</source>
|
||||
<target>拒否</target>
|
||||
<note>reject incoming call via notification</note>
|
||||
<note>reject incoming call via notification
|
||||
swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Reject (sender NOT notified)" xml:space="preserve">
|
||||
<source>Reject (sender NOT notified)</source>
|
||||
@@ -5089,6 +5120,10 @@ Enable in *Network & servers* settings.</source>
|
||||
<target>戻す</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Reset all hints" xml:space="preserve">
|
||||
<source>Reset all hints</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Reset all statistics" xml:space="preserve">
|
||||
<source>Reset all statistics</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -5365,6 +5400,10 @@ Enable in *Network & servers* settings.</source>
|
||||
<target>選択</target>
|
||||
<note>chat item action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Select chat profile" xml:space="preserve">
|
||||
<source>Select chat profile</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Selected %lld" xml:space="preserve">
|
||||
<source>Selected %lld</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -5693,11 +5732,19 @@ Enable in *Network & servers* settings.</source>
|
||||
<target>アドレスを連絡先と共有しますか?</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Share from other apps." xml:space="preserve">
|
||||
<source>Share from other apps.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Share link" xml:space="preserve">
|
||||
<source>Share link</source>
|
||||
<target>リンクを送る</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Share profile" xml:space="preserve">
|
||||
<source>Share profile</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Share this 1-time invite link" xml:space="preserve">
|
||||
<source>Share this 1-time invite link</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -6014,6 +6061,10 @@ Enable in *Network & servers* settings.</source>
|
||||
<target>TCP_KEEPINTVL</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Tail" xml:space="preserve">
|
||||
<source>Tail</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Take picture" xml:space="preserve">
|
||||
<source>Take picture</source>
|
||||
<target>写真を撮影</target>
|
||||
@@ -6332,10 +6383,18 @@ You will be prompted to complete authentication before this feature is enabled.<
|
||||
<target>エンドツーエンド暗号化を確認するには、ご自分の端末と連絡先の端末のコードを比べます (スキャンします)。</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Toggle chat list:" xml:space="preserve">
|
||||
<source>Toggle chat list:</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Toggle incognito when connecting." xml:space="preserve">
|
||||
<source>Toggle incognito when connecting.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Toolbar opacity" xml:space="preserve">
|
||||
<source>Toolbar opacity</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Total" xml:space="preserve">
|
||||
<source>Total</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -6406,7 +6465,7 @@ You will be prompted to complete authentication before this feature is enabled.<
|
||||
<trans-unit id="Unfav." xml:space="preserve">
|
||||
<source>Unfav.</source>
|
||||
<target>お気に入りを取り消す。</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
<note>swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Unhide" xml:space="preserve">
|
||||
<source>Unhide</source>
|
||||
@@ -6480,12 +6539,12 @@ To connect, please ask your contact to create another connection link and check
|
||||
<trans-unit id="Unmute" xml:space="preserve">
|
||||
<source>Unmute</source>
|
||||
<target>ミュート解除</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
<note>swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Unread" xml:space="preserve">
|
||||
<source>Unread</source>
|
||||
<target>未読</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
<note>swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Up to 100 last messages are sent to new members." xml:space="preserve">
|
||||
<source>Up to 100 last messages are sent to new members.</source>
|
||||
@@ -6931,6 +6990,10 @@ Repeat join request?</source>
|
||||
<target>デバイスやアプリの認証を行わずに、ロック画面から通話を受けることができます。</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="You can change it in Appearance settings." xml:space="preserve">
|
||||
<source>You can change it in Appearance settings.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="You can create it later" xml:space="preserve">
|
||||
<source>You can create it later</source>
|
||||
<target>後からでも作成できます</target>
|
||||
@@ -7185,6 +7248,10 @@ Repeat connection request?</source>
|
||||
<target>あなたのチャットプロフィール</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Your connection was moved to %@ but an unexpected error occurred while redirecting you to the profile." xml:space="preserve">
|
||||
<source>Your connection was moved to %@ but an unexpected error occurred while redirecting you to the profile.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Your contact sent a file that is larger than currently supported maximum size (%@)." xml:space="preserve">
|
||||
<source>Your contact sent a file that is larger than currently supported maximum size (%@).</source>
|
||||
<target>連絡先が現在サポートされている最大サイズ (%@) より大きいファイルを送信しました。</target>
|
||||
@@ -7200,10 +7267,6 @@ Repeat connection request?</source>
|
||||
<target>連絡先は接続されたままになります。</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Your contacts your way" xml:space="preserve">
|
||||
<source>Your contacts your way</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Your current chat database will be DELETED and REPLACED with the imported one." xml:space="preserve">
|
||||
<source>Your current chat database will be DELETED and REPLACED with the imported one.</source>
|
||||
<target>現在のチャット データベースは削除され、インポートされたデータベースに置き換えられます。</target>
|
||||
|
||||
@@ -137,6 +137,10 @@
|
||||
<target>%@ wil verbinding maken!</target>
|
||||
<note>notification title</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="%@, %@" xml:space="preserve">
|
||||
<source>%1$@, %2$@</source>
|
||||
<note>format for date separator in chat</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="%@, %@ and %lld members" xml:space="preserve">
|
||||
<source>%@, %@ and %lld members</source>
|
||||
<target>%@, %@ en %lld leden</target>
|
||||
@@ -392,11 +396,6 @@
|
||||
<target>, </target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="- Search contacts when starting chat. - Archive contacts to chat later." xml:space="preserve">
|
||||
<source>- Search contacts when starting chat.
|
||||
- Archive contacts to chat later.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="- connect to [directory service](simplex:/contact#/?v=1-4&smp=smp%3A%2F%2Fu2dS9sG8nMNURyZwqASV4yROM28Er0luVTx5X1CsMrU%3D%40smp4.simplex.im%2FeXSPwqTkKyDO3px4fLf1wx3MvPdjdLW3%23%2F%3Fv%3D1-2%26dh%3DMCowBQYDK2VuAyEAaiv6MkMH44L2TcYrt_CsX3ZvM11WgbMEUn0hkIKTOho%253D%26srv%3Do5vmywmrnaxalvz6wi3zicyftgio6psuvyniis6gco6bp6ekl4cqj4id.onion) (BETA)! - delivery receipts (up to 20 members). - faster and more stable." xml:space="preserve">
|
||||
<source>- connect to [directory service](simplex:/contact#/?v=1-4&smp=smp%3A%2F%2Fu2dS9sG8nMNURyZwqASV4yROM28Er0luVTx5X1CsMrU%3D%40smp4.simplex.im%2FeXSPwqTkKyDO3px4fLf1wx3MvPdjdLW3%23%2F%3Fv%3D1-2%26dh%3DMCowBQYDK2VuAyEAaiv6MkMH44L2TcYrt_CsX3ZvM11WgbMEUn0hkIKTOho%253D%26srv%3Do5vmywmrnaxalvz6wi3zicyftgio6psuvyniis6gco6bp6ekl4cqj4id.onion) (BETA)!
|
||||
- delivery receipts (up to 20 members).
|
||||
@@ -566,7 +565,8 @@
|
||||
<source>Accept</source>
|
||||
<target>Accepteer</target>
|
||||
<note>accept contact request via notification
|
||||
accept incoming call via notification</note>
|
||||
accept incoming call via notification
|
||||
swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Accept connection request?" xml:space="preserve">
|
||||
<source>Accept connection request?</source>
|
||||
@@ -581,7 +581,8 @@
|
||||
<trans-unit id="Accept incognito" xml:space="preserve">
|
||||
<source>Accept incognito</source>
|
||||
<target>Accepteer incognito</target>
|
||||
<note>accept contact request via notification</note>
|
||||
<note>accept contact request via notification
|
||||
swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Acknowledged" xml:space="preserve">
|
||||
<source>Acknowledged</source>
|
||||
@@ -755,6 +756,7 @@
|
||||
</trans-unit>
|
||||
<trans-unit id="Allow calls?" xml:space="preserve">
|
||||
<source>Allow calls?</source>
|
||||
<target>Oproepen toestaan?</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Allow disappearing messages only if your contact allows it to you." xml:space="preserve">
|
||||
@@ -947,8 +949,14 @@
|
||||
<target>Archiveren en uploaden</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Archive contacts to chat later." xml:space="preserve">
|
||||
<source>Archive contacts to chat later.</source>
|
||||
<target>Archiveer contacten om later te chatten.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Archived contacts" xml:space="preserve">
|
||||
<source>Archived contacts</source>
|
||||
<target>Gearchiveerde contacten</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Archiving database" xml:space="preserve">
|
||||
@@ -1051,6 +1059,11 @@
|
||||
<target>Betere berichten</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Better networking" xml:space="preserve">
|
||||
<source>Better networking</source>
|
||||
<target>Beter netwerk</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Black" xml:space="preserve">
|
||||
<source>Black</source>
|
||||
<target>Zwart</target>
|
||||
@@ -1091,6 +1104,11 @@
|
||||
<target>Geblokkeerd door beheerder</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Blur for better privacy." xml:space="preserve">
|
||||
<source>Blur for better privacy.</source>
|
||||
<target>Vervagen voor betere privacy.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Blur media" xml:space="preserve">
|
||||
<source>Blur media</source>
|
||||
<target>Vervaag media</target>
|
||||
@@ -1143,6 +1161,7 @@
|
||||
</trans-unit>
|
||||
<trans-unit id="Calls prohibited!" xml:space="preserve">
|
||||
<source>Calls prohibited!</source>
|
||||
<target>Bellen verboden!</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Camera not available" xml:space="preserve">
|
||||
@@ -1152,10 +1171,12 @@
|
||||
</trans-unit>
|
||||
<trans-unit id="Can't call contact" xml:space="preserve">
|
||||
<source>Can't call contact</source>
|
||||
<target>Kan contact niet bellen</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Can't call member" xml:space="preserve">
|
||||
<source>Can't call member</source>
|
||||
<target>Kan lid niet bellen</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Can't invite contact!" xml:space="preserve">
|
||||
@@ -1170,6 +1191,7 @@
|
||||
</trans-unit>
|
||||
<trans-unit id="Can't message member" xml:space="preserve">
|
||||
<source>Can't message member</source>
|
||||
<target>Kan geen bericht sturen naar lid</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Cancel" xml:space="preserve">
|
||||
@@ -1308,6 +1330,11 @@
|
||||
<target>Chat is gestopt. Als je deze database al op een ander apparaat hebt gebruikt, moet je deze terugzetten voordat je met chatten begint.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Chat list" xml:space="preserve">
|
||||
<source>Chat list</source>
|
||||
<target>Chatlijst</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Chat migrated!" xml:space="preserve">
|
||||
<source>Chat migrated!</source>
|
||||
<target>Chat gemigreerd!</target>
|
||||
@@ -1371,7 +1398,7 @@
|
||||
<trans-unit id="Clear" xml:space="preserve">
|
||||
<source>Clear</source>
|
||||
<target>Wissen</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
<note>swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Clear conversation" xml:space="preserve">
|
||||
<source>Clear conversation</source>
|
||||
@@ -1393,6 +1420,11 @@
|
||||
<target>Verwijderd verificatie</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Color chats with the new themes." xml:space="preserve">
|
||||
<source>Color chats with the new themes.</source>
|
||||
<target>Kleurchats met de nieuwe thema's.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Color mode" xml:space="preserve">
|
||||
<source>Color mode</source>
|
||||
<target>Kleur mode</target>
|
||||
@@ -1435,6 +1467,7 @@
|
||||
</trans-unit>
|
||||
<trans-unit id="Confirm contact deletion?" xml:space="preserve">
|
||||
<source>Confirm contact deletion?</source>
|
||||
<target>Contact verwijderen bevestigen?</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Confirm database upgrades" xml:space="preserve">
|
||||
@@ -1492,8 +1525,9 @@
|
||||
<target>Verbinden met desktop</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Connect to your friends faster" xml:space="preserve">
|
||||
<source>Connect to your friends faster</source>
|
||||
<trans-unit id="Connect to your friends faster." xml:space="preserve">
|
||||
<source>Connect to your friends faster.</source>
|
||||
<target>Maak sneller verbinding met je vrienden.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Connect to yourself?" xml:space="preserve">
|
||||
@@ -1572,6 +1606,7 @@ Dit is uw eigen eenmalige link!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Connecting to contact, please wait or check later!" xml:space="preserve">
|
||||
<source>Connecting to contact, please wait or check later!</source>
|
||||
<target>Er wordt verbinding gemaakt met het contact. Even geduld of controleer het later!</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Connecting to desktop" xml:space="preserve">
|
||||
@@ -1586,6 +1621,7 @@ Dit is uw eigen eenmalige link!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Connection and servers status." xml:space="preserve">
|
||||
<source>Connection and servers status.</source>
|
||||
<target>Verbindings- en serverstatus.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Connection error" xml:space="preserve">
|
||||
@@ -1640,6 +1676,7 @@ Dit is uw eigen eenmalige link!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Contact deleted!" xml:space="preserve">
|
||||
<source>Contact deleted!</source>
|
||||
<target>Contact verwijderd!</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Contact hidden:" xml:space="preserve">
|
||||
@@ -1654,6 +1691,7 @@ Dit is uw eigen eenmalige link!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Contact is deleted." xml:space="preserve">
|
||||
<source>Contact is deleted.</source>
|
||||
<target>Contact is verwijderd.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Contact name" xml:space="preserve">
|
||||
@@ -1668,6 +1706,7 @@ Dit is uw eigen eenmalige link!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Contact will be deleted - this cannot be undone!" xml:space="preserve">
|
||||
<source>Contact will be deleted - this cannot be undone!</source>
|
||||
<target>Het contact wordt verwijderd. Dit kan niet ongedaan worden gemaakt!</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Contacts" xml:space="preserve">
|
||||
@@ -1685,12 +1724,9 @@ Dit is uw eigen eenmalige link!</target>
|
||||
<target>Doorgaan</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Control your network" xml:space="preserve">
|
||||
<source>Control your network</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Conversation deleted!" xml:space="preserve">
|
||||
<source>Conversation deleted!</source>
|
||||
<target>Gesprek verwijderd!</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Copy" xml:space="preserve">
|
||||
@@ -1708,6 +1744,10 @@ Dit is uw eigen eenmalige link!</target>
|
||||
<target>Core versie: v% @</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Corner" xml:space="preserve">
|
||||
<source>Corner</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Correct name to %@?" xml:space="preserve">
|
||||
<source>Correct name to %@?</source>
|
||||
<target>Juiste naam voor %@?</target>
|
||||
@@ -1964,7 +2004,8 @@ Dit is uw eigen eenmalige link!</target>
|
||||
<trans-unit id="Delete" xml:space="preserve">
|
||||
<source>Delete</source>
|
||||
<target>Verwijderen</target>
|
||||
<note>chat item action</note>
|
||||
<note>chat item action
|
||||
swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Delete %lld messages of members?" xml:space="preserve">
|
||||
<source>Delete %lld messages of members?</source>
|
||||
@@ -2033,6 +2074,7 @@ Dit is uw eigen eenmalige link!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Delete contact?" xml:space="preserve">
|
||||
<source>Delete contact?</source>
|
||||
<target>Verwijder contact?</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Delete database" xml:space="preserve">
|
||||
@@ -2142,6 +2184,7 @@ Dit is uw eigen eenmalige link!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Delete up to 20 messages at once." xml:space="preserve">
|
||||
<source>Delete up to 20 messages at once.</source>
|
||||
<target>Verwijder maximaal 20 berichten tegelijk.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Delete user profile?" xml:space="preserve">
|
||||
@@ -2151,6 +2194,7 @@ Dit is uw eigen eenmalige link!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Delete without notification" xml:space="preserve">
|
||||
<source>Delete without notification</source>
|
||||
<target>Verwijderen zonder melding</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Deleted" xml:space="preserve">
|
||||
@@ -2168,10 +2212,6 @@ Dit is uw eigen eenmalige link!</target>
|
||||
<target>Verwijderd om: %@</target>
|
||||
<note>copied message info</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Deleted chats" xml:space="preserve">
|
||||
<source>Deleted chats</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Deletion errors" xml:space="preserve">
|
||||
<source>Deletion errors</source>
|
||||
<target>Verwijderingsfouten</target>
|
||||
@@ -2244,6 +2284,7 @@ Dit is uw eigen eenmalige link!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Developer options" xml:space="preserve">
|
||||
<source>Developer options</source>
|
||||
<target>Ontwikkelaars opties</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Developer tools" xml:space="preserve">
|
||||
@@ -2691,6 +2732,10 @@ Dit is uw eigen eenmalige link!</target>
|
||||
<target>Fout bij wijzigen van adres</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Error changing connection profile" xml:space="preserve">
|
||||
<source>Error changing connection profile</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Error changing role" xml:space="preserve">
|
||||
<source>Error changing role</source>
|
||||
<target>Fout bij wisselen van rol</target>
|
||||
@@ -2701,6 +2746,10 @@ Dit is uw eigen eenmalige link!</target>
|
||||
<target>Fout bij wijzigen van instelling</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Error changing to incognito!" xml:space="preserve">
|
||||
<source>Error changing to incognito!</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Error connecting to forwarding server %@. Please try later." xml:space="preserve">
|
||||
<source>Error connecting to forwarding server %@. Please try later.</source>
|
||||
<target>Fout bij het verbinden met doorstuurserver %@. Probeer het later opnieuw.</target>
|
||||
@@ -2921,6 +2970,10 @@ Dit is uw eigen eenmalige link!</target>
|
||||
<target>Fout bij het stoppen van de chat</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Error switching profile" xml:space="preserve">
|
||||
<source>Error switching profile</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Error switching profile!" xml:space="preserve">
|
||||
<source>Error switching profile!</source>
|
||||
<target>Fout bij wisselen van profiel!</target>
|
||||
@@ -2992,10 +3045,6 @@ Dit is uw eigen eenmalige link!</target>
|
||||
<target>Zelfs wanneer uitgeschakeld in het gesprek.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Even when they are offline." xml:space="preserve">
|
||||
<source>Even when they are offline.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Exit without saving" xml:space="preserve">
|
||||
<source>Exit without saving</source>
|
||||
<target>Afsluiten zonder opslaan</target>
|
||||
@@ -3054,7 +3103,7 @@ Dit is uw eigen eenmalige link!</target>
|
||||
<trans-unit id="Favorite" xml:space="preserve">
|
||||
<source>Favorite</source>
|
||||
<target>Favoriet</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
<note>swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="File error" xml:space="preserve">
|
||||
<source>File error</source>
|
||||
@@ -3810,6 +3859,7 @@ Fout: %2$@</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="It protects your IP address and connections." xml:space="preserve">
|
||||
<source>It protects your IP address and connections.</source>
|
||||
<target>Het beschermt uw IP-adres en verbindingen.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</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">
|
||||
@@ -3830,7 +3880,7 @@ Fout: %2$@</target>
|
||||
<trans-unit id="Join" xml:space="preserve">
|
||||
<source>Join</source>
|
||||
<target>Word lid van</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
<note>swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Join group" xml:space="preserve">
|
||||
<source>Join group</source>
|
||||
@@ -3876,6 +3926,7 @@ Dit is jouw link voor groep %@!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Keep conversation" xml:space="preserve">
|
||||
<source>Keep conversation</source>
|
||||
<target>Behoud het gesprek</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">
|
||||
@@ -3921,7 +3972,7 @@ Dit is jouw link voor groep %@!</target>
|
||||
<trans-unit id="Leave" xml:space="preserve">
|
||||
<source>Leave</source>
|
||||
<target>Verlaten</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
<note>swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Leave group" xml:space="preserve">
|
||||
<source>Leave group</source>
|
||||
@@ -4153,6 +4204,10 @@ Dit is jouw link voor groep %@!</target>
|
||||
<target>Berichtservers</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message shape" xml:space="preserve">
|
||||
<source>Message shape</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message source remains private." xml:space="preserve">
|
||||
<source>Message source remains private.</source>
|
||||
<target>Berichtbron blijft privé.</target>
|
||||
@@ -4260,7 +4315,7 @@ Dit is jouw link voor groep %@!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Migration failed. Tap **Skip** below to continue using the current database. Please report the issue to the app developers via chat or email [chat@simplex.chat](mailto:chat@simplex.chat)." xml:space="preserve">
|
||||
<source>Migration failed. Tap **Skip** below to continue using the current database. Please report the issue to the app developers via chat or email [chat@simplex.chat](mailto:chat@simplex.chat).</source>
|
||||
<target>Migratie mislukt. Tik hieronder op **Overslaan** om de huidige database te blijven gebruiken. Meld het probleem aan de app-ontwikkelaars via chat of e-mail [chat@simplex.chat](mailto:chat@simplex.chat).</target>
|
||||
<target>Migratie mislukt. Tik hier onder op **Overslaan** om de huidige database te blijven gebruiken. Meld het probleem aan de app-ontwikkelaars via chat of e-mail [chat@simplex.chat](mailto:chat@simplex.chat).</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Migration is completed" xml:space="preserve">
|
||||
@@ -4278,10 +4333,6 @@ Dit is jouw link voor groep %@!</target>
|
||||
<target>Modereren</target>
|
||||
<note>chat item action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Moderate like a pro ✋" xml:space="preserve">
|
||||
<source>Moderate like a pro ✋</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Moderated at" xml:space="preserve">
|
||||
<source>Moderated at</source>
|
||||
<target>Gemodereerd om</target>
|
||||
@@ -4315,7 +4366,7 @@ Dit is jouw link voor groep %@!</target>
|
||||
<trans-unit id="Mute" xml:space="preserve">
|
||||
<source>Mute</source>
|
||||
<target>Dempen</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
<note>swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Muted when inactive!" xml:space="preserve">
|
||||
<source>Muted when inactive!</source>
|
||||
@@ -4325,7 +4376,7 @@ Dit is jouw link voor groep %@!</target>
|
||||
<trans-unit id="Name" xml:space="preserve">
|
||||
<source>Name</source>
|
||||
<target>Naam</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
<note>swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Network & servers" xml:space="preserve">
|
||||
<source>Network & servers</source>
|
||||
@@ -4357,10 +4408,6 @@ Dit is jouw link voor groep %@!</target>
|
||||
<target>Netwerk status</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="New Chat" xml:space="preserve">
|
||||
<source>New Chat</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="New Passcode" xml:space="preserve">
|
||||
<source>New Passcode</source>
|
||||
<target>Nieuwe toegangscode</target>
|
||||
@@ -4371,6 +4418,11 @@ Dit is jouw link voor groep %@!</target>
|
||||
<target>Nieuw gesprek</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="New chat experience 🎉" xml:space="preserve">
|
||||
<source>New chat experience 🎉</source>
|
||||
<target>Nieuwe chatervaring 🎉</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="New contact request" xml:space="preserve">
|
||||
<source>New contact request</source>
|
||||
<target>Nieuw contactverzoek</target>
|
||||
@@ -4401,6 +4453,11 @@ Dit is jouw link voor groep %@!</target>
|
||||
<target>Nieuw in %@</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="New media options" xml:space="preserve">
|
||||
<source>New media options</source>
|
||||
<target>Nieuwe media-opties</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="New member role" xml:space="preserve">
|
||||
<source>New member role</source>
|
||||
<target>Nieuwe leden rol</target>
|
||||
@@ -4540,10 +4597,6 @@ Dit is jouw link voor groep %@!</target>
|
||||
<target>Oud database archief</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="One-hand UI" xml:space="preserve">
|
||||
<source>One-hand UI</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="One-time invitation link" xml:space="preserve">
|
||||
<source>One-time invitation link</source>
|
||||
<target>Eenmalige uitnodiging link</target>
|
||||
@@ -4575,6 +4628,7 @@ Vereist het inschakelen van VPN.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Only delete conversation" xml:space="preserve">
|
||||
<source>Only delete conversation</source>
|
||||
<target>Alleen conversatie verwijderen</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Only group owners can change group preferences." xml:space="preserve">
|
||||
@@ -4812,8 +4866,14 @@ Vereist het inschakelen van VPN.</target>
|
||||
<target>Beeld-in-beeld oproepen</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Play from the chat list." xml:space="preserve">
|
||||
<source>Play from the chat list.</source>
|
||||
<target>Afspelen via de gesprekken lijst.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Please ask your contact to enable calls." xml:space="preserve">
|
||||
<source>Please ask your contact to enable calls.</source>
|
||||
<target>Vraag uw contactpersoon om oproepen in te schakelen.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Please ask your contact to enable sending voice messages." xml:space="preserve">
|
||||
@@ -5117,8 +5177,9 @@ Schakel dit in in *Netwerk en servers*-instellingen.</target>
|
||||
<target>Beoordeel de app</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Reachable chat toolbar 👋" xml:space="preserve">
|
||||
<source>Reachable chat toolbar 👋</source>
|
||||
<trans-unit id="Reachable chat toolbar" xml:space="preserve">
|
||||
<source>Reachable chat toolbar</source>
|
||||
<target>Toegankelijke chatwerkbalk</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="React…" xml:space="preserve">
|
||||
@@ -5129,7 +5190,7 @@ Schakel dit in in *Netwerk en servers*-instellingen.</target>
|
||||
<trans-unit id="Read" xml:space="preserve">
|
||||
<source>Read</source>
|
||||
<target>Lees</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
<note>swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Read more" xml:space="preserve">
|
||||
<source>Read more</source>
|
||||
@@ -5289,7 +5350,8 @@ Schakel dit in in *Netwerk en servers*-instellingen.</target>
|
||||
<trans-unit id="Reject" xml:space="preserve">
|
||||
<source>Reject</source>
|
||||
<target>Afwijzen</target>
|
||||
<note>reject incoming call via notification</note>
|
||||
<note>reject incoming call via notification
|
||||
swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Reject (sender NOT notified)" xml:space="preserve">
|
||||
<source>Reject (sender NOT notified)</source>
|
||||
@@ -5391,6 +5453,11 @@ Schakel dit in in *Netwerk en servers*-instellingen.</target>
|
||||
<target>Resetten</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Reset all hints" xml:space="preserve">
|
||||
<source>Reset all hints</source>
|
||||
<target>Alle hints resetten</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Reset all statistics" xml:space="preserve">
|
||||
<source>Reset all statistics</source>
|
||||
<target>Reset alle statistieken</target>
|
||||
@@ -5686,6 +5753,10 @@ Schakel dit in in *Netwerk en servers*-instellingen.</target>
|
||||
<target>Selecteer</target>
|
||||
<note>chat item action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Select chat profile" xml:space="preserve">
|
||||
<source>Select chat profile</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Selected %lld" xml:space="preserve">
|
||||
<source>Selected %lld</source>
|
||||
<target>%lld geselecteerd</target>
|
||||
@@ -5758,6 +5829,7 @@ Schakel dit in in *Netwerk en servers*-instellingen.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Send message to enable calls." xml:space="preserve">
|
||||
<source>Send message to enable calls.</source>
|
||||
<target>Stuur een bericht om oproepen mogelijk te maken.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Send messages directly when IP address is protected and your or destination server does not support private routing." xml:space="preserve">
|
||||
@@ -6045,11 +6117,20 @@ Schakel dit in in *Netwerk en servers*-instellingen.</target>
|
||||
<target>Adres delen met contacten?</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Share from other apps." xml:space="preserve">
|
||||
<source>Share from other apps.</source>
|
||||
<target>Delen vanuit andere apps.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Share link" xml:space="preserve">
|
||||
<source>Share link</source>
|
||||
<target>Deel link</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Share profile" xml:space="preserve">
|
||||
<source>Share profile</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Share this 1-time invite link" xml:space="preserve">
|
||||
<source>Share this 1-time invite link</source>
|
||||
<target>Deel deze eenmalige uitnodigingslink</target>
|
||||
@@ -6390,6 +6471,10 @@ Schakel dit in in *Netwerk en servers*-instellingen.</target>
|
||||
<target>TCP_KEEPINTVL</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Tail" xml:space="preserve">
|
||||
<source>Tail</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Take picture" xml:space="preserve">
|
||||
<source>Take picture</source>
|
||||
<target>Foto nemen</target>
|
||||
@@ -6402,32 +6487,32 @@ Schakel dit in in *Netwerk en servers*-instellingen.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Tap to Connect" xml:space="preserve">
|
||||
<source>Tap to Connect</source>
|
||||
<target>Tik om verbinding te maken</target>
|
||||
<target>Tik hier om verbinding te maken</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Tap to activate profile." xml:space="preserve">
|
||||
<source>Tap to activate profile.</source>
|
||||
<target>Tik om profiel te activeren.</target>
|
||||
<target>Tik hier om profiel te activeren.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Tap to join" xml:space="preserve">
|
||||
<source>Tap to join</source>
|
||||
<target>Tik om lid te worden</target>
|
||||
<target>Tik hier 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 lid te worden</target>
|
||||
<target>Tik hier om incognito lid te worden</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Tap to paste link" xml:space="preserve">
|
||||
<source>Tap to paste link</source>
|
||||
<target>Tik om de link te plakken</target>
|
||||
<target>Tik hier om de link te plakken</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Tap to scan" xml:space="preserve">
|
||||
<source>Tap to scan</source>
|
||||
<target>Tik om te scannen</target>
|
||||
<target>Tik hier om te scannen</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Temporary file error" xml:space="preserve">
|
||||
@@ -6729,11 +6814,21 @@ U wordt gevraagd de authenticatie te voltooien voordat deze functie wordt ingesc
|
||||
<target>Vergelijk (of scan) de code op uw apparaten om end-to-end-codering met uw contact te verifiëren.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Toggle chat list:" xml:space="preserve">
|
||||
<source>Toggle chat list:</source>
|
||||
<target>Chatlijst wisselen:</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Toggle incognito when connecting." xml:space="preserve">
|
||||
<source>Toggle incognito when connecting.</source>
|
||||
<target>Schakel incognito in tijdens het verbinden.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Toolbar opacity" xml:space="preserve">
|
||||
<source>Toolbar opacity</source>
|
||||
<target>De transparantie van de werkbalk</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Total" xml:space="preserve">
|
||||
<source>Total</source>
|
||||
<target>Totaal</target>
|
||||
@@ -6812,7 +6907,7 @@ U wordt gevraagd de authenticatie te voltooien voordat deze functie wordt ingesc
|
||||
<trans-unit id="Unfav." xml:space="preserve">
|
||||
<source>Unfav.</source>
|
||||
<target>Niet fav.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
<note>swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Unhide" xml:space="preserve">
|
||||
<source>Unhide</source>
|
||||
@@ -6889,12 +6984,12 @@ Om verbinding te maken, vraagt u uw contact om een andere verbinding link te mak
|
||||
<trans-unit id="Unmute" xml:space="preserve">
|
||||
<source>Unmute</source>
|
||||
<target>Dempen opheffen</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
<note>swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Unread" xml:space="preserve">
|
||||
<source>Unread</source>
|
||||
<target>Ongelezen</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
<note>swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Up to 100 last messages are sent to new members." xml:space="preserve">
|
||||
<source>Up to 100 last messages are sent to new members.</source>
|
||||
@@ -7028,6 +7123,7 @@ Om verbinding te maken, vraagt u uw contact om een andere verbinding link te mak
|
||||
</trans-unit>
|
||||
<trans-unit id="Use the app with one hand." xml:space="preserve">
|
||||
<source>Use the app with one hand.</source>
|
||||
<target>Gebruik de app met één hand.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="User profile" xml:space="preserve">
|
||||
@@ -7387,6 +7483,11 @@ Deelnameverzoek herhalen?</target>
|
||||
<target>U kunt oproepen van het vergrendelingsscherm accepteren, zonder apparaat- en app-verificatie.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="You can change it in Appearance settings." xml:space="preserve">
|
||||
<source>You can change it in Appearance settings.</source>
|
||||
<target>U kunt dit wijzigen in de instellingen onder uiterlijk.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="You can create it later" xml:space="preserve">
|
||||
<source>You can create it later</source>
|
||||
<target>U kan het later maken</target>
|
||||
@@ -7424,6 +7525,7 @@ Deelnameverzoek herhalen?</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="You can send messages to %@ from Archived contacts." xml:space="preserve">
|
||||
<source>You can send messages to %@ from Archived contacts.</source>
|
||||
<target>U kunt berichten naar %@ sturen vanuit gearchiveerde contacten.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="You can set lock screen notification preview via settings." xml:space="preserve">
|
||||
@@ -7453,6 +7555,7 @@ Deelnameverzoek herhalen?</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="You can still view conversation with %@ in the list of chats." xml:space="preserve">
|
||||
<source>You can still view conversation with %@ in the list of chats.</source>
|
||||
<target>Je kunt het gesprek met %@ nog steeds bekijken in de lijst met chats.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="You can turn on SimpleX Lock via Settings." xml:space="preserve">
|
||||
@@ -7534,6 +7637,7 @@ Verbindingsverzoek herhalen?</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="You need to allow your contact to call to be able to call them." xml:space="preserve">
|
||||
<source>You need to allow your contact to call to be able to call them.</source>
|
||||
<target>U moet uw contactpersoon toestemming geven om te bellen, zodat hij/zij je kan bellen.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="You need to allow your contact to send voice messages to be able to send them." xml:space="preserve">
|
||||
@@ -7651,6 +7755,10 @@ Verbindingsverzoek herhalen?</target>
|
||||
<target>Uw chat profielen</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Your connection was moved to %@ but an unexpected error occurred while redirecting you to the profile." xml:space="preserve">
|
||||
<source>Your connection was moved to %@ but an unexpected error occurred while redirecting you to the profile.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Your contact sent a file that is larger than currently supported maximum size (%@)." xml:space="preserve">
|
||||
<source>Your contact sent a file that is larger than currently supported maximum size (%@).</source>
|
||||
<target>Uw contact heeft een bestand verzonden dat groter is dan de momenteel ondersteunde maximale grootte (%@).</target>
|
||||
@@ -7666,10 +7774,6 @@ Verbindingsverzoek herhalen?</target>
|
||||
<target>Uw contacten blijven verbonden.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Your contacts your way" xml:space="preserve">
|
||||
<source>Your contacts your way</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Your current chat database will be DELETED and REPLACED with the imported one." xml:space="preserve">
|
||||
<source>Your current chat database will be DELETED and REPLACED with the imported one.</source>
|
||||
<target>Uw huidige chat database wordt VERWIJDERD en VERVANGEN door de geïmporteerde.</target>
|
||||
@@ -7849,6 +7953,7 @@ SimpleX servers kunnen uw profiel niet zien.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="call" xml:space="preserve">
|
||||
<source>call</source>
|
||||
<target>bellen</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="call error" xml:space="preserve">
|
||||
@@ -8223,6 +8328,7 @@ SimpleX servers kunnen uw profiel niet zien.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="invite" xml:space="preserve">
|
||||
<source>invite</source>
|
||||
<target>uitnodiging</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="invited" xml:space="preserve">
|
||||
@@ -8282,6 +8388,7 @@ SimpleX servers kunnen uw profiel niet zien.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="message" xml:space="preserve">
|
||||
<source>message</source>
|
||||
<target>bericht</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="message received" xml:space="preserve">
|
||||
@@ -8316,6 +8423,7 @@ SimpleX servers kunnen uw profiel niet zien.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="mute" xml:space="preserve">
|
||||
<source>mute</source>
|
||||
<target>dempen</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="never" xml:space="preserve">
|
||||
@@ -8452,6 +8560,7 @@ SimpleX servers kunnen uw profiel niet zien.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="search" xml:space="preserve">
|
||||
<source>search</source>
|
||||
<target>zoekopdracht</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="sec" xml:space="preserve">
|
||||
@@ -8540,6 +8649,7 @@ laatst ontvangen bericht: %2$@</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="unmute" xml:space="preserve">
|
||||
<source>unmute</source>
|
||||
<target>dempen opheffen</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="unprotected" xml:space="preserve">
|
||||
@@ -8589,6 +8699,7 @@ laatst ontvangen bericht: %2$@</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="video" xml:space="preserve">
|
||||
<source>video</source>
|
||||
<target>video</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="video call (not e2e encrypted)" xml:space="preserve">
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -5234,6 +5234,274 @@ Isso pode acontecer por causa de algum bug ou quando a conexão está comprometi
|
||||
<target state="translated">%1$@ em %2$@:</target>
|
||||
<note>copied message info, <sender> at <time></note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Allow your contacts to irreversibly delete sent messages. (24 hours)" xml:space="preserve" approved="no">
|
||||
<source>Allow your contacts to irreversibly delete sent messages. (24 hours)</source>
|
||||
<target state="translated">Permitir que seus contatos deletem mensagens enviadas de maneira irreversível. (24 horas)</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="%@ downloaded" xml:space="preserve" approved="no">
|
||||
<source>%@ downloaded</source>
|
||||
<target state="translated">baixado</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="%@ uploaded" xml:space="preserve" approved="no">
|
||||
<source>%@ uploaded</source>
|
||||
<target state="translated">transferido</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="A new random profile will be shared." xml:space="preserve" approved="no">
|
||||
<source>A new random profile will be shared.</source>
|
||||
<target state="translated">Um novo perfil aleatório será compartilhado.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Camera not available" xml:space="preserve" approved="no">
|
||||
<source>Camera not available</source>
|
||||
<target state="translated">Câmera indisponível</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Admins can block a member for all." xml:space="preserve" approved="no">
|
||||
<source>Admins can block a member for all.</source>
|
||||
<target state="translated">Administradores podem bloquear um membro para todos.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Allow to irreversibly delete sent messages. (24 hours)" xml:space="preserve" approved="no">
|
||||
<source>Allow to irreversibly delete sent messages. (24 hours)</source>
|
||||
<target state="translated">Permitir que mensagens enviadas sejam deletadas de maneira irreversível. (24 horas)</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Apply" xml:space="preserve" approved="no">
|
||||
<source>Apply</source>
|
||||
<target state="translated">Aplicar</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Accent" xml:space="preserve" approved="no">
|
||||
<source>Accent</source>
|
||||
<target state="translated">Esquema</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Accept connection request?" xml:space="preserve" approved="no">
|
||||
<source>Accept connection request?</source>
|
||||
<target state="translated">Aceitar solicitação de conexão?</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Active connections" xml:space="preserve" approved="no">
|
||||
<source>Active connections</source>
|
||||
<target state="translated">Conexões ativas</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add contact" xml:space="preserve" approved="no">
|
||||
<source>Add contact</source>
|
||||
<target state="translated">Adicionar contato</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Additional accent" xml:space="preserve" approved="no">
|
||||
<source>Additional accent</source>
|
||||
<target state="translated">Esquema adicional</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="All new messages from %@ will be hidden!" xml:space="preserve" approved="no">
|
||||
<source>All new messages from %@ will be hidden!</source>
|
||||
<target state="translated">Todas as novas mensagens de %@ serão ocultas!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="All profiles" xml:space="preserve" approved="no">
|
||||
<source>All profiles</source>
|
||||
<target state="translated">Todos perfis</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Allow calls?" xml:space="preserve" approved="no">
|
||||
<source>Allow calls?</source>
|
||||
<target state="translated">Permitir chamadas?</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Archive contacts to chat later." xml:space="preserve" approved="no">
|
||||
<source>Archive contacts to chat later.</source>
|
||||
<target state="translated">Arquivar contatos para conversar depois.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Blur media" xml:space="preserve" approved="no">
|
||||
<source>Blur media</source>
|
||||
<target state="translated">Censurar mídia</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Calls prohibited!" xml:space="preserve" approved="no">
|
||||
<source>Calls prohibited!</source>
|
||||
<target state="translated">Chamadas proibidas!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Can't call contact" xml:space="preserve" approved="no">
|
||||
<source>Can't call contact</source>
|
||||
<target state="translated">Não foi possível ligar para o contato</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="%lld messages marked deleted" xml:space="preserve" approved="no">
|
||||
<source>%lld messages marked deleted</source>
|
||||
<target state="translated">mensagens deletadas</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="0 sec" xml:space="preserve" approved="no">
|
||||
<source>0 sec</source>
|
||||
<target state="translated">0 seg</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="%lld messages blocked" xml:space="preserve" approved="no">
|
||||
<source>%lld messages blocked</source>
|
||||
<target state="translated">mensagens bloqueadas</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="%lld messages blocked by admin" xml:space="preserve" approved="no">
|
||||
<source>%lld messages blocked by admin</source>
|
||||
<target state="translated">mensagens bloqueadas pelo administrador</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="**Please note**: using the same database on two devices will break the decryption of messages from your connections, as a security protection." xml:space="preserve" approved="no">
|
||||
<source>**Please note**: using the same database on two devices will break the decryption of messages from your connections, as a security protection.</source>
|
||||
<target state="translated">**Nota**: usar o mesmo banco de dados em dois dispositivos irá quebrar a desencriptação das mensagens de suas conexões como uma medida de segurança.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="- more stable message delivery. - a bit better groups. - and more!" xml:space="preserve" approved="no">
|
||||
<source>- more stable message delivery.
|
||||
- a bit better groups.
|
||||
- and more!</source>
|
||||
<target state="translated">- entrega de mensagens mais estável.
|
||||
- grupos melhorados.
|
||||
- e muito mais!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="All messages will be deleted - this cannot be undone!" xml:space="preserve" approved="no">
|
||||
<source>All messages will be deleted - this cannot be undone!</source>
|
||||
<target state="translated">Todas as mensagens serão deletadas - isto não pode ser desfeito!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Allow to send files and media." xml:space="preserve" approved="no">
|
||||
<source>Allow to send files and media.</source>
|
||||
<target state="translated">Permitir o envio de arquivos e mídia.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Allow to send SimpleX links." xml:space="preserve" approved="no">
|
||||
<source>Allow to send SimpleX links.</source>
|
||||
<target state="translated">Permitir envio de links SimpleX.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Block for all" xml:space="preserve" approved="no">
|
||||
<source>Block for all</source>
|
||||
<target state="translated">Bloquear para todos</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Block member" xml:space="preserve" approved="no">
|
||||
<source>Block member</source>
|
||||
<target state="translated">Bloquear membro</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Blocked by admin" xml:space="preserve" approved="no">
|
||||
<source>Blocked by admin</source>
|
||||
<target state="translated">Bloqueado por um administrador</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Block group members" xml:space="preserve" approved="no">
|
||||
<source>Block group members</source>
|
||||
<target state="translated">Bloquear membros de grupo</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Block member for all?" xml:space="preserve" approved="no">
|
||||
<source>Block member for all?</source>
|
||||
<target state="translated">Bloquear membro para todos?</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Block member?" xml:space="preserve" approved="no">
|
||||
<source>Block member?</source>
|
||||
<target state="translated">Bloquear membro?</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Both you and your contact can irreversibly delete sent messages. (24 hours)" xml:space="preserve" approved="no">
|
||||
<source>Both you and your contact can irreversibly delete sent messages. (24 hours)</source>
|
||||
<target state="translated">Você e seu contato podem apagar mensagens enviadas de maneira irreversível. (24 horas)</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Can't call member" xml:space="preserve" approved="no">
|
||||
<source>Can't call member</source>
|
||||
<target state="translated">Não foi possível ligar para este membro</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Can't message member" xml:space="preserve" approved="no">
|
||||
<source>Can't message member</source>
|
||||
<target state="translated">Não foi possível enviar mensagem para este membro</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Cancel migration" xml:space="preserve" approved="no">
|
||||
<source>Cancel migration</source>
|
||||
<target state="translated">Cancelar migração</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Abort" xml:space="preserve" approved="no">
|
||||
<source>Abort</source>
|
||||
<target state="translated">Abortar</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Abort changing address" xml:space="preserve" approved="no">
|
||||
<source>Abort changing address</source>
|
||||
<target state="translated">Abortar troca de endereço</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Abort changing address?" xml:space="preserve" approved="no">
|
||||
<source>Abort changing address?</source>
|
||||
<target state="translated">Abortar troca de endereço?</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="- optionally notify deleted contacts. - profile names with spaces. - and more!" xml:space="preserve" approved="no">
|
||||
<source>- optionally notify deleted contacts.
|
||||
- profile names with spaces.
|
||||
- and more!</source>
|
||||
<target state="translated">- notificar contatos apagados de maneira opcional.
|
||||
- nome de perfil com espaços.
|
||||
- e muito mais!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Allow sharing" xml:space="preserve" approved="no">
|
||||
<source>Allow sharing</source>
|
||||
<target state="translated">Permitir compartilhamento</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Block" xml:space="preserve" approved="no">
|
||||
<source>Block</source>
|
||||
<target state="translated">Bloquear</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Additional accent 2" xml:space="preserve" approved="no">
|
||||
<source>Additional accent 2</source>
|
||||
<target state="translated">Esquema adicional 2</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Address change will be aborted. Old receiving address will be used." xml:space="preserve" approved="no">
|
||||
<source>Address change will be aborted. Old receiving address will be used.</source>
|
||||
<target state="translated">Alteração de endereço será abortada. O endereço antigo será utilizado.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Advanced settings" xml:space="preserve" approved="no">
|
||||
<source>Advanced settings</source>
|
||||
<target state="translated">Configurações avançadas</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="All data is private to your device." xml:space="preserve" approved="no">
|
||||
<source>All data is private to your device.</source>
|
||||
<target state="translated">Toda informação é privada em seu dispositivo.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="All your contacts, conversations and files will be securely encrypted and uploaded in chunks to configured XFTP relays." xml:space="preserve" approved="no">
|
||||
<source>All your contacts, conversations and files will be securely encrypted and uploaded in chunks to configured XFTP relays.</source>
|
||||
<target state="translated">Todos os seus contatos, conversas e arquivos serão encriptados e enviados em pedaços para nós XFTP.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Allow irreversible message deletion only if your contact allows it to you. (24 hours)" xml:space="preserve" approved="no">
|
||||
<source>Allow irreversible message deletion only if your contact allows it to you. (24 hours)</source>
|
||||
<target state="translated">Permitir deletar mensagens de maneira irreversível apenas se seu contato permitir para você. (24 horas)</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Already connecting!" xml:space="preserve" approved="no">
|
||||
<source>Already connecting!</source>
|
||||
<target state="translated">Já está conectando!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Already joining the group!" xml:space="preserve" approved="no">
|
||||
<source>Already joining the group!</source>
|
||||
<target state="translated">Já está entrando no grupo!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Always use private routing." xml:space="preserve" approved="no">
|
||||
<source>Always use private routing.</source>
|
||||
<target state="translated">Sempre use rotas privadas.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Apply to" xml:space="preserve" approved="no">
|
||||
<source>Apply to</source>
|
||||
<target state="translated">Aplicar em</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Archiving database" xml:space="preserve" approved="no">
|
||||
<source>Archiving database</source>
|
||||
<target state="translated">Arquivando banco de dados</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Black" xml:space="preserve" approved="no">
|
||||
<source>Black</source>
|
||||
<target state="translated">Preto</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Cannot forward message" xml:space="preserve" approved="no">
|
||||
<source>Cannot forward message</source>
|
||||
<target state="translated">Não é possível encaminhar mensagem</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="(new)" xml:space="preserve" approved="no">
|
||||
<source>(new)</source>
|
||||
<target state="translated">(novo)</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="(this device v%@)" xml:space="preserve" approved="no">
|
||||
<source>(this device v%@)</source>
|
||||
<target state="translated">este dispositivo</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="**Add contact**: to create a new invitation link, or connect via a link you received." xml:space="preserve" approved="no">
|
||||
<source>**Add contact**: to create a new invitation link, or connect via a link you received.</source>
|
||||
<target state="translated">**Adicionar contato**: criar um novo link de convite ou conectar via um link que você recebeu.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="**Create group**: to create a new group." xml:space="preserve" approved="no">
|
||||
<source>**Create group**: to create a new group.</source>
|
||||
<target state="translated">**Criar grupo**: criar um novo grupo.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="**Warning**: the archive will be removed." xml:space="preserve" approved="no">
|
||||
<source>**Warning**: the archive will be removed.</source>
|
||||
<target state="translated">**Aviso**: o arquivo será removido.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="A few more things" xml:space="preserve" approved="no">
|
||||
<source>A few more things</source>
|
||||
<target state="translated">E mais algumas coisas</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Archived contacts" xml:space="preserve" approved="no">
|
||||
<source>Archived contacts</source>
|
||||
<target state="translated">Contatos arquivados</target>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
<file original="en.lproj/SimpleX--iOS--InfoPlist.strings" source-language="en" target-language="pt-BR" datatype="plaintext">
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -129,6 +129,10 @@
|
||||
<target>%@ อยากเชื่อมต่อ!</target>
|
||||
<note>notification title</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="%@, %@" xml:space="preserve">
|
||||
<source>%1$@, %2$@</source>
|
||||
<note>format for date separator in chat</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="%@, %@ and %lld members" xml:space="preserve">
|
||||
<source>%@, %@ and %lld members</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -370,11 +374,6 @@
|
||||
<target>, </target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="- Search contacts when starting chat. - Archive contacts to chat later." xml:space="preserve">
|
||||
<source>- Search contacts when starting chat.
|
||||
- Archive contacts to chat later.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="- connect to [directory service](simplex:/contact#/?v=1-4&smp=smp%3A%2F%2Fu2dS9sG8nMNURyZwqASV4yROM28Er0luVTx5X1CsMrU%3D%40smp4.simplex.im%2FeXSPwqTkKyDO3px4fLf1wx3MvPdjdLW3%23%2F%3Fv%3D1-2%26dh%3DMCowBQYDK2VuAyEAaiv6MkMH44L2TcYrt_CsX3ZvM11WgbMEUn0hkIKTOho%253D%26srv%3Do5vmywmrnaxalvz6wi3zicyftgio6psuvyniis6gco6bp6ekl4cqj4id.onion) (BETA)! - delivery receipts (up to 20 members). - faster and more stable." xml:space="preserve">
|
||||
<source>- connect to [directory service](simplex:/contact#/?v=1-4&smp=smp%3A%2F%2Fu2dS9sG8nMNURyZwqASV4yROM28Er0luVTx5X1CsMrU%3D%40smp4.simplex.im%2FeXSPwqTkKyDO3px4fLf1wx3MvPdjdLW3%23%2F%3Fv%3D1-2%26dh%3DMCowBQYDK2VuAyEAaiv6MkMH44L2TcYrt_CsX3ZvM11WgbMEUn0hkIKTOho%253D%26srv%3Do5vmywmrnaxalvz6wi3zicyftgio6psuvyniis6gco6bp6ekl4cqj4id.onion) (BETA)!
|
||||
- delivery receipts (up to 20 members).
|
||||
@@ -535,7 +534,8 @@
|
||||
<source>Accept</source>
|
||||
<target>รับ</target>
|
||||
<note>accept contact request via notification
|
||||
accept incoming call via notification</note>
|
||||
accept incoming call via notification
|
||||
swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Accept connection request?" xml:space="preserve">
|
||||
<source>Accept connection request?</source>
|
||||
@@ -549,7 +549,8 @@
|
||||
<trans-unit id="Accept incognito" xml:space="preserve">
|
||||
<source>Accept incognito</source>
|
||||
<target>ยอมรับโหมดไม่ระบุตัวตน</target>
|
||||
<note>accept contact request via notification</note>
|
||||
<note>accept contact request via notification
|
||||
swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Acknowledged" xml:space="preserve">
|
||||
<source>Acknowledged</source>
|
||||
@@ -890,6 +891,10 @@
|
||||
<source>Archive and upload</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Archive contacts to chat later." xml:space="preserve">
|
||||
<source>Archive contacts to chat later.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Archived contacts" xml:space="preserve">
|
||||
<source>Archived contacts</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -990,6 +995,10 @@
|
||||
<target>ข้อความที่ดีขึ้น</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Better networking" xml:space="preserve">
|
||||
<source>Better networking</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Black" xml:space="preserve">
|
||||
<source>Black</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -1022,6 +1031,10 @@
|
||||
<source>Blocked by admin</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Blur for better privacy." xml:space="preserve">
|
||||
<source>Blur for better privacy.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Blur media" xml:space="preserve">
|
||||
<source>Blur media</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -1229,6 +1242,10 @@
|
||||
<source>Chat is stopped. If you already used this database on another device, you should transfer it back before starting chat.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Chat list" xml:space="preserve">
|
||||
<source>Chat list</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Chat migrated!" xml:space="preserve">
|
||||
<source>Chat migrated!</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -1286,7 +1303,7 @@
|
||||
<trans-unit id="Clear" xml:space="preserve">
|
||||
<source>Clear</source>
|
||||
<target>ลบ</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
<note>swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Clear conversation" xml:space="preserve">
|
||||
<source>Clear conversation</source>
|
||||
@@ -1307,6 +1324,10 @@
|
||||
<target>ล้างการยืนยัน</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Color chats with the new themes." xml:space="preserve">
|
||||
<source>Color chats with the new themes.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Color mode" xml:space="preserve">
|
||||
<source>Color mode</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -1396,8 +1417,8 @@
|
||||
<source>Connect to desktop</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Connect to your friends faster" xml:space="preserve">
|
||||
<source>Connect to your friends faster</source>
|
||||
<trans-unit id="Connect to your friends faster." xml:space="preserve">
|
||||
<source>Connect to your friends faster.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Connect to yourself?" xml:space="preserve">
|
||||
@@ -1571,10 +1592,6 @@ This is your own one-time link!</source>
|
||||
<target>ดำเนินการต่อ</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Control your network" xml:space="preserve">
|
||||
<source>Control your network</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Conversation deleted!" xml:space="preserve">
|
||||
<source>Conversation deleted!</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -1593,6 +1610,10 @@ This is your own one-time link!</source>
|
||||
<target>รุ่นหลัก: v%@</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Corner" xml:space="preserve">
|
||||
<source>Corner</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Correct name to %@?" xml:space="preserve">
|
||||
<source>Correct name to %@?</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -1835,7 +1856,8 @@ This is your own one-time link!</source>
|
||||
<trans-unit id="Delete" xml:space="preserve">
|
||||
<source>Delete</source>
|
||||
<target>ลบ</target>
|
||||
<note>chat item action</note>
|
||||
<note>chat item action
|
||||
swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Delete %lld messages of members?" xml:space="preserve">
|
||||
<source>Delete %lld messages of members?</source>
|
||||
@@ -2034,10 +2056,6 @@ This is your own one-time link!</source>
|
||||
<target>ลบที่: %@</target>
|
||||
<note>copied message info</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Deleted chats" xml:space="preserve">
|
||||
<source>Deleted chats</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Deletion errors" xml:space="preserve">
|
||||
<source>Deletion errors</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -2520,6 +2538,10 @@ This is your own one-time link!</source>
|
||||
<target>เกิดข้อผิดพลาดในการเปลี่ยนที่อยู่</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Error changing connection profile" xml:space="preserve">
|
||||
<source>Error changing connection profile</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Error changing role" xml:space="preserve">
|
||||
<source>Error changing role</source>
|
||||
<target>เกิดข้อผิดพลาดในการเปลี่ยนบทบาท</target>
|
||||
@@ -2530,6 +2552,10 @@ This is your own one-time link!</source>
|
||||
<target>เกิดข้อผิดพลาดในการเปลี่ยนการตั้งค่า</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Error changing to incognito!" xml:space="preserve">
|
||||
<source>Error changing to incognito!</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Error connecting to forwarding server %@. Please try later." xml:space="preserve">
|
||||
<source>Error connecting to forwarding server %@. Please try later.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -2737,6 +2763,10 @@ This is your own one-time link!</source>
|
||||
<target>เกิดข้อผิดพลาดในการหยุดแชท</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Error switching profile" xml:space="preserve">
|
||||
<source>Error switching profile</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Error switching profile!" xml:space="preserve">
|
||||
<source>Error switching profile!</source>
|
||||
<target>เกิดข้อผิดพลาดในการเปลี่ยนโปรไฟล์!</target>
|
||||
@@ -2805,10 +2835,6 @@ This is your own one-time link!</source>
|
||||
<target>แม้ในขณะที่ปิดใช้งานในการสนทนา</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Even when they are offline." xml:space="preserve">
|
||||
<source>Even when they are offline.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Exit without saving" xml:space="preserve">
|
||||
<source>Exit without saving</source>
|
||||
<target>ออกโดยไม่บันทึก</target>
|
||||
@@ -2863,7 +2889,7 @@ This is your own one-time link!</source>
|
||||
<trans-unit id="Favorite" xml:space="preserve">
|
||||
<source>Favorite</source>
|
||||
<target>ที่ชอบ</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
<note>swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="File error" xml:space="preserve">
|
||||
<source>File error</source>
|
||||
@@ -3593,7 +3619,7 @@ Error: %2$@</source>
|
||||
<trans-unit id="Join" xml:space="preserve">
|
||||
<source>Join</source>
|
||||
<target>เข้าร่วม</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
<note>swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Join group" xml:space="preserve">
|
||||
<source>Join group</source>
|
||||
@@ -3676,7 +3702,7 @@ This is your link for group %@!</source>
|
||||
<trans-unit id="Leave" xml:space="preserve">
|
||||
<source>Leave</source>
|
||||
<target>ออกจาก</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
<note>swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Leave group" xml:space="preserve">
|
||||
<source>Leave group</source>
|
||||
@@ -3895,6 +3921,10 @@ This is your link for group %@!</source>
|
||||
<source>Message servers</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message shape" xml:space="preserve">
|
||||
<source>Message shape</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message source remains private." xml:space="preserve">
|
||||
<source>Message source remains private.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -4004,10 +4034,6 @@ This is your link for group %@!</source>
|
||||
<target>กลั่นกรอง</target>
|
||||
<note>chat item action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Moderate like a pro ✋" xml:space="preserve">
|
||||
<source>Moderate like a pro ✋</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Moderated at" xml:space="preserve">
|
||||
<source>Moderated at</source>
|
||||
<target>กลั่นกรองที่</target>
|
||||
@@ -4039,7 +4065,7 @@ This is your link for group %@!</source>
|
||||
<trans-unit id="Mute" xml:space="preserve">
|
||||
<source>Mute</source>
|
||||
<target>ปิดเสียง</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
<note>swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Muted when inactive!" xml:space="preserve">
|
||||
<source>Muted when inactive!</source>
|
||||
@@ -4049,7 +4075,7 @@ This is your link for group %@!</source>
|
||||
<trans-unit id="Name" xml:space="preserve">
|
||||
<source>Name</source>
|
||||
<target>ชื่อ</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
<note>swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Network & servers" xml:space="preserve">
|
||||
<source>Network & servers</source>
|
||||
@@ -4078,10 +4104,6 @@ This is your link for group %@!</source>
|
||||
<target>สถานะเครือข่าย</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="New Chat" xml:space="preserve">
|
||||
<source>New Chat</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="New Passcode" xml:space="preserve">
|
||||
<source>New Passcode</source>
|
||||
<target>รหัสผ่านใหม่</target>
|
||||
@@ -4091,6 +4113,10 @@ This is your link for group %@!</source>
|
||||
<source>New chat</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="New chat experience 🎉" xml:space="preserve">
|
||||
<source>New chat experience 🎉</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="New contact request" xml:space="preserve">
|
||||
<source>New contact request</source>
|
||||
<target>คำขอติดต่อใหม่</target>
|
||||
@@ -4120,6 +4146,10 @@ This is your link for group %@!</source>
|
||||
<target>ใหม่ใน %@</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="New media options" xml:space="preserve">
|
||||
<source>New media options</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="New member role" xml:space="preserve">
|
||||
<source>New member role</source>
|
||||
<target>บทบาทของสมาชิกใหม่</target>
|
||||
@@ -4252,10 +4282,6 @@ This is your link for group %@!</source>
|
||||
<target>คลังฐานข้อมูลเก่า</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="One-hand UI" xml:space="preserve">
|
||||
<source>One-hand UI</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="One-time invitation link" xml:space="preserve">
|
||||
<source>One-time invitation link</source>
|
||||
<target>ลิงก์คำเชิญแบบใช้ครั้งเดียว</target>
|
||||
@@ -4505,6 +4531,10 @@ Requires compatible VPN.</source>
|
||||
<source>Picture-in-picture calls</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Play from the chat list." xml:space="preserve">
|
||||
<source>Play from the chat list.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Please ask your contact to enable calls." xml:space="preserve">
|
||||
<source>Please ask your contact to enable calls.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -4787,8 +4817,8 @@ Enable in *Network & servers* settings.</source>
|
||||
<target>ให้คะแนนแอป</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Reachable chat toolbar 👋" xml:space="preserve">
|
||||
<source>Reachable chat toolbar 👋</source>
|
||||
<trans-unit id="Reachable chat toolbar" xml:space="preserve">
|
||||
<source>Reachable chat toolbar</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="React…" xml:space="preserve">
|
||||
@@ -4799,7 +4829,7 @@ Enable in *Network & servers* settings.</source>
|
||||
<trans-unit id="Read" xml:space="preserve">
|
||||
<source>Read</source>
|
||||
<target>อ่าน</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
<note>swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Read more" xml:space="preserve">
|
||||
<source>Read more</source>
|
||||
@@ -4946,7 +4976,8 @@ Enable in *Network & servers* settings.</source>
|
||||
<trans-unit id="Reject" xml:space="preserve">
|
||||
<source>Reject</source>
|
||||
<target>ปฏิเสธ</target>
|
||||
<note>reject incoming call via notification</note>
|
||||
<note>reject incoming call via notification
|
||||
swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Reject (sender NOT notified)" xml:space="preserve">
|
||||
<source>Reject (sender NOT notified)</source>
|
||||
@@ -5041,6 +5072,10 @@ Enable in *Network & servers* settings.</source>
|
||||
<target>รีเซ็ต</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Reset all hints" xml:space="preserve">
|
||||
<source>Reset all hints</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Reset all statistics" xml:space="preserve">
|
||||
<source>Reset all statistics</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -5317,6 +5352,10 @@ Enable in *Network & servers* settings.</source>
|
||||
<target>เลือก</target>
|
||||
<note>chat item action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Select chat profile" xml:space="preserve">
|
||||
<source>Select chat profile</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Selected %lld" xml:space="preserve">
|
||||
<source>Selected %lld</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -5650,11 +5689,19 @@ Enable in *Network & servers* settings.</source>
|
||||
<target>แชร์ที่อยู่กับผู้ติดต่อ?</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Share from other apps." xml:space="preserve">
|
||||
<source>Share from other apps.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Share link" xml:space="preserve">
|
||||
<source>Share link</source>
|
||||
<target>แชร์ลิงก์</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Share profile" xml:space="preserve">
|
||||
<source>Share profile</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Share this 1-time invite link" xml:space="preserve">
|
||||
<source>Share this 1-time invite link</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -5968,6 +6015,10 @@ Enable in *Network & servers* settings.</source>
|
||||
<target>TCP_KEEPINTVL</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Tail" xml:space="preserve">
|
||||
<source>Tail</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Take picture" xml:space="preserve">
|
||||
<source>Take picture</source>
|
||||
<target>ถ่ายภาพ</target>
|
||||
@@ -6286,10 +6337,18 @@ You will be prompted to complete authentication before this feature is enabled.<
|
||||
<target>ในการตรวจสอบการเข้ารหัสแบบ encrypt จากต้นจนจบ กับผู้ติดต่อของคุณ ให้เปรียบเทียบ (หรือสแกน) รหัสบนอุปกรณ์ของคุณ</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Toggle chat list:" xml:space="preserve">
|
||||
<source>Toggle chat list:</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Toggle incognito when connecting." xml:space="preserve">
|
||||
<source>Toggle incognito when connecting.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Toolbar opacity" xml:space="preserve">
|
||||
<source>Toolbar opacity</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Total" xml:space="preserve">
|
||||
<source>Total</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -6360,7 +6419,7 @@ You will be prompted to complete authentication before this feature is enabled.<
|
||||
<trans-unit id="Unfav." xml:space="preserve">
|
||||
<source>Unfav.</source>
|
||||
<target>เลิกชอบ</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
<note>swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Unhide" xml:space="preserve">
|
||||
<source>Unhide</source>
|
||||
@@ -6434,12 +6493,12 @@ To connect, please ask your contact to create another connection link and check
|
||||
<trans-unit id="Unmute" xml:space="preserve">
|
||||
<source>Unmute</source>
|
||||
<target>เปิดเสียง</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
<note>swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Unread" xml:space="preserve">
|
||||
<source>Unread</source>
|
||||
<target>เปลี่ยนเป็นยังไม่ได้อ่าน</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
<note>swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Up to 100 last messages are sent to new members." xml:space="preserve">
|
||||
<source>Up to 100 last messages are sent to new members.</source>
|
||||
@@ -6883,6 +6942,10 @@ Repeat join request?</source>
|
||||
<target>คุณสามารถรับสายจากหน้าจอล็อกโดยไม่ต้องมีการตรวจสอบสิทธิ์อุปกรณ์และแอป</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="You can change it in Appearance settings." xml:space="preserve">
|
||||
<source>You can change it in Appearance settings.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="You can create it later" xml:space="preserve">
|
||||
<source>You can create it later</source>
|
||||
<target>คุณสามารถสร้างได้ในภายหลัง</target>
|
||||
@@ -7136,6 +7199,10 @@ Repeat connection request?</source>
|
||||
<target>โปรไฟล์แชทของคุณ</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Your connection was moved to %@ but an unexpected error occurred while redirecting you to the profile." xml:space="preserve">
|
||||
<source>Your connection was moved to %@ but an unexpected error occurred while redirecting you to the profile.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Your contact sent a file that is larger than currently supported maximum size (%@)." xml:space="preserve">
|
||||
<source>Your contact sent a file that is larger than currently supported maximum size (%@).</source>
|
||||
<target>ผู้ติดต่อของคุณส่งไฟล์ที่ใหญ่กว่าขนาดสูงสุดที่รองรับในปัจจุบัน (%@)</target>
|
||||
@@ -7151,10 +7218,6 @@ Repeat connection request?</source>
|
||||
<target>ผู้ติดต่อของคุณจะยังคงเชื่อมต่ออยู่</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Your contacts your way" xml:space="preserve">
|
||||
<source>Your contacts your way</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Your current chat database will be DELETED and REPLACED with the imported one." xml:space="preserve">
|
||||
<source>Your current chat database will be DELETED and REPLACED with the imported one.</source>
|
||||
<target>ฐานข้อมูลแชทปัจจุบันของคุณจะถูกลบและแทนที่ด้วยฐานข้อมูลที่นำเข้า</target>
|
||||
|
||||
@@ -137,6 +137,10 @@
|
||||
<target>%@ bağlanmak istiyor!</target>
|
||||
<note>notification title</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="%@, %@" xml:space="preserve">
|
||||
<source>%1$@, %2$@</source>
|
||||
<note>format for date separator in chat</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="%@, %@ and %lld members" xml:space="preserve">
|
||||
<source>%@, %@ and %lld members</source>
|
||||
<target>%@, %@ ve %lld üyeleri</target>
|
||||
@@ -392,11 +396,6 @@
|
||||
<target>, </target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="- Search contacts when starting chat. - Archive contacts to chat later." xml:space="preserve">
|
||||
<source>- Search contacts when starting chat.
|
||||
- Archive contacts to chat later.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="- connect to [directory service](simplex:/contact#/?v=1-4&smp=smp%3A%2F%2Fu2dS9sG8nMNURyZwqASV4yROM28Er0luVTx5X1CsMrU%3D%40smp4.simplex.im%2FeXSPwqTkKyDO3px4fLf1wx3MvPdjdLW3%23%2F%3Fv%3D1-2%26dh%3DMCowBQYDK2VuAyEAaiv6MkMH44L2TcYrt_CsX3ZvM11WgbMEUn0hkIKTOho%253D%26srv%3Do5vmywmrnaxalvz6wi3zicyftgio6psuvyniis6gco6bp6ekl4cqj4id.onion) (BETA)! - delivery receipts (up to 20 members). - faster and more stable." xml:space="preserve">
|
||||
<source>- connect to [directory service](simplex:/contact#/?v=1-4&smp=smp%3A%2F%2Fu2dS9sG8nMNURyZwqASV4yROM28Er0luVTx5X1CsMrU%3D%40smp4.simplex.im%2FeXSPwqTkKyDO3px4fLf1wx3MvPdjdLW3%23%2F%3Fv%3D1-2%26dh%3DMCowBQYDK2VuAyEAaiv6MkMH44L2TcYrt_CsX3ZvM11WgbMEUn0hkIKTOho%253D%26srv%3Do5vmywmrnaxalvz6wi3zicyftgio6psuvyniis6gco6bp6ekl4cqj4id.onion) (BETA)!
|
||||
- delivery receipts (up to 20 members).
|
||||
@@ -565,7 +564,8 @@
|
||||
<source>Accept</source>
|
||||
<target>Kabul et</target>
|
||||
<note>accept contact request via notification
|
||||
accept incoming call via notification</note>
|
||||
accept incoming call via notification
|
||||
swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Accept connection request?" xml:space="preserve">
|
||||
<source>Accept connection request?</source>
|
||||
@@ -580,7 +580,8 @@
|
||||
<trans-unit id="Accept incognito" xml:space="preserve">
|
||||
<source>Accept incognito</source>
|
||||
<target>Takma adla kabul et</target>
|
||||
<note>accept contact request via notification</note>
|
||||
<note>accept contact request via notification
|
||||
swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Acknowledged" xml:space="preserve">
|
||||
<source>Acknowledged</source>
|
||||
@@ -935,6 +936,10 @@
|
||||
<target>Arşivle ve yükle</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Archive contacts to chat later." xml:space="preserve">
|
||||
<source>Archive contacts to chat later.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Archived contacts" xml:space="preserve">
|
||||
<source>Archived contacts</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -1038,6 +1043,10 @@
|
||||
<target>Daha iyi mesajlar</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Better networking" xml:space="preserve">
|
||||
<source>Better networking</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Black" xml:space="preserve">
|
||||
<source>Black</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -1077,6 +1086,10 @@
|
||||
<target>Yönetici tarafından engellendi</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Blur for better privacy." xml:space="preserve">
|
||||
<source>Blur for better privacy.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Blur media" xml:space="preserve">
|
||||
<source>Blur media</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -1290,6 +1303,10 @@
|
||||
<target>Sohbet durduruldu. Bu veritabanını zaten başka bir cihazda kullandıysanız, sohbete başlamadan önce onu geri aktarmalısınız.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Chat list" xml:space="preserve">
|
||||
<source>Chat list</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Chat migrated!" xml:space="preserve">
|
||||
<source>Chat migrated!</source>
|
||||
<target>Sohbet taşındı!</target>
|
||||
@@ -1349,7 +1366,7 @@
|
||||
<trans-unit id="Clear" xml:space="preserve">
|
||||
<source>Clear</source>
|
||||
<target>Temizle</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
<note>swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Clear conversation" xml:space="preserve">
|
||||
<source>Clear conversation</source>
|
||||
@@ -1371,6 +1388,10 @@
|
||||
<target>Doğrulamayı temizle</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Color chats with the new themes." xml:space="preserve">
|
||||
<source>Color chats with the new themes.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Color mode" xml:space="preserve">
|
||||
<source>Color mode</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -1467,8 +1488,8 @@
|
||||
<target>Bilgisayara bağlan</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Connect to your friends faster" xml:space="preserve">
|
||||
<source>Connect to your friends faster</source>
|
||||
<trans-unit id="Connect to your friends faster." xml:space="preserve">
|
||||
<source>Connect to your friends faster.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Connect to yourself?" xml:space="preserve">
|
||||
@@ -1654,10 +1675,6 @@ Bu senin kendi tek kullanımlık bağlantın!</target>
|
||||
<target>Devam et</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Control your network" xml:space="preserve">
|
||||
<source>Control your network</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Conversation deleted!" xml:space="preserve">
|
||||
<source>Conversation deleted!</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -1676,6 +1693,10 @@ Bu senin kendi tek kullanımlık bağlantın!</target>
|
||||
<target>Çekirdek sürümü: v%@</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Corner" xml:space="preserve">
|
||||
<source>Corner</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Correct name to %@?" xml:space="preserve">
|
||||
<source>Correct name to %@?</source>
|
||||
<target>İsim %@ olarak düzeltilsin mi?</target>
|
||||
@@ -1928,7 +1949,8 @@ Bu senin kendi tek kullanımlık bağlantın!</target>
|
||||
<trans-unit id="Delete" xml:space="preserve">
|
||||
<source>Delete</source>
|
||||
<target>Sil</target>
|
||||
<note>chat item action</note>
|
||||
<note>chat item action
|
||||
swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Delete %lld messages of members?" xml:space="preserve">
|
||||
<source>Delete %lld messages of members?</source>
|
||||
@@ -2130,10 +2152,6 @@ Bu senin kendi tek kullanımlık bağlantın!</target>
|
||||
<target>%@ de silindi</target>
|
||||
<note>copied message info</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Deleted chats" xml:space="preserve">
|
||||
<source>Deleted chats</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Deletion errors" xml:space="preserve">
|
||||
<source>Deletion errors</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -2643,6 +2661,10 @@ Bu senin kendi tek kullanımlık bağlantın!</target>
|
||||
<target>Adres değiştirilirken hata oluştu</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Error changing connection profile" xml:space="preserve">
|
||||
<source>Error changing connection profile</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Error changing role" xml:space="preserve">
|
||||
<source>Error changing role</source>
|
||||
<target>Rol değiştirilirken hata oluştu</target>
|
||||
@@ -2653,6 +2675,10 @@ Bu senin kendi tek kullanımlık bağlantın!</target>
|
||||
<target>Ayar değiştirilirken hata oluştu</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Error changing to incognito!" xml:space="preserve">
|
||||
<source>Error changing to incognito!</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Error connecting to forwarding server %@. Please try later." xml:space="preserve">
|
||||
<source>Error connecting to forwarding server %@. Please try later.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -2868,6 +2894,10 @@ Bu senin kendi tek kullanımlık bağlantın!</target>
|
||||
<target>Sohbet durdurulurken hata oluştu</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Error switching profile" xml:space="preserve">
|
||||
<source>Error switching profile</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Error switching profile!" xml:space="preserve">
|
||||
<source>Error switching profile!</source>
|
||||
<target>Profil değiştirilirken hata oluştu!</target>
|
||||
@@ -2938,10 +2968,6 @@ Bu senin kendi tek kullanımlık bağlantın!</target>
|
||||
<target>Konuşma sırasında devre dışı bırakılsa bile.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Even when they are offline." xml:space="preserve">
|
||||
<source>Even when they are offline.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Exit without saving" xml:space="preserve">
|
||||
<source>Exit without saving</source>
|
||||
<target>Kaydetmeden çık</target>
|
||||
@@ -2999,7 +3025,7 @@ Bu senin kendi tek kullanımlık bağlantın!</target>
|
||||
<trans-unit id="Favorite" xml:space="preserve">
|
||||
<source>Favorite</source>
|
||||
<target>Favori</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
<note>swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="File error" xml:space="preserve">
|
||||
<source>File error</source>
|
||||
@@ -3763,7 +3789,7 @@ Hata: %2$@</target>
|
||||
<trans-unit id="Join" xml:space="preserve">
|
||||
<source>Join</source>
|
||||
<target>Katıl</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
<note>swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Join group" xml:space="preserve">
|
||||
<source>Join group</source>
|
||||
@@ -3854,7 +3880,7 @@ Bu senin grup için bağlantın %@!</target>
|
||||
<trans-unit id="Leave" xml:space="preserve">
|
||||
<source>Leave</source>
|
||||
<target>Ayrıl</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
<note>swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Leave group" xml:space="preserve">
|
||||
<source>Leave group</source>
|
||||
@@ -4078,6 +4104,10 @@ Bu senin grup için bağlantın %@!</target>
|
||||
<source>Message servers</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message shape" xml:space="preserve">
|
||||
<source>Message shape</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message source remains private." xml:space="preserve">
|
||||
<source>Message source remains private.</source>
|
||||
<target>Mesaj kaynağı gizli kalır.</target>
|
||||
@@ -4199,10 +4229,6 @@ Bu senin grup için bağlantın %@!</target>
|
||||
<target>Yönet</target>
|
||||
<note>chat item action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Moderate like a pro ✋" xml:space="preserve">
|
||||
<source>Moderate like a pro ✋</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Moderated at" xml:space="preserve">
|
||||
<source>Moderated at</source>
|
||||
<target>de yönetildi</target>
|
||||
@@ -4236,7 +4262,7 @@ Bu senin grup için bağlantın %@!</target>
|
||||
<trans-unit id="Mute" xml:space="preserve">
|
||||
<source>Mute</source>
|
||||
<target>Sustur</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
<note>swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Muted when inactive!" xml:space="preserve">
|
||||
<source>Muted when inactive!</source>
|
||||
@@ -4246,7 +4272,7 @@ Bu senin grup için bağlantın %@!</target>
|
||||
<trans-unit id="Name" xml:space="preserve">
|
||||
<source>Name</source>
|
||||
<target>İsim</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
<note>swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Network & servers" xml:space="preserve">
|
||||
<source>Network & servers</source>
|
||||
@@ -4278,10 +4304,6 @@ Bu senin grup için bağlantın %@!</target>
|
||||
<target>Ağ durumu</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="New Chat" xml:space="preserve">
|
||||
<source>New Chat</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="New Passcode" xml:space="preserve">
|
||||
<source>New Passcode</source>
|
||||
<target>Yeni şifre</target>
|
||||
@@ -4292,6 +4314,10 @@ Bu senin grup için bağlantın %@!</target>
|
||||
<target>Yeni sohbet</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="New chat experience 🎉" xml:space="preserve">
|
||||
<source>New chat experience 🎉</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="New contact request" xml:space="preserve">
|
||||
<source>New contact request</source>
|
||||
<target>Yeni bağlantı isteği</target>
|
||||
@@ -4322,6 +4348,10 @@ Bu senin grup için bağlantın %@!</target>
|
||||
<target>%@ da yeni</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="New media options" xml:space="preserve">
|
||||
<source>New media options</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="New member role" xml:space="preserve">
|
||||
<source>New member role</source>
|
||||
<target>Yeni üye rolü</target>
|
||||
@@ -4458,10 +4488,6 @@ Bu senin grup için bağlantın %@!</target>
|
||||
<target>Eski veritabanı arşivi</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="One-hand UI" xml:space="preserve">
|
||||
<source>One-hand UI</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="One-time invitation link" xml:space="preserve">
|
||||
<source>One-time invitation link</source>
|
||||
<target>Tek zamanlı bağlantı daveti</target>
|
||||
@@ -4727,6 +4753,10 @@ VPN'nin etkinleştirilmesi gerekir.</target>
|
||||
<target>Resim içinde resim aramaları</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Play from the chat list." xml:space="preserve">
|
||||
<source>Play from the chat list.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Please ask your contact to enable calls." xml:space="preserve">
|
||||
<source>Please ask your contact to enable calls.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -5025,8 +5055,8 @@ Enable in *Network & servers* settings.</source>
|
||||
<target>Uygulamayı değerlendir</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Reachable chat toolbar 👋" xml:space="preserve">
|
||||
<source>Reachable chat toolbar 👋</source>
|
||||
<trans-unit id="Reachable chat toolbar" xml:space="preserve">
|
||||
<source>Reachable chat toolbar</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="React…" xml:space="preserve">
|
||||
@@ -5037,7 +5067,7 @@ Enable in *Network & servers* settings.</source>
|
||||
<trans-unit id="Read" xml:space="preserve">
|
||||
<source>Read</source>
|
||||
<target>Oku</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
<note>swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Read more" xml:space="preserve">
|
||||
<source>Read more</source>
|
||||
@@ -5188,7 +5218,8 @@ Enable in *Network & servers* settings.</source>
|
||||
<trans-unit id="Reject" xml:space="preserve">
|
||||
<source>Reject</source>
|
||||
<target>Reddet</target>
|
||||
<note>reject incoming call via notification</note>
|
||||
<note>reject incoming call via notification
|
||||
swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Reject (sender NOT notified)" xml:space="preserve">
|
||||
<source>Reject (sender NOT notified)</source>
|
||||
@@ -5289,6 +5320,10 @@ Enable in *Network & servers* settings.</source>
|
||||
<target>Sıfırla</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Reset all hints" xml:space="preserve">
|
||||
<source>Reset all hints</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Reset all statistics" xml:space="preserve">
|
||||
<source>Reset all statistics</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -5574,6 +5609,10 @@ Enable in *Network & servers* settings.</source>
|
||||
<target>Seç</target>
|
||||
<note>chat item action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Select chat profile" xml:space="preserve">
|
||||
<source>Select chat profile</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Selected %lld" xml:space="preserve">
|
||||
<source>Selected %lld</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -5918,11 +5957,19 @@ Enable in *Network & servers* settings.</source>
|
||||
<target>Kişilerle adres paylaşılsın mı?</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Share from other apps." xml:space="preserve">
|
||||
<source>Share from other apps.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Share link" xml:space="preserve">
|
||||
<source>Share link</source>
|
||||
<target>Bağlantıyı paylaş</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Share profile" xml:space="preserve">
|
||||
<source>Share profile</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Share this 1-time invite link" xml:space="preserve">
|
||||
<source>Share this 1-time invite link</source>
|
||||
<target>Bu tek kullanımlık bağlantı davetini paylaş</target>
|
||||
@@ -6249,6 +6296,10 @@ Enable in *Network & servers* settings.</source>
|
||||
<target>TCP_TVLDEKAL</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Tail" xml:space="preserve">
|
||||
<source>Tail</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Take picture" xml:space="preserve">
|
||||
<source>Take picture</source>
|
||||
<target>Fotoğraf çek</target>
|
||||
@@ -6582,11 +6633,19 @@ Bu özellik etkinleştirilmeden önce kimlik doğrulamayı tamamlamanız istenec
|
||||
<target>Kişinizle uçtan uca şifrelemeyi doğrulamak için cihazlarınızdaki kodu karşılaştırın (veya tarayın).</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Toggle chat list:" xml:space="preserve">
|
||||
<source>Toggle chat list:</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Toggle incognito when connecting." xml:space="preserve">
|
||||
<source>Toggle incognito when connecting.</source>
|
||||
<target>Bağlanırken gizli moda geçiş yap.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Toolbar opacity" xml:space="preserve">
|
||||
<source>Toolbar opacity</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Total" xml:space="preserve">
|
||||
<source>Total</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -6663,7 +6722,7 @@ Bu özellik etkinleştirilmeden önce kimlik doğrulamayı tamamlamanız istenec
|
||||
<trans-unit id="Unfav." xml:space="preserve">
|
||||
<source>Unfav.</source>
|
||||
<target>Favorilerden çık.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
<note>swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Unhide" xml:space="preserve">
|
||||
<source>Unhide</source>
|
||||
@@ -6740,12 +6799,12 @@ Bağlanmak için lütfen kişinizden başka bir bağlantı oluşturmasını iste
|
||||
<trans-unit id="Unmute" xml:space="preserve">
|
||||
<source>Unmute</source>
|
||||
<target>Susturmayı kaldır</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
<note>swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Unread" xml:space="preserve">
|
||||
<source>Unread</source>
|
||||
<target>Okunmamış</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
<note>swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Up to 100 last messages are sent to new members." xml:space="preserve">
|
||||
<source>Up to 100 last messages are sent to new members.</source>
|
||||
@@ -7228,6 +7287,10 @@ Katılma isteği tekrarlansın mı?</target>
|
||||
<target>Cihaz ve uygulama kimlik doğrulaması olmadan kilit ekranından çağrı kabul edebilirsiniz.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="You can change it in Appearance settings." xml:space="preserve">
|
||||
<source>You can change it in Appearance settings.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="You can create it later" xml:space="preserve">
|
||||
<source>You can create it later</source>
|
||||
<target>Daha sonra oluşturabilirsiniz</target>
|
||||
@@ -7490,6 +7553,10 @@ Bağlantı isteği tekrarlansın mı?</target>
|
||||
<target>Sohbet profillerin</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Your connection was moved to %@ but an unexpected error occurred while redirecting you to the profile." xml:space="preserve">
|
||||
<source>Your connection was moved to %@ but an unexpected error occurred while redirecting you to the profile.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Your contact sent a file that is larger than currently supported maximum size (%@)." xml:space="preserve">
|
||||
<source>Your contact sent a file that is larger than currently supported maximum size (%@).</source>
|
||||
<target>Kişiniz şu anda desteklenen maksimum boyuttan (%@) daha büyük bir dosya gönderdi.</target>
|
||||
@@ -7505,10 +7572,6 @@ Bağlantı isteği tekrarlansın mı?</target>
|
||||
<target>Kişileriniz bağlı kalacaktır.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Your contacts your way" xml:space="preserve">
|
||||
<source>Your contacts your way</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Your current chat database will be DELETED and REPLACED with the imported one." xml:space="preserve">
|
||||
<source>Your current chat database will be DELETED and REPLACED with the imported one.</source>
|
||||
<target>Mevcut sohbet veritabanınız SİLİNECEK ve içe aktarılan veritabanıyla DEĞİŞTİRİLECEKTİR.</target>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -135,6 +135,10 @@
|
||||
<target>%@ 要连接!</target>
|
||||
<note>notification title</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="%@, %@" xml:space="preserve">
|
||||
<source>%1$@, %2$@</source>
|
||||
<note>format for date separator in chat</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="%@, %@ and %lld members" xml:space="preserve">
|
||||
<source>%@, %@ and %lld members</source>
|
||||
<target>%@, %@ 和 %lld 成员</target>
|
||||
@@ -381,11 +385,6 @@
|
||||
<target>, </target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="- Search contacts when starting chat. - Archive contacts to chat later." xml:space="preserve">
|
||||
<source>- Search contacts when starting chat.
|
||||
- Archive contacts to chat later.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="- connect to [directory service](simplex:/contact#/?v=1-4&smp=smp%3A%2F%2Fu2dS9sG8nMNURyZwqASV4yROM28Er0luVTx5X1CsMrU%3D%40smp4.simplex.im%2FeXSPwqTkKyDO3px4fLf1wx3MvPdjdLW3%23%2F%3Fv%3D1-2%26dh%3DMCowBQYDK2VuAyEAaiv6MkMH44L2TcYrt_CsX3ZvM11WgbMEUn0hkIKTOho%253D%26srv%3Do5vmywmrnaxalvz6wi3zicyftgio6psuvyniis6gco6bp6ekl4cqj4id.onion) (BETA)! - delivery receipts (up to 20 members). - faster and more stable." xml:space="preserve">
|
||||
<source>- connect to [directory service](simplex:/contact#/?v=1-4&smp=smp%3A%2F%2Fu2dS9sG8nMNURyZwqASV4yROM28Er0luVTx5X1CsMrU%3D%40smp4.simplex.im%2FeXSPwqTkKyDO3px4fLf1wx3MvPdjdLW3%23%2F%3Fv%3D1-2%26dh%3DMCowBQYDK2VuAyEAaiv6MkMH44L2TcYrt_CsX3ZvM11WgbMEUn0hkIKTOho%253D%26srv%3Do5vmywmrnaxalvz6wi3zicyftgio6psuvyniis6gco6bp6ekl4cqj4id.onion) (BETA)!
|
||||
- delivery receipts (up to 20 members).
|
||||
@@ -553,7 +552,8 @@
|
||||
<source>Accept</source>
|
||||
<target>接受</target>
|
||||
<note>accept contact request via notification
|
||||
accept incoming call via notification</note>
|
||||
accept incoming call via notification
|
||||
swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Accept connection request?" xml:space="preserve">
|
||||
<source>Accept connection request?</source>
|
||||
@@ -568,7 +568,8 @@
|
||||
<trans-unit id="Accept incognito" xml:space="preserve">
|
||||
<source>Accept incognito</source>
|
||||
<target>接受隐身聊天</target>
|
||||
<note>accept contact request via notification</note>
|
||||
<note>accept contact request via notification
|
||||
swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Acknowledged" xml:space="preserve">
|
||||
<source>Acknowledged</source>
|
||||
@@ -920,6 +921,10 @@
|
||||
<target>存档和上传</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Archive contacts to chat later." xml:space="preserve">
|
||||
<source>Archive contacts to chat later.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Archived contacts" xml:space="preserve">
|
||||
<source>Archived contacts</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -1023,6 +1028,10 @@
|
||||
<target>更好的消息</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Better networking" xml:space="preserve">
|
||||
<source>Better networking</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Black" xml:space="preserve">
|
||||
<source>Black</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -1062,6 +1071,10 @@
|
||||
<target>由管理员封禁</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Blur for better privacy." xml:space="preserve">
|
||||
<source>Blur for better privacy.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Blur media" xml:space="preserve">
|
||||
<source>Blur media</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -1274,6 +1287,10 @@
|
||||
<target>聊天已停止。如果你已经在另一台设备商使用过此数据库,你应该在启动聊天前将数据库传输回来。</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Chat list" xml:space="preserve">
|
||||
<source>Chat list</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Chat migrated!" xml:space="preserve">
|
||||
<source>Chat migrated!</source>
|
||||
<target>已迁移聊天!</target>
|
||||
@@ -1332,7 +1349,7 @@
|
||||
<trans-unit id="Clear" xml:space="preserve">
|
||||
<source>Clear</source>
|
||||
<target>清除</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
<note>swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Clear conversation" xml:space="preserve">
|
||||
<source>Clear conversation</source>
|
||||
@@ -1354,6 +1371,10 @@
|
||||
<target>清除验证</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Color chats with the new themes." xml:space="preserve">
|
||||
<source>Color chats with the new themes.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Color mode" xml:space="preserve">
|
||||
<source>Color mode</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -1449,8 +1470,8 @@
|
||||
<target>连接到桌面</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Connect to your friends faster" xml:space="preserve">
|
||||
<source>Connect to your friends faster</source>
|
||||
<trans-unit id="Connect to your friends faster." xml:space="preserve">
|
||||
<source>Connect to your friends faster.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Connect to yourself?" xml:space="preserve">
|
||||
@@ -1630,10 +1651,6 @@ This is your own one-time link!</source>
|
||||
<target>继续</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Control your network" xml:space="preserve">
|
||||
<source>Control your network</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Conversation deleted!" xml:space="preserve">
|
||||
<source>Conversation deleted!</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -1652,6 +1669,10 @@ This is your own one-time link!</source>
|
||||
<target>核心版本: v%@</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Corner" xml:space="preserve">
|
||||
<source>Corner</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Correct name to %@?" xml:space="preserve">
|
||||
<source>Correct name to %@?</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -1901,7 +1922,8 @@ This is your own one-time link!</source>
|
||||
<trans-unit id="Delete" xml:space="preserve">
|
||||
<source>Delete</source>
|
||||
<target>删除</target>
|
||||
<note>chat item action</note>
|
||||
<note>chat item action
|
||||
swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Delete %lld messages of members?" xml:space="preserve">
|
||||
<source>Delete %lld messages of members?</source>
|
||||
@@ -2102,10 +2124,6 @@ This is your own one-time link!</source>
|
||||
<target>已删除于:%@</target>
|
||||
<note>copied message info</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Deleted chats" xml:space="preserve">
|
||||
<source>Deleted chats</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Deletion errors" xml:space="preserve">
|
||||
<source>Deletion errors</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -2608,6 +2626,10 @@ This is your own one-time link!</source>
|
||||
<target>更改地址错误</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Error changing connection profile" xml:space="preserve">
|
||||
<source>Error changing connection profile</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Error changing role" xml:space="preserve">
|
||||
<source>Error changing role</source>
|
||||
<target>更改角色错误</target>
|
||||
@@ -2618,6 +2640,10 @@ This is your own one-time link!</source>
|
||||
<target>更改设置错误</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Error changing to incognito!" xml:space="preserve">
|
||||
<source>Error changing to incognito!</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Error connecting to forwarding server %@. Please try later." xml:space="preserve">
|
||||
<source>Error connecting to forwarding server %@. Please try later.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -2831,6 +2857,10 @@ This is your own one-time link!</source>
|
||||
<target>停止聊天错误</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Error switching profile" xml:space="preserve">
|
||||
<source>Error switching profile</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Error switching profile!" xml:space="preserve">
|
||||
<source>Error switching profile!</source>
|
||||
<target>切换资料错误!</target>
|
||||
@@ -2901,10 +2931,6 @@ This is your own one-time link!</source>
|
||||
<target>即使在对话中被禁用。</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Even when they are offline." xml:space="preserve">
|
||||
<source>Even when they are offline.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Exit without saving" xml:space="preserve">
|
||||
<source>Exit without saving</source>
|
||||
<target>退出而不保存</target>
|
||||
@@ -2962,7 +2988,7 @@ This is your own one-time link!</source>
|
||||
<trans-unit id="Favorite" xml:space="preserve">
|
||||
<source>Favorite</source>
|
||||
<target>最喜欢</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
<note>swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="File error" xml:space="preserve">
|
||||
<source>File error</source>
|
||||
@@ -3718,7 +3744,7 @@ Error: %2$@</source>
|
||||
<trans-unit id="Join" xml:space="preserve">
|
||||
<source>Join</source>
|
||||
<target>加入</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
<note>swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Join group" xml:space="preserve">
|
||||
<source>Join group</source>
|
||||
@@ -3805,7 +3831,7 @@ This is your link for group %@!</source>
|
||||
<trans-unit id="Leave" xml:space="preserve">
|
||||
<source>Leave</source>
|
||||
<target>离开</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
<note>swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Leave group" xml:space="preserve">
|
||||
<source>Leave group</source>
|
||||
@@ -4027,6 +4053,10 @@ This is your link for group %@!</source>
|
||||
<source>Message servers</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message shape" xml:space="preserve">
|
||||
<source>Message shape</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message source remains private." xml:space="preserve">
|
||||
<source>Message source remains private.</source>
|
||||
<target>消息来源保持私密。</target>
|
||||
@@ -4145,10 +4175,6 @@ This is your link for group %@!</source>
|
||||
<target>管理员移除</target>
|
||||
<note>chat item action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Moderate like a pro ✋" xml:space="preserve">
|
||||
<source>Moderate like a pro ✋</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Moderated at" xml:space="preserve">
|
||||
<source>Moderated at</source>
|
||||
<target>已被管理员移除于</target>
|
||||
@@ -4182,7 +4208,7 @@ This is your link for group %@!</source>
|
||||
<trans-unit id="Mute" xml:space="preserve">
|
||||
<source>Mute</source>
|
||||
<target>静音</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
<note>swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Muted when inactive!" xml:space="preserve">
|
||||
<source>Muted when inactive!</source>
|
||||
@@ -4192,7 +4218,7 @@ This is your link for group %@!</source>
|
||||
<trans-unit id="Name" xml:space="preserve">
|
||||
<source>Name</source>
|
||||
<target>名称</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
<note>swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Network & servers" xml:space="preserve">
|
||||
<source>Network & servers</source>
|
||||
@@ -4223,10 +4249,6 @@ This is your link for group %@!</source>
|
||||
<target>网络状态</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="New Chat" xml:space="preserve">
|
||||
<source>New Chat</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="New Passcode" xml:space="preserve">
|
||||
<source>New Passcode</source>
|
||||
<target>新密码</target>
|
||||
@@ -4237,6 +4259,10 @@ This is your link for group %@!</source>
|
||||
<target>新聊天</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="New chat experience 🎉" xml:space="preserve">
|
||||
<source>New chat experience 🎉</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="New contact request" xml:space="preserve">
|
||||
<source>New contact request</source>
|
||||
<target>新联系人请求</target>
|
||||
@@ -4267,6 +4293,10 @@ This is your link for group %@!</source>
|
||||
<target>%@ 的新内容</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="New media options" xml:space="preserve">
|
||||
<source>New media options</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="New member role" xml:space="preserve">
|
||||
<source>New member role</source>
|
||||
<target>新成员角色</target>
|
||||
@@ -4403,10 +4433,6 @@ This is your link for group %@!</source>
|
||||
<target>旧数据库存档</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="One-hand UI" xml:space="preserve">
|
||||
<source>One-hand UI</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="One-time invitation link" xml:space="preserve">
|
||||
<source>One-time invitation link</source>
|
||||
<target>一次性邀请链接</target>
|
||||
@@ -4667,6 +4693,10 @@ Requires compatible VPN.</source>
|
||||
<target>画中画通话</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Play from the chat list." xml:space="preserve">
|
||||
<source>Play from the chat list.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Please ask your contact to enable calls." xml:space="preserve">
|
||||
<source>Please ask your contact to enable calls.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -4954,8 +4984,8 @@ Enable in *Network & servers* settings.</source>
|
||||
<target>评价此应用程序</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Reachable chat toolbar 👋" xml:space="preserve">
|
||||
<source>Reachable chat toolbar 👋</source>
|
||||
<trans-unit id="Reachable chat toolbar" xml:space="preserve">
|
||||
<source>Reachable chat toolbar</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="React…" xml:space="preserve">
|
||||
@@ -4966,7 +4996,7 @@ Enable in *Network & servers* settings.</source>
|
||||
<trans-unit id="Read" xml:space="preserve">
|
||||
<source>Read</source>
|
||||
<target>已读</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
<note>swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Read more" xml:space="preserve">
|
||||
<source>Read more</source>
|
||||
@@ -5116,7 +5146,8 @@ Enable in *Network & servers* settings.</source>
|
||||
<trans-unit id="Reject" xml:space="preserve">
|
||||
<source>Reject</source>
|
||||
<target>拒绝</target>
|
||||
<note>reject incoming call via notification</note>
|
||||
<note>reject incoming call via notification
|
||||
swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Reject (sender NOT notified)" xml:space="preserve">
|
||||
<source>Reject (sender NOT notified)</source>
|
||||
@@ -5217,6 +5248,10 @@ Enable in *Network & servers* settings.</source>
|
||||
<target>重置</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Reset all hints" xml:space="preserve">
|
||||
<source>Reset all hints</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Reset all statistics" xml:space="preserve">
|
||||
<source>Reset all statistics</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -5501,6 +5536,10 @@ Enable in *Network & servers* settings.</source>
|
||||
<target>选择</target>
|
||||
<note>chat item action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Select chat profile" xml:space="preserve">
|
||||
<source>Select chat profile</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Selected %lld" xml:space="preserve">
|
||||
<source>Selected %lld</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -5841,11 +5880,19 @@ Enable in *Network & servers* settings.</source>
|
||||
<target>与联系人分享地址?</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Share from other apps." xml:space="preserve">
|
||||
<source>Share from other apps.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Share link" xml:space="preserve">
|
||||
<source>Share link</source>
|
||||
<target>分享链接</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Share profile" xml:space="preserve">
|
||||
<source>Share profile</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Share this 1-time invite link" xml:space="preserve">
|
||||
<source>Share this 1-time invite link</source>
|
||||
<target>分享此一次性邀请链接</target>
|
||||
@@ -6170,6 +6217,10 @@ Enable in *Network & servers* settings.</source>
|
||||
<target>TCP_KEEPINTVL</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Tail" xml:space="preserve">
|
||||
<source>Tail</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Take picture" xml:space="preserve">
|
||||
<source>Take picture</source>
|
||||
<target>拍照</target>
|
||||
@@ -6501,11 +6552,19 @@ You will be prompted to complete authentication before this feature is enabled.<
|
||||
<target>要与您的联系人验证端到端加密,请比较(或扫描)您设备上的代码。</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Toggle chat list:" xml:space="preserve">
|
||||
<source>Toggle chat list:</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Toggle incognito when connecting." xml:space="preserve">
|
||||
<source>Toggle incognito when connecting.</source>
|
||||
<target>在连接时切换隐身模式。</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Toolbar opacity" xml:space="preserve">
|
||||
<source>Toolbar opacity</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Total" xml:space="preserve">
|
||||
<source>Total</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -6581,7 +6640,7 @@ You will be prompted to complete authentication before this feature is enabled.<
|
||||
<trans-unit id="Unfav." xml:space="preserve">
|
||||
<source>Unfav.</source>
|
||||
<target>取消最喜欢</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
<note>swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Unhide" xml:space="preserve">
|
||||
<source>Unhide</source>
|
||||
@@ -6657,12 +6716,12 @@ To connect, please ask your contact to create another connection link and check
|
||||
<trans-unit id="Unmute" xml:space="preserve">
|
||||
<source>Unmute</source>
|
||||
<target>取消静音</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
<note>swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Unread" xml:space="preserve">
|
||||
<source>Unread</source>
|
||||
<target>未读</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
<note>swipe action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Up to 100 last messages are sent to new members." xml:space="preserve">
|
||||
<source>Up to 100 last messages are sent to new members.</source>
|
||||
@@ -7131,6 +7190,10 @@ Repeat join request?</source>
|
||||
<target>您可以从锁屏上接听电话,无需设备和应用程序的认证。</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="You can change it in Appearance settings." xml:space="preserve">
|
||||
<source>You can change it in Appearance settings.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="You can create it later" xml:space="preserve">
|
||||
<source>You can create it later</source>
|
||||
<target>您可以以后创建它</target>
|
||||
@@ -7390,6 +7453,10 @@ Repeat connection request?</source>
|
||||
<target>您的聊天资料</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Your connection was moved to %@ but an unexpected error occurred while redirecting you to the profile." xml:space="preserve">
|
||||
<source>Your connection was moved to %@ but an unexpected error occurred while redirecting you to the profile.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Your contact sent a file that is larger than currently supported maximum size (%@)." xml:space="preserve">
|
||||
<source>Your contact sent a file that is larger than currently supported maximum size (%@).</source>
|
||||
<target>您的联系人发送的文件大于当前支持的最大大小 (%@)。</target>
|
||||
@@ -7405,10 +7472,6 @@ Repeat connection request?</source>
|
||||
<target>与您的联系人保持连接。</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Your contacts your way" xml:space="preserve">
|
||||
<source>Your contacts your way</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Your current chat database will be DELETED and REPLACED with the imported one." xml:space="preserve">
|
||||
<source>Your current chat database will be DELETED and REPLACED with the imported one.</source>
|
||||
<target>您当前的聊天数据库将被删除并替换为导入的数据库。</target>
|
||||
|
||||
@@ -314,7 +314,7 @@
|
||||
</trans-unit>
|
||||
<trans-unit id="About SimpleX Chat" xml:space="preserve" approved="no">
|
||||
<source>About SimpleX Chat</source>
|
||||
<target state="translated">關於 SimpleX 對話</target>
|
||||
<target state="translated">關於 SimpleX Chat</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Accent color" xml:space="preserve" approved="no">
|
||||
@@ -445,7 +445,7 @@
|
||||
</trans-unit>
|
||||
<trans-unit id="Allow your contacts to send disappearing messages." xml:space="preserve" approved="no">
|
||||
<source>Allow your contacts to send disappearing messages.</source>
|
||||
<target state="translated">允許你的聯絡人傳送自動銷毀的訊息。</target>
|
||||
<target state="translated">允許您的聯絡人傳送限時訊息。</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Allow your contacts to send voice messages." xml:space="preserve" approved="no">
|
||||
@@ -5898,6 +5898,230 @@ It can happen because of some bug or when the connection is compromised.</source
|
||||
<target state="translated">%@ 和 %@ 已連接</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="%@ downloaded" xml:space="preserve" approved="no">
|
||||
<source>%@ downloaded</source>
|
||||
<target state="translated">%@ 下載</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="%@ uploaded" xml:space="preserve" approved="no">
|
||||
<source>%@ uploaded</source>
|
||||
<target state="translated">%@ 上傳</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Abort" xml:space="preserve" approved="no">
|
||||
<source>Abort</source>
|
||||
<target state="translated">中止</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="**Create group**: to create a new group." xml:space="preserve" approved="no">
|
||||
<source>**Create group**: to create a new group.</source>
|
||||
<target state="translated">**創建群組**: 創建一個新的群組。</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Abort changing address" xml:space="preserve" approved="no">
|
||||
<source>Abort changing address</source>
|
||||
<target state="translated">中止更改地址</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Accept connection request?" xml:space="preserve" approved="no">
|
||||
<source>Accept connection request?</source>
|
||||
<target state="translated">接受連線請求?</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Camera not available" xml:space="preserve" approved="no">
|
||||
<source>Camera not available</source>
|
||||
<target state="translated">相機不可用</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="All messages will be deleted - this cannot be undone!" xml:space="preserve" approved="no">
|
||||
<source>All messages will be deleted - this cannot be undone!</source>
|
||||
<target state="translated">所有訊息都將被刪除 - 這不能還原!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Allow irreversible message deletion only if your contact allows it to you. (24 hours)" xml:space="preserve" approved="no">
|
||||
<source>Allow irreversible message deletion only if your contact allows it to you. (24 hours)</source>
|
||||
<target state="translated">只有你的聯絡人允許的情況下,才允許不可逆地將訊息刪除。(24小時)</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Allow to irreversibly delete sent messages. (24 hours)" xml:space="preserve" approved="no">
|
||||
<source>Allow to irreversibly delete sent messages. (24 hours)</source>
|
||||
<target state="translated">允許將不可撤銷的訊息刪除。(24小時)</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Allow your contacts to irreversibly delete sent messages. (24 hours)" xml:space="preserve" approved="no">
|
||||
<source>Allow your contacts to irreversibly delete sent messages. (24 hours)</source>
|
||||
<target state="translated">允許您的聯絡人不可復原地刪除已傳送的訊息。(24小時)</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Bad desktop address" xml:space="preserve" approved="no">
|
||||
<source>Bad desktop address</source>
|
||||
<target state="translated">無效的桌面地址</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Error decrypting file" xml:space="preserve" approved="no">
|
||||
<source>Error decrypting file</source>
|
||||
<target state="translated">解密檔案時出錯</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Add contact" xml:space="preserve" approved="no">
|
||||
<source>Add contact</source>
|
||||
<target state="translated">新增聯絡人</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Advanced settings" xml:space="preserve" approved="no">
|
||||
<source>Advanced settings</source>
|
||||
<target state="translated">進階設定</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Allow calls?" xml:space="preserve" approved="no">
|
||||
<source>Allow calls?</source>
|
||||
<target state="translated">允許通話?</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Allow to send files and media." xml:space="preserve" approved="no">
|
||||
<source>Allow to send files and media.</source>
|
||||
<target state="translated">允許傳送檔案和媒體。</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Already joining the group!" xml:space="preserve" approved="no">
|
||||
<source>Already joining the group!</source>
|
||||
<target state="translated">已加入群組!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="App data migration" xml:space="preserve" approved="no">
|
||||
<source>App data migration</source>
|
||||
<target state="translated">應用資料轉移</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Apply" xml:space="preserve" approved="no">
|
||||
<source>Apply</source>
|
||||
<target state="translated">應用</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Apply to" xml:space="preserve" approved="no">
|
||||
<source>Apply to</source>
|
||||
<target state="translated">應用到</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Archive and upload" xml:space="preserve" approved="no">
|
||||
<source>Archive and upload</source>
|
||||
<target state="translated">儲存並上傳</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Block" xml:space="preserve" approved="no">
|
||||
<source>Block</source>
|
||||
<target state="translated">封鎖</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Block group members" xml:space="preserve" approved="no">
|
||||
<source>Block group members</source>
|
||||
<target state="translated">封鎖群組成員</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Block member" xml:space="preserve" approved="no">
|
||||
<source>Block member</source>
|
||||
<target state="translated">封鎖成員</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Bulgarian, Finnish, Thai and Ukrainian - thanks to the users and [Weblate](https://github.com/simplex-chat/simplex-chat/tree/stable#help-translating-simplex-chat)!" xml:space="preserve" approved="no">
|
||||
<source>Bulgarian, Finnish, Thai and Ukrainian - thanks to the users and [Weblate](https://github.com/simplex-chat/simplex-chat/tree/stable#help-translating-simplex-chat)!</source>
|
||||
<target state="translated">保加利亞語、芬蘭語、泰語和烏克蘭語——感謝使用者們和[Weblate](https://github.com/simplex-chat/simplex-chat/tree/stable#help-translating-simplex-chat)!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Can't call member" xml:space="preserve" approved="no">
|
||||
<source>Can't call member</source>
|
||||
<target state="translated">無法與成員通話</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Can't message member" xml:space="preserve" approved="no">
|
||||
<source>Can't message member</source>
|
||||
<target state="translated">無法傳送訊息給成員</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Cancel migration" xml:space="preserve" approved="no">
|
||||
<source>Cancel migration</source>
|
||||
<target state="translated">取消遷移</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Chat database exported" xml:space="preserve" approved="no">
|
||||
<source>Chat database exported</source>
|
||||
<target state="translated">導出聊天數據庫</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="0 sec" xml:space="preserve" approved="no">
|
||||
<source>0 sec</source>
|
||||
<target state="translated">0 秒</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="All your contacts, conversations and files will be securely encrypted and uploaded in chunks to configured XFTP relays." xml:space="preserve" approved="no">
|
||||
<source>All your contacts, conversations and files will be securely encrypted and uploaded in chunks to configured XFTP relays.</source>
|
||||
<target state="translated">你的所有聯絡人、對話和文件將被安全加密並切塊上傳到設置的 XFTP 中繼。</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Address change will be aborted. Old receiving address will be used." xml:space="preserve" approved="no">
|
||||
<source>Address change will be aborted. Old receiving address will be used.</source>
|
||||
<target state="translated">將取消地址更改。將使用舊聯絡地址。</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Archiving database" xml:space="preserve" approved="no">
|
||||
<source>Archiving database</source>
|
||||
<target state="translated">正在儲存資料庫</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Cellular" xml:space="preserve" approved="no">
|
||||
<source>Cellular</source>
|
||||
<target state="translated">行動網路</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="%@, %@ and %lld members" xml:space="preserve" approved="no">
|
||||
<source>%@, %@ and %lld members</source>
|
||||
<target state="translated">%@, %@ 和 %lld 成員</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="%lld messages marked deleted" xml:space="preserve" approved="no">
|
||||
<source>%lld messages marked deleted</source>
|
||||
<target state="translated">%lld 條訊息已刪除</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Already connecting!" xml:space="preserve" approved="no">
|
||||
<source>Already connecting!</source>
|
||||
<target state="translated">已連接!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Block member?" xml:space="preserve" approved="no">
|
||||
<source>Block member?</source>
|
||||
<target state="translated">封鎖成員?</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="(new)" xml:space="preserve" approved="no">
|
||||
<source>(new)</source>
|
||||
<target state="translated">(新)</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="%@, %@ and %lld other members connected" xml:space="preserve" approved="no">
|
||||
<source>%@, %@ and %lld other members connected</source>
|
||||
<target state="translated">%@, %@ 和 %lld 個成員已連接</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="A few more things" xml:space="preserve" approved="no">
|
||||
<source>A few more things</source>
|
||||
<target state="translated">其他</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Show last messages" xml:space="preserve" approved="no">
|
||||
<source>Show last messages</source>
|
||||
<target state="translated">顯示最新的訊息</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="App encrypts new local files (except videos)." xml:space="preserve" approved="no">
|
||||
<source>App encrypts new local files (except videos).</source>
|
||||
<target state="translated">應用程式將為新的本機文件(影片除外)加密。</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Better groups" xml:space="preserve" approved="no">
|
||||
<source>Better groups</source>
|
||||
<target state="translated">更加的群組</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="%lld new interface languages" xml:space="preserve" approved="no">
|
||||
<source>%lld new interface languages</source>
|
||||
<target state="translated">%lld 種新的介面語言</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Blocked by admin" xml:space="preserve" approved="no">
|
||||
<source>Blocked by admin</source>
|
||||
<target state="translated">由管理員封鎖</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Both you and your contact can irreversibly delete sent messages. (24 hours)" xml:space="preserve" approved="no">
|
||||
<source>Both you and your contact can irreversibly delete sent messages. (24 hours)</source>
|
||||
<target state="translated">您與您的聯絡人都可以不可復原地删除已傳送的訊息。(24小時)</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Encrypt local files" xml:space="preserve" approved="no">
|
||||
<source>Encrypt local files</source>
|
||||
<target state="translated">加密本機檔案</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="- more stable message delivery. - a bit better groups. - and more!" xml:space="preserve" approved="no">
|
||||
<source>- more stable message delivery.
|
||||
- a bit better groups.
|
||||
- and more!</source>
|
||||
<target state="translated">- 更穩定的傳送!
|
||||
- 更好的社群!
|
||||
- 以及更多!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="- optionally notify deleted contacts. - profile names with spaces. - and more!" xml:space="preserve" approved="no">
|
||||
<source>- optionally notify deleted contacts.
|
||||
- profile names with spaces.
|
||||
- and more!</source>
|
||||
<target state="translated">- 可選擇通知已刪除的聯絡人
|
||||
- 帶空格的共人資料名稱。
|
||||
-以及更多!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Abort changing address?" xml:space="preserve" approved="no">
|
||||
<source>Abort changing address?</source>
|
||||
<target state="translated">中止更改地址?</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Allow to send SimpleX links." xml:space="preserve" approved="no">
|
||||
<source>Allow to send SimpleX links.</source>
|
||||
<target state="translated">允許傳送 SimpleX 連結。</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Background" xml:space="preserve" approved="no">
|
||||
<source>Background</source>
|
||||
<target state="translated">後台</target>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
<file original="en.lproj/SimpleX--iOS--InfoPlist.strings" source-language="en" target-language="zh-Hant" datatype="plaintext">
|
||||
|
||||
@@ -339,7 +339,9 @@ class NotificationService: UNNotificationServiceExtension {
|
||||
CXProvider.reportNewIncomingVoIPPushPayload([
|
||||
"displayName": invitation.contact.displayName,
|
||||
"contactId": invitation.contact.id,
|
||||
"media": invitation.callType.media.rawValue
|
||||
"callUUID": invitation.callUUID ?? "",
|
||||
"media": invitation.callType.media.rawValue,
|
||||
"callTs": invitation.callTs.timeIntervalSince1970
|
||||
]) { error in
|
||||
logger.debug("reportNewIncomingVoIPPushPayload result: \(error)")
|
||||
deliver(error == nil ? nil : createCallInvitationNtf(invitation))
|
||||
@@ -571,17 +573,22 @@ func receivedMsgNtf(_ res: ChatResponse) async -> (String, NSENotification)? {
|
||||
// TODO profile update
|
||||
case let .receivedContactRequest(user, contactRequest):
|
||||
return (UserContact(contactRequest: contactRequest).id, .nse(createContactRequestNtf(user, contactRequest)))
|
||||
case let .newChatItem(user, aChatItem):
|
||||
let cInfo = aChatItem.chatInfo
|
||||
var cItem = aChatItem.chatItem
|
||||
if !cInfo.ntfsEnabled {
|
||||
ntfBadgeCountGroupDefault.set(max(0, ntfBadgeCountGroupDefault.get() - 1))
|
||||
case let .newChatItems(user, chatItems):
|
||||
// Received items are created one at a time
|
||||
if let chatItem = chatItems.first {
|
||||
let cInfo = chatItem.chatInfo
|
||||
var cItem = chatItem.chatItem
|
||||
if !cInfo.ntfsEnabled {
|
||||
ntfBadgeCountGroupDefault.set(max(0, ntfBadgeCountGroupDefault.get() - 1))
|
||||
}
|
||||
if let file = cItem.autoReceiveFile() {
|
||||
cItem = autoReceiveFile(file) ?? cItem
|
||||
}
|
||||
let ntf: NSENotification = cInfo.ntfsEnabled ? .nse(createMessageReceivedNtf(user, cInfo, cItem)) : .empty
|
||||
return cItem.showNotification ? (chatItem.chatId, ntf) : nil
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
if let file = cItem.autoReceiveFile() {
|
||||
cItem = autoReceiveFile(file) ?? cItem
|
||||
}
|
||||
let ntf: NSENotification = cInfo.ntfsEnabled ? .nse(createMessageReceivedNtf(user, cInfo, cItem)) : .empty
|
||||
return cItem.showNotification ? (aChatItem.chatId, ntf) : nil
|
||||
case let .rcvFileSndCancelled(_, aChatItem, _):
|
||||
cleanupFile(aChatItem)
|
||||
return nil
|
||||
|
||||
@@ -54,32 +54,30 @@ func apiGetChats(userId: User.ID) throws -> Array<ChatData> {
|
||||
throw r
|
||||
}
|
||||
|
||||
func apiSendMessage(
|
||||
func apiSendMessages(
|
||||
chatInfo: ChatInfo,
|
||||
cryptoFile: CryptoFile?,
|
||||
msgContent: MsgContent
|
||||
) throws -> AChatItem {
|
||||
composedMessages: [ComposedMessage]
|
||||
) throws -> [AChatItem] {
|
||||
let r = sendSimpleXCmd(
|
||||
chatInfo.chatType == .local
|
||||
? .apiCreateChatItem(
|
||||
? .apiCreateChatItems(
|
||||
noteFolderId: chatInfo.apiId,
|
||||
file: cryptoFile,
|
||||
msg: msgContent
|
||||
composedMessages: composedMessages
|
||||
)
|
||||
: .apiSendMessage(
|
||||
: .apiSendMessages(
|
||||
type: chatInfo.chatType,
|
||||
id: chatInfo.apiId,
|
||||
file: cryptoFile,
|
||||
quotedItemId: nil,
|
||||
msg: msgContent,
|
||||
live: false,
|
||||
ttl: nil
|
||||
ttl: nil,
|
||||
composedMessages: composedMessages
|
||||
)
|
||||
)
|
||||
if case let .newChatItem(_, chatItem) = r {
|
||||
return chatItem
|
||||
if case let .newChatItems(_, chatItems) = r {
|
||||
return chatItems
|
||||
} else {
|
||||
if let filePath = cryptoFile?.filePath { removeFile(filePath) }
|
||||
for composedMessage in composedMessages {
|
||||
if let filePath = composedMessage.fileSource?.filePath { removeFile(filePath) }
|
||||
}
|
||||
throw r
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,7 +74,7 @@ class ShareModel: ObservableObject {
|
||||
}
|
||||
|
||||
func setup(context: NSExtensionContext) {
|
||||
if performLAGroupDefault.get() && !allowShareExtensionGroupDefault.get() {
|
||||
if appLocalAuthEnabledGroupDefault.get() && !allowShareExtensionGroupDefault.get() {
|
||||
errorAlert = ErrorAlert(title: "App is locked!", message: "You can allow sharing in Privacy & Security / SimpleX Lock settings.")
|
||||
return
|
||||
}
|
||||
@@ -104,7 +104,7 @@ class ShareModel: ObservableObject {
|
||||
// Decode base64 images on background thread
|
||||
let profileImages = chats.reduce(into: Dictionary<ChatInfo.ID, UIImage>()) { dict, chatData in
|
||||
if let profileImage = chatData.chatInfo.image,
|
||||
let uiImage = UIImage(base64Encoded: profileImage) {
|
||||
let uiImage = imageFromBase64(profileImage) {
|
||||
dict[chatData.id] = uiImage
|
||||
}
|
||||
}
|
||||
@@ -141,23 +141,25 @@ class ShareModel: ObservableObject {
|
||||
do {
|
||||
SEChatState.shared.set(.sendingMessage)
|
||||
await waitForOtherProcessesToSuspend()
|
||||
let ci = try apiSendMessage(
|
||||
let chatItems = try apiSendMessages(
|
||||
chatInfo: selected.chatInfo,
|
||||
cryptoFile: sharedContent.cryptoFile,
|
||||
msgContent: sharedContent.msgContent(comment: self.comment)
|
||||
composedMessages: [ComposedMessage(fileSource: sharedContent.cryptoFile, msgContent: sharedContent.msgContent(comment: self.comment))]
|
||||
)
|
||||
if selected.chatInfo.chatType == .local {
|
||||
completion()
|
||||
} else {
|
||||
await MainActor.run { self.bottomBar = .loadingBar(progress: 0) }
|
||||
if let e = await handleEvents(
|
||||
isGroupChat: ci.chatInfo.chatType == .group,
|
||||
isWithoutFile: sharedContent.cryptoFile == nil,
|
||||
chatItemId: ci.chatItem.id
|
||||
) {
|
||||
await MainActor.run { errorAlert = e }
|
||||
} else {
|
||||
completion()
|
||||
// TODO batch send: share multiple items
|
||||
if let ci = chatItems.first {
|
||||
await MainActor.run { self.bottomBar = .loadingBar(progress: 0) }
|
||||
if let e = await handleEvents(
|
||||
isGroupChat: ci.chatInfo.chatType == .group,
|
||||
isWithoutFile: sharedContent.cryptoFile == nil,
|
||||
chatItemId: ci.chatItem.id
|
||||
) {
|
||||
await MainActor.run { errorAlert = e }
|
||||
} else {
|
||||
completion()
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
|
||||
@@ -132,7 +132,7 @@ struct ShareView: View {
|
||||
switch content {
|
||||
case let .image(preview, _): imagePreview(preview)
|
||||
case let .movie(preview, _, _): imagePreview(preview)
|
||||
case let .url(linkPreview): imagePreview(linkPreview.image)
|
||||
case let .url(preview): linkPreview(preview)
|
||||
case let .data(cryptoFile):
|
||||
previewArea {
|
||||
Image(systemName: "doc.fill")
|
||||
@@ -147,8 +147,8 @@ struct ShareView: View {
|
||||
}
|
||||
}
|
||||
|
||||
@ViewBuilder private func imagePreview(_ img: String) -> some View {
|
||||
if let img = UIImage(base64Encoded: img) {
|
||||
@ViewBuilder private func imagePreview(_ imgStr: String) -> some View {
|
||||
if let img = imageFromBase64(imgStr) {
|
||||
previewArea {
|
||||
Image(uiImage: img)
|
||||
.resizable()
|
||||
@@ -160,6 +160,29 @@ struct ShareView: View {
|
||||
}
|
||||
}
|
||||
|
||||
@ViewBuilder private func linkPreview(_ linkPreview: LinkPreview) -> some View {
|
||||
previewArea {
|
||||
HStack(alignment: .center, spacing: 8) {
|
||||
if let uiImage = imageFromBase64(linkPreview.image) {
|
||||
Image(uiImage: uiImage)
|
||||
.resizable()
|
||||
.aspectRatio(contentMode: .fit)
|
||||
.frame(maxWidth: 80, maxHeight: 60)
|
||||
}
|
||||
VStack(alignment: .center, spacing: 4) {
|
||||
Text(linkPreview.title)
|
||||
.lineLimit(1)
|
||||
Text(linkPreview.uri.absoluteString)
|
||||
.font(.caption)
|
||||
.lineLimit(1)
|
||||
.foregroundColor(.secondary)
|
||||
}
|
||||
.padding(.vertical, 5)
|
||||
.frame(maxWidth: .infinity, minHeight: 60)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ViewBuilder private func previewArea<V: View>(@ViewBuilder content: @escaping () -> V) -> some View {
|
||||
HStack(alignment: .center, spacing: 8) {
|
||||
content()
|
||||
|
||||
@@ -107,5 +107,5 @@
|
||||
"Wrong database passphrase" = "Falsches Datenbank-Passwort";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"You can allow sharing in Privacy & Security / SimpleX Lock settings." = "Du kannst das Teilen in den Einstellungen zu Datenschutz & Sicherheit bzw. SimpleX-Sperre erlauben.";
|
||||
"You can allow sharing in Privacy & Security / SimpleX Lock settings." = "Du kannst das Teilen in den Einstellungen zu Datenschutz & Sicherheit - SimpleX-Sperre erlauben.";
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user