Compare commits

..

2 Commits

Author SHA1 Message Date
Avently e2d00fb68a android <= 11 2024-10-11 16:53:54 +07:00
Avently 98ccf5a17c android: prevent WebView from changing audio device when toggling mic 2024-10-11 16:27:49 +07:00
66 changed files with 435 additions and 1876 deletions
+1 -1
View File
@@ -462,7 +462,7 @@ func apiGetNtfToken() -> (DeviceToken?, NtfTknStatus?, NotificationsMode, String
let r = chatSendCmdSync(.apiGetNtfToken)
switch r {
case let .ntfToken(token, status, ntfMode, ntfServer): return (token, status, ntfMode, ntfServer)
case .chatCmdError(_, .errorAgent(.CMD(.PROHIBITED, _))): return (nil, nil, .off, nil)
case .chatCmdError(_, .errorAgent(.CMD(.PROHIBITED))): return (nil, nil, .off, nil)
default:
logger.debug("apiGetNtfToken response: \(String(describing: r))")
return (nil, nil, .off, nil)
+1 -1
View File
@@ -1187,7 +1187,7 @@ struct ChatView: View {
allowMenu: $allowMenu
)
.environment(\.showTimestamp, itemSeparation.timestamp)
.modifier(ChatItemClipped(ci, tailVisible: itemSeparation.largeGap && (ci.meta.itemDeleted == nil || revealed)))
.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 {
@@ -36,7 +36,12 @@ struct ChatItemClipped: ViewModifier {
.sndMsgContent,
.rcvMsgContent,
.rcvDecryptionError,
.sndDeleted,
.rcvDeleted,
.rcvIntegrityError,
.sndModerated,
.rcvModerated,
.rcvBlocked,
.invalidJSON:
let tail = if let mc = ci.content.msgContent, mc.isImageOrVideo && mc.text.isEmpty {
false
@@ -1087,7 +1087,6 @@
</trans-unit>
<trans-unit id="Better calls" xml:space="preserve">
<source>Better calls</source>
<target>Verbesserte Anrufe</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Better groups" xml:space="preserve">
@@ -1097,7 +1096,6 @@
</trans-unit>
<trans-unit id="Better message dates." xml:space="preserve">
<source>Better message dates.</source>
<target>Verbesserte Nachrichten-Datumsinformation</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Better messages" xml:space="preserve">
@@ -1112,17 +1110,14 @@
</trans-unit>
<trans-unit id="Better notifications" xml:space="preserve">
<source>Better notifications</source>
<target>Verbesserte Benachrichtigungen</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Better security ✅" xml:space="preserve">
<source>Better security ✅</source>
<target>Verbesserte Sicherheit ✅</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Better user experience" xml:space="preserve">
<source>Better user experience</source>
<target>Verbesserte Nutzer-Erfahrung</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Black" xml:space="preserve">
@@ -1947,7 +1942,6 @@ Das ist Ihr eigener Einmal-Link!</target>
</trans-unit>
<trans-unit id="Customizable message shape." xml:space="preserve">
<source>Customizable message shape.</source>
<target>Anpassbares Format des Nachrichtenfelds</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Customize theme" xml:space="preserve">
@@ -2246,7 +2240,6 @@ Das ist Ihr eigener Einmal-Link!</target>
</trans-unit>
<trans-unit id="Delete or moderate up to 200 messages." xml:space="preserve">
<source>Delete or moderate up to 200 messages.</source>
<target>Bis zu 200 Nachrichten löschen oder moderieren</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Delete pending connection?" xml:space="preserve">
@@ -3374,7 +3367,6 @@ Das ist Ihr eigener Einmal-Link!</target>
</trans-unit>
<trans-unit id="Forward up to 20 messages at once." xml:space="preserve">
<source>Forward up to 20 messages at once.</source>
<target>Bis zu 20 Nachrichten auf einmal weiterleiten</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Forwarded" xml:space="preserve">
@@ -3769,8 +3761,6 @@ Fehler: %2$@</target>
<trans-unit id="Improved delivery, reduced traffic usage.&#10;More improvements are coming soon!" xml:space="preserve">
<source>Improved delivery, reduced traffic usage.
More improvements are coming soon!</source>
<target>Verbesserte Nachrichten-Auslieferung und verringerter Datenverbrauch.
Weitere Verbesserungen sind bald verfügbar!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Improved message delivery" xml:space="preserve">
@@ -6473,7 +6463,6 @@ Aktivieren Sie es in den *Netzwerk &amp; Server* Einstellungen.</target>
</trans-unit>
<trans-unit id="SimpleX protocols reviewed by Trail of Bits." xml:space="preserve">
<source>SimpleX protocols reviewed by Trail of Bits.</source>
<target>Die SimpleX-Protokolle wurden von Trail of Bits überprüft.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Simplified incognito mode" xml:space="preserve">
@@ -6653,12 +6642,10 @@ Aktivieren Sie es in den *Netzwerk &amp; Server* Einstellungen.</target>
</trans-unit>
<trans-unit id="Switch audio and video during the call." xml:space="preserve">
<source>Switch audio and video during the call.</source>
<target>Während des Anrufs zwischen Audio und Video wechseln</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Switch chat profile for 1-time invitations." xml:space="preserve">
<source>Switch chat profile for 1-time invitations.</source>
<target>Das Chat-Profil für Einmal-Einladungen wechseln</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="System" xml:space="preserve">
@@ -1087,7 +1087,6 @@
</trans-unit>
<trans-unit id="Better calls" xml:space="preserve">
<source>Better calls</source>
<target>Llamadas mejoradas</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Better groups" xml:space="preserve">
@@ -1097,7 +1096,6 @@
</trans-unit>
<trans-unit id="Better message dates." xml:space="preserve">
<source>Better message dates.</source>
<target>Sistema de fechas mejorado.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Better messages" xml:space="preserve">
@@ -1112,17 +1110,14 @@
</trans-unit>
<trans-unit id="Better notifications" xml:space="preserve">
<source>Better notifications</source>
<target>Notificaciones mejoradas</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Better security ✅" xml:space="preserve">
<source>Better security ✅</source>
<target>Seguridad mejorada ✅</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Better user experience" xml:space="preserve">
<source>Better user experience</source>
<target>Experiencia de usuario mejorada</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Black" xml:space="preserve">
@@ -1947,7 +1942,6 @@ This is your own one-time link!</source>
</trans-unit>
<trans-unit id="Customizable message shape." xml:space="preserve">
<source>Customizable message shape.</source>
<target>Forma personalizable de los mensajes.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Customize theme" xml:space="preserve">
@@ -2246,7 +2240,6 @@ This is your own one-time link!</source>
</trans-unit>
<trans-unit id="Delete or moderate up to 200 messages." xml:space="preserve">
<source>Delete or moderate up to 200 messages.</source>
<target>Borra o modera hasta 200 mensajes a la vez.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Delete pending connection?" xml:space="preserve">
@@ -3374,7 +3367,6 @@ This is your own one-time link!</source>
</trans-unit>
<trans-unit id="Forward up to 20 messages at once." xml:space="preserve">
<source>Forward up to 20 messages at once.</source>
<target>Desplazamiento de hasta 20 mensajes.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Forwarded" xml:space="preserve">
@@ -3769,8 +3761,6 @@ Error: %2$@</target>
<trans-unit id="Improved delivery, reduced traffic usage.&#10;More improvements are coming soon!" xml:space="preserve">
<source>Improved delivery, reduced traffic usage.
More improvements are coming soon!</source>
<target>Reducción del tráfico y entrega mejorada.
¡Pronto habrá nuevas mejoras!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Improved message delivery" xml:space="preserve">
@@ -6473,7 +6463,6 @@ Actívalo en ajustes de *Servidores y Redes*.</target>
</trans-unit>
<trans-unit id="SimpleX protocols reviewed by Trail of Bits." xml:space="preserve">
<source>SimpleX protocols reviewed by Trail of Bits.</source>
<target>Protocolos de SimpleX auditados por Trail of Bits.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Simplified incognito mode" xml:space="preserve">
@@ -6653,12 +6642,10 @@ Actívalo en ajustes de *Servidores y Redes*.</target>
</trans-unit>
<trans-unit id="Switch audio and video during the call." xml:space="preserve">
<source>Switch audio and video during the call.</source>
<target>Intercambia audio y video durante la llamada.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Switch chat profile for 1-time invitations." xml:space="preserve">
<source>Switch chat profile for 1-time invitations.</source>
<target>Cambia el perfil de chat para invitaciones de un solo uso.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="System" xml:space="preserve">
@@ -762,7 +762,7 @@
</trans-unit>
<trans-unit id="All your contacts will remain connected. Profile update will be sent to your contacts." xml:space="preserve">
<source>All your contacts will remain connected. Profile update will be sent to your contacts.</source>
<target>Az ismerőseivel kapcsolatban marad. A profil-változtatások frissítésre kerülnek az ismerősöknél.</target>
<target>Az ismerőseivel kapcsolatban marad. A profil változtatások frissítésre kerülnek az ismerősöknél.</target>
<note>No comment provided by engineer.</note>
</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">
@@ -1087,7 +1087,6 @@
</trans-unit>
<trans-unit id="Better calls" xml:space="preserve">
<source>Better calls</source>
<target>Továbbfejlesztett hívásélmény</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Better groups" xml:space="preserve">
@@ -1097,7 +1096,6 @@
</trans-unit>
<trans-unit id="Better message dates." xml:space="preserve">
<source>Better message dates.</source>
<target>Továbbfejlesztett üzenetdátumok.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Better messages" xml:space="preserve">
@@ -1112,17 +1110,14 @@
</trans-unit>
<trans-unit id="Better notifications" xml:space="preserve">
<source>Better notifications</source>
<target>Továbbfejlesztett értesítések</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Better security ✅" xml:space="preserve">
<source>Better security ✅</source>
<target>Továbbfejlesztett biztonság ✅</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Better user experience" xml:space="preserve">
<source>Better user experience</source>
<target>Továbbfejlesztett felhasználói élmény</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Black" xml:space="preserve">
@@ -1413,7 +1408,7 @@
</trans-unit>
<trans-unit id="Chat profile" xml:space="preserve">
<source>Chat profile</source>
<target>Csevegési profil</target>
<target>Felhasználói profil</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Chat theme" xml:space="preserve">
@@ -1438,7 +1433,7 @@
</trans-unit>
<trans-unit id="Choose _Migrate from another device_ on the new device and scan QR code." xml:space="preserve">
<source>Choose _Migrate from another device_ on the new device and scan QR code.</source>
<target>Válassza az _Átköltöztetés egy másik eszközről_ opciót az új eszközén és olvassa be a QR-kódot.</target>
<target>Válassza az _Átköltöztetés egy másik eszközről opciót az új eszközén és olvassa be a QR-kódot.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Choose file" xml:space="preserve">
@@ -1722,7 +1717,7 @@ Ez az Ön egyszer használható hivatkozása!</target>
</trans-unit>
<trans-unit id="Connection timeout" xml:space="preserve">
<source>Connection timeout</source>
<target>Időtúllépés kapcsolódáskor</target>
<target>Kapcsolat időtúllépés</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Connection with desktop stopped" xml:space="preserve">
@@ -1947,7 +1942,6 @@ Ez az Ön egyszer használható hivatkozása!</target>
</trans-unit>
<trans-unit id="Customizable message shape." xml:space="preserve">
<source>Customizable message shape.</source>
<target>Testreszabható üzenetbuborékok.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Customize theme" xml:space="preserve">
@@ -1977,7 +1971,7 @@ Ez az Ön egyszer használható hivatkozása!</target>
</trans-unit>
<trans-unit id="Database IDs and Transport isolation option." xml:space="preserve">
<source>Database IDs and Transport isolation option.</source>
<target>Adatbázis-azonosítók és átvitel-izolációs beállítások.</target>
<target>Adatbázis-azonosítók és átviteli izolációs beállítások.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Database downgrade" xml:space="preserve">
@@ -2246,7 +2240,6 @@ Ez az Ön egyszer használható hivatkozása!</target>
</trans-unit>
<trans-unit id="Delete or moderate up to 200 messages." xml:space="preserve">
<source>Delete or moderate up to 200 messages.</source>
<target>Legfeljebb 200 üzenet egyszerre való törlése, vagy moderálása.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Delete pending connection?" xml:space="preserve">
@@ -2356,7 +2349,7 @@ Ez az Ön egyszer használható hivatkozása!</target>
</trans-unit>
<trans-unit id="Details" xml:space="preserve">
<source>Details</source>
<target>További részletek</target>
<target>Részletek</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Develop" xml:space="preserve">
@@ -2391,7 +2384,7 @@ Ez az Ön egyszer használható hivatkozása!</target>
</trans-unit>
<trans-unit id="Different names, avatars and transport isolation." xml:space="preserve">
<source>Different names, avatars and transport isolation.</source>
<target>Különböző nevek, profilképek és átvitel-izoláció.</target>
<target>Különböző nevek, avatarok és átviteli izoláció.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Direct messages" xml:space="preserve">
@@ -2917,7 +2910,7 @@ Ez az Ön egyszer használható hivatkozása!</target>
</trans-unit>
<trans-unit id="Error deleting user profile" xml:space="preserve">
<source>Error deleting user profile</source>
<target>Hiba a felhasználó-profil törlésekor</target>
<target>Hiba a felhasználói profil törlésekor</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Error downloading the archive" xml:space="preserve">
@@ -3032,7 +3025,7 @@ Ez az Ön egyszer használható hivatkozása!</target>
</trans-unit>
<trans-unit id="Error saving user password" xml:space="preserve">
<source>Error saving user password</source>
<target>Hiba a felhasználói jelszó mentésekor</target>
<target>Hiba a felhasználó jelszavának mentésekor</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Error scanning code: %@" xml:space="preserve">
@@ -3102,7 +3095,7 @@ Ez az Ön egyszer használható hivatkozása!</target>
</trans-unit>
<trans-unit id="Error updating user privacy" xml:space="preserve">
<source>Error updating user privacy</source>
<target>Hiba a felhasználói adatvédelem frissítésekor</target>
<target>Hiba a felhasználói beállítások frissítésekor</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Error uploading the archive" xml:space="preserve">
@@ -3374,7 +3367,6 @@ Ez az Ön egyszer használható hivatkozása!</target>
</trans-unit>
<trans-unit id="Forward up to 20 messages at once." xml:space="preserve">
<source>Forward up to 20 messages at once.</source>
<target>Legfeljebb 20 üzenet egyszerre való továbbítása.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Forwarded" xml:space="preserve">
@@ -3623,7 +3615,7 @@ Hiba: %2$@</target>
</trans-unit>
<trans-unit id="Hide" xml:space="preserve">
<source>Hide</source>
<target>Összecsukás</target>
<target>Elrejtés</target>
<note>chat item action</note>
</trans-unit>
<trans-unit id="Hide app screen in the recent apps." xml:space="preserve">
@@ -3708,7 +3700,7 @@ Hiba: %2$@</target>
</trans-unit>
<trans-unit id="If you need to use the chat now tap **Do it later** below (you will be offered to migrate the database when you restart the app)." xml:space="preserve">
<source>If you need to use the chat now tap **Do it later** below (you will be offered to migrate the database when you restart the app).</source>
<target>Ha most kell használnia a csevegést, koppintson alább a **Befejezés később** lehetőségre (az alkalmazás újraindításakor felajánlásra kerül az adatbázis átköltöztetése).</target>
<target>Ha most kell használnia a csevegést, koppintson alább az **Befejezés később** lehetőségre (az alkalmazás újraindításakor felajánlásra kerül az adatbázis átköltöztetése).</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Ignore" xml:space="preserve">
@@ -3769,8 +3761,6 @@ Hiba: %2$@</target>
<trans-unit id="Improved delivery, reduced traffic usage.&#10;More improvements are coming soon!" xml:space="preserve">
<source>Improved delivery, reduced traffic usage.
More improvements are coming soon!</source>
<target>Továbbfejlesztett kézbesítés, csökkentett adatforgalom-használat.
További fejlesztések hamarosan!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Improved message delivery" xml:space="preserve">
@@ -4215,7 +4205,7 @@ Ez az Ön hivatkozása a(z) %@ csoporthoz!</target>
</trans-unit>
<trans-unit id="Many people asked: *if SimpleX has no user identifiers, how can it deliver messages?*" xml:space="preserve">
<source>Many people asked: *if SimpleX has no user identifiers, how can it deliver messages?*</source>
<target>Sokan kérdezték: *ha a SimpleX Chatnek nincsenek felhasználó-azonosítói, akkor hogyan tud üzeneteket kézbesíteni?*</target>
<target>Sokan kérdezték: *ha a SimpleX Chatnek nincsenek felhasználói azonosítói, akkor hogyan tud üzeneteket kézbesíteni?*</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Mark deleted for everyone" xml:space="preserve">
@@ -4793,7 +4783,7 @@ VPN engedélyezése szükséges.</target>
</trans-unit>
<trans-unit id="Only client devices store user profiles, contacts, groups, and messages sent with **2-layer end-to-end encryption**." xml:space="preserve">
<source>Only client devices store user profiles, contacts, groups, and messages sent with **2-layer end-to-end encryption**.</source>
<target>Csak az eszközök alkalmazásai tárolják a felhasználó-profilokat, névjegyeket, csoportokat és a **2 rétegű végpontok közötti titkosítással** küldött üzeneteket.</target>
<target>Csak az eszközök alkalmazásai tárolják a felhasználói profilokat, névjegyeket, csoportokat és a **2 rétegű végpontok közötti titkosítással** küldött üzeneteket.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Only delete conversation" xml:space="preserve">
@@ -4903,7 +4893,7 @@ VPN engedélyezése szükséges.</target>
</trans-unit>
<trans-unit id="Open user profiles" xml:space="preserve">
<source>Open user profiles</source>
<target>Felhasználó-profilok megnyitása</target>
<target>Felhasználói profilok megnyitása</target>
<note>authentication reason</note>
</trans-unit>
<trans-unit id="Open-source protocol and code anybody can run the servers." xml:space="preserve">
@@ -4955,12 +4945,12 @@ VPN engedélyezése szükséges.</target>
</trans-unit>
<trans-unit id="PING count" xml:space="preserve">
<source>PING count</source>
<target>PING-ek száma</target>
<target>PING számláló</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="PING interval" xml:space="preserve">
<source>PING interval</source>
<target>Időtartam a PING-ek között</target>
<target>PING időköze</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Passcode" xml:space="preserve">
@@ -5316,12 +5306,12 @@ Engedélyezze a „Beállítások -&gt; Hálózat és kiszolgálók” menüben.
</trans-unit>
<trans-unit id="Protocol timeout" xml:space="preserve">
<source>Protocol timeout</source>
<target>Protokoll időtúllépése</target>
<target>Protokoll időtúllépés</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Protocol timeout per KB" xml:space="preserve">
<source>Protocol timeout per KB</source>
<target>Protokoll időtúllépése KB-onként</target>
<target>Protokoll időkorlát KB-onként</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Proxied" xml:space="preserve">
@@ -5446,7 +5436,7 @@ Engedélyezze a „Beállítások -&gt; Hálózat és kiszolgálók” menüben.
</trans-unit>
<trans-unit id="Received total" xml:space="preserve">
<source>Received total</source>
<target>Összes fogadott üzenet</target>
<target>Összes fogadott</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Receiving address will be changed to a different server. Address change will complete after sender comes online." xml:space="preserve">
@@ -5818,7 +5808,7 @@ Engedélyezze a „Beállítások -&gt; Hálózat és kiszolgálók” menüben.
</trans-unit>
<trans-unit id="Save profile password" xml:space="preserve">
<source>Save profile password</source>
<target>Profiljelszó mentése</target>
<target>Felhasználói fiók jelszavának mentése</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Save servers" xml:space="preserve">
@@ -6158,7 +6148,7 @@ Engedélyezze a „Beállítások -&gt; Hálózat és kiszolgálók” menüben.
</trans-unit>
<trans-unit id="Sent total" xml:space="preserve">
<source>Sent total</source>
<target>Összes elküldött üzenet</target>
<target>Összes elküldött</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Sent via proxy" xml:space="preserve">
@@ -6373,7 +6363,7 @@ Engedélyezze a „Beállítások -&gt; Hálózat és kiszolgálók” menüben.
</trans-unit>
<trans-unit id="Show message status" xml:space="preserve">
<source>Show message status</source>
<target>Üzenetállapot megjelenítése</target>
<target>Üzenet állapot megjelenítése</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Show percentage" xml:space="preserve">
@@ -6473,7 +6463,6 @@ Engedélyezze a „Beállítások -&gt; Hálózat és kiszolgálók” menüben.
</trans-unit>
<trans-unit id="SimpleX protocols reviewed by Trail of Bits." xml:space="preserve">
<source>SimpleX protocols reviewed by Trail of Bits.</source>
<target>A SimpleX Chat biztonsága a Trail of Bits által lett újraauditálva.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Simplified incognito mode" xml:space="preserve">
@@ -6653,12 +6642,10 @@ Engedélyezze a „Beállítások -&gt; Hálózat és kiszolgálók” menüben.
</trans-unit>
<trans-unit id="Switch audio and video during the call." xml:space="preserve">
<source>Switch audio and video during the call.</source>
<target>Hang/Videó váltása hívás közben.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Switch chat profile for 1-time invitations." xml:space="preserve">
<source>Switch chat profile for 1-time invitations.</source>
<target>Csevegési profilváltás az egyszer használható meghívókhoz.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="System" xml:space="preserve">
@@ -6678,7 +6665,7 @@ Engedélyezze a „Beállítások -&gt; Hálózat és kiszolgálók” menüben.
</trans-unit>
<trans-unit id="TCP connection timeout" xml:space="preserve">
<source>TCP connection timeout</source>
<target>TCP kapcsolat időtúllépése</target>
<target>TCP kapcsolat időtúllépés</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="TCP_KEEPCNT" xml:space="preserve">
@@ -6713,7 +6700,7 @@ Engedélyezze a „Beállítások -&gt; Hálózat és kiszolgálók” menüben.
</trans-unit>
<trans-unit id="Tap to Connect" xml:space="preserve">
<source>Tap to Connect</source>
<target>Koppintson ide a kapcsolódáshoz</target>
<target>Koppintson a kapcsolódáshoz</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Tap to activate profile." xml:space="preserve">
@@ -6723,12 +6710,12 @@ Engedélyezze a „Beállítások -&gt; Hálózat és kiszolgálók” menüben.
</trans-unit>
<trans-unit id="Tap to join" xml:space="preserve">
<source>Tap to join</source>
<target>Koppintson ide a csatlakozáshoz</target>
<target>Koppintson a csatlakozáshoz</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>Koppintson ide az inkognitóban való csatlakozáshoz</target>
<target>Koppintson az inkognitóban való csatlakozáshoz</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Tap to paste link" xml:space="preserve">
@@ -6738,7 +6725,7 @@ Engedélyezze a „Beállítások -&gt; Hálózat és kiszolgálók” menüben.
</trans-unit>
<trans-unit id="Tap to scan" xml:space="preserve">
<source>Tap to scan</source>
<target>Koppintson ide a QR-kód beolvasáshoz</target>
<target>Koppintson a beolvasáshoz</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Temporary file error" xml:space="preserve">
@@ -6783,7 +6770,7 @@ Engedélyezze a „Beállítások -&gt; Hálózat és kiszolgálók” menüben.
</trans-unit>
<trans-unit id="The 1st platform without any user identifiers private by design." xml:space="preserve">
<source>The 1st platform without any user identifiers private by design.</source>
<target>Az első csevegési rendszer bármiféle felhasználó-azonosító nélkül - privátra lett tervezre.</target>
<target>Az első csevegési rendszer bármiféle felhasználó azonosító nélkül - privátra lett tervezre.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="The ID of the next message is incorrect (less or equal to the previous).&#10;It can happen because of some bug or when the connection is compromised." xml:space="preserve">
@@ -7005,7 +6992,7 @@ Ez valamilyen hiba, vagy sérült kapcsolat esetén fordulhat elő.</target>
</trans-unit>
<trans-unit id="To protect privacy, instead of user IDs used by all other platforms, SimpleX has identifiers for message queues, separate for each of your contacts." xml:space="preserve">
<source>To protect privacy, instead of user IDs used by all other platforms, SimpleX has identifiers for message queues, separate for each of your contacts.</source>
<target>Az adatvédelem érdekében, a más csevegési platformokon megszokott felhasználó-azonosítók helyett, a SimpleX csak az üzenetek sorbaállításához használ azonosítókat, minden egyes ismerőshöz egy-egy különbözőt.</target>
<target>Az adatvédelem érdekében, a más csevegési platformokon megszokott felhasználói azonosítók helyett, a SimpleX csak az üzenetek sorbaállításához használ azonosítókat, minden egyes ismerőshöz egy-egy különbözőt.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="To protect timezone, image/voice files use UTC." xml:space="preserve">
@@ -7072,12 +7059,12 @@ A funkció bekapcsolása előtt a rendszer felszólítja a képernyőzár beáll
</trans-unit>
<trans-unit id="Total" xml:space="preserve">
<source>Total</source>
<target>Összes kapcsolat</target>
<target>Összesen</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Transport isolation" xml:space="preserve">
<source>Transport isolation</source>
<target>Átvitel-izoláció módja</target>
<target>Kapcsolat izolációs mód</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Transport sessions" xml:space="preserve">
@@ -7741,7 +7728,7 @@ Csatlakozáskérés megismétlése?</target>
</trans-unit>
<trans-unit id="You can enable them later via app Privacy &amp; Security settings." xml:space="preserve">
<source>You can enable them later via app Privacy &amp; Security settings.</source>
<target>Később engedélyezheti őket az alkalmazás „Adatvédelem és biztonság” menüben.</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">
@@ -7751,7 +7738,7 @@ Csatlakozáskérés megismétlése?</target>
</trans-unit>
<trans-unit id="You can hide or mute a user profile - swipe it to the right." xml:space="preserve">
<source>You can hide or mute a user profile - swipe it to the right.</source>
<target>Elrejtheti vagy lenémíthatja a felhasználó -profiljait - csúsztassa jobbra a profilt.</target>
<target>Elrejtheti vagy lenémíthatja a felhasználó profiljait - csúsztassa jobbra a profilt.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="You can make it visible to your SimpleX contacts via Settings." xml:space="preserve">
@@ -9081,7 +9068,7 @@ utoljára fogadott üzenet: %2$@</target>
</trans-unit>
<trans-unit id="NSCameraUsageDescription" xml:space="preserve">
<source>SimpleX needs camera access to scan QR codes to connect to other users and for video calls.</source>
<target>A SimpleXnek kamera-hozzáférésre van szüksége a QR-kódok beolvasásához, hogy kapcsolódhasson más felhasználókhoz és videohívásokhoz.</target>
<target>A SimpleX-nek kamera-hozzáférésre van szüksége a QR-kódok beolvasásához, hogy kapcsolódhasson más felhasználókhoz és videohívásokhoz.</target>
<note>Privacy - Camera Usage Description</note>
</trans-unit>
<trans-unit id="NSFaceIDUsageDescription" xml:space="preserve">
@@ -9096,12 +9083,12 @@ utoljára fogadott üzenet: %2$@</target>
</trans-unit>
<trans-unit id="NSMicrophoneUsageDescription" xml:space="preserve">
<source>SimpleX needs microphone access for audio and video calls, and to record voice messages.</source>
<target>A SimpleXnek mikrofon-hozzáférésre van szüksége hang- és videohívásokhoz, valamint hangüzenetek rögzítéséhez.</target>
<target>A SimpleX-nek mikrofon-hozzáférésre van szüksége hang- és videohívásokhoz, valamint hangüzenetek rögzítéséhez.</target>
<note>Privacy - Microphone Usage Description</note>
</trans-unit>
<trans-unit id="NSPhotoLibraryAddUsageDescription" xml:space="preserve">
<source>SimpleX needs access to Photo Library for saving captured and received media</source>
<target>A SimpleXnek galéria-hozzáférésre van szüksége a rögzített és fogadott média mentéséhez</target>
<target>A SimpleX-nek hozzáférésre van szüksége a Galériához a rögzített és fogadott média mentéséhez</target>
<note>Privacy - Photo Library Additions Usage Description</note>
</trans-unit>
</body>
@@ -1087,7 +1087,6 @@
</trans-unit>
<trans-unit id="Better calls" xml:space="preserve">
<source>Better calls</source>
<target>Chiamate migliorate</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Better groups" xml:space="preserve">
@@ -1097,7 +1096,6 @@
</trans-unit>
<trans-unit id="Better message dates." xml:space="preserve">
<source>Better message dates.</source>
<target>Date dei messaggi migliorate.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Better messages" xml:space="preserve">
@@ -1112,17 +1110,14 @@
</trans-unit>
<trans-unit id="Better notifications" xml:space="preserve">
<source>Better notifications</source>
<target>Notifiche migliorate</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Better security ✅" xml:space="preserve">
<source>Better security ✅</source>
<target>Sicurezza migliorata ✅</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Better user experience" xml:space="preserve">
<source>Better user experience</source>
<target>Esperienza utente migliorata</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Black" xml:space="preserve">
@@ -1947,7 +1942,6 @@ Questo è il tuo link una tantum!</target>
</trans-unit>
<trans-unit id="Customizable message shape." xml:space="preserve">
<source>Customizable message shape.</source>
<target>Forma dei messaggi personalizzabile.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Customize theme" xml:space="preserve">
@@ -2246,7 +2240,6 @@ Questo è il tuo link una tantum!</target>
</trans-unit>
<trans-unit id="Delete or moderate up to 200 messages." xml:space="preserve">
<source>Delete or moderate up to 200 messages.</source>
<target>Elimina o modera fino a 200 messaggi.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Delete pending connection?" xml:space="preserve">
@@ -3374,7 +3367,6 @@ Questo è il tuo link una tantum!</target>
</trans-unit>
<trans-unit id="Forward up to 20 messages at once." xml:space="preserve">
<source>Forward up to 20 messages at once.</source>
<target>Inoltra fino a 20 messaggi alla volta.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Forwarded" xml:space="preserve">
@@ -3769,8 +3761,6 @@ Errore: %2$@</target>
<trans-unit id="Improved delivery, reduced traffic usage.&#10;More improvements are coming soon!" xml:space="preserve">
<source>Improved delivery, reduced traffic usage.
More improvements are coming soon!</source>
<target>Consegna migliorata, utilizzo di traffico ridotto.
Altri miglioramenti sono in arrivo!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Improved message delivery" xml:space="preserve">
@@ -6473,7 +6463,6 @@ Attivalo nelle impostazioni *Rete e server*.</target>
</trans-unit>
<trans-unit id="SimpleX protocols reviewed by Trail of Bits." xml:space="preserve">
<source>SimpleX protocols reviewed by Trail of Bits.</source>
<target>Protocolli di SimpleX esaminati da Trail of Bits.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Simplified incognito mode" xml:space="preserve">
@@ -6653,12 +6642,10 @@ Attivalo nelle impostazioni *Rete e server*.</target>
</trans-unit>
<trans-unit id="Switch audio and video during the call." xml:space="preserve">
<source>Switch audio and video during the call.</source>
<target>Cambia tra audio e video durante la chiamata.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Switch chat profile for 1-time invitations." xml:space="preserve">
<source>Switch chat profile for 1-time invitations.</source>
<target>Cambia profilo di chat per inviti una tantum.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="System" xml:space="preserve">
@@ -4121,12 +4121,10 @@ This is your link for group %@!</source>
</trans-unit>
<trans-unit id="Messages, files and calls are protected by **end-to-end encryption** with perfect forward secrecy, repudiation and break-in recovery." xml:space="preserve">
<source>Messages, files and calls are protected by **end-to-end encryption** with perfect forward secrecy, repudiation and break-in recovery.</source>
<target>メッセージ、ファイル、通話は、前方秘匿性、否認可能性および侵入復元性を備えた**エンドツーエンドの暗号化**によって保護されます。</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Messages, files and calls are protected by **quantum resistant e2e encryption** with perfect forward secrecy, repudiation and break-in recovery." xml:space="preserve">
<source>Messages, files and calls are protected by **quantum resistant e2e encryption** with perfect forward secrecy, repudiation and break-in recovery.</source>
<target>メッセージ、ファイル、通話は、前方秘匿性、否認可能性および侵入復元性を備えた**耐量子E2E暗号化**によって保護されます。</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Migrate device" xml:space="preserve">
@@ -1087,7 +1087,6 @@
</trans-unit>
<trans-unit id="Better calls" xml:space="preserve">
<source>Better calls</source>
<target>Betere gesprekken</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Better groups" xml:space="preserve">
@@ -1097,7 +1096,6 @@
</trans-unit>
<trans-unit id="Better message dates." xml:space="preserve">
<source>Better message dates.</source>
<target>Betere datums voor berichten.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Better messages" xml:space="preserve">
@@ -1112,17 +1110,14 @@
</trans-unit>
<trans-unit id="Better notifications" xml:space="preserve">
<source>Better notifications</source>
<target>Betere meldingen</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Better security ✅" xml:space="preserve">
<source>Better security ✅</source>
<target>Betere beveiliging ✅</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Better user experience" xml:space="preserve">
<source>Better user experience</source>
<target>Betere gebruikerservaring</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Black" xml:space="preserve">
@@ -1947,7 +1942,6 @@ Dit is uw eigen eenmalige link!</target>
</trans-unit>
<trans-unit id="Customizable message shape." xml:space="preserve">
<source>Customizable message shape.</source>
<target>Aanpasbare berichtvorm.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Customize theme" xml:space="preserve">
@@ -2246,7 +2240,6 @@ Dit is uw eigen eenmalige link!</target>
</trans-unit>
<trans-unit id="Delete or moderate up to 200 messages." xml:space="preserve">
<source>Delete or moderate up to 200 messages.</source>
<target>Maximaal 200 berichten verwijderen of modereren.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Delete pending connection?" xml:space="preserve">
@@ -3374,7 +3367,6 @@ Dit is uw eigen eenmalige link!</target>
</trans-unit>
<trans-unit id="Forward up to 20 messages at once." xml:space="preserve">
<source>Forward up to 20 messages at once.</source>
<target>Stuur maximaal 20 berichten tegelijk door.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Forwarded" xml:space="preserve">
@@ -3769,8 +3761,6 @@ Fout: %2$@</target>
<trans-unit id="Improved delivery, reduced traffic usage.&#10;More improvements are coming soon!" xml:space="preserve">
<source>Improved delivery, reduced traffic usage.
More improvements are coming soon!</source>
<target>Verbeterde levering, minder data gebruik.
Binnenkort meer verbeteringen!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Improved message delivery" xml:space="preserve">
@@ -6473,7 +6463,6 @@ Schakel dit in in *Netwerk en servers*-instellingen.</target>
</trans-unit>
<trans-unit id="SimpleX protocols reviewed by Trail of Bits." xml:space="preserve">
<source>SimpleX protocols reviewed by Trail of Bits.</source>
<target>SimpleX-protocollen beoordeeld door Trail of Bits.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Simplified incognito mode" xml:space="preserve">
@@ -6653,12 +6642,10 @@ Schakel dit in in *Netwerk en servers*-instellingen.</target>
</trans-unit>
<trans-unit id="Switch audio and video during the call." xml:space="preserve">
<source>Switch audio and video during the call.</source>
<target>Wisselen tussen audio en video tijdens het gesprek.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Switch chat profile for 1-time invitations." xml:space="preserve">
<source>Switch chat profile for 1-time invitations.</source>
<target>Wijzig chatprofiel voor eenmalige uitnodigingen.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="System" xml:space="preserve">
@@ -139,7 +139,6 @@
</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">
@@ -1087,7 +1086,6 @@
</trans-unit>
<trans-unit id="Better calls" xml:space="preserve">
<source>Better calls</source>
<target>Улучшенные звонки</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Better groups" xml:space="preserve">
@@ -1097,7 +1095,6 @@
</trans-unit>
<trans-unit id="Better message dates." xml:space="preserve">
<source>Better message dates.</source>
<target>Улучшенные даты сообщений.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Better messages" xml:space="preserve">
@@ -1112,17 +1109,14 @@
</trans-unit>
<trans-unit id="Better notifications" xml:space="preserve">
<source>Better notifications</source>
<target>Улучшенные уведомления</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Better security ✅" xml:space="preserve">
<source>Better security ✅</source>
<target>Улучшенная безопасность ✅</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Better user experience" xml:space="preserve">
<source>Better user experience</source>
<target>Улучшенный интерфейс</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Black" xml:space="preserve">
@@ -1947,7 +1941,6 @@ This is your own one-time link!</source>
</trans-unit>
<trans-unit id="Customizable message shape." xml:space="preserve">
<source>Customizable message shape.</source>
<target>Настраиваемая форма сообщений.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Customize theme" xml:space="preserve">
@@ -2246,7 +2239,6 @@ This is your own one-time link!</source>
</trans-unit>
<trans-unit id="Delete or moderate up to 200 messages." xml:space="preserve">
<source>Delete or moderate up to 200 messages.</source>
<target>Удаляйте или модерируйте до 200 сообщений.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Delete pending connection?" xml:space="preserve">
@@ -3374,7 +3366,6 @@ This is your own one-time link!</source>
</trans-unit>
<trans-unit id="Forward up to 20 messages at once." xml:space="preserve">
<source>Forward up to 20 messages at once.</source>
<target>Пересылайте до 20 сообщений за раз.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Forwarded" xml:space="preserve">
@@ -3769,7 +3760,6 @@ Error: %2$@</source>
<trans-unit id="Improved delivery, reduced traffic usage.&#10;More improvements are coming soon!" xml:space="preserve">
<source>Improved delivery, reduced traffic usage.
More improvements are coming soon!</source>
<target>Улучшенная доставка, меньше трафик.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Improved message delivery" xml:space="preserve">
@@ -6472,7 +6462,6 @@ Enable in *Network &amp; servers* settings.</source>
</trans-unit>
<trans-unit id="SimpleX protocols reviewed by Trail of Bits." xml:space="preserve">
<source>SimpleX protocols reviewed by Trail of Bits.</source>
<target>Аудит SimpleX протоколов от Trail of Bits.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Simplified incognito mode" xml:space="preserve">
@@ -6652,12 +6641,10 @@ Enable in *Network &amp; servers* settings.</source>
</trans-unit>
<trans-unit id="Switch audio and video during the call." xml:space="preserve">
<source>Switch audio and video during the call.</source>
<target>Переключайте звук и видео во время звонка.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Switch chat profile for 1-time invitations." xml:space="preserve">
<source>Switch chat profile for 1-time invitations.</source>
<target>Переключайте профиль чата для одноразовых приглашений.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="System" xml:space="preserve">
@@ -1087,7 +1087,6 @@
</trans-unit>
<trans-unit id="Better calls" xml:space="preserve">
<source>Better calls</source>
<target>Daha iyi aramalar</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Better groups" xml:space="preserve">
@@ -1097,7 +1096,6 @@
</trans-unit>
<trans-unit id="Better message dates." xml:space="preserve">
<source>Better message dates.</source>
<target>Daha iyi mesaj tarihleri.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Better messages" xml:space="preserve">
@@ -1112,17 +1110,14 @@
</trans-unit>
<trans-unit id="Better notifications" xml:space="preserve">
<source>Better notifications</source>
<target>Daha iyi bildirimler</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Better security ✅" xml:space="preserve">
<source>Better security ✅</source>
<target>Daha iyi güvenlik ✅</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Better user experience" xml:space="preserve">
<source>Better user experience</source>
<target>Daha iyi kullanıcı deneyimi</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Black" xml:space="preserve">
@@ -1947,7 +1942,6 @@ Bu senin kendi tek kullanımlık bağlantın!</target>
</trans-unit>
<trans-unit id="Customizable message shape." xml:space="preserve">
<source>Customizable message shape.</source>
<target>Özelleştirilebilir mesaj şekli.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Customize theme" xml:space="preserve">
@@ -2246,7 +2240,6 @@ Bu senin kendi tek kullanımlık bağlantın!</target>
</trans-unit>
<trans-unit id="Delete or moderate up to 200 messages." xml:space="preserve">
<source>Delete or moderate up to 200 messages.</source>
<target>200'e kadar mesajı silin veya düzenleyin.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Delete pending connection?" xml:space="preserve">
@@ -3374,7 +3367,6 @@ Bu senin kendi tek kullanımlık bağlantın!</target>
</trans-unit>
<trans-unit id="Forward up to 20 messages at once." xml:space="preserve">
<source>Forward up to 20 messages at once.</source>
<target>Aynı anda en fazla 20 mesaj iletin.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Forwarded" xml:space="preserve">
@@ -3769,8 +3761,6 @@ Hata: %2$@</target>
<trans-unit id="Improved delivery, reduced traffic usage.&#10;More improvements are coming soon!" xml:space="preserve">
<source>Improved delivery, reduced traffic usage.
More improvements are coming soon!</source>
<target>İyileştirilmiş teslimat, azaltılmış trafik kullanımı.
Daha fazla iyileştirme yakında geliyor!</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Improved message delivery" xml:space="preserve">
@@ -6473,7 +6463,6 @@ Enable in *Network &amp; servers* settings.</source>
</trans-unit>
<trans-unit id="SimpleX protocols reviewed by Trail of Bits." xml:space="preserve">
<source>SimpleX protocols reviewed by Trail of Bits.</source>
<target>SimpleX protokolleri Trail of Bits tarafından incelenmiştir.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Simplified incognito mode" xml:space="preserve">
@@ -6653,12 +6642,10 @@ Enable in *Network &amp; servers* settings.</source>
</trans-unit>
<trans-unit id="Switch audio and video during the call." xml:space="preserve">
<source>Switch audio and video during the call.</source>
<target>Görüşme sırasında ses ve görüntüyü değiştirin.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Switch chat profile for 1-time invitations." xml:space="preserve">
<source>Switch chat profile for 1-time invitations.</source>
<target>Sohbet profilini 1 kerelik davetler için değiştirin.</target>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="System" xml:space="preserve">
+30 -30
View File
@@ -144,6 +144,11 @@
5CFE0922282EEAF60002594B /* ZoomableScrollView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CFE0920282EEAF60002594B /* ZoomableScrollView.swift */; };
640417CD2B29B8C200CCB412 /* NewChatMenuButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 640417CB2B29B8C200CCB412 /* NewChatMenuButton.swift */; };
640417CE2B29B8C200CCB412 /* NewChatView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 640417CC2B29B8C200CCB412 /* NewChatView.swift */; };
640548A32CB56735005DE1E4 /* libgmpxx.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6405489E2CB56735005DE1E4 /* libgmpxx.a */; };
640548A42CB56735005DE1E4 /* libgmp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6405489F2CB56735005DE1E4 /* libgmp.a */; };
640548A52CB56735005DE1E4 /* libffi.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 640548A02CB56735005DE1E4 /* libffi.a */; };
640548A62CB56735005DE1E4 /* libHSsimplex-chat-6.1.0.7-EtclnBf7vnkLnhnDA1lixv-ghc9.6.3.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 640548A12CB56735005DE1E4 /* libHSsimplex-chat-6.1.0.7-EtclnBf7vnkLnhnDA1lixv-ghc9.6.3.a */; };
640548A72CB56735005DE1E4 /* libHSsimplex-chat-6.1.0.7-EtclnBf7vnkLnhnDA1lixv.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 640548A22CB56735005DE1E4 /* libHSsimplex-chat-6.1.0.7-EtclnBf7vnkLnhnDA1lixv.a */; };
6407BA83295DA85D0082BA18 /* CIInvalidJSONView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6407BA82295DA85D0082BA18 /* CIInvalidJSONView.swift */; };
6419EC562AB8BC8B004A607A /* ContextInvitingContactMemberView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6419EC552AB8BC8B004A607A /* ContextInvitingContactMemberView.swift */; };
6419EC582AB97507004A607A /* CIMemberCreatedContactView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6419EC572AB97507004A607A /* CIMemberCreatedContactView.swift */; };
@@ -223,11 +228,6 @@
E5DCF9712C590272007928CC /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = E5DCF96F2C590272007928CC /* Localizable.strings */; };
E5DCF9842C5902CE007928CC /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = E5DCF9822C5902CE007928CC /* Localizable.strings */; };
E5DCF9982C5906FF007928CC /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = E5DCF9962C5906FF007928CC /* InfoPlist.strings */; };
E5E997C92CBA891A00D7A2FA /* libgmpxx.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E5E997C42CBA891A00D7A2FA /* libgmpxx.a */; };
E5E997CA2CBA891A00D7A2FA /* libgmp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E5E997C52CBA891A00D7A2FA /* libgmp.a */; };
E5E997CB2CBA891A00D7A2FA /* libHSsimplex-chat-6.1.0.9-3X73OucN19a19eYgUK66sv-ghc9.6.3.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E5E997C62CBA891A00D7A2FA /* libHSsimplex-chat-6.1.0.9-3X73OucN19a19eYgUK66sv-ghc9.6.3.a */; };
E5E997CC2CBA891A00D7A2FA /* libffi.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E5E997C72CBA891A00D7A2FA /* libffi.a */; };
E5E997CD2CBA891A00D7A2FA /* libHSsimplex-chat-6.1.0.9-3X73OucN19a19eYgUK66sv.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E5E997C82CBA891A00D7A2FA /* libHSsimplex-chat-6.1.0.9-3X73OucN19a19eYgUK66sv.a */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
@@ -486,6 +486,11 @@
5CFE0920282EEAF60002594B /* ZoomableScrollView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = ZoomableScrollView.swift; path = Shared/Views/ZoomableScrollView.swift; sourceTree = SOURCE_ROOT; };
640417CB2B29B8C200CCB412 /* NewChatMenuButton.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NewChatMenuButton.swift; sourceTree = "<group>"; };
640417CC2B29B8C200CCB412 /* NewChatView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NewChatView.swift; sourceTree = "<group>"; };
6405489E2CB56735005DE1E4 /* libgmpxx.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libgmpxx.a; sourceTree = "<group>"; };
6405489F2CB56735005DE1E4 /* libgmp.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libgmp.a; sourceTree = "<group>"; };
640548A02CB56735005DE1E4 /* libffi.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libffi.a; sourceTree = "<group>"; };
640548A12CB56735005DE1E4 /* libHSsimplex-chat-6.1.0.7-EtclnBf7vnkLnhnDA1lixv-ghc9.6.3.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libHSsimplex-chat-6.1.0.7-EtclnBf7vnkLnhnDA1lixv-ghc9.6.3.a"; sourceTree = "<group>"; };
640548A22CB56735005DE1E4 /* libHSsimplex-chat-6.1.0.7-EtclnBf7vnkLnhnDA1lixv.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libHSsimplex-chat-6.1.0.7-EtclnBf7vnkLnhnDA1lixv.a"; sourceTree = "<group>"; };
6407BA82295DA85D0082BA18 /* CIInvalidJSONView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CIInvalidJSONView.swift; sourceTree = "<group>"; };
6419EC552AB8BC8B004A607A /* ContextInvitingContactMemberView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContextInvitingContactMemberView.swift; sourceTree = "<group>"; };
6419EC572AB97507004A607A /* CIMemberCreatedContactView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CIMemberCreatedContactView.swift; sourceTree = "<group>"; };
@@ -612,11 +617,6 @@
E5DCF9A62C590731007928CC /* th */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = th; path = th.lproj/InfoPlist.strings; sourceTree = "<group>"; };
E5DCF9A72C590732007928CC /* tr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = tr; path = tr.lproj/InfoPlist.strings; sourceTree = "<group>"; };
E5DCF9A82C590732007928CC /* uk */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = uk; path = uk.lproj/InfoPlist.strings; sourceTree = "<group>"; };
E5E997C42CBA891A00D7A2FA /* libgmpxx.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libgmpxx.a; sourceTree = "<group>"; };
E5E997C52CBA891A00D7A2FA /* libgmp.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libgmp.a; sourceTree = "<group>"; };
E5E997C62CBA891A00D7A2FA /* libHSsimplex-chat-6.1.0.9-3X73OucN19a19eYgUK66sv-ghc9.6.3.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libHSsimplex-chat-6.1.0.9-3X73OucN19a19eYgUK66sv-ghc9.6.3.a"; sourceTree = "<group>"; };
E5E997C72CBA891A00D7A2FA /* libffi.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libffi.a; sourceTree = "<group>"; };
E5E997C82CBA891A00D7A2FA /* libHSsimplex-chat-6.1.0.9-3X73OucN19a19eYgUK66sv.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libHSsimplex-chat-6.1.0.9-3X73OucN19a19eYgUK66sv.a"; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@@ -655,14 +655,14 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
E5E997C92CBA891A00D7A2FA /* libgmpxx.a in Frameworks */,
E5E997CB2CBA891A00D7A2FA /* libHSsimplex-chat-6.1.0.9-3X73OucN19a19eYgUK66sv-ghc9.6.3.a in Frameworks */,
E5E997CA2CBA891A00D7A2FA /* libgmp.a in Frameworks */,
640548A32CB56735005DE1E4 /* libgmpxx.a in Frameworks */,
640548A72CB56735005DE1E4 /* libHSsimplex-chat-6.1.0.7-EtclnBf7vnkLnhnDA1lixv.a in Frameworks */,
640548A52CB56735005DE1E4 /* libffi.a in Frameworks */,
640548A42CB56735005DE1E4 /* libgmp.a in Frameworks */,
5CE2BA93284534B000EC33A6 /* libiconv.tbd in Frameworks */,
E5E997CC2CBA891A00D7A2FA /* libffi.a in Frameworks */,
640548A62CB56735005DE1E4 /* libHSsimplex-chat-6.1.0.7-EtclnBf7vnkLnhnDA1lixv-ghc9.6.3.a in Frameworks */,
5CE2BA94284534BB00EC33A6 /* libz.tbd in Frameworks */,
CE38A29C2C3FCD72005ED185 /* SwiftyGif in Frameworks */,
E5E997CD2CBA891A00D7A2FA /* libHSsimplex-chat-6.1.0.9-3X73OucN19a19eYgUK66sv.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -739,11 +739,11 @@
5C764E5C279C70B7000C6508 /* Libraries */ = {
isa = PBXGroup;
children = (
E5E997C72CBA891A00D7A2FA /* libffi.a */,
E5E997C52CBA891A00D7A2FA /* libgmp.a */,
E5E997C42CBA891A00D7A2FA /* libgmpxx.a */,
E5E997C62CBA891A00D7A2FA /* libHSsimplex-chat-6.1.0.9-3X73OucN19a19eYgUK66sv-ghc9.6.3.a */,
E5E997C82CBA891A00D7A2FA /* libHSsimplex-chat-6.1.0.9-3X73OucN19a19eYgUK66sv.a */,
640548A02CB56735005DE1E4 /* libffi.a */,
6405489F2CB56735005DE1E4 /* libgmp.a */,
6405489E2CB56735005DE1E4 /* libgmpxx.a */,
640548A12CB56735005DE1E4 /* libHSsimplex-chat-6.1.0.7-EtclnBf7vnkLnhnDA1lixv-ghc9.6.3.a */,
640548A22CB56735005DE1E4 /* libHSsimplex-chat-6.1.0.7-EtclnBf7vnkLnhnDA1lixv.a */,
);
path = Libraries;
sourceTree = "<group>";
@@ -1899,7 +1899,7 @@
CLANG_TIDY_MISC_REDUNDANT_EXPRESSION = YES;
CODE_SIGN_ENTITLEMENTS = "SimpleX (iOS).entitlements";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 244;
CURRENT_PROJECT_VERSION = 242;
DEAD_CODE_STRIPPING = YES;
DEVELOPMENT_TEAM = 5NN7GUYB6T;
ENABLE_BITCODE = NO;
@@ -1948,7 +1948,7 @@
CLANG_TIDY_MISC_REDUNDANT_EXPRESSION = YES;
CODE_SIGN_ENTITLEMENTS = "SimpleX (iOS).entitlements";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 244;
CURRENT_PROJECT_VERSION = 242;
DEAD_CODE_STRIPPING = YES;
DEVELOPMENT_TEAM = 5NN7GUYB6T;
ENABLE_BITCODE = NO;
@@ -1989,7 +1989,7 @@
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 244;
CURRENT_PROJECT_VERSION = 242;
DEVELOPMENT_TEAM = 5NN7GUYB6T;
GENERATE_INFOPLIST_FILE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
@@ -2009,7 +2009,7 @@
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 244;
CURRENT_PROJECT_VERSION = 242;
DEVELOPMENT_TEAM = 5NN7GUYB6T;
GENERATE_INFOPLIST_FILE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
@@ -2034,7 +2034,7 @@
CODE_SIGN_ENTITLEMENTS = "SimpleX NSE/SimpleX NSE.entitlements";
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 244;
CURRENT_PROJECT_VERSION = 242;
DEVELOPMENT_TEAM = 5NN7GUYB6T;
ENABLE_BITCODE = NO;
GCC_OPTIMIZATION_LEVEL = s;
@@ -2071,7 +2071,7 @@
CODE_SIGN_ENTITLEMENTS = "SimpleX NSE/SimpleX NSE.entitlements";
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 244;
CURRENT_PROJECT_VERSION = 242;
DEVELOPMENT_TEAM = 5NN7GUYB6T;
ENABLE_BITCODE = NO;
ENABLE_CODE_COVERAGE = NO;
@@ -2108,7 +2108,7 @@
CLANG_TIDY_BUGPRONE_REDUNDANT_BRANCH_CONDITION = YES;
CLANG_TIDY_MISC_REDUNDANT_EXPRESSION = YES;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 244;
CURRENT_PROJECT_VERSION = 242;
DEFINES_MODULE = YES;
DEVELOPMENT_TEAM = 5NN7GUYB6T;
DYLIB_COMPATIBILITY_VERSION = 1;
@@ -2159,7 +2159,7 @@
CLANG_TIDY_BUGPRONE_REDUNDANT_BRANCH_CONDITION = YES;
CLANG_TIDY_MISC_REDUNDANT_EXPRESSION = YES;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 244;
CURRENT_PROJECT_VERSION = 242;
DEFINES_MODULE = YES;
DEVELOPMENT_TEAM = 5NN7GUYB6T;
DYLIB_COMPATIBILITY_VERSION = 1;
@@ -2210,7 +2210,7 @@
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
CODE_SIGN_ENTITLEMENTS = "SimpleX SE/SimpleX SE.entitlements";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 244;
CURRENT_PROJECT_VERSION = 242;
DEVELOPMENT_TEAM = 5NN7GUYB6T;
ENABLE_USER_SCRIPT_SANDBOXING = YES;
GCC_C_LANGUAGE_STANDARD = gnu17;
@@ -2244,7 +2244,7 @@
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
CODE_SIGN_ENTITLEMENTS = "SimpleX SE/SimpleX SE.entitlements";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 244;
CURRENT_PROJECT_VERSION = 242;
DEVELOPMENT_TEAM = 5NN7GUYB6T;
ENABLE_USER_SCRIPT_SANDBOXING = YES;
GCC_C_LANGUAGE_STANDARD = gnu17;
+1 -1
View File
@@ -2041,7 +2041,7 @@ public enum SQLiteError: Decodable, Hashable {
}
public enum AgentErrorType: Decodable, Hashable {
case CMD(cmdErr: CommandErrorType, errContext: String)
case CMD(cmdErr: CommandErrorType)
case CONN(connErr: ConnectionErrorType)
case SMP(serverAddress: String, smpErr: ProtocolErrorType)
case NTF(ntfErr: ProtocolErrorType)
+1 -1
View File
@@ -85,7 +85,7 @@ public func registerGroupDefaults() {
GROUP_DEFAULT_INITIAL_RANDOM_DB_PASSPHRASE: false,
GROUP_DEFAULT_APP_LOCAL_AUTH_ENABLED: true,
GROUP_DEFAULT_ALLOW_SHARE_EXTENSION: false,
GROUP_DEFAULT_PRIVACY_LINK_PREVIEWS: true,
GROUP_DEFAULT_PRIVACY_LINK_PREVIEWS: false,
GROUP_DEFAULT_PRIVACY_ACCEPT_IMAGES: true,
GROUP_DEFAULT_PRIVACY_TRANSFER_IMAGES_INLINE: false,
GROUP_DEFAULT_PRIVACY_ENCRYPT_LOCAL_FILES: true,
-2
View File
@@ -1852,7 +1852,6 @@ public struct PendingContactConnection: Decodable, NamedChat, Hashable {
public enum ConnStatus: String, Decodable, Hashable {
case new = "new"
case prepared = "prepared"
case joined = "joined"
case requested = "requested"
case accepted = "accepted"
@@ -1864,7 +1863,6 @@ public enum ConnStatus: String, Decodable, Hashable {
get {
switch self {
case .new: return true
case .prepared: return false
case .joined: return false
case .requested: return true
case .accepted: return true
-36
View File
@@ -694,30 +694,15 @@
/* No comment provided by engineer. */
"Bad message ID" = "Falsche Nachrichten-ID";
/* No comment provided by engineer. */
"Better calls" = "Verbesserte Anrufe";
/* No comment provided by engineer. */
"Better groups" = "Bessere Gruppen";
/* No comment provided by engineer. */
"Better message dates." = "Verbesserte Nachrichten-Datumsinformation";
/* No comment provided by engineer. */
"Better messages" = "Verbesserungen bei Nachrichten";
/* No comment provided by engineer. */
"Better networking" = "Kontrollieren Sie Ihr Netzwerk";
/* No comment provided by engineer. */
"Better notifications" = "Verbesserte Benachrichtigungen";
/* No comment provided by engineer. */
"Better security ✅" = "Verbesserte Sicherheit ✅";
/* No comment provided by engineer. */
"Better user experience" = "Verbesserte Nutzer-Erfahrung";
/* No comment provided by engineer. */
"Black" = "Schwarz";
@@ -1307,9 +1292,6 @@
/* No comment provided by engineer. */
"Custom time" = "Zeit anpassen";
/* No comment provided by engineer. */
"Customizable message shape." = "Anpassbares Format des Nachrichtenfelds";
/* No comment provided by engineer. */
"Customize theme" = "Design anpassen";
@@ -1500,9 +1482,6 @@
/* No comment provided by engineer. */
"Delete old database?" = "Alte Datenbank löschen?";
/* No comment provided by engineer. */
"Delete or moderate up to 200 messages." = "Bis zu 200 Nachrichten löschen oder moderieren";
/* No comment provided by engineer. */
"Delete pending connection?" = "Ausstehende Verbindung löschen?";
@@ -2251,9 +2230,6 @@
/* alert message */
"Forward messages without files?" = "Nachrichten ohne Dateien weiterleiten?";
/* No comment provided by engineer. */
"Forward up to 20 messages at once." = "Bis zu 20 Nachrichten auf einmal weiterleiten";
/* No comment provided by engineer. */
"forwarded" = "weitergeleitet";
@@ -2494,9 +2470,6 @@
/* No comment provided by engineer. */
"Importing archive" = "Archiv wird importiert";
/* No comment provided by engineer. */
"Improved delivery, reduced traffic usage.\nMore improvements are coming soon!" = "Verbesserte Nachrichten-Auslieferung und verringerter Datenverbrauch.\nWeitere Verbesserungen sind bald verfügbar!";
/* No comment provided by engineer. */
"Improved message delivery" = "Verbesserte Zustellung von Nachrichten";
@@ -4298,9 +4271,6 @@
/* simplex link type */
"SimpleX one-time invitation" = "SimpleX-Einmal-Einladung";
/* No comment provided by engineer. */
"SimpleX protocols reviewed by Trail of Bits." = "Die SimpleX-Protokolle wurden von Trail of Bits überprüft.";
/* No comment provided by engineer. */
"Simplified incognito mode" = "Vereinfachter Inkognito-Modus";
@@ -4421,12 +4391,6 @@
/* No comment provided by engineer. */
"Support SimpleX Chat" = "Unterstützung von SimpleX Chat";
/* No comment provided by engineer. */
"Switch audio and video during the call." = "Während des Anrufs zwischen Audio und Video wechseln";
/* No comment provided by engineer. */
"Switch chat profile for 1-time invitations." = "Das Chat-Profil für Einmal-Einladungen wechseln";
/* No comment provided by engineer. */
"System" = "System";
-36
View File
@@ -694,30 +694,15 @@
/* No comment provided by engineer. */
"Bad message ID" = "ID de mensaje incorrecto";
/* No comment provided by engineer. */
"Better calls" = "Llamadas mejoradas";
/* No comment provided by engineer. */
"Better groups" = "Grupos mejorados";
/* No comment provided by engineer. */
"Better message dates." = "Sistema de fechas mejorado.";
/* No comment provided by engineer. */
"Better messages" = "Mensajes mejorados";
/* No comment provided by engineer. */
"Better networking" = "Uso de red mejorado";
/* No comment provided by engineer. */
"Better notifications" = "Notificaciones mejoradas";
/* No comment provided by engineer. */
"Better security ✅" = "Seguridad mejorada ✅";
/* No comment provided by engineer. */
"Better user experience" = "Experiencia de usuario mejorada";
/* No comment provided by engineer. */
"Black" = "Negro";
@@ -1307,9 +1292,6 @@
/* No comment provided by engineer. */
"Custom time" = "Tiempo personalizado";
/* No comment provided by engineer. */
"Customizable message shape." = "Forma personalizable de los mensajes.";
/* No comment provided by engineer. */
"Customize theme" = "Personalizar tema";
@@ -1500,9 +1482,6 @@
/* No comment provided by engineer. */
"Delete old database?" = "¿Eliminar base de datos antigua?";
/* No comment provided by engineer. */
"Delete or moderate up to 200 messages." = "Borra o modera hasta 200 mensajes a la vez.";
/* No comment provided by engineer. */
"Delete pending connection?" = "¿Eliminar conexión pendiente?";
@@ -2251,9 +2230,6 @@
/* alert message */
"Forward messages without files?" = "¿Reenviar mensajes sin los archivos?";
/* No comment provided by engineer. */
"Forward up to 20 messages at once." = "Desplazamiento de hasta 20 mensajes.";
/* No comment provided by engineer. */
"forwarded" = "reenviado";
@@ -2494,9 +2470,6 @@
/* No comment provided by engineer. */
"Importing archive" = "Importando archivo";
/* No comment provided by engineer. */
"Improved delivery, reduced traffic usage.\nMore improvements are coming soon!" = "Reducción del tráfico y entrega mejorada.\n¡Pronto habrá nuevas mejoras!";
/* No comment provided by engineer. */
"Improved message delivery" = "Entrega de mensajes mejorada";
@@ -4298,9 +4271,6 @@
/* simplex link type */
"SimpleX one-time invitation" = "Invitación SimpleX de un uso";
/* No comment provided by engineer. */
"SimpleX protocols reviewed by Trail of Bits." = "Protocolos de SimpleX auditados por Trail of Bits.";
/* No comment provided by engineer. */
"Simplified incognito mode" = "Modo incógnito simplificado";
@@ -4421,12 +4391,6 @@
/* No comment provided by engineer. */
"Support SimpleX Chat" = "Soporte SimpleX Chat";
/* No comment provided by engineer. */
"Switch audio and video during the call." = "Intercambia audio y video durante la llamada.";
/* No comment provided by engineer. */
"Switch chat profile for 1-time invitations." = "Cambia el perfil de chat para invitaciones de un solo uso.";
/* No comment provided by engineer. */
"System" = "Sistema";
+34 -70
View File
@@ -479,7 +479,7 @@
"All your contacts will remain connected." = "Minden ismerősével kapcsolatban marad.";
/* No comment provided by engineer. */
"All your contacts will remain connected. Profile update will be sent to your contacts." = "Az ismerőseivel kapcsolatban marad. A profil-változtatások frissítésre kerülnek az ismerősöknél.";
"All your contacts will remain connected. Profile update will be sent to your contacts." = "Az ismerőseivel kapcsolatban marad. A profil változtatások frissítésre kerülnek az ismerősöknél.";
/* No comment provided by engineer. */
"All your contacts, conversations and files will be securely encrypted and uploaded in chunks to configured XFTP relays." = "Minden ismerőse, a beszélgetései és a fájljai biztonságosan titkosításra kerülnek, melyek részletekben feltöltődnek a beállított XFTP-közvetítő-kiszolgálóra.";
@@ -694,30 +694,15 @@
/* No comment provided by engineer. */
"Bad message ID" = "Téves üzenet ID";
/* No comment provided by engineer. */
"Better calls" = "Továbbfejlesztett hívásélmény";
/* No comment provided by engineer. */
"Better groups" = "Javított csoportok";
/* No comment provided by engineer. */
"Better message dates." = "Továbbfejlesztett üzenetdátumok.";
/* No comment provided by engineer. */
"Better messages" = "Jobb üzenetek";
/* No comment provided by engineer. */
"Better networking" = "Jobb hálózatkezelés";
/* No comment provided by engineer. */
"Better notifications" = "Továbbfejlesztett értesítések";
/* No comment provided by engineer. */
"Better security ✅" = "Továbbfejlesztett biztonság ✅";
/* No comment provided by engineer. */
"Better user experience" = "Továbbfejlesztett felhasználói élmény";
/* No comment provided by engineer. */
"Black" = "Fekete";
@@ -933,7 +918,7 @@
"Chat preferences were changed." = "A csevegési beállítások megváltoztak.";
/* No comment provided by engineer. */
"Chat profile" = "Csevegési profil";
"Chat profile" = "Felhasználói profil";
/* No comment provided by engineer. */
"Chat theme" = "Csevegés témája";
@@ -948,7 +933,7 @@
"Chinese and Spanish interface" = "Kínai és spanyol kezelőfelület";
/* No comment provided by engineer. */
"Choose _Migrate from another device_ on the new device and scan QR code." = "Válassza az _Átköltöztetés egy másik eszközről_ opciót az új eszközén és olvassa be a QR-kódot.";
"Choose _Migrate from another device_ on the new device and scan QR code." = "Válassza az _Átköltöztetés egy másik eszközről opciót az új eszközén és olvassa be a QR-kódot.";
/* No comment provided by engineer. */
"Choose file" = "Fájl kiválasztása";
@@ -1155,7 +1140,7 @@
"Connection terminated" = "Kapcsolat megszakítva";
/* No comment provided by engineer. */
"Connection timeout" = "Időtúllépés kapcsolódáskor";
"Connection timeout" = "Kapcsolat időtúllépés";
/* No comment provided by engineer. */
"Connection with desktop stopped" = "A kapcsolat a számítógéppel megszakadt";
@@ -1307,9 +1292,6 @@
/* No comment provided by engineer. */
"Custom time" = "Személyreszabott idő";
/* No comment provided by engineer. */
"Customizable message shape." = "Testreszabható üzenetbuborékok.";
/* No comment provided by engineer. */
"Customize theme" = "Téma személyre szabása";
@@ -1341,7 +1323,7 @@
"Database ID: %d" = "Adatbázis-azonosító: %d";
/* No comment provided by engineer. */
"Database IDs and Transport isolation option." = "Adatbázis-azonosítók és átvitel-izolációs beállítások.";
"Database IDs and Transport isolation option." = "Adatbázis-azonosítók és átviteli izolációs beállítások.";
/* No comment provided by engineer. */
"Database is encrypted using a random passphrase, you can change it." = "Az adatbázis egy véletlenszerű jelmondattal van titkosítva, ami megváltoztatható.";
@@ -1500,9 +1482,6 @@
/* No comment provided by engineer. */
"Delete old database?" = "Régi adatbázis törlése?";
/* No comment provided by engineer. */
"Delete or moderate up to 200 messages." = "Legfeljebb 200 üzenet egyszerre való törlése, vagy moderálása.";
/* No comment provided by engineer. */
"Delete pending connection?" = "Függőben lévő ismerőskérelem törlése?";
@@ -1576,7 +1555,7 @@
"Detailed statistics" = "Részletes statisztikák";
/* No comment provided by engineer. */
"Details" = "További részletek";
"Details" = "Részletek";
/* No comment provided by engineer. */
"Develop" = "Fejlesztés";
@@ -1600,7 +1579,7 @@
"different migration in the app/database: %@ / %@" = "különböző átköltöztetések az alkalmazásban/adatbázisban: %@ / %@";
/* No comment provided by engineer. */
"Different names, avatars and transport isolation." = "Különböző nevek, profilképek és átvitel-izoláció.";
"Different names, avatars and transport isolation." = "Különböző nevek, avatarok és átviteli izoláció.";
/* connection level description */
"direct" = "közvetlen";
@@ -1973,7 +1952,7 @@
"Error deleting token" = "Hiba a token törlésekor";
/* No comment provided by engineer. */
"Error deleting user profile" = "Hiba a felhasználó-profil törlésekor";
"Error deleting user profile" = "Hiba a felhasználói profil törlésekor";
/* No comment provided by engineer. */
"Error downloading the archive" = "Hiba az archívum letöltésekor";
@@ -2042,7 +2021,7 @@
"Error saving settings" = "Hiba a beállítások mentésekor";
/* No comment provided by engineer. */
"Error saving user password" = "Hiba a felhasználói jelszó mentésekor";
"Error saving user password" = "Hiba a felhasználó jelszavának mentésekor";
/* No comment provided by engineer. */
"Error scanning code: %@" = "Hiba a kód beolvasásakor: %@";
@@ -2084,7 +2063,7 @@
"Error updating settings" = "Hiba történt a beállítások frissítésekor";
/* No comment provided by engineer. */
"Error updating user privacy" = "Hiba a felhasználói adatvédelem frissítésekor";
"Error updating user privacy" = "Hiba a felhasználói beállítások frissítésekor";
/* No comment provided by engineer. */
"Error uploading the archive" = "Hiba az archívum feltöltésekor";
@@ -2251,9 +2230,6 @@
/* alert message */
"Forward messages without files?" = "Üzenetek továbbítása fájlok nélkül?";
/* No comment provided by engineer. */
"Forward up to 20 messages at once." = "Legfeljebb 20 üzenet egyszerre való továbbítása.";
/* No comment provided by engineer. */
"forwarded" = "továbbított";
@@ -2408,7 +2384,7 @@
"Hidden profile password" = "Rejtett profiljelszó";
/* chat item action */
"Hide" = "Összecsukás";
"Hide" = "Elrejtés";
/* No comment provided by engineer. */
"Hide app screen in the recent apps." = "Alkalmazás képernyőjének elrejtése a gyakran használt alkalmazások között.";
@@ -2459,7 +2435,7 @@
"If you enter your self-destruct passcode while opening the app:" = "Ha az alkalmazás megnyitásakor megadja az önmegsemmisítő jelkódot:";
/* No comment provided by engineer. */
"If you need to use the chat now tap **Do it later** below (you will be offered to migrate the database when you restart the app)." = "Ha most kell használnia a csevegést, koppintson alább a **Befejezés később** lehetőségre (az alkalmazás újraindításakor felajánlásra kerül az adatbázis átköltöztetése).";
"If you need to use the chat now tap **Do it later** below (you will be offered to migrate the database when you restart the app)." = "Ha most kell használnia a csevegést, koppintson alább az **Befejezés később** lehetőségre (az alkalmazás újraindításakor felajánlásra kerül az adatbázis átköltöztetése).";
/* No comment provided by engineer. */
"Ignore" = "Mellőzés";
@@ -2494,9 +2470,6 @@
/* No comment provided by engineer. */
"Importing archive" = "Archívum importálása";
/* No comment provided by engineer. */
"Improved delivery, reduced traffic usage.\nMore improvements are coming soon!" = "Továbbfejlesztett kézbesítés, csökkentett adatforgalom-használat.\nTovábbi fejlesztések hamarosan!";
/* No comment provided by engineer. */
"Improved message delivery" = "Továbbfejlesztett üzenetkézbesítés";
@@ -2816,7 +2789,7 @@
"Make sure WebRTC ICE server addresses are in correct format, line separated and are not duplicated." = "Győződjön meg arról, hogy a WebRTC ICE-kiszolgáló címei megfelelő formátumúak, sorszeparáltak és nincsenek duplikálva.";
/* No comment provided by engineer. */
"Many people asked: *if SimpleX has no user identifiers, how can it deliver messages?*" = "Sokan kérdezték: *ha a SimpleX Chatnek nincsenek felhasználó-azonosítói, akkor hogyan tud üzeneteket kézbesíteni?*";
"Many people asked: *if SimpleX has no user identifiers, how can it deliver messages?*" = "Sokan kérdezték: *ha a SimpleX Chatnek nincsenek felhasználói azonosítói, akkor hogyan tud üzeneteket kézbesíteni?*";
/* No comment provided by engineer. */
"Mark deleted for everyone" = "Jelölje meg mindenki számára töröltként";
@@ -3226,7 +3199,7 @@
"Onion hosts will not be used." = "Onion-kiszolgálók nem lesznek használva.";
/* No comment provided by engineer. */
"Only client devices store user profiles, contacts, groups, and messages sent with **2-layer end-to-end encryption**." = "Csak az eszközök alkalmazásai tárolják a felhasználó-profilokat, névjegyeket, csoportokat és a **2 rétegű végpontok közötti titkosítással** küldött üzeneteket.";
"Only client devices store user profiles, contacts, groups, and messages sent with **2-layer end-to-end encryption**." = "Csak az eszközök alkalmazásai tárolják a felhasználói profilokat, névjegyeket, csoportokat és a **2 rétegű végpontok közötti titkosítással** küldött üzeneteket.";
/* No comment provided by engineer. */
"Only delete conversation" = "Csak a beszélgetés törlése";
@@ -3292,7 +3265,7 @@
"Open Settings" = "Beállítások megnyitása";
/* authentication reason */
"Open user profiles" = "Felhasználó-profilok megnyitása";
"Open user profiles" = "Felhasználói profilok megnyitása";
/* No comment provided by engineer. */
"Open-source protocol and code anybody can run the servers." = "Nyílt forráskódú protokoll és forráskód bárki üzemeltethet kiszolgálókat.";
@@ -3388,10 +3361,10 @@
"Picture-in-picture calls" = "Kép a képben hívások";
/* No comment provided by engineer. */
"PING count" = "PING-ek száma";
"PING count" = "PING számláló";
/* No comment provided by engineer. */
"PING interval" = "Időtartam a PING-ek között";
"PING interval" = "PING időköze";
/* No comment provided by engineer. */
"Play from the chat list." = "Lejátszás a csevegési listából.";
@@ -3550,10 +3523,10 @@
"Protect your IP address from the messaging relays chosen by your contacts.\nEnable in *Network & servers* settings." = "Védje IP-címét az ismerősei által kiválasztott üzenet-közvetítő-kiszolgálókkal szemben.\nEngedélyezze a „Beállítások -> Hálózat és kiszolgálók” menüben.";
/* No comment provided by engineer. */
"Protocol timeout" = "Protokoll időtúllépése";
"Protocol timeout" = "Protokoll időtúllépés";
/* No comment provided by engineer. */
"Protocol timeout per KB" = "Protokoll időtúllépése KB-onként";
"Protocol timeout per KB" = "Protokoll időkorlát KB-onként";
/* No comment provided by engineer. */
"Proxied" = "Proxyzott";
@@ -3637,7 +3610,7 @@
"Received reply" = "Fogadott válaszüzenet-buborék színe";
/* No comment provided by engineer. */
"Received total" = "Összes fogadott üzenet";
"Received total" = "Összes fogadott";
/* No comment provided by engineer. */
"Receiving address will be changed to a different server. Address change will complete after sender comes online." = "A fogadó cím egy másik kiszolgálóra változik. A címváltoztatás a feladó online állapotba kerülése után fejeződik be.";
@@ -3873,7 +3846,7 @@
"Save preferences?" = "Beállítások mentése?";
/* No comment provided by engineer. */
"Save profile password" = "Profiljelszó mentése";
"Save profile password" = "Felhasználói fiók jelszavának mentése";
/* No comment provided by engineer. */
"Save servers" = "Kiszolgálók mentése";
@@ -4101,7 +4074,7 @@
"Sent reply" = "Válaszüzenet-buborék színe";
/* No comment provided by engineer. */
"Sent total" = "Összes elküldött üzenet";
"Sent total" = "Összes elküldött";
/* No comment provided by engineer. */
"Sent via proxy" = "Proxyn keresztül küldve";
@@ -4239,7 +4212,7 @@
"Show last messages" = "Szobák utolsó üzeneteinek megjelenítése a listanézetben";
/* No comment provided by engineer. */
"Show message status" = "Üzenetállapot megjelenítése";
"Show message status" = "Üzenet állapot megjelenítése";
/* No comment provided by engineer. */
"Show percentage" = "Százalék megjelenítése";
@@ -4298,9 +4271,6 @@
/* simplex link type */
"SimpleX one-time invitation" = "Egyszer használható SimpleX-meghívó";
/* No comment provided by engineer. */
"SimpleX protocols reviewed by Trail of Bits." = "A SimpleX Chat biztonsága a Trail of Bits által lett újraauditálva.";
/* No comment provided by engineer. */
"Simplified incognito mode" = "Egyszerűsített inkognitómód";
@@ -4421,12 +4391,6 @@
/* No comment provided by engineer. */
"Support SimpleX Chat" = "SimpleX Chat támogatása";
/* No comment provided by engineer. */
"Switch audio and video during the call." = "Hang/Videó váltása hívás közben.";
/* No comment provided by engineer. */
"Switch chat profile for 1-time invitations." = "Csevegési profilváltás az egyszer használható meghívókhoz.";
/* No comment provided by engineer. */
"System" = "Rendszer";
@@ -4446,25 +4410,25 @@
"Tap to activate profile." = "A profil aktiválásához koppintson az ikonra.";
/* No comment provided by engineer. */
"Tap to Connect" = "Koppintson ide a kapcsolódáshoz";
"Tap to Connect" = "Koppintson a kapcsolódáshoz";
/* No comment provided by engineer. */
"Tap to join" = "Koppintson ide a csatlakozáshoz";
"Tap to join" = "Koppintson a csatlakozáshoz";
/* No comment provided by engineer. */
"Tap to join incognito" = "Koppintson ide az inkognitóban való csatlakozáshoz";
"Tap to join incognito" = "Koppintson az inkognitóban való csatlakozáshoz";
/* No comment provided by engineer. */
"Tap to paste link" = "Koppintson ide a hivatkozás beillesztéséhez";
/* No comment provided by engineer. */
"Tap to scan" = "Koppintson ide a QR-kód beolvasáshoz";
"Tap to scan" = "Koppintson a beolvasáshoz";
/* No comment provided by engineer. */
"TCP connection" = "TCP kapcsolat";
/* No comment provided by engineer. */
"TCP connection timeout" = "TCP kapcsolat időtúllépése";
"TCP connection timeout" = "TCP kapcsolat időtúllépés";
/* No comment provided by engineer. */
"TCP_KEEPCNT" = "TCP_KEEPCNT";
@@ -4500,7 +4464,7 @@
"Thanks to the users contribute via Weblate!" = "Köszönet a felhasználóknak - hozzájárulás a Weblate-en!";
/* No comment provided by engineer. */
"The 1st platform without any user identifiers private by design." = "Az első csevegési rendszer bármiféle felhasználó-azonosító nélkül - privátra lett tervezre.";
"The 1st platform without any user identifiers private by design." = "Az első csevegési rendszer bármiféle felhasználó azonosító nélkül - privátra lett tervezre.";
/* No comment provided by engineer. */
"The app can notify you when you receive messages or contact requests - please open settings to enable." = "Az alkalmazás értesíteni fogja, amikor üzeneteket vagy kapcsolatkéréseket kap beállítások megnyitása az engedélyezéshez.";
@@ -4635,7 +4599,7 @@
"To make a new connection" = "Új kapcsolat létrehozásához";
/* No comment provided by engineer. */
"To protect privacy, instead of user IDs used by all other platforms, SimpleX has identifiers for message queues, separate for each of your contacts." = "Az adatvédelem érdekében, a más csevegési platformokon megszokott felhasználó-azonosítók helyett, a SimpleX csak az üzenetek sorbaállításához használ azonosítókat, minden egyes ismerőshöz egy-egy különbözőt.";
"To protect privacy, instead of user IDs used by all other platforms, SimpleX has identifiers for message queues, separate for each of your contacts." = "Az adatvédelem érdekében, a más csevegési platformokon megszokott felhasználói azonosítók helyett, a SimpleX csak az üzenetek sorbaállításához használ azonosítókat, minden egyes ismerőshöz egy-egy különbözőt.";
/* No comment provided by engineer. */
"To protect timezone, image/voice files use UTC." = "Az időzóna védelme érdekében a kép-/hangfájlok UTC-t használnak.";
@@ -4674,10 +4638,10 @@
"Toolbar opacity" = "Eszköztár átlátszatlansága";
/* No comment provided by engineer. */
"Total" = "Összes kapcsolat";
"Total" = "Összesen";
/* No comment provided by engineer. */
"Transport isolation" = "Átvitel-izoláció módja";
"Transport isolation" = "Kapcsolat izolációs mód";
/* No comment provided by engineer. */
"Transport sessions" = "Munkamenetek átvitele";
@@ -5151,13 +5115,13 @@
"You can enable later via Settings" = "Később engedélyezheti a „Beállításokban”";
/* No comment provided by engineer. */
"You can enable them later via app Privacy & Security settings." = "Később engedélyezheti őket az alkalmazás „Adatvédelem és biztonság” menüben.";
"You can enable them later via app Privacy & Security settings." = "Később engedélyezheti őket az alkalmazás „Adatvédelem és biztonság” menüben.";
/* No comment provided by engineer. */
"You can give another try." = "Megpróbálhatja még egyszer.";
/* No comment provided by engineer. */
"You can hide or mute a user profile - swipe it to the right." = "Elrejtheti vagy lenémíthatja a felhasználó -profiljait - csúsztassa jobbra a profilt.";
"You can hide or mute a user profile - swipe it to the right." = "Elrejtheti vagy lenémíthatja a felhasználó profiljait - csúsztassa jobbra a profilt.";
/* No comment provided by engineer. */
"You can make it visible to your SimpleX contacts via Settings." = "Láthatóvá teheti a SimpleXbeli ismerősei számára a „Beállításokban”.";
@@ -2,7 +2,7 @@
"CFBundleName" = "SimpleX";
/* Privacy - Camera Usage Description */
"NSCameraUsageDescription" = "A SimpleXnek kamera-hozzáférésre van szüksége a QR-kódok beolvasásához, hogy kapcsolódhasson más felhasználókhoz és videohívásokhoz.";
"NSCameraUsageDescription" = "A SimpleX-nek kamera-hozzáférésre van szüksége a QR-kódok beolvasásához, hogy kapcsolódhasson más felhasználókhoz és videohívásokhoz.";
/* Privacy - Face ID Usage Description */
"NSFaceIDUsageDescription" = "A SimpleX Face ID-t használ a helyi hitelesítéshez";
@@ -11,8 +11,8 @@
"NSLocalNetworkUsageDescription" = "A SimpleX helyi hálózati hozzáférést használ, hogy lehetővé tegye a felhasználói csevegőprofil használatát számítógépen keresztül ugyanazon a hálózaton.";
/* Privacy - Microphone Usage Description */
"NSMicrophoneUsageDescription" = "A SimpleXnek mikrofon-hozzáférésre van szüksége hang- és videohívásokhoz, valamint hangüzenetek rögzítéséhez.";
"NSMicrophoneUsageDescription" = "A SimpleX-nek mikrofon-hozzáférésre van szüksége hang- és videohívásokhoz, valamint hangüzenetek rögzítéséhez.";
/* Privacy - Photo Library Additions Usage Description */
"NSPhotoLibraryAddUsageDescription" = "A SimpleXnek galéria-hozzáférésre van szüksége a rögzített és fogadott média mentéséhez";
"NSPhotoLibraryAddUsageDescription" = "A SimpleX-nek hozzáférésre van szüksége a Galériához a rögzített és fogadott média mentéséhez";
-36
View File
@@ -694,30 +694,15 @@
/* No comment provided by engineer. */
"Bad message ID" = "ID del messaggio errato";
/* No comment provided by engineer. */
"Better calls" = "Chiamate migliorate";
/* No comment provided by engineer. */
"Better groups" = "Gruppi migliorati";
/* No comment provided by engineer. */
"Better message dates." = "Date dei messaggi migliorate.";
/* No comment provided by engineer. */
"Better messages" = "Messaggi migliorati";
/* No comment provided by engineer. */
"Better networking" = "Rete migliorata";
/* No comment provided by engineer. */
"Better notifications" = "Notifiche migliorate";
/* No comment provided by engineer. */
"Better security ✅" = "Sicurezza migliorata ✅";
/* No comment provided by engineer. */
"Better user experience" = "Esperienza utente migliorata";
/* No comment provided by engineer. */
"Black" = "Nero";
@@ -1307,9 +1292,6 @@
/* No comment provided by engineer. */
"Custom time" = "Tempo personalizzato";
/* No comment provided by engineer. */
"Customizable message shape." = "Forma dei messaggi personalizzabile.";
/* No comment provided by engineer. */
"Customize theme" = "Personalizza il tema";
@@ -1500,9 +1482,6 @@
/* No comment provided by engineer. */
"Delete old database?" = "Eliminare il database vecchio?";
/* No comment provided by engineer. */
"Delete or moderate up to 200 messages." = "Elimina o modera fino a 200 messaggi.";
/* No comment provided by engineer. */
"Delete pending connection?" = "Eliminare la connessione in attesa?";
@@ -2251,9 +2230,6 @@
/* alert message */
"Forward messages without files?" = "Inoltrare i messaggi senza file?";
/* No comment provided by engineer. */
"Forward up to 20 messages at once." = "Inoltra fino a 20 messaggi alla volta.";
/* No comment provided by engineer. */
"forwarded" = "inoltrato";
@@ -2494,9 +2470,6 @@
/* No comment provided by engineer. */
"Importing archive" = "Importazione archivio";
/* No comment provided by engineer. */
"Improved delivery, reduced traffic usage.\nMore improvements are coming soon!" = "Consegna migliorata, utilizzo di traffico ridotto.\nAltri miglioramenti sono in arrivo!";
/* No comment provided by engineer. */
"Improved message delivery" = "Consegna dei messaggi migliorata";
@@ -4298,9 +4271,6 @@
/* simplex link type */
"SimpleX one-time invitation" = "Invito SimpleX una tantum";
/* No comment provided by engineer. */
"SimpleX protocols reviewed by Trail of Bits." = "Protocolli di SimpleX esaminati da Trail of Bits.";
/* No comment provided by engineer. */
"Simplified incognito mode" = "Modalità incognito semplificata";
@@ -4421,12 +4391,6 @@
/* No comment provided by engineer. */
"Support SimpleX Chat" = "Supporta SimpleX Chat";
/* No comment provided by engineer. */
"Switch audio and video during the call." = "Cambia tra audio e video durante la chiamata.";
/* No comment provided by engineer. */
"Switch chat profile for 1-time invitations." = "Cambia profilo di chat per inviti una tantum.";
/* No comment provided by engineer. */
"System" = "Sistema";
-6
View File
@@ -2067,12 +2067,6 @@
/* No comment provided by engineer. */
"Messages & files" = "メッセージ & ファイル";
/* No comment provided by engineer. */
"Messages, files and calls are protected by **end-to-end encryption** with perfect forward secrecy, repudiation and break-in recovery." = "メッセージ、ファイル、通話は、前方秘匿性、否認可能性および侵入復元性を備えた**エンドツーエンドの暗号化**によって保護されます。";
/* No comment provided by engineer. */
"Messages, files and calls are protected by **quantum resistant e2e encryption** with perfect forward secrecy, repudiation and break-in recovery." = "メッセージ、ファイル、通話は、前方秘匿性、否認可能性および侵入復元性を備えた**耐量子E2E暗号化**によって保護されます。";
/* No comment provided by engineer. */
"Migrating database archive…" = "データベースのアーカイブを移行しています…";
-36
View File
@@ -694,30 +694,15 @@
/* No comment provided by engineer. */
"Bad message ID" = "Onjuiste bericht-ID";
/* No comment provided by engineer. */
"Better calls" = "Betere gesprekken";
/* No comment provided by engineer. */
"Better groups" = "Betere groepen";
/* No comment provided by engineer. */
"Better message dates." = "Betere datums voor berichten.";
/* No comment provided by engineer. */
"Better messages" = "Betere berichten";
/* No comment provided by engineer. */
"Better networking" = "Beter netwerk";
/* No comment provided by engineer. */
"Better notifications" = "Betere meldingen";
/* No comment provided by engineer. */
"Better security ✅" = "Betere beveiliging ✅";
/* No comment provided by engineer. */
"Better user experience" = "Betere gebruikerservaring";
/* No comment provided by engineer. */
"Black" = "Zwart";
@@ -1307,9 +1292,6 @@
/* No comment provided by engineer. */
"Custom time" = "Aangepaste tijd";
/* No comment provided by engineer. */
"Customizable message shape." = "Aanpasbare berichtvorm.";
/* No comment provided by engineer. */
"Customize theme" = "Thema aanpassen";
@@ -1500,9 +1482,6 @@
/* No comment provided by engineer. */
"Delete old database?" = "Oude database verwijderen?";
/* No comment provided by engineer. */
"Delete or moderate up to 200 messages." = "Maximaal 200 berichten verwijderen of modereren.";
/* No comment provided by engineer. */
"Delete pending connection?" = "Wachtende verbinding verwijderen?";
@@ -2251,9 +2230,6 @@
/* alert message */
"Forward messages without files?" = "Berichten doorsturen zonder bestanden?";
/* No comment provided by engineer. */
"Forward up to 20 messages at once." = "Stuur maximaal 20 berichten tegelijk door.";
/* No comment provided by engineer. */
"forwarded" = "doorgestuurd";
@@ -2494,9 +2470,6 @@
/* No comment provided by engineer. */
"Importing archive" = "Archief importeren";
/* No comment provided by engineer. */
"Improved delivery, reduced traffic usage.\nMore improvements are coming soon!" = "Verbeterde levering, minder data gebruik.\nBinnenkort meer verbeteringen!";
/* No comment provided by engineer. */
"Improved message delivery" = "Verbeterde berichtbezorging";
@@ -4298,9 +4271,6 @@
/* simplex link type */
"SimpleX one-time invitation" = "Eenmalige SimpleX uitnodiging";
/* No comment provided by engineer. */
"SimpleX protocols reviewed by Trail of Bits." = "SimpleX-protocollen beoordeeld door Trail of Bits.";
/* No comment provided by engineer. */
"Simplified incognito mode" = "Vereenvoudigde incognitomodus";
@@ -4421,12 +4391,6 @@
/* No comment provided by engineer. */
"Support SimpleX Chat" = "Ondersteuning van SimpleX Chat";
/* No comment provided by engineer. */
"Switch audio and video during the call." = "Wisselen tussen audio en video tijdens het gesprek.";
/* No comment provided by engineer. */
"Switch chat profile for 1-time invitations." = "Wijzig chatprofiel voor eenmalige uitnodigingen.";
/* No comment provided by engineer. */
"System" = "Systeem";
-39
View File
@@ -160,9 +160,6 @@
/* notification title */
"%@ wants to connect!" = "%@ хочет соединиться!";
/* format for date separator in chat */
"%@, %@" = "%1$@, %2$@";
/* No comment provided by engineer. */
"%@, %@ and %lld members" = "%@, %@ и %lld членов группы";
@@ -694,30 +691,15 @@
/* No comment provided by engineer. */
"Bad message ID" = "Ошибка ID сообщения";
/* No comment provided by engineer. */
"Better calls" = "Улучшенные звонки";
/* No comment provided by engineer. */
"Better groups" = "Улучшенные группы";
/* No comment provided by engineer. */
"Better message dates." = "Улучшенные даты сообщений.";
/* No comment provided by engineer. */
"Better messages" = "Улучшенные сообщения";
/* No comment provided by engineer. */
"Better networking" = "Улучшенные сетевые функции";
/* No comment provided by engineer. */
"Better notifications" = "Улучшенные уведомления";
/* No comment provided by engineer. */
"Better security ✅" = "Улучшенная безопасность ✅";
/* No comment provided by engineer. */
"Better user experience" = "Улучшенный интерфейс";
/* No comment provided by engineer. */
"Black" = "Черная";
@@ -1307,9 +1289,6 @@
/* No comment provided by engineer. */
"Custom time" = "Пользовательское время";
/* No comment provided by engineer. */
"Customizable message shape." = "Настраиваемая форма сообщений.";
/* No comment provided by engineer. */
"Customize theme" = "Настроить тему";
@@ -1500,9 +1479,6 @@
/* No comment provided by engineer. */
"Delete old database?" = "Удалить предыдущую версию данных?";
/* No comment provided by engineer. */
"Delete or moderate up to 200 messages." = "Удаляйте или модерируйте до 200 сообщений.";
/* No comment provided by engineer. */
"Delete pending connection?" = "Удалить ожидаемое соединение?";
@@ -2251,9 +2227,6 @@
/* alert message */
"Forward messages without files?" = "Переслать сообщения без файлов?";
/* No comment provided by engineer. */
"Forward up to 20 messages at once." = "Пересылайте до 20 сообщений за раз.";
/* No comment provided by engineer. */
"forwarded" = "переслано";
@@ -2494,9 +2467,6 @@
/* No comment provided by engineer. */
"Importing archive" = "Импорт архива";
/* No comment provided by engineer. */
"Improved delivery, reduced traffic usage.\nMore improvements are coming soon!" = "Улучшенная доставка, меньше трафик.";
/* No comment provided by engineer. */
"Improved message delivery" = "Улучшенная доставка сообщений";
@@ -4298,9 +4268,6 @@
/* simplex link type */
"SimpleX one-time invitation" = "SimpleX одноразовая ссылка";
/* No comment provided by engineer. */
"SimpleX protocols reviewed by Trail of Bits." = "Аудит SimpleX протоколов от Trail of Bits.";
/* No comment provided by engineer. */
"Simplified incognito mode" = "Упрощенный режим Инкогнито";
@@ -4421,12 +4388,6 @@
/* No comment provided by engineer. */
"Support SimpleX Chat" = "Поддержать SimpleX Chat";
/* No comment provided by engineer. */
"Switch audio and video during the call." = "Переключайте звук и видео во время звонка.";
/* No comment provided by engineer. */
"Switch chat profile for 1-time invitations." = "Переключайте профиль чата для одноразовых приглашений.";
/* No comment provided by engineer. */
"System" = "Системная";
-36
View File
@@ -694,30 +694,15 @@
/* No comment provided by engineer. */
"Bad message ID" = "Kötü mesaj kimliği";
/* No comment provided by engineer. */
"Better calls" = "Daha iyi aramalar";
/* No comment provided by engineer. */
"Better groups" = "Daha iyi gruplar";
/* No comment provided by engineer. */
"Better message dates." = "Daha iyi mesaj tarihleri.";
/* No comment provided by engineer. */
"Better messages" = "Daha iyi mesajlar";
/* No comment provided by engineer. */
"Better networking" = "Daha iyi ağ oluşturma";
/* No comment provided by engineer. */
"Better notifications" = "Daha iyi bildirimler";
/* No comment provided by engineer. */
"Better security ✅" = "Daha iyi güvenlik ✅";
/* No comment provided by engineer. */
"Better user experience" = "Daha iyi kullanıcı deneyimi";
/* No comment provided by engineer. */
"Black" = "Siyah";
@@ -1307,9 +1292,6 @@
/* No comment provided by engineer. */
"Custom time" = "Özel saat";
/* No comment provided by engineer. */
"Customizable message shape." = "Özelleştirilebilir mesaj şekli.";
/* No comment provided by engineer. */
"Customize theme" = "Renk temalarını kişiselleştir";
@@ -1500,9 +1482,6 @@
/* No comment provided by engineer. */
"Delete old database?" = "Eski veritabanı silinsin mi?";
/* No comment provided by engineer. */
"Delete or moderate up to 200 messages." = "200'e kadar mesajı silin veya düzenleyin.";
/* No comment provided by engineer. */
"Delete pending connection?" = "Bekleyen bağlantı silinsin mi?";
@@ -2251,9 +2230,6 @@
/* alert message */
"Forward messages without files?" = "Mesajlar dosyalar olmadan iletilsin mi ?";
/* No comment provided by engineer. */
"Forward up to 20 messages at once." = "Aynı anda en fazla 20 mesaj iletin.";
/* No comment provided by engineer. */
"forwarded" = "iletildi";
@@ -2494,9 +2470,6 @@
/* No comment provided by engineer. */
"Importing archive" = "Arşiv içe aktarılıyor";
/* No comment provided by engineer. */
"Improved delivery, reduced traffic usage.\nMore improvements are coming soon!" = "İyileştirilmiş teslimat, azaltılmış trafik kullanımı.\nDaha fazla iyileştirme yakında geliyor!";
/* No comment provided by engineer. */
"Improved message delivery" = "İyileştirilmiş mesaj iletimi";
@@ -4298,9 +4271,6 @@
/* simplex link type */
"SimpleX one-time invitation" = "SimpleX tek kullanımlık davet";
/* No comment provided by engineer. */
"SimpleX protocols reviewed by Trail of Bits." = "SimpleX protokolleri Trail of Bits tarafından incelenmiştir.";
/* No comment provided by engineer. */
"Simplified incognito mode" = "Basitleştirilmiş gizli mod";
@@ -4421,12 +4391,6 @@
/* No comment provided by engineer. */
"Support SimpleX Chat" = "SimpleX Chat'e destek ol";
/* No comment provided by engineer. */
"Switch audio and video during the call." = "Görüşme sırasında ses ve görüntüyü değiştirin.";
/* No comment provided by engineer. */
"Switch chat profile for 1-time invitations." = "Sohbet profilini 1 kerelik davetler için değiştirin.";
/* No comment provided by engineer. */
"System" = "Sistem";
@@ -24,7 +24,8 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.scale
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.painter.Painter
import androidx.compose.ui.platform.*
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalView
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
@@ -36,9 +37,7 @@ import chat.simplex.app.R
import chat.simplex.app.TAG
import chat.simplex.app.model.NtfManager
import chat.simplex.app.model.NtfManager.AcceptCallAction
import chat.simplex.common.helpers.applyAppLocale
import chat.simplex.common.model.*
import chat.simplex.common.model.ChatController.appPrefs
import chat.simplex.common.platform.*
import chat.simplex.common.platform.chatModel
import chat.simplex.common.ui.theme.*
@@ -50,7 +49,6 @@ import dev.icerock.moko.resources.compose.stringResource
import kotlinx.coroutines.launch
import kotlinx.datetime.Clock
import java.lang.ref.WeakReference
import java.util.*
import chat.simplex.common.platform.chatModel as m
class CallActivity: ComponentActivity(), ServiceConnection {
@@ -58,7 +56,6 @@ class CallActivity: ComponentActivity(), ServiceConnection {
var boundService: CallService? = null
override fun onCreate(savedInstanceState: Bundle?) {
applyAppLocale(appPrefs.appLanguage)
super.onCreate(savedInstanceState)
callActivity = WeakReference(this)
when (intent?.action) {
@@ -83,7 +80,6 @@ class CallActivity: ComponentActivity(), ServiceConnection {
override fun onDestroy() {
super.onDestroy()
(mainActivity.get() ?: this).applyAppLocale(appPrefs.appLanguage)
if (isOnLockScreenNow()) {
lockAfterIncomingCall()
}
@@ -237,7 +233,7 @@ fun CallActivityView() {
}
SimpleXTheme {
var prevCall by remember { mutableStateOf(call) }
KeyChangeEffect(m.activeCall.value, remember { appPrefs.appLanguage.state }.value) {
KeyChangeEffect(m.activeCall.value) {
if (m.activeCall.value != null) {
prevCall = m.activeCall.value
activity.boundService?.updateNotification()
@@ -31,7 +31,8 @@ private fun Activity.applyLocale(locale: Locale) {
Locale.setDefault(locale)
val appConf = Configuration(androidAppContext.resources.configuration).apply { setLocale(locale) }
val activityConf = Configuration(resources.configuration).apply { setLocale(locale) }
androidAppContext = androidAppContext.createConfigurationContext(appConf)
@Suppress("DEPRECATION")
androidAppContext.resources.updateConfiguration(appConf, resources.displayMetrics)
@Suppress("DEPRECATION")
resources.updateConfiguration(activityConf, resources.displayMetrics)
}
@@ -7,9 +7,12 @@ import android.os.Build
import androidx.annotation.RequiresApi
import androidx.compose.runtime.*
import chat.simplex.common.platform.*
import chat.simplex.common.views.helpers.withBGApi
import dev.icerock.moko.resources.ImageResource
import chat.simplex.res.MR
import dev.icerock.moko.resources.StringResource
import kotlinx.coroutines.Job
import kotlinx.coroutines.delay
import java.util.concurrent.Executors
interface CallAudioDeviceManagerInterface {
@@ -19,6 +22,7 @@ interface CallAudioDeviceManagerInterface {
fun stop()
// AudioDeviceInfo.AudioDeviceType
fun selectLastExternalDeviceOrDefault(speaker: Boolean, keepAnyExternal: Boolean)
fun selectSameDeviceOnWebViewChange()
// AudioDeviceInfo.AudioDeviceType
fun selectDevice(id: Int)
@@ -35,12 +39,15 @@ interface CallAudioDeviceManagerInterface {
@RequiresApi(Build.VERSION_CODES.S)
class PostSCallAudioDeviceManager: CallAudioDeviceManagerInterface {
private val am = androidAppContext.getSystemService(Context.AUDIO_SERVICE) as AudioManager
private var resetCurrentToDevice: AudioDeviceInfo? = null
private var resetCurrentToDeviceJob: Job = Job()
override val devices: MutableState<List<AudioDeviceInfo>> = mutableStateOf(emptyList())
override val currentDevice: MutableState<AudioDeviceInfo?> = mutableStateOf(null)
private val audioCallback = object: AudioDeviceCallback() {
override fun onAudioDevicesAdded(addedDevices: Array<out AudioDeviceInfo>) {
Log.d(TAG, "Added audio devices: ${addedDevices.map { it.type }}")
resetCurrentToDevice = null
super.onAudioDevicesAdded(addedDevices)
val oldDevices = devices.value
devices.value = am.availableCommunicationDevices
@@ -53,13 +60,21 @@ class PostSCallAudioDeviceManager: CallAudioDeviceManagerInterface {
override fun onAudioDevicesRemoved(removedDevices: Array<out AudioDeviceInfo>) {
Log.d(TAG, "Removed audio devices: ${removedDevices.map { it.type }}")
resetCurrentToDevice = null
super.onAudioDevicesRemoved(removedDevices)
devices.value = am.availableCommunicationDevices
}
}
private val listener: OnCommunicationDeviceChangedListener = OnCommunicationDeviceChangedListener { device ->
val resetTo = resetCurrentToDevice
if (resetTo != null && device != null && resetTo.id != device.id) {
Log.w(TAG, "Resetting device that was set by WebView ${device.name?.localized()} to previously set device ${resetTo.name?.localized()}")
selectDevice(resetTo.id)
return@OnCommunicationDeviceChangedListener
}
devices.value = am.availableCommunicationDevices
//Log.d(TAG, "Devices changed ${device?.details()} | ${devices.value.map { it.details() }}")
currentDevice.value = device
}
@@ -98,7 +113,18 @@ class PostSCallAudioDeviceManager: CallAudioDeviceManagerInterface {
}
}
// WebView modifies speaker when muting/unmuting microphone. It's not needed at all, returning back current device if it will be changed
override fun selectSameDeviceOnWebViewChange() {
resetCurrentToDevice = currentDevice.value
resetCurrentToDeviceJob.cancel()
resetCurrentToDeviceJob = withBGApi {
delay(5000)
resetCurrentToDevice = null
}
}
override fun selectDevice(id: Int) {
resetCurrentToDevice = null
val device = devices.value.lastOrNull { it.id == id }
if (device != null && am.communicationDevice?.id != id ) {
am.setCommunicationDevice(device)
@@ -108,12 +134,14 @@ class PostSCallAudioDeviceManager: CallAudioDeviceManagerInterface {
class PreSCallAudioDeviceManager: CallAudioDeviceManagerInterface {
private val am = androidAppContext.getSystemService(Context.AUDIO_SERVICE) as AudioManager
private var resetCurrentToDeviceJob: Job = Job()
override val devices: MutableState<List<AudioDeviceInfo>> = mutableStateOf(emptyList())
override val currentDevice: MutableState<AudioDeviceInfo?> = mutableStateOf(null)
private val audioCallback = object: AudioDeviceCallback() {
override fun onAudioDevicesAdded(addedDevices: Array<out AudioDeviceInfo>) {
Log.d(TAG, "Added audio devices: ${addedDevices.map { it.type }}")
resetCurrentToDeviceJob.cancel()
super.onAudioDevicesAdded(addedDevices)
devices.value = am.getDevices(AudioManager.GET_DEVICES_OUTPUTS).filter { it.hasSupportedType() }.excludeSameType().excludeEarpieceIfWired()
selectLastExternalDeviceOrDefault(chatModel.activeCall.value?.hasVideo == true, false)
@@ -121,6 +149,7 @@ class PreSCallAudioDeviceManager: CallAudioDeviceManagerInterface {
override fun onAudioDevicesRemoved(removedDevices: Array<out AudioDeviceInfo>) {
Log.d(TAG, "Removed audio devices: ${removedDevices.map { it.type }}")
resetCurrentToDeviceJob.cancel()
super.onAudioDevicesRemoved(removedDevices)
devices.value = am.getDevices(AudioManager.GET_DEVICES_OUTPUTS).filter { it.hasSupportedType() }.excludeSameType().excludeEarpieceIfWired()
selectLastExternalDeviceOrDefault(chatModel.activeCall.value?.hasVideo == true, true)
@@ -153,7 +182,22 @@ class PreSCallAudioDeviceManager: CallAudioDeviceManagerInterface {
}
}
override fun selectSameDeviceOnWebViewChange() {
val current = currentDevice.value ?: return
resetCurrentToDeviceJob.cancel()
resetCurrentToDeviceJob = withBGApi {
// select old device manually because WebView will change it for sure.
// smaller delay first if it's possible to make the switch less noticeable
delay(300)
selectDevice(current.id)
// and in order to be sure that it will be selected even if WebView will be slow in changing its device
delay(700)
selectDevice(current.id)
}
}
override fun selectDevice(id: Int) {
resetCurrentToDeviceJob.cancel()
val device = devices.value.lastOrNull { it.id == id }
val isExternalDevice = device != null && device.type != AudioDeviceInfo.TYPE_BUILTIN_EARPIECE && device.type != AudioDeviceInfo.TYPE_BUILTIN_SPEAKER
if (isExternalDevice) {
@@ -216,6 +260,8 @@ val AudioDeviceInfo.icon: ImageResource
else -> MR.images.ic_brand_awareness_filled
}
private fun AudioDeviceInfo.details(): String = "$productName id:$id name:${name?.localized()} type:$type sink:$isSink source:$isSource"
val AudioDeviceInfo.name: StringResource?
get() = when (this.type) {
AudioDeviceInfo.TYPE_BUILTIN_EARPIECE -> MR.strings.audio_device_earpiece
@@ -41,10 +41,8 @@ import androidx.core.content.ContextCompat
import androidx.lifecycle.*
import androidx.webkit.WebViewAssetLoader
import androidx.webkit.WebViewClientCompat
import chat.simplex.common.helpers.applyAppLocale
import chat.simplex.common.helpers.showAllowPermissionInSettingsAlert
import chat.simplex.common.model.*
import chat.simplex.common.model.ChatController.appPrefs
import chat.simplex.common.platform.*
import chat.simplex.common.ui.theme.*
import chat.simplex.common.views.helpers.*
@@ -194,11 +192,7 @@ actual fun ActiveCallView() {
updateActiveCall(call) {
val sources = it.localMediaSources
when (cmd.source) {
CallMediaSource.Mic -> {
val am = androidAppContext.getSystemService(Context.AUDIO_SERVICE) as AudioManager
am.isMicrophoneMute = !cmd.enable
it.copy(localMediaSources = sources.copy(mic = cmd.enable))
}
CallMediaSource.Mic -> it.copy(localMediaSources = sources.copy(mic = cmd.enable))
CallMediaSource.Camera -> it.copy(localMediaSources = sources.copy(camera = cmd.enable))
CallMediaSource.ScreenAudio -> it.copy(localMediaSources = sources.copy(screenAudio = cmd.enable))
CallMediaSource.ScreenVideo -> it.copy(localMediaSources = sources.copy(screenVideo = cmd.enable))
@@ -208,6 +202,7 @@ actual fun ActiveCallView() {
is WCallCommand.Camera -> {
updateActiveCall(call) { it.copy(localCamera = cmd.camera) }
if (!call.localMediaSources.mic) {
callAudioDeviceManager.selectSameDeviceOnWebViewChange()
chatModel.callCommand.add(WCallCommand.Media(CallMediaSource.Mic, enable = false))
}
}
@@ -267,7 +262,10 @@ private fun ActiveCallOverlay(call: Call, chatModel: ChatModel, callAudioDeviceM
devices = remember { callAudioDeviceManager.devices }.value,
currentDevice = remember { callAudioDeviceManager.currentDevice },
dismiss = { withBGApi { chatModel.callManager.endCall(call) } },
toggleAudio = { chatModel.callCommand.add(WCallCommand.Media(CallMediaSource.Mic, enable = !call.localMediaSources.mic)) },
toggleAudio = {
callAudioDeviceManager.selectSameDeviceOnWebViewChange()
chatModel.callCommand.add(WCallCommand.Media(CallMediaSource.Mic, enable = !call.localMediaSources.mic))
},
selectDevice = { callAudioDeviceManager.selectDevice(it.id) },
toggleVideo = {
if (ContextCompat.checkSelfPermission(androidAppContext, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED) {
@@ -708,10 +706,9 @@ fun WebRTCView(callCommand: SnapshotStateList<WCallCommand>, onResponse: (WVAPIM
Box(Modifier.fillMaxSize()) {
AndroidView(
factory = {
factory = { AndroidViewContext ->
try {
(staticWebView ?: WebView(androidAppContext)).apply {
reapplyLocale()
layoutParams = ViewGroup.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT,
@@ -782,16 +779,6 @@ private fun updateActiveCall(initial: Call, transform: (Call) -> Call) {
}
}
/*
* Creating WebView automatically drops user's custom app locale to default system locale.
* Preventing it by re-applying custom locale
* https://issuetracker.google.com/issues/109833940
* */
private fun reapplyLocale() {
mainActivity.get()?.applyAppLocale(appPrefs.appLanguage)
callActivity.get()?.applyAppLocale(appPrefs.appLanguage)
}
private class LocalContentWebViewClient(val webView: MutableState<WebView?>, private val assetLoader: WebViewAssetLoader) : WebViewClientCompat() {
override fun shouldInterceptRequest(
view: WebView,
@@ -1889,7 +1889,6 @@ class PendingContactConnection(
@Serializable
enum class ConnStatus {
@SerialName("new") New,
@SerialName("prepared") Prepared,
@SerialName("joined") Joined,
@SerialName("requested") Requested,
@SerialName("accepted") Accepted,
@@ -1899,7 +1898,6 @@ enum class ConnStatus {
val initiated: Boolean? get() = when (this) {
New -> true
Prepared -> false
Joined -> false
Requested -> true
Accepted -> true
@@ -1,60 +0,0 @@
package chat.simplex.common.views.chat
import androidx.compose.runtime.snapshots.SnapshotStateList
import chat.simplex.common.model.*
data class SectionItems (
val mergeCategory: CIMergeCategory?,
val items: SnapshotStateList<ChatItem>,
val revealed: Boolean,
val showAvatar: MutableSet<Long>,
)
fun List<ChatItem>.putIntoGroups(revealedItems: Set<Long>): List<SectionItems> {
println("LALAL LENGTH ${size}")
val start = System.currentTimeMillis()
val groups = ArrayList<SectionItems>()
var recent: SectionItems = if (isNotEmpty()) {
val first = this[0]
SectionItems(
mergeCategory = first.mergeCategory,
items = SnapshotStateList<ChatItem>().also { it.add(first) },
revealed = first.mergeCategory == null || revealedItems.contains(first.id),
showAvatar = mutableSetOf<Long>().also { if (first.chatDir is CIDirection.GroupRcv) it.add(first.id) })
} else {
return emptyList()
}
groups.add(recent)
var prev = this[0]
var index = 0
while (index < size) {
if (index == 0) {
index++
continue
}
val item = this[index]
val category = item.mergeCategory
if (recent.mergeCategory == category) {
recent.items.add(item)
if (item.chatDir is CIDirection.GroupRcv && prev.chatDir is CIDirection.GroupRcv && item.chatDir.groupMember == (prev.chatDir as CIDirection.GroupRcv).groupMember) {
recent.showAvatar.add(item.id)
}
} else {
recent = SectionItems(
mergeCategory = item.mergeCategory,
items = SnapshotStateList<ChatItem>().also { it.add(item) },
revealed = item.mergeCategory == null || revealedItems.contains(item.id),
showAvatar = mutableSetOf<Long>().also {
if (item.chatDir is CIDirection.GroupRcv && (prev.chatDir !is CIDirection.GroupRcv || (prev.chatDir as CIDirection.GroupRcv).groupMember != item.chatDir.groupMember)) {
it.add(item.id)
}
}
)
groups.add(recent)
}
prev = item
index++
}
println("LALAL RES ${System.currentTimeMillis() - start}, groups: ${groups.size}")
return groups
}
@@ -11,7 +11,6 @@ import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.*
import androidx.compose.runtime.*
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.snapshots.AutoboxingStateValueProperty
import androidx.compose.ui.*
import androidx.compose.ui.draw.clip
import androidx.compose.ui.draw.drawWithCache
@@ -989,8 +988,6 @@ fun BoxWithConstraintsScope.ChatItemsList(
Spacer(Modifier.size(8.dp))
val reversedChatItems by remember { derivedStateOf { chatModel.chatItems.asReversed() } }
val revealedItems = rememberSaveable { mutableStateOf(setOf<Long>()) }
val groups by remember { derivedStateOf { (reversedChatItems + reversedChatItems + reversedChatItems + reversedChatItems + reversedChatItems + reversedChatItems + reversedChatItems + reversedChatItems + reversedChatItems + reversedChatItems + reversedChatItems + reversedChatItems + reversedChatItems + reversedChatItems + reversedChatItems + reversedChatItems + reversedChatItems + reversedChatItems + reversedChatItems + reversedChatItems + reversedChatItems + reversedChatItems + reversedChatItems + reversedChatItems + reversedChatItems + reversedChatItems + reversedChatItems + reversedChatItems + reversedChatItems + reversedChatItems + reversedChatItems + reversedChatItems).putIntoGroups(revealedItems.value) } }
val maxHeightRounded = with(LocalDensity.current) { maxHeight.roundToPx() }
val scrollToItem: (Long) -> Unit = { itemId: Long ->
val index = reversedChatItems.indexOfFirst { it.id == itemId }
@@ -1014,8 +1011,8 @@ fun BoxWithConstraintsScope.ChatItemsList(
VideoPlayerHolder.releaseAll()
}
)
@Composable
fun ChatViewListItem(i: Int, showAvatar: Boolean, cItem: ChatItem) {
LazyColumnWithScrollBar(Modifier.align(Alignment.BottomCenter), state = listState, reverseLayout = true) {
itemsIndexed(reversedChatItems, key = { _, item -> item.id to item.meta.createdAt.toEpochMilliseconds() }) { i, cItem ->
CompositionLocalProvider(
// Makes horizontal and vertical scrolling to coexist nicely.
// With default touchSlop when you scroll LazyColumn, you can unintentionally open reply view
@@ -1107,7 +1104,7 @@ fun BoxWithConstraintsScope.ChatItemsList(
} else {
null to 1
}
if (showMemberImage(member, prevItem) || showAvatar) {
if (prevItem == null || showMemberImage(member, prevItem) || prevMember != null) {
Column(
Modifier
.padding(top = 8.dp)
@@ -1228,6 +1225,37 @@ fun BoxWithConstraintsScope.ChatItemsList(
}
}
}
val (currIndex, nextItem) = chatModel.getNextChatItem(cItem)
val ciCategory = cItem.mergeCategory
if (ciCategory != null && ciCategory == nextItem?.mergeCategory) {
// memberConnected events and deleted items are aggregated at the last chat item in a row, see ChatItemView
} else {
val (prevHidden, prevItem) = chatModel.getPrevShownChatItem(currIndex, ciCategory)
val itemSeparation = getItemSeparation(cItem, nextItem)
val previousItemSeparation = if (prevItem != null) getItemSeparation(prevItem, cItem) else null
if (itemSeparation.date != null) {
DateSeparator(itemSeparation.date)
}
val range = chatViewItemsRange(currIndex, prevHidden)
if (revealed.value && range != null) {
reversedChatItems.subList(range.first, range.last + 1).forEachIndexed { index, ci ->
val prev = if (index + range.first == prevHidden) prevItem else reversedChatItems[index + range.first + 1]
ChatItemView(ci, null, prev, itemSeparation, previousItemSeparation)
}
} else {
ChatItemView(cItem, range, prevItem, itemSeparation, previousItemSeparation)
}
if (i == reversedChatItems.lastIndex) {
DateSeparator(cItem.meta.itemTs)
}
}
if (cItem.isRcvNew && chatInfo.id == ChatModel.chatId.value) {
LaunchedEffect(cItem.id) {
scope.launch {
@@ -1236,29 +1264,6 @@ fun BoxWithConstraintsScope.ChatItemsList(
}
}
}
val itemSeparation = getItemSeparation(cItem, null)
ChatItemView(cItem, null, null, itemSeparation, null)
}
}
LazyColumnWithScrollBar(Modifier.align(Alignment.BottomCenter), state = listState, reverseLayout = true) {
for (group in groups) {
if (group.revealed) {
itemsIndexed(group.items, key = { _, item -> (item.id to item.meta.createdAt.toEpochMilliseconds()).toString() }) { i, cItem ->
// index here is just temporary, should be removed at all or put in the section items
ChatViewListItem(reversedChatItems.indexOf(cItem), showAvatar = group.showAvatar.contains(cItem.id), cItem)
}
} else {
val item = group.items.last()
item(key = { (item.id to item.meta.createdAt.toEpochMilliseconds()).toString() }) {
// here you make one collapsed item from multiple items (should be already in section items)
ChatViewListItem(reversedChatItems.indexOf(item), showAvatar = group.showAvatar.contains(item.id), item)
}
}
}
if (reversedChatItems.isNotEmpty()) {
item {
DateSeparator(reversedChatItems.last().meta.itemTs)
}
}
}
@@ -667,8 +667,8 @@
<string name="callstate_received_confirmation">obdržel potvrzení…</string>
<string name="callstate_connecting">připojování…</string>
<string name="privacy_redefined">Nové vymezení soukromí</string>
<string name="first_platform_without_user_ids">Bez uživatelských identifikátorů</string>
<string name="immune_to_spam_and_abuse">Odolná vůči spamu</string>
<string name="first_platform_without_user_ids">1. platforma bez jakýchkoliv uživatelských identifikátorů soukromá již od návrhu.</string>
<string name="immune_to_spam_and_abuse">Odolná vůči spamu a zneužití</string>
<string name="to_protect_privacy_simplex_has_ids_for_queues">K ochraně soukromí, místo uživatelských ID užívaných všemi ostatními platformami, SimpleX používá identifikátory pro fronty zpráv, zvlášť pro každý z vašich kontaktů.</string>
<string name="many_people_asked_how_can_it_deliver"><![CDATA[Mnoho lidí se ptá: <i>když SimpleX nemá žádný identifikátor uživatelů, jak může doručovat zprávy\?</i>]]></string>
<string name="you_control_servers_to_receive_your_contacts_to_send"><![CDATA[Vy určujete, přes které servery <b>přijímat</b> zprávy, vaše kontakty servery, které používáte k zasílání zpráv.]]></string>
@@ -679,8 +679,8 @@
<string name="onboarding_notifications_mode_off">Když aplikace běží</string>
<string name="onboarding_notifications_mode_service">Okamžité</string>
<string name="onboarding_notifications_mode_off_desc"><![CDATA[<b>Nejlepší pro baterii</b>. Budete přijímat oznámení pouze když aplikace běží (žádná služba na pozadí).]]></string>
<string name="onboarding_notifications_mode_periodic_desc"><![CDATA[<b>Dobré pro baterii</b>. Apka bude kontrolovat zprávy každých 10 minut. Můžete zmeškat volání nebo naléhavé zprávy.]]></string>
<string name="onboarding_notifications_mode_service_desc"><![CDATA[<b>Využívá více baterie</b>! Apka stále běží na pozadí - oznámení se zobrazí okamžitě.]]></string>
<string name="onboarding_notifications_mode_periodic_desc"><![CDATA[<b>Dobré pro baterii</b>. Služba na pozadí bude kontrolovat každých 10 minut. Můžete zmeškat hovory nebo naléhavé zprávy.]]></string>
<string name="onboarding_notifications_mode_service_desc"><![CDATA[<b>Využívá více baterie</b>! Služba na pozadí je spuštěna vždy - oznámení se zobrazí, jakmile jsou zprávy k dispozici.]]></string>
<string name="paste_the_link_you_received">Vložte přijatý odkaz</string>
<string name="incoming_video_call">Příchozí videohovor</string>
<string name="incoming_audio_call">Příchozí zvukový hovor</string>
@@ -1582,7 +1582,7 @@
<string name="profile_update_event_member_name_changed">člen %1$s změněn na %2$s</string>
<string name="member_info_member_blocked">blokováno</string>
<string name="member_blocked_by_admin">Blokováno adminem</string>
<string name="share_text_created_at">Vytvořen v: %s</string>
<string name="share_text_created_at">Vytvořeno v: %s</string>
<string name="message_too_large">Zpráva příliš velká</string>
<string name="remote_host_disconnected_from"><![CDATA[Odpojeno z mobilu <b>%s</b> z důvodu: %s]]></string>
<string name="remote_host_was_disconnected_title">Spojení zastaveno</string>
@@ -1817,7 +1817,8 @@
<string name="v5_8_safe_files">Bezpečné přijímání souborů</string>
<string name="v5_8_chat_themes">Nové motivy chatu</string>
<string name="v5_8_private_routing">Soukromé směrování zpráv 🚀</string>
<string name="v5_8_private_routing_descr">Chraňte vaši IP adresu před relé zpráv vašich kontaktů.\nPovolte v nastavení *Síť &amp; servery*.</string>
<string name="v5_8_private_routing_descr">Chraňte vaši IP adresu před relé zpráv, které jste si vybrali.
\nPovolit v nastavení *Síť &amp; servery*.</string>
<string name="v5_8_message_delivery">Vylepšené doručování zpráv</string>
<string name="v5_8_persian_ui">Perské UI</string>
<string name="remote_ctrl_connection_stopped_desc">Prosím zkontrolujte, že mobil a desktop jsou připojeny ke stejné místní síti, a že stolní firewall umožňuje připojení.
@@ -1861,193 +1862,4 @@
<string name="cant_call_member_alert_title">Nelze zavolat člena skupiny</string>
<string name="deleted_chats">Archivované kontakty</string>
<string name="v6_0_your_contacts_descr">Archivujte kontakty pro pozdější chatování.</string>
<string name="smp_proxy_error_broker_host">Adresa předávacího serveru je nekompatibilní s nastavením sítě: %1$s.</string>
<string name="smp_proxy_error_broker_version">Verze předávacího serveru je nekompatibilní s nastavením sítě: %1$s.</string>
<string name="proxy_destination_error_broker_host">Cílová adresa serveru %1$s je nekompatibilní s nastavením přeposílajícího serveru %2$s.</string>
<string name="smp_proxy_error_connecting">Chyba připojení k přeposílajícímu serveru %1$s. Prosím, zkuste to později.</string>
<string name="proxy_destination_error_failed_to_connect">Předávacímu serveru %1$s se nepodařilo připojit k cílovému serveru %2$s. Prosím, zkuste to později.</string>
<string name="cannot_share_message_alert_text">Vybrané nastavení chatu zakazuje tuto zprávu.</string>
<string name="smp_servers_other">Jiné SMP servery</string>
<string name="smp_servers_configured">Nastavené SMP servery</string>
<string name="servers_info_subscriptions_connections_pending">Probíhá</string>
<string name="chunks_uploaded">Části nahrány</string>
<string name="n_file_errors">%1$d chuba souboru(ů):\n%2$s</string>
<string name="n_other_file_errors">%1$d jiná chyba souboru(ů).</string>
<string name="error_forwarding_messages">Chyba přeposílaní zpráv</string>
<string name="srv_error_host">Adresa serveru není kompatibilní s nastavením sítě.</string>
<string name="forward_alert_title_messages_to_forward">Předat %1$s zpráv(u)?</string>
<string name="forward_alert_title_nothing_to_forward">Nic k předání!</string>
<string name="forward_alert_forward_messages_without_files">Předat zprávy bez souborů?</string>
<string name="forward_files_failed_to_receive_desc">%1$d soubor(y) se nepodařilo stáhnout.</string>
<string name="forward_files_not_accepted_desc">%1$d soubor(y) nestažen(y).</string>
<string name="forward_files_missing_desc">%1$d soubor(y) smazán(y).</string>
<string name="forward_files_messages_deleted_after_selection_title">%1$s zprávy nepředány</string>
<string name="forward_files_not_accepted_receive_files">Stáhnout</string>
<string name="compose_forward_messages_n">Předávám %1$s zpráv</string>
<string name="forward_multiple">Předat zprávy…</string>
<string name="compose_save_messages_n">Uložit %1$s zpráv</string>
<string name="network_proxy_auth_mode_no_auth">Nepoužívat autorizaci s proxy.</string>
<string name="network_proxy_incorrect_config_title">Chyba ukládání proxy</string>
<string name="network_proxy_incorrect_config_desc">Ujistěte se, že nastavení proxy je správné.</string>
<string name="network_proxy_password">Heslo</string>
<string name="network_proxy_auth">Proxy autentizace</string>
<string name="app_check_for_updates_button_install">Instalovat aktualizace</string>
<string name="app_check_for_updates_button_open">Otevřít umístění souboru</string>
<string name="app_check_for_updates_download_started">Stahování aktualizace, nezavírejte aplikaci</string>
<string name="app_check_for_updates_installed_successfully_desc">Prosím restartujte aplikaci.</string>
<string name="app_check_for_updates_installed_successfully_title">Instalovány úspěšně</string>
<string name="app_check_for_updates_button_remind_later">Připomenout později</string>
<string name="app_check_for_updates_notice_title">Zkontrolovat aktualizace</string>
<string name="privacy_media_blur_radius_off">Vypnuto</string>
<string name="settings_section_title_chat_database">CHAT DATABÁZE</string>
<string name="member_info_member_disabled">vypnut</string>
<string name="message_queue_info_server_info">info fronty serveru: %1$s\n\nposlední obdržená zpráva: %2$s</string>
<string name="network_options_save_and_reconnect">Uložit a připojit znovu</string>
<string name="v6_0_chat_list_media">Hrajte ze seznamu chatů.</string>
<string name="servers_info_messages_received">Přijatých zprávy</string>
<string name="servers_info_reconnect_servers_title">Znovu připojit servery?</string>
<string name="completed">Kompletní</string>
<string name="secured">Zabezpečeno</string>
<string name="error_parsing_uri_desc">Prosím zkontrolujte, že SimpleX odkaz je správný.</string>
<string name="error_parsing_uri_title">Chybný odkaz</string>
<string name="proxy_destination_error_broker_version">Verze cílového serveru %1$s je nekompatibilní s nastavením přeposílajícího serveru %2$s.</string>
<string name="message_forwarded_title">Zpráva předána</string>
<string name="keep_conversation">Udržujte konverzaci</string>
<string name="only_delete_conversation">Jen smazat konverzaci</string>
<string name="confirm_delete_contact_question">Potvrdit smazání kontaktu?</string>
<string name="delete_contact_cannot_undo_warning">Kontakt bude smazán - nelze vrátit!</string>
<string name="conversation_deleted">Konverzace odstraněna!</string>
<string name="paste_link">Vložit odkaz</string>
<string name="chat_database_exported_title">Chat databáze exportována</string>
<string name="cant_send_message_to_member_alert_title">Členu skupiny nelze odeslat zprávu</string>
<string name="calls_prohibited_ask_to_enable_calls_alert_text">Požádejte váš kontakt ať povolí volání.</string>
<string name="color_sent_quote">Odeslaných odpovědí</string>
<string name="wallpaper_scale">Škálovat</string>
<string name="wallpaper_scale_fit">Přizpůsobit</string>
<string name="v6_0_privacy_blur">Rozmazání pro lepší soukromí.</string>
<string name="v6_0_connect_faster_descr">Připojte se k vašim přátelům rychleji.</string>
<string name="v6_0_delete_many_messages_descr">Smazat až 20 zpráv najednou.</string>
<string name="v6_0_increase_font_size">Zvětšit velikost písma.</string>
<string name="v6_0_connection_servers_status_descr">Stav připojení a serverů.</string>
<string name="v6_0_connection_servers_status">Kontrolujte svou síť</string>
<string name="servers_info_sessions_errors">Chyby</string>
<string name="servers_info_sessions_connected">Připojen</string>
<string name="servers_info_sessions_connecting">Připojování</string>
<string name="servers_info_connected_servers_section_header">Připojené servery</string>
<string name="servers_info_previously_connected_servers_section_header">Dříve připojené servery</string>
<string name="acknowledged">Potvrzeno</string>
<string name="duplicates_label">duplikáty</string>
<string name="deleted">Smazán</string>
<string name="open_server_settings_button">Otevřít nastavení serveru</string>
<string name="v6_0_new_chat_experience">Nový zážitek z chatu 🎉</string>
<string name="v6_0_new_media_options">Nové možnosti médií</string>
<string name="new_message">Nová zpráva</string>
<string name="scan_paste_link">Skenovat / Vložit odkaz</string>
<string name="no_filtered_contacts">Žádné filtrované kontakty</string>
<string name="error_initializing_web_view_wrong_arch">Chyba inicializace WebView. Ujistěte se, že máte nainstalován WebView podporující architekturu arm64.\nChyba: %s</string>
<string name="v6_0_private_routing_descr">Chrání vaši IP adresu a připojení.</string>
<string name="forward_files_messages_deleted_after_selection_desc">Zprávy byly odstraněny poté, co jste je vybrali.</string>
<string name="network_session_mode_session_description">Nové přihlašovací údaje SOCKS budou použity pokaždé, když zapnete aplikaci.</string>
<string name="network_session_mode_server_description">Nové přihlašovací údaje SOCKS budou použity pro každý server.</string>
<string name="servers_info_reconnect_servers_message">Znovu připojte všechny připojené servery pro vynucení doručení. Využívá další provoz.</string>
<string name="reset_all_hints">Resetovat všechny tipy</string>
<string name="forward_files_in_progress_desc">%1$d soubor(y) stále stahuji.</string>
<string name="v6_1_message_dates_descr">Lepší datování zpráv.</string>
<string name="v6_1_better_security">Lepší zabezpečení ✅</string>
<string name="chunks_deleted">Části odstraněny</string>
<string name="info_view_connect_button">připojení</string>
<string name="current_user">Aktuální profil</string>
<string name="servers_info_reconnect_server_error">Chyba znovu připojení serveru</string>
<string name="servers_info_reconnect_servers_error">Chyba při opětovném připojování serverů</string>
<string name="servers_info_reconnect_server_message">Znovu připojte server pro vynucení doručení. Využívá další provoz.</string>
<string name="servers_info_modal_error_title">Chyba</string>
<string name="delete_messages_cannot_be_undone_warning">Zprávy budou smazány - nelze vrátit!</string>
<string name="delete_without_notification">Smazat bez upozornění</string>
<string name="info_view_search_button">hledat</string>
<string name="switching_profile_error_title">Chyba přepínání profilu</string>
<string name="select_chat_profile">Vyberte chat profil</string>
<string name="info_view_message_button">zpráva</string>
<string name="info_view_open_button">otevřít</string>
<string name="contact_deleted">Kontakt smazán!</string>
<string name="member_info_member_inactive">neaktivní</string>
<string name="servers_info_details">Detaily</string>
<string name="servers_info_reset_stats">Resetovat všechny statistiky</string>
<string name="please_try_later">Prosím zkuste později.</string>
<string name="private_routing_error">Chyba soukromého směrování</string>
<string name="network_error_broker_host_desc">Adresa serveru není kompatibilní s nastavením sítě: %1$s.</string>
<string name="member_inactive_title">Člen neaktivní</string>
<string name="member_inactive_desc">Zpráva může být doručena později až bude člen aktivní.</string>
<string name="message_forwarded_desc">Zatím bez přímého spojení, zpráva je předána adminem.</string>
<string name="cant_call_contact_connecting_wait_alert_text">Připojování ke kontaktu, počkejte nebo se podívejte později!</string>
<string name="cant_call_contact_deleted_alert_text">Kontakt odstraněn.</string>
<string name="deletion_errors">Chyby mazání</string>
<string name="servers_info_detailed_statistics">Podrobné statistiky</string>
<string name="chunks_downloaded">Části staženy</string>
<string name="network_session_mode_server">Server</string>
<string name="network_smp_proxy_fallback_allow_protected_description">Odesílat zprávy přímo, když je IP adresa chráněna a váš nebo cílový server nepodporuje soukromé směrování.</string>
<string name="network_smp_proxy_fallback_allow_description">Odeslat zprávy přímo, když váš nebo cílový server nepodporuje soukromé směrování.</string>
<string name="app_check_for_updates">Zkontrolovat aktualizace</string>
<string name="app_check_for_updates_notice_disable">Vypnout</string>
<string name="app_check_for_updates_disabled">Vypnut</string>
<string name="app_check_for_updates_button_download">Stáhnout %s (%s)</string>
<string name="invite_friends_short">Pozvat</string>
<string name="create_address_button">Vytvořit</string>
<string name="settings_message_shape_corner">Roh</string>
<string name="settings_section_title_message_shape">Tvar zpráv</string>
<string name="chat_database_exported_continue">Pokračovat</string>
<string name="call_desktop_permission_denied_chrome">Klikněte na info tlačítko blízko pole adresy, pro použití mikrofonu.</string>
<string name="call_desktop_permission_denied_safari">Otevřete nastavení Safari / Webové stránky / mikrofon, vyberte možnost Povolit pro localhost.</string>
<string name="appearance_font_size">Velikost písma</string>
<string name="v6_0_upgrade_app_descr">Stáhnout nové verze z GitHubu.</string>
<string name="v6_0_reachable_chat_toolbar">Dosažitelný panel nástrojů chatu</string>
<string name="migrate_from_device_remove_archive_question">Odebrat archiv?</string>
<string name="servers_info_files_tab">Soubory</string>
<string name="servers_info_messages_sent">Odeslaných zpráv</string>
<string name="servers_info_downloaded">Staženo</string>
<string name="servers_info_reconnect_server_title">Znovu připojit server?</string>
<string name="decryption_errors">chyba dešifrování</string>
<string name="v6_1_better_calls">Lepší volání</string>
<string name="v6_1_better_user_experience">Větší přívětivost</string>
<string name="v6_1_customizable_message_descr">Přizpůsobitelný tvar zpráv.</string>
<string name="v6_1_delete_many_messages_descr">Smazat nebo moderovat až 200 zpráv.</string>
<string name="v6_1_forward_many_messages_descr">Předat až 20 zpráv najednou.</string>
<string name="servers_info_missing">Žádné info, zkuste načíst znovu</string>
<string name="servers_info">Informace o serverech</string>
<string name="downloaded_files">Stažené soubory</string>
<string name="download_errors">Chyby stahování</string>
<string name="servers_info_reset_stats_alert_error_title">Chyba resetování statistik</string>
<string name="servers_info_detailed_statistics_received_messages_header">Přijaté zprávy</string>
<string name="servers_info_detailed_statistics_received_total">Přijato celkem</string>
<string name="servers_info_detailed_statistics_receive_errors">Chyb přijmutí</string>
<string name="servers_info_reconnect_all_servers_button">Připojte znovu všechny servery</string>
<string name="servers_info_reset_stats_alert_confirm">Reset</string>
<string name="servers_info_reset_stats_alert_title">Resetovat všechny statistiky?</string>
<string name="servers_info_detailed_statistics_sent_messages_header">Odeslané zprávy</string>
<string name="servers_info_detailed_statistics_sent_messages_total">Odeslaných celkem</string>
<string name="server_address">Adresa serveru</string>
<string name="one_hand_ui">Dosažitelný panel nástrojů chatu</string>
<string name="acknowledgement_errors">Chyba potvrzení</string>
<string name="connections">Připojení</string>
<string name="created">Vytvořen</string>
<string name="expired_label">prošlý</string>
<string name="other_label">jiné</string>
<string name="other_errors">jiné chyby</string>
<string name="reconnect">Znovu připojit</string>
<string name="send_errors">Chyby odesílání</string>
<string name="sent_directly">Odesláno přímo</string>
<string name="sent_via_proxy">Odeslaných přes proxy</string>
<string name="delete_members_messages__question">Odstranit %d zpráv členů?</string>
<string name="delete_messages_mark_deleted_warning">Zprávy budou označeny pro smazání. Příjemci budou moci tyto zprávy odhalit.</string>
<string name="select_verb">Vybrat</string>
<string name="compose_message_placeholder">Zpráva</string>
<string name="selected_chat_items_nothing_selected">Nic nevybráno</string>
<string name="selected_chat_items_selected_n">Vybrány %d</string>
<string name="privacy_media_blur_radius_medium">Střední</string>
<string name="servers_info_subscriptions_section_header">Příjem zpráv</string>
<string name="xftp_servers_configured">Nastavené XFTP servery</string>
<string name="media_and_file_servers">Servery médií a souborů</string>
<string name="message_servers">Servery zpráv</string>
<string name="xftp_servers_other">Jiné FXTP servery</string>
<string name="action_button_add_members">Pozvat</string>
<string name="cant_call_member_send_message_alert_text">Pošlete zprávu pro povolení volání.</string>
</resources>
@@ -2119,13 +2119,13 @@
<string name="network_session_mode_server_description">Se usarán credenciales SOCKS nuevas por cada servidor.</string>
<string name="network_session_mode_server">Servidor</string>
<string name="v6_1_better_calls">Llamadas mejoradas</string>
<string name="v6_1_message_dates_descr">Sistema de fechas mejorado.</string>
<string name="v6_1_message_dates_descr">Mensajes mejor datados.</string>
<string name="v6_1_better_user_experience">Experiencia de usuario mejorada</string>
<string name="v6_1_customizable_message_descr">Forma personalizable de los mensajes.</string>
<string name="v6_1_forward_many_messages_descr">Desplazamiento de hasta 20 mensajes.</string>
<string name="v6_1_better_security_descr">Protocolos de SimpleX auditados por Trail of Bits.</string>
<string name="v6_1_better_calls_descr">Intercambia audio y video durante la llamada.</string>
<string name="v6_1_better_security">Seguridad mejorada ✅</string>
<string name="v6_1_delete_many_messages_descr">Borra o modera hasta 200 mensajes a la vez.</string>
<string name="v6_1_delete_many_messages_descr">Borrar o moderar hasta 200 mensajes.</string>
<string name="v6_1_switch_chat_profile_descr">Cambia el perfil de chat para invitaciones de un solo uso.</string>
</resources>
@@ -49,7 +49,7 @@
<string name="socks_proxy_setting_limitations"><![CDATA[<b>Megjegyzés:</b> az üzenet- és fájlközvetítő-kiszolgálók SOCKS proxyn keresztül kapcsolódnak. A hívások és a hivatkozások előnézetének elküldése közvetlen kapcsolatot használnak.]]></string>
<string name="full_backup">Alkalmazásadatok biztonsági mentése</string>
<string name="database_initialization_error_title">Az adatbázis előkészítése sikertelen</string>
<string name="all_your_contacts_will_remain_connected_update_sent">Az ismerőseivel kapcsolatban marad. A profil-változtatások frissítésre kerülnek az ismerősöknél.</string>
<string name="all_your_contacts_will_remain_connected_update_sent">Az ismerőseivel kapcsolatban marad. A profil változtatások frissítésre kerülnek az ismerősöknél.</string>
<string name="v4_5_transport_isolation_descr">A csevegési profillal (alapértelmezett), vagy a kapcsolattal (BÉTA).</string>
<string name="connect__a_new_random_profile_will_be_shared">Egy új véletlenszerű profil lesz megosztva.</string>
<string name="allow_voice_messages_only_if">A hangüzenetek küldése csak abban az esetben van engedélyezve, ha az ismerőse is engedélyezi.</string>
@@ -219,7 +219,7 @@
<string name="connecting_to_desktop">Kapcsolódás a számítógéphez</string>
<string name="network_session_mode_entity">Kapcsolat</string>
<string name="correct_name_to">Név helyesbítése erre: %s?</string>
<string name="connection_timeout">Időtúllépés kapcsolódáskor</string>
<string name="connection_timeout">Kapcsolat időtúllépés</string>
<string name="connect_with_contact_name_question">Kapcsolódás %1$s által?</string>
<string name="create_profile_button">Létrehozás</string>
<string name="contact_preferences">Ismerős beállításai</string>
@@ -357,7 +357,7 @@
<string name="database_encryption_will_be_updated_in_settings">Adatbázis titkosítási jelmondat frissül és eltárolásra kerül a beállításokban.</string>
<string name="info_row_database_id">Adatbázis-azonosító</string>
<string name="share_text_database_id">Adatbázis-azonosító: %d</string>
<string name="developer_options">Adatbázis-azonosítók és átvitel-izolációs beállítások.</string>
<string name="developer_options">Adatbázis-azonosítók és átviteli izolációs beállítások.</string>
<string name="database_encryption_will_be_updated">Az adatbázis-titkosítási jelmondat megváltoztatásra és mentésre kerül a Keystore-ban.</string>
<string name="database_will_be_encrypted_and_passphrase_stored_in_settings">Az adatbázis titkosításra kerül és a jelmondat eltárolásra a beállításokban.</string>
<string name="smp_servers_delete_server">Kiszolgáló törlése</string>
@@ -504,7 +504,7 @@
<string name="error_starting_chat">Hiba a csevegés elindításakor</string>
<string name="group_profile_is_stored_on_members_devices">A csoport profilja a tagok eszközein tárolódik, nem a kiszolgálókon.</string>
<string name="enter_passphrase">Jelmondat megadása…</string>
<string name="error_updating_user_privacy">Hiba a felhasználói adatvédelem frissítésekor</string>
<string name="error_updating_user_privacy">Hiba a felhasználói beállítások frissítésekor</string>
<string name="encrypt_database">Titkosít</string>
<string name="alert_title_no_group">Csoport nem található!</string>
<string name="error_saving_smp_servers">Hiba az SMP-kiszolgálók mentésekor</string>
@@ -542,7 +542,7 @@
<string name="files_and_media">Fájlok és médiatartalmak</string>
<string name="section_title_for_console">KONZOLHOZ</string>
<string name="alert_text_encryption_renegotiation_failed">Sikertelen titkosítás-újraegyeztetés.</string>
<string name="error_deleting_user">Hiba a felhasználó-profil törlésekor</string>
<string name="error_deleting_user">Hiba a felhasználói profil törlésekor</string>
<string name="fix_connection_not_supported_by_group_member">Csoporttag általi javítás nem támogatott</string>
<string name="enter_welcome_message">Üdvözlőüzenet megadása…</string>
<string name="encrypted_database">Titkosított adatbázis</string>
@@ -642,7 +642,7 @@
<string name="onboarding_notifications_mode_service">Azonnali</string>
<string name="v5_4_incognito_groups">Inkognitócsoportok</string>
<string name="how_to">Hogyan</string>
<string name="hide_verb">Összecsukás</string>
<string name="hide_verb">Elrejtés</string>
<string name="gallery_image_button">Kép</string>
<string name="v4_3_improved_privacy_and_security">Fejlesztett adatvédelem és biztonság</string>
<string name="ignore">Mellőzés</string>
@@ -677,7 +677,7 @@
<string name="if_you_cannot_meet_in_person_show_QR_in_video_call_or_via_another_channel"><![CDATA[Ha nem tud személyesen találkozni, <b>mutassa meg a QR-kódot a videohívásban</b>, vagy ossza meg a hivatkozást.]]></string>
<string name="network_disable_socks_info">Megerősítés esetén az üzenetküldő-kiszolgálók látni fogják az IP-címét és a szolgáltatóját azt, hogy mely kiszolgálókhoz kapcsolódik.</string>
<string name="image_will_be_received_when_contact_completes_uploading">A kép akkor érkezik meg, amikor a küldője befejezte annak feltöltését.</string>
<string name="desktop_scan_QR_code_from_app_via_scan_QR_code"><![CDATA[💻 számítógép: a megjelenített QR-kód beolvasása az alkalmazásból, a <b>QR-kód beolvasásával</b>.]]></string>
<string name="desktop_scan_QR_code_from_app_via_scan_QR_code"><![CDATA[💻 számítógép: a megjelenített QR-kód beolvasása az alkalmazásból, a <b>QR kód beolvasásával</b>.]]></string>
<string name="if_you_received_simplex_invitation_link_you_can_open_in_browser">A kapott SimpleX Chat-meghívó-hivatkozását megnyithatja a böngészőjében:</string>
<string name="if_you_enter_self_destruct_code">Ha az alkalmazás megnyitásakor megadja az önmegsemmisítő jelkódot:</string>
<string name="found_desktop">Megtalált számítógép</string>
@@ -686,7 +686,7 @@
<string name="create_chat_profile">Csevegési profil létrehozása</string>
<string name="immune_to_spam_and_abuse">Levélszemét elleni védelem</string>
<string name="disconnect_remote_hosts">Hordozható eszközök leválasztása</string>
<string name="v4_5_multiple_chat_profiles_descr">Különböző nevek, profilképek és átvitel-izoláció.</string>
<string name="v4_5_multiple_chat_profiles_descr">Különböző nevek, avatarok és átviteli izoláció.</string>
<string name="if_you_choose_to_reject_the_sender_will_not_be_notified">Elutasítás esetén a feladó NEM kap értesítést.</string>
<string name="icon_descr_expand_role">Szerepkörválasztás bővítése</string>
<string name="image_will_be_received_when_contact_is_online">A kép akkor érkezik meg, amikor a küldője elérhető lesz, várjon, vagy ellenőrizze később!</string>
@@ -801,10 +801,10 @@
<string name="v4_5_multiple_chat_profiles">Több csevegőprofil</string>
<string name="marked_deleted_description">törlésre jelölve</string>
<string name="user_mute">Némítás</string>
<string name="link_a_mobile">Hordozható eszköz társítása</string>
<string name="link_a_mobile">Egy hordozható eszköz társítása</string>
<string name="settings_notifications_mode_title">Értesítési szolgáltatás</string>
<string name="only_group_owners_can_enable_voice">Csak a csoporttulajdonosok engedélyezhetik a hangüzenetek küldését.</string>
<string name="only_client_devices_store_contacts_groups_e2e_encrypted_messages"><![CDATA[Csak az alkalmazások tárolják a felhasználó-profilokat, ismerősöket, csoportokat és a <b>2 rétegű végpontok közötti titkosítással</b> küldött üzeneteket.]]></string>
<string name="only_client_devices_store_contacts_groups_e2e_encrypted_messages"><![CDATA[Csak az alkalmazások tárolják a felhasználói profilokat, ismerősöket, csoportokat és a <b>2 rétegű végpontok közötti titkosítással</b> küldött üzeneteket.]]></string>
<string name="invalid_migration_confirmation">Érvénytelen átköltöztetési visszaigazolás</string>
<string name="only_group_owners_can_change_prefs">Csak a csoporttulajdonosok módosíthatják a csoportbeállításokat.</string>
<string name="no_history">Nincsenek előzmények</string>
@@ -822,7 +822,7 @@
<string name="feature_offered_item">ajánlott %s</string>
<string name="button_leave_group">Csoport elhagyása</string>
<string name="unblock_member_desc">Minden %s által írt üzenet megjelenik!</string>
<string name="many_people_asked_how_can_it_deliver"><![CDATA[Sokan kérdezték: <i>Ha a SimpleX Chatnek nincs felhasználó-azonosítója, hogyan lehet mégis üzeneteket küldeni?</i>]]></string>
<string name="many_people_asked_how_can_it_deliver"><![CDATA[Sokan kérdezték: <i>Ha a SimpleX Chatnek nincs felhasználói azonosítója, hogyan lehet mégis üzeneteket küldeni?</i>]]></string>
<string name="alert_text_skipped_messages_it_can_happen_when">Ez akkor fordulhat elő, ha:\n1. Az üzenetek 2 nap után, vagy a kiszolgálón 30 nap után lejártak.\n2. Az üzenet visszafejtése sikertelen volt, mert Ön, vagy az ismerőse régebbi adatbázis biztonsági mentést használt.\n3. A kapcsolat sérült.</string>
<string name="group_member_role_observer">megfigyelő</string>
<string name="description_via_group_link_incognito">inkognitó a csoporthivatkozáson keresztül</string>
@@ -893,13 +893,13 @@
<string name="add_contact_or_create_group">Új csevegés kezdése</string>
<string name="opensource_protocol_and_code_anybody_can_run_servers">Bárki üzemeltethet kiszolgálókat.</string>
<string name="rcv_group_event_open_chat">Megnyitás</string>
<string name="network_option_protocol_timeout">Protokoll időtúllépése</string>
<string name="network_option_protocol_timeout">Protokoll időtúllépés</string>
<string name="secret_text">titkos</string>
<string name="settings_notification_preview_mode_title">Értesítés előnézete</string>
<string name="callstate_waiting_for_confirmation">várakozás a visszaigazolásra…</string>
<string name="stop_file__action">Fájl megállítása</string>
<string name="description_via_group_link">a csoporthivatkozáson keresztül</string>
<string name="network_option_ping_interval">Időtartam a PING-ek között</string>
<string name="network_option_ping_interval">PING időköze</string>
<string name="send_disappearing_message">Eltűnő üzenet küldése</string>
<string name="self_destruct_passcode">Önmegsemmisítési jelkód</string>
<string name="save_and_update_group_profile">Mentés és a csoportprofil frissítése</string>
@@ -979,12 +979,12 @@
<string name="reject_contact_button">Elutasítás</string>
<string name="notification_preview_mode_message_desc">Ismerős nevének és az üzenet tartalmának megjelenítése</string>
<string name="settings_section_title_settings">BEÁLLÍTÁSOK</string>
<string name="save_profile_password">Profiljelszó mentése</string>
<string name="save_profile_password">Felhasználói fiók jelszavának mentése</string>
<string name="stop_snd_file__title">Fájlküldés megállítása?</string>
<string name="unlink_desktop_question">Számítógép leválasztása?</string>
<string name="voice_messages_prohibited">A hangüzenetek le vannak tilva!</string>
<string name="compose_send_direct_message_to_connect">Közvetlen üzenet küldése a kapcsolódáshoz</string>
<string name="network_option_ping_count">PING-ek száma</string>
<string name="network_option_ping_count">PING számláló</string>
<string name="show_developer_options">Fejlesztői beállítások megjelenítése</string>
<string name="rcv_group_event_1_member_connected">%s kapcsolódott</string>
<string name="theme_system">Rendszer</string>
@@ -1065,7 +1065,7 @@
<string name="onboarding_notifications_mode_title">Privát értesítések</string>
<string name="you_invited_a_contact">Meghívta egy ismerősét</string>
<string name="is_not_verified">%s nincs hitelesítve</string>
<string name="contact_tap_to_connect">Koppintson ide a kapcsolódáshoz</string>
<string name="contact_tap_to_connect">Koppintson a kapcsolódáshoz</string>
<string name="this_device_name">Ennek az eszköznek a neve</string>
<string name="your_current_profile">Jelenlegi profil</string>
<string name="smp_server_test_upload_file">Fájl feltöltése</string>
@@ -1124,7 +1124,7 @@
<string name="settings_section_title_use_from_desktop">Társítás számítógéppel</string>
<string name="settings_section_title_you">PROFIL</string>
<string name="network_proxy_port">port %d</string>
<string name="to_connect_via_link_title">Kapcsolódás egy hivatkozáson keresztül</string>
<string name="to_connect_via_link_title">Kapcsolódás hivatkozáson keresztül</string>
<string name="share_address">Cím megosztása</string>
<string name="smp_servers_scan_qr">A kiszolgáló QR-kódjának beolvasása</string>
<string name="stop_chat_confirmation">Megállítás</string>
@@ -1218,7 +1218,7 @@
<string name="snd_group_event_member_deleted">Ön eltávolította őt: %1$s</string>
<string name="save_passphrase_and_open_chat">Jelmondat mentése és a csevegés megnyitása</string>
<string name="save_preferences_question">Beállítások mentése?</string>
<string name="first_platform_without_user_ids">Nincsenek felhasználó-azonosítók.</string>
<string name="first_platform_without_user_ids">Nincsenek felhasználói azonosítók.</string>
<string name="prohibit_direct_messages">A közvetlen üzenetek küldése a tagok között le van tiltva.</string>
<string name="network_enable_socks">SOCKS proxy használata?</string>
<string name="icon_descr_speaker_off">Hangszóró kikapcsolva</string>
@@ -1279,14 +1279,14 @@
<string name="use_simplex_chat_servers__question">SimpleX Chat-kiszolgálók használata?</string>
<string name="unhide_chat_profile">Csevegési profil felfedése</string>
<string name="v5_0_large_files_support">Videók és fájlok 1Gb méretig</string>
<string name="network_option_tcp_connection_timeout">TCP kapcsolat időtúllépése</string>
<string name="network_option_tcp_connection_timeout">TCP kapcsolat időtúllépés</string>
<string name="connect__your_profile_will_be_shared">A(z) %1$s nevű profiljának SimpleX-címe megosztásra fog kerülni.</string>
<string name="you_are_already_connected_to_vName_via_this_link">Ön már kapcsolódva van ehhez: %1$s.</string>
<string name="your_current_chat_database_will_be_deleted_and_replaced_with_the_imported_one">Jelenlegi csevegési adatbázis TÖRLÉSRE és FELCSERÉLÉSRE kerül az importált által!
\nEz a művelet nem vonható vissza - profiljai, ismerősei, csevegési üzenetei és fájljai véglegesen törölve lesznek.</string>
<string name="chat_with_the_founder">Ötletek és javaslatok</string>
<string name="database_downgrade_warning">Figyelmeztetés: néhány adat elveszhet!</string>
<string name="tap_to_start_new_chat">Koppintson ide az új csevegés indításához</string>
<string name="tap_to_start_new_chat">Koppintson az új csevegés indításához</string>
<string name="waiting_for_desktop">Várakozás a számítógépre…</string>
<string name="next_generation_of_private_messaging">A privát üzenetküldés
\nkövetkező generációja</string>
@@ -1311,7 +1311,7 @@
<string name="restore_passphrase_not_found_desc">A jelszó nem található a Keystore-ban, ezért kézzel szükséges megadni. Ez akkor történhetett meg, ha visszaállította az alkalmazás adatait egy biztonságimentési eszközzel. Ha nem így történt, akkor lépjen kapcsolatba a fejlesztőkkel.</string>
<string name="your_contacts_will_remain_connected">Az ismerősei továbbra is kapcsolódva maradnak.</string>
<string name="error_xftp_test_server_auth">A kiszolgálónak engedélyre van szüksége a várólisták létrehozásához, ellenőrizze jelszavát</string>
<string name="database_initialization_error_desc">Az adatbázis nem működik megfelelően. Koppintson ide a további információkért</string>
<string name="database_initialization_error_desc">Az adatbázis nem működik megfelelően. Koppintson további információért</string>
<string name="stop_snd_file__message">A fájl küldése leállt.</string>
<string name="trying_to_connect_to_server_to_receive_messages">Kapcsolódási kísérlet ahhoz a kiszolgálóhoz, amely az adott ismerősétől érkező üzenetek fogadására szolgál.</string>
<string name="la_could_not_be_verified">Nem sikerült hitelesíteni; próbálja meg újra.</string>
@@ -1368,7 +1368,7 @@
<string name="connect_plan_you_are_already_joining_the_group_vName"><![CDATA[A csatlakozás már folyamatban van a(z) <b>%1$s</b> nevű csoporthoz.]]></string>
<string name="onboarding_notifications_mode_off">Amikor az alkalmazás fut</string>
<string name="alert_title_cant_invite_contacts_descr">Inkognitóprofilt használ ehhez a csoporthoz - fő profilja megosztásának elkerülése érdekében a meghívók küldése le van tiltva</string>
<string name="v4_5_transport_isolation">Átvitel-izoláció</string>
<string name="v4_5_transport_isolation">Kapcsolat izolációs mód</string>
<string name="you_will_be_connected_when_your_connection_request_is_accepted">Akkor lesz kapcsolódva, ha a kapcsolatkérése elfogadásra kerül, várjon, vagy ellenőrizze később!</string>
<string name="voice_messages_are_prohibited">A hangüzenetek küldése le van tiltva ebben a csoportban.</string>
<string name="system_restricted_background_in_call_warn"><![CDATA[A háttérben való hívásokhoz válassza ki az <b>Alkalmazás akkumulátor-használata</b> / <b>Korlátlan</b> módot az alkalmazás beállításaiban.]]></string>
@@ -1386,11 +1386,11 @@
<string name="your_profile_is_stored_on_device_and_shared_only_with_contacts_simplex_cannot_see_it">A profilja az eszközén van tárolva és csak az ismerőseivel kerül megosztásra. A SimpleX-kiszolgálók nem láthatják a profilját.</string>
<string name="snd_group_event_changed_member_role">Ön megváltoztatta %s szerepkörét erre: %s</string>
<string name="you_rejected_group_invitation">Csoportmeghívó elutasítva</string>
<string name="to_protect_privacy_simplex_has_ids_for_queues">Az adatvédelem érdekében, a más csevegési platformokon megszokott felhasználó-azonosítók helyett, a SimpleX csak az üzenetek sorbaállításához használ azonosítókat, minden egyes ismerőshöz egy-egy különbözőt.</string>
<string name="to_protect_privacy_simplex_has_ids_for_queues">Az adatvédelem érdekében, a más csevegési platformokon megszokott felhasználói azonosítók helyett, a SimpleX csak az üzenetek sorbaállításához használ azonosítókat, minden egyes ismerőshöz egy-egy különbözőt.</string>
<string name="to_share_with_your_contact">(a megosztáshoz az ismerősével)</string>
<string name="you_sent_group_invitation">Csoportmeghívó elküldve</string>
<string name="update_network_session_mode_question">Átvitel-izoláció módjának frissítése?</string>
<string name="network_session_mode_transport_isolation">Átvitel-izoláció</string>
<string name="update_network_session_mode_question">Kapcsolat izolációs mód frissítése?</string>
<string name="network_session_mode_transport_isolation">Kapcsolat izolációs mód</string>
<string name="you_will_stop_receiving_messages_from_this_group_chat_history_will_be_preserved">Ettől a csoporttól nem fog értesítéseket kapni. A csevegési előzmények megmaradnak.</string>
<string name="database_is_not_encrypted">A csevegési adatbázis nem titkosított - állítson be egy jelmondatot annak védelméhez.</string>
<string name="network_disable_socks">Közvetlen internet kapcsolat használata?</string>
@@ -1421,7 +1421,7 @@
<string name="you_can_connect_to_simplex_chat_founder"><![CDATA[Kapcsolatba léphet <font color="#0088ff">a SimpleX Chat fejlesztőivel, ahol bármiről kérdezhet és értesülhet az újdonságokról</font>.]]></string>
<string name="v4_2_auto_accept_contact_requests_desc">Nem kötelező üdvözlőüzenettel.</string>
<string name="unknown_database_error_with_info">Ismeretlen adatbázishiba: %s</string>
<string name="you_can_hide_or_mute_user_profile">Elrejtheti vagy lenémíthatja a felhasználó-profiljait - koppintson (vagy számítógép-alkalmazásban kattintson) hosszan a profilra a felugró menühöz.</string>
<string name="you_can_hide_or_mute_user_profile">Elrejtheti vagy lenémíthatja a felhasználó profiljait - koppintson (vagy számítógép-alkalmazásban kattintson) hosszan a profilra a felugró menühöz.</string>
<string name="v5_3_simpler_incognito_mode_descr">Inkognitómód használata kapcsolódáskor.</string>
<string name="you_can_share_group_link_anybody_will_be_able_to_connect">Megoszthat egy hivatkozást vagy QR-kódot - így bárki csatlakozhat a csoporthoz. Ha a csoport később törlésre kerül, akkor nem fogja elveszíteni annak tagjait.</string>
<string name="you_joined_this_group">Csatlakozott ehhez a csoporthoz</string>
@@ -1438,12 +1438,12 @@
<string name="v4_6_group_welcome_message_descr">Megjelenítendő üzenet beállítása az új tagok számára!</string>
<string name="whats_new_thanks_to_users_contribute_weblate">Köszönet a felhasználóknak - hozzájárulás a Weblate-en!</string>
<string name="sending_delivery_receipts_will_be_enabled">A kézbesítési jelentés küldése minden ismerőse számára engedélyezésre kerül.</string>
<string name="network_option_protocol_timeout_per_kb">Protokoll időtúllépése KB-onként</string>
<string name="network_option_protocol_timeout_per_kb">Protokoll időkorlát KB-onként</string>
<string name="database_backup_can_be_restored">Az adatbázis-jelmondat megváltoztatására tett kísérlet nem fejeződött be.</string>
<string name="enable_automatic_deletion_message">Ez a művelet nem vonható vissza - a kiválasztottnál korábban küldött és fogadott üzenetek törlésre kerülnek. Ez több percet is igénybe vehet.</string>
<string name="profile_is_only_shared_with_your_contacts">A profilja csak az ismerőseivel kerül megosztásra.</string>
<string name="smp_servers_test_some_failed">Néhány kiszolgáló megbukott a teszten:</string>
<string name="group_invitation_tap_to_join">Koppintson ide a csatlakozáshoz</string>
<string name="group_invitation_tap_to_join">Koppintson a csatlakozáshoz</string>
<string name="delete_files_and_media_desc">Ez a művelet nem vonható vissza - az összes fogadott és küldött fájl a médiatartalmakkal együtt törlésre kerülnek. Az alacsony felbontású képek viszont megmaradnak.</string>
<string name="receipts_contacts_override_enabled">A kézbesítési jelentések engedélyezve vannak %d ismerősnél</string>
<string name="sending_via">Küldés ezen keresztül:</string>
@@ -1457,7 +1457,7 @@
<string name="contact_you_shared_link_with_wont_be_able_to_connect">Az ismerőse, akivel megosztotta ezt a hivatkozást, NEM fog tudni kapcsolódni!</string>
<string name="you_can_change_it_later">A véletlenszerű jelmondat egyszerű szövegként van tárolva a beállításokban.
\nEz később megváltoztatható.</string>
<string name="group_invitation_tap_to_join_incognito">Koppintson ide az inkognitóban való kapcsolódáshoz</string>
<string name="group_invitation_tap_to_join_incognito">Koppintson az inkognitóban való kapcsolódáshoz</string>
<string name="set_password_to_export">Jelmondat beállítása az exportáláshoz</string>
<string name="receipts_groups_override_disabled">A kézbesítési jelentések le vannak tiltva %d csoportban</string>
<string name="non_fatal_errors_occured_during_import">Néhány nem végzetes hiba történt az importáláskor:</string>
@@ -1519,7 +1519,7 @@
<string name="recent_history">Látható előzmények</string>
<string name="la_app_passcode">Alkalmazás jelkód</string>
<string name="add_contact_tab">Ismerős hozzáadása</string>
<string name="tap_to_scan">Koppintson ide a QR-kód beolvasásához</string>
<string name="tap_to_scan">Koppintson a beolvasáshoz</string>
<string name="tap_to_paste_link">Koppintson ide a hivatkozás beillesztéséhez</string>
<string name="add_contact_button_to_create_link_or_connect_via_link"><![CDATA[<b>Ismerős hozzáadása</b>: új meghívó-hivatkozás létrehozásához, vagy egy kapott hivatkozáson keresztül történő kapcsolódáshoz.]]></string>
<string name="create_group_button_to_create_new_group"><![CDATA[<b>Csoport létrehozása</b>: új csoport létrehozásához.]]></string>
@@ -1768,7 +1768,7 @@
<string name="network_smp_proxy_mode_never">Soha</string>
<string name="network_smp_proxy_mode_unknown">Ismeretlen kiszolgálók</string>
<string name="network_smp_proxy_fallback_allow_protected">Ha az IP-cím rejtett</string>
<string name="private_routing_show_message_status">Üzenetállapot megjelenítése</string>
<string name="private_routing_show_message_status">Üzenet állapot megjelenítése</string>
<string name="network_smp_proxy_fallback_allow_downgrade">Visszafejlesztés engedélyezése</string>
<string name="network_smp_proxy_mode_always">Mindig</string>
<string name="network_smp_proxy_fallback_prohibit">Nem</string>
@@ -1874,7 +1874,8 @@
<string name="servers_info_sessions_connecting">Kapcsolódás</string>
<string name="servers_info_sessions_errors">Hibák</string>
<string name="servers_info_subscriptions_connections_pending">Függőben</string>
<string name="servers_info_private_data_disclaimer">Statisztikagyűjtés kezdete: %s.\nMinden adat biztonságban van az eszközén.</string>
<string name="servers_info_private_data_disclaimer">Ekkortól kezdve: %s.
\nMinden adat biztonságban van az eszközén.</string>
<string name="servers_info_messages_sent">Elküldött üzenetek</string>
<string name="servers_info_proxied_servers_section_header">Proxyzott kiszolgálók</string>
<string name="servers_info_reconnect_servers_title">Újrakapcsolódás a kiszolgálókhoz?</string>
@@ -1890,15 +1891,15 @@
<string name="servers_info_downloaded">Letöltve</string>
<string name="expired_label">lejárt</string>
<string name="other_label">egyéb</string>
<string name="servers_info_detailed_statistics_received_total">Összes fogadott üzenet</string>
<string name="servers_info_detailed_statistics_received_total">Összes fogadott</string>
<string name="servers_info_detailed_statistics_receive_errors">Üzenetfogadási hibák</string>
<string name="reconnect">Újrakapcsolás</string>
<string name="send_errors">Üzenetküldési hibák</string>
<string name="sent_directly">Közvetlenül küldött</string>
<string name="servers_info_detailed_statistics_sent_messages_total">Összes elküldött üzenet</string>
<string name="servers_info_detailed_statistics_sent_messages_total">Összes elküldött</string>
<string name="sent_via_proxy">Proxyn keresztül küldve</string>
<string name="smp_server">SMP-kiszolgáló</string>
<string name="servers_info_starting_from">Statisztikagyűjtés kezdete: %s.</string>
<string name="servers_info_starting_from">Ekkortól kezdve: %s.</string>
<string name="servers_info_uploaded">Feltöltve</string>
<string name="xftp_server">XFTP-kiszolgáló</string>
<string name="proxied">Proxyzott</string>
@@ -1926,7 +1927,7 @@
<string name="xftp_servers_configured">Konfigurált XFTP-kiszolgálók</string>
<string name="servers_info_sessions_connected">Kapcsolódva</string>
<string name="current_user">Jelenlegi profil</string>
<string name="servers_info_details">További részletek</string>
<string name="servers_info_details">Részletek</string>
<string name="decryption_errors">visszafejtési hibák</string>
<string name="deleted">Törölve</string>
<string name="servers_info_messages_received">Fogadott üzenetek</string>
@@ -1943,7 +1944,7 @@
<string name="servers_info_reconnect_server_message">A kiszolgálóhoz való újrakapcsolódás az üzenetkézbesítési jelentések kikényszerítéséhez. Ez további adatforgalmat használ.</string>
<string name="servers_info_detailed_statistics_sent_messages_header">Elküldött üzenetek</string>
<string name="servers_info_transport_sessions_section_header">Munkamenetek átvitele</string>
<string name="servers_info_subscriptions_total">Összes kapcsolat</string>
<string name="servers_info_subscriptions_total">Összesen</string>
<string name="servers_info_statistics_section_header">Statisztikák</string>
<string name="servers_info_target">Információk megjelenítése ehhez:</string>
<string name="network_error_broker_version_desc">A kiszolgáló verziója nem kompatibilis az alkalmazással: %1$s.</string>
@@ -2120,7 +2120,7 @@
<string name="v6_1_message_dates_descr">Betere datums voor berichten.</string>
<string name="v6_1_better_user_experience">Betere gebruikerservaring</string>
<string name="v6_1_customizable_message_descr">Aanpasbare berichtvorm.</string>
<string name="v6_1_better_calls_descr">Wisselen tussen audio en video tijdens het gesprek.</string>
<string name="v6_1_better_calls_descr">Wissel tussen audio en video tijdens het gesprek.</string>
<string name="v6_1_switch_chat_profile_descr">Wijzig chatprofiel voor eenmalige uitnodigingen.</string>
<string name="v6_1_delete_many_messages_descr">Maximaal 200 berichten verwijderen of modereren.</string>
<string name="v6_1_forward_many_messages_descr">Stuur maximaal 20 berichten tegelijk door.</string>
@@ -2198,7 +2198,7 @@
<string name="v6_1_forward_many_messages_descr">Пересылайте до 20 сообщений за раз.</string>
<string name="v6_1_better_calls_descr">Переключайте звук и видео во время звонка.</string>
<string name="v6_1_switch_chat_profile_descr">Переключайте профиль чата для одноразовых приглашений.</string>
<string name="v6_1_better_security_descr">Аудит SimpleX протоколов от Trail of Bits.</string>
<string name="v6_1_better_security_descr">Анализ безопасности протоколов SimpleX от Trail of Bits.</string>
<string name="call_desktop_permission_denied_title">Чтобы совершать звонки, разрешите использовать микрофон. Завершите вызов и попробуйте позвонить снова.</string>
<string name="network_proxy_auth_mode_no_auth">Не использовать учетные данные с прокси.</string>
<string name="network_proxy_incorrect_config_title">Ошибка сохранения прокси</string>
@@ -63,7 +63,6 @@ const allowSendScreenAudio = false;
// When one side of a call sends candidates tot fast (until local & remote descriptions are set), that candidates
// will be stored here and then set when the call will be ready to process them
let afterCallInitializedCandidates = [];
const stopTrackOnAndroid = false;
const processCommand = (function () {
const defaultIceServers = [
{ urls: ["stuns:stun.simplex.im:443"] },
@@ -845,10 +844,7 @@ const processCommand = (function () {
// doing it vice versa gives an error like "too many cameras were open" on some Android devices or webViews
// which means the second camera will never be opened
for (const t of source == CallMediaSource.Mic ? call.localStream.getAudioTracks() : call.localStream.getVideoTracks()) {
if (isDesktop || source != CallMediaSource.Mic || stopTrackOnAndroid)
t.stop();
else
t.enabled = false;
t.stop();
call.localStream.removeTrack(t);
}
let localStream;
@@ -898,7 +894,7 @@ const processCommand = (function () {
if (!localStream || !oldCamera || !videos)
return;
if (!inactiveCallMediaSources.mic) {
localStream.getAudioTracks().forEach((elem) => (isDesktop || stopTrackOnAndroid ? elem.stop() : (elem.enabled = false)));
localStream.getAudioTracks().forEach((elem) => elem.stop());
localStream.getAudioTracks().forEach((elem) => localStream.removeTrack(elem));
}
if (!inactiveCallMediaSources.camera || oldCamera != newCamera) {
@@ -1161,10 +1157,7 @@ const processCommand = (function () {
transceiver.sender.replaceTrack(t);
}
else {
if (isDesktop || t.kind == CallMediaType.Video || stopTrackOnAndroid)
t.stop();
else
t.enabled = false;
t.stop();
s.removeTrack(t);
transceiver.sender.replaceTrack(null);
}
+4 -4
View File
@@ -26,11 +26,11 @@ android.enableJetifier=true
kotlin.mpp.androidSourceSetLayoutVersion=2
kotlin.jvm.target=11
android.version_name=6.1
android.version_code=247
android.version_name=6.1-beta.4
android.version_code=245
desktop.version_name=6.1
desktop.version_code=73
desktop.version_name=6.1-beta.4
desktop.version_code=71
kotlin.version=1.9.23
gradle.plugin.version=8.2.0
@@ -106,13 +106,11 @@ data DirectoryCmdTag (r :: DirectoryRole) where
DCConfirmDuplicateGroup_ :: DirectoryCmdTag 'DRUser
DCListUserGroups_ :: DirectoryCmdTag 'DRUser
DCDeleteGroup_ :: DirectoryCmdTag 'DRUser
DCSetRole_ :: DirectoryCmdTag 'DRUser
DCApproveGroup_ :: DirectoryCmdTag 'DRSuperUser
DCRejectGroup_ :: DirectoryCmdTag 'DRSuperUser
DCSuspendGroup_ :: DirectoryCmdTag 'DRSuperUser
DCResumeGroup_ :: DirectoryCmdTag 'DRSuperUser
DCListLastGroups_ :: DirectoryCmdTag 'DRSuperUser
DCListPendingGroups_ :: DirectoryCmdTag 'DRSuperUser
DCExecuteCommand_ :: DirectoryCmdTag 'DRSuperUser
deriving instance Show (DirectoryCmdTag r)
@@ -129,13 +127,11 @@ data DirectoryCmd (r :: DirectoryRole) where
DCConfirmDuplicateGroup :: UserGroupRegId -> GroupName -> DirectoryCmd 'DRUser
DCListUserGroups :: DirectoryCmd 'DRUser
DCDeleteGroup :: UserGroupRegId -> GroupName -> DirectoryCmd 'DRUser
DCSetRole :: GroupId -> GroupName -> GroupMemberRole -> DirectoryCmd 'DRUser
DCApproveGroup :: {groupId :: GroupId, displayName :: GroupName, groupApprovalId :: GroupApprovalId} -> DirectoryCmd 'DRSuperUser
DCRejectGroup :: GroupId -> GroupName -> DirectoryCmd 'DRSuperUser
DCSuspendGroup :: GroupId -> GroupName -> DirectoryCmd 'DRSuperUser
DCResumeGroup :: GroupId -> GroupName -> DirectoryCmd 'DRSuperUser
DCListLastGroups :: Int -> DirectoryCmd 'DRSuperUser
DCListPendingGroups :: Int -> DirectoryCmd 'DRSuperUser
DCExecuteCommand :: String -> DirectoryCmd 'DRSuperUser
DCUnknownCommand :: DirectoryCmd 'DRUser
DCCommandError :: DirectoryCmdTag r -> DirectoryCmd r
@@ -167,13 +163,11 @@ directoryCmdP =
"list" -> u DCListUserGroups_
"ls" -> u DCListUserGroups_
"delete" -> u DCDeleteGroup_
"role" -> u DCSetRole_
"approve" -> su DCApproveGroup_
"reject" -> su DCRejectGroup_
"suspend" -> su DCSuspendGroup_
"resume" -> su DCResumeGroup_
"last" -> su DCListLastGroups_
"pending" -> su DCListPendingGroups_
"exec" -> su DCExecuteCommand_
"x" -> su DCExecuteCommand_
_ -> fail "bad command tag"
@@ -190,19 +184,14 @@ directoryCmdP =
DCConfirmDuplicateGroup_ -> gc DCConfirmDuplicateGroup
DCListUserGroups_ -> pure DCListUserGroups
DCDeleteGroup_ -> gc DCDeleteGroup
DCSetRole_ -> do
(groupId, displayName) <- gc (,)
memberRole <- A.space *> ("member" $> GRMember <|> "observer" $> GRObserver)
pure $ DCSetRole groupId displayName memberRole
DCApproveGroup_ -> do
(groupId, displayName) <- gc (,)
groupApprovalId <- A.space *> A.decimal
pure DCApproveGroup {groupId, displayName, groupApprovalId}
pure $ DCApproveGroup {groupId, displayName, groupApprovalId}
DCRejectGroup_ -> gc DCRejectGroup
DCSuspendGroup_ -> gc DCSuspendGroup
DCResumeGroup_ -> gc DCResumeGroup
DCListLastGroups_ -> DCListLastGroups <$> (A.space *> A.decimal <|> pure 10)
DCListPendingGroups_ -> DCListPendingGroups <$> (A.space *> A.decimal <|> pure 10)
DCExecuteCommand_ -> DCExecuteCommand . T.unpack <$> (A.space *> A.takeText)
where
gc f = f <$> (A.space *> A.decimal <* A.char ':') <*> displayNameP
@@ -225,15 +214,13 @@ directoryCmdTag = \case
DCRecentGroups -> "new"
DCSubmitGroup _ -> "submit"
DCConfirmDuplicateGroup {} -> "confirm"
DCListUserGroups -> "list"
DCListUserGroups -> "list"
DCDeleteGroup {} -> "delete"
DCApproveGroup {} -> "approve"
DCSetRole {} -> "role"
DCRejectGroup {} -> "reject"
DCSuspendGroup {} -> "suspend"
DCResumeGroup {} -> "resume"
DCListLastGroups _ -> "last"
DCListPendingGroups _ -> "pending"
DCExecuteCommand _ -> "exec"
DCUnknownCommand -> "unknown"
DCCommandError _ -> "error"
@@ -23,7 +23,6 @@ import Data.Set (Set)
import qualified Data.Set as S
import Data.Text (Text)
import qualified Data.Text as T
import Data.Text.Encoding (decodeLatin1)
import Data.Time.Clock (diffUTCTime, getCurrentTime)
import Data.Time.LocalTime (getCurrentTimeZone)
import Directory.Events
@@ -448,43 +447,30 @@ directoryService st DirectoryOpts {superUsers, serviceName, searchResults, testi
DCRecentGroups -> withFoundListedGroups Nothing $ sendAllGroups takeRecent "the most recent" STRecent
DCSubmitGroup _link -> pure ()
DCConfirmDuplicateGroup ugrId gName ->
withUserGroupReg ugrId gName $ \gr g@GroupInfo {groupProfile = GroupProfile {displayName}} ->
readTVarIO (groupRegStatus gr) >>= \case
GRSPendingConfirmation ->
getDuplicateGroup g >>= \case
Nothing -> sendMessage cc ct "Error: getDuplicateGroup. Please notify the developers."
Just DGReserved -> sendMessage cc ct $ groupAlreadyListed g
_ -> processInvitation ct g
_ -> sendReply $ "Error: the group ID " <> show ugrId <> " (" <> T.unpack displayName <> ") is not pending confirmation."
atomically (getUserGroupReg st (contactId' ct) ugrId) >>= \case
Nothing -> sendReply $ "Group ID " <> show ugrId <> " not found"
Just GroupReg {dbGroupId, groupRegStatus} -> do
getGroup cc dbGroupId >>= \case
Nothing -> sendReply $ "Group ID " <> show ugrId <> " not found"
Just g@GroupInfo {groupProfile = GroupProfile {displayName}}
| displayName == gName ->
readTVarIO groupRegStatus >>= \case
GRSPendingConfirmation -> do
getDuplicateGroup g >>= \case
Nothing -> sendMessage cc ct "Error: getDuplicateGroup. Please notify the developers."
Just DGReserved -> sendMessage cc ct $ groupAlreadyListed g
_ -> processInvitation ct g
_ -> sendReply $ "Error: the group ID " <> show ugrId <> " (" <> T.unpack displayName <> ") is not pending confirmation."
| otherwise -> sendReply $ "Group ID " <> show ugrId <> " has the display name " <> T.unpack displayName
DCListUserGroups ->
atomically (getUserGroupRegs st $ contactId' ct) >>= \grs -> do
sendReply $ show (length grs) <> " registered group(s)"
void . forkIO $ forM_ (reverse grs) $ \gr@GroupReg {userGroupRegId} ->
sendGroupInfo ct gr userGroupRegId Nothing
DCDeleteGroup ugrId gName ->
withUserGroupReg ugrId gName $ \gr GroupInfo {groupProfile = GroupProfile {displayName}} -> do
delGroupReg st gr
sendReply $ T.unpack $ "Your group " <> displayName <> " is deleted from the directory"
DCSetRole ugrId gName mRole ->
withUserGroupReg ugrId gName $ \_gr GroupInfo {groupId, groupProfile = GroupProfile {displayName}} -> do
gLink_ <- setGroupLinkRole cc groupId mRole
sendReply $ T.unpack $ case gLink_ of
Nothing -> "Error: the initial member role for the group " <> displayName <> " was NOT upgated"
Just gLink ->
("The initial member role for the group " <> displayName <> " is set to *" <> decodeLatin1 (strEncode mRole) <> "*\n\n")
<> ("*Please note*: it applies only to members joining via this link: " <> safeDecodeUtf8 (strEncode $ simplexChatContact gLink))
DCDeleteGroup _ugrId _gName -> pure ()
DCUnknownCommand -> sendReply "Unknown command"
DCCommandError tag -> sendReply $ "Command error: " <> show tag
where
withUserGroupReg ugrId gName action =
atomically (getUserGroupReg st (contactId' ct) ugrId) >>= \case
Nothing -> sendReply $ "Group ID " <> show ugrId <> " not found"
Just gr@GroupReg {dbGroupId} -> do
getGroup cc dbGroupId >>= \case
Nothing -> sendReply $ "Group ID " <> show ugrId <> " not found"
Just g@GroupInfo {groupProfile = GroupProfile {displayName}}
| displayName == gName -> action gr g
| otherwise -> sendReply $ "Group ID " <> show ugrId <> " has the display name " <> T.unpack displayName
sendReply = sendComposedMessage cc ct (Just ciId) . textMsgContent
withFoundListedGroups s_ action =
getGroups_ s_ >>= \case
@@ -590,8 +576,13 @@ directoryService st DirectoryOpts {superUsers, serviceName, searchResults, testi
notifyOwner gr $ "The group " <> userGroupReference' gr gName <> " is listed in the directory again!"
sendReply "Group listing resumed!"
_ -> sendReply $ "The group " <> groupRef <> " is not suspended, can't be resumed."
DCListLastGroups count -> listGroups count False
DCListPendingGroups count -> listGroups count True
DCListLastGroups count ->
readTVarIO (groupRegs st) >>= \grs -> do
sendReply $ show (length grs) <> " registered group(s)" <> (if length grs > count then ", showing the last " <> show count else "")
void . forkIO $ forM_ (reverse $ take count grs) $ \gr@GroupReg {dbGroupId, dbContactId} -> do
ct_ <- getContact cc dbContactId
let ownerStr = "Owner: " <> maybe "getContact error" localDisplayName' ct_
sendGroupInfo ct gr dbGroupId $ Just ownerStr
DCExecuteCommand cmdStr ->
sendChatCmdStr cc cmdStr >>= \r -> do
ts <- getCurrentTime
@@ -602,17 +593,6 @@ directoryService st DirectoryOpts {superUsers, serviceName, searchResults, testi
where
superUser = KnownContact {contactId = contactId' ct, localDisplayName = localDisplayName' ct}
sendReply = sendComposedMessage cc ct (Just ciId) . textMsgContent
listGroups count pending =
readTVarIO (groupRegs st) >>= \groups -> do
grs <-
if pending
then filterM (fmap pendingApproval . readTVarIO . groupRegStatus) groups
else pure groups
sendReply $ show (length grs) <> " registered group(s)" <> (if length grs > count then ", showing the last " <> show count else "")
void . forkIO $ forM_ (reverse $ take count grs) $ \gr@GroupReg {dbGroupId, dbContactId} -> do
ct_ <- getContact cc dbContactId
let ownerStr = "Owner: " <> maybe "getContact error" localDisplayName' ct_
sendGroupInfo ct gr dbGroupId $ Just ownerStr
getGroupAndReg :: GroupId -> GroupName -> IO (Maybe (GroupInfo, GroupReg))
getGroupAndReg gId gName =
@@ -661,12 +641,5 @@ getGroupAndSummary cc gId = resp <$> sendChatCmd cc (APIGroupInfo gId)
CRGroupInfo {groupInfo, groupSummary} -> Just (groupInfo, groupSummary)
_ -> Nothing
setGroupLinkRole :: ChatController -> GroupId -> GroupMemberRole -> IO (Maybe ConnReqContact)
setGroupLinkRole cc gId mRole = resp <$> sendChatCmd cc (APIGroupLinkMemberRole gId mRole)
where
resp = \case
CRGroupLink _ _ gLink _ -> Just gLink
_ -> Nothing
unexpectedError :: String -> String
unexpectedError err = "Unexpected error: " <> err <> ", please notify the developers."
@@ -12,7 +12,6 @@ module Directory.Store
GroupApprovalId,
restoreDirectoryStore,
addGroupReg,
delGroupReg,
setGroupStatus,
setGroupRegOwner,
getGroupReg,
@@ -20,7 +19,6 @@ module Directory.Store
getUserGroupRegs,
filterListedGroups,
groupRegStatusText,
pendingApproval,
)
where
@@ -81,11 +79,6 @@ data GroupRegStatus
| GRSSuspendedBadRoles
| GRSRemoved
pendingApproval :: GroupRegStatus -> Bool
pendingApproval = \case
GRSPendingApproval _ -> True
_ -> False
data DirectoryStatus = DSListed | DSReserved | DSRegistered
groupRegStatusText :: GroupRegStatus -> Text
@@ -125,12 +118,6 @@ addGroupReg st ct GroupInfo {groupId} grStatus = do
| dbContactId == ctId && userGroupRegId > mx = userGroupRegId
| otherwise = mx
delGroupReg :: DirectoryStore -> GroupReg -> IO ()
delGroupReg st GroupReg {dbGroupId = gId} = do
logGDelete st gId
atomically $ unlistGroup st gId
atomically $ modifyTVar' (groupRegs st) $ filter ((gId ==) . dbGroupId)
setGroupStatus :: DirectoryStore -> GroupReg -> GroupRegStatus -> IO ()
setGroupStatus st gr grStatus = do
logGUpdateStatus st (dbGroupId gr) grStatus
@@ -180,15 +167,10 @@ unlistGroup st gId = do
data DirectoryLogRecord
= GRCreate GroupRegData
| GRDelete GroupId
| GRUpdateStatus GroupId GroupRegStatus
| GRUpdateOwner GroupId GroupMemberId
data DLRTag
= GRCreate_
| GRDelete_
| GRUpdateStatus_
| GRUpdateOwner_
data DLRTag = GRCreate_ | GRUpdateStatus_ | GRUpdateOwner_
logDLR :: DirectoryStore -> DirectoryLogRecord -> IO ()
logDLR st r = forM_ (directoryLogFile st) $ \h -> B.hPutStrLn h (strEncode r)
@@ -196,9 +178,6 @@ logDLR st r = forM_ (directoryLogFile st) $ \h -> B.hPutStrLn h (strEncode r)
logGCreate :: DirectoryStore -> GroupRegData -> IO ()
logGCreate st = logDLR st . GRCreate
logGDelete :: DirectoryStore -> GroupId -> IO ()
logGDelete st = logDLR st . GRDelete
logGUpdateStatus :: DirectoryStore -> GroupId -> GroupRegStatus -> IO ()
logGUpdateStatus st = logDLR st .: GRUpdateStatus
@@ -208,13 +187,11 @@ logGUpdateOwner st = logDLR st .: GRUpdateOwner
instance StrEncoding DLRTag where
strEncode = \case
GRCreate_ -> "GCREATE"
GRDelete_ -> "GDELETE"
GRUpdateStatus_ -> "GSTATUS"
GRUpdateOwner_ -> "GOWNER"
strP =
A.takeTill (== ' ') >>= \case
"GCREATE" -> pure GRCreate_
"GDELETE" -> pure GRDelete_
"GSTATUS" -> pure GRUpdateStatus_
"GOWNER" -> pure GRUpdateOwner_
_ -> fail "invalid DLRTag"
@@ -222,15 +199,13 @@ instance StrEncoding DLRTag where
instance StrEncoding DirectoryLogRecord where
strEncode = \case
GRCreate gr -> strEncode (GRCreate_, gr)
GRDelete gId -> strEncode (GRDelete_, gId)
GRUpdateStatus gId grStatus -> strEncode (GRUpdateStatus_, gId, grStatus)
GRUpdateOwner gId grOwnerId -> strEncode (GRUpdateOwner_, gId, grOwnerId)
strP =
strP_ >>= \case
GRCreate_ -> GRCreate <$> strP
GRDelete_ -> GRDelete <$> strP
GRUpdateStatus_ -> GRUpdateStatus <$> A.decimal <*> _strP
GRUpdateOwner_ -> GRUpdateOwner <$> A.decimal <* A.space <*> A.decimal
strP >>= \case
GRCreate_ -> GRCreate <$> (A.space *> strP)
GRUpdateStatus_ -> GRUpdateStatus <$> (A.space *> A.decimal) <*> (A.space *> strP)
GRUpdateOwner_ -> GRUpdateOwner <$> (A.space *> A.decimal) <*> (A.space *> A.decimal)
instance StrEncoding GroupRegData where
strEncode GroupRegData {dbGroupId_, userGroupRegId_, dbContactId_, dbOwnerMemberId_, groupRegStatus_} =
@@ -339,9 +314,6 @@ readDirectoryData f =
putStrLn $
"Warning: duplicate group with ID " <> show gId <> ", group replaced."
pure $ M.insert gId gr m
GRDelete gId -> case M.lookup gId m of
Just _ -> pure $ M.delete gId m
Nothing -> m <$ putStrLn ("Warning: no group with ID " <> show gId <> ", deletion ignored.")
GRUpdateStatus gId groupRegStatus_ -> case M.lookup gId m of
Just gr -> pure $ M.insert gId gr {groupRegStatus_} m
Nothing -> m <$ putStrLn ("Warning: no group with ID " <> show gId <> ", status update ignored.")
@@ -1,18 +0,0 @@
---
layout: layouts/article.html
title: "SimpleX network: cryptographic design review by Trail of Bits, v6.1 released with better calls and user experience."
date: 2024-10-14
# image: images/20240814-reachable.png
# previewBody: blog_previews/20240814.html
permalink: "/blog/20241014-simplex-network-v6-1-security-review-better-calls-user-experience.html"
draft: true
---
# SimpleX network: security review of protocols design by Trail of Bits, v6.1 released with better calls and user experience.
**Published:** Oct 14, 2024
This is the placeholder for the security review and release announcement.
Come back on Monday afternoon!
+1 -1
View File
@@ -12,7 +12,7 @@ constraints: zip +disable-bzip2 +disable-zstd
source-repository-package
type: git
location: https://github.com/simplex-chat/simplexmq.git
tag: c41bfe831d6d3fdf068f7419cbfed6afa46cb5b5
tag: b8971a31bcb82fffabcb792c9afd6bc4a96ec649
source-repository-package
type: git
+62 -414
View File
@@ -1,16 +1,13 @@
---
title: Hosting your own SMP Server
revision: 12.10.2024
revision: 03.06.2024
---
# Hosting your own SMP Server
| Updated 12.10.2024 | Languages: EN, [FR](/docs/lang/fr/SERVER.md), [CZ](/docs/lang/cs/SERVER.md), [PL](/docs/lang/pl/SERVER.md) |
| Updated 28.05.2024 | Languages: EN, [FR](/docs/lang/fr/SERVER.md), [CZ](/docs/lang/cs/SERVER.md), [PL](/docs/lang/pl/SERVER.md) |
### Table of Contents
- [Quick start](#quick-start)
- [Detailed guide](#detailed-guide)
- [Hosting your own SMP server](#hosting-your-own-smp-server)
- [Overview](#overview)
- [Installation](#installation)
- [Configuration](#configuration)
@@ -32,218 +29,17 @@ revision: 12.10.2024
- [Updating your SMP server](#updating-your-smp-server)
- [Configuring the app to use the server](#configuring-the-app-to-use-the-server)
## Quick start
# Hosting your own SMP Server
To create SMP server, you'll need:
- VPS or any other server.
- Your server domain, with A and AAAA records specifying server IPv4 and IPv6 addresses (`smp1.example.com`)
- A basic Linux knowledge.
*Please note*: while you can run an SMP server without a domain name, in the near future client applications will start using server domain name in the invitation links (instead of `simplex.chat` domain they use now). In case a server does not have domain name and server pages (see below), the clients will be generaing the links with `simplex:` scheme that cannot be opened in the browsers.
1. Install server with [Installation script](https://github.com/simplex-chat/simplexmq#using-installation-script).
2. Adjust firewall:
```sh
ufw allow 80/tcp &&\
ufw allow 443/tcp &&\
ufw allow 5223/tcp
```
3. Init server:
Replace `smp1.example.com` with your actual server domain.
```sh
su smp -c 'smp-server init --yes \
--store-log \
--no-password \
--control-port \
--socks-proxy \
--source-code \
--fqdn=smp1.example.com
```
4. Install tor:
```sh
CODENAME="$(lsb_release -c | awk '{print $2}')"
echo "deb [signed-by=/usr/share/keyrings/tor-archive-keyring.gpg] https://deb.torproject.org/torproject.org ${CODENAME} main
deb-src [signed-by=/usr/share/keyrings/tor-archive-keyring.gpg] https://deb.torproject.org/torproject.org ${CODENAME} main" > /etc/apt/sources.list.d/tor.list &&\
curl --proto '=https' --tlsv1.2 -sSf https://deb.torproject.org/torproject.org/A3C4F0F979CAA22CDBA8F512EE8CBC9E886DDD89.asc | gpg --dearmor | tee /usr/share/keyrings/tor-archive-keyring.gpg >/dev/null &&\
apt update && apt install -y tor deb.torproject.org-keyring
```
5. Configure tor:
```sh
tor-instance-create tor2 &&\
mkdir /var/lib/tor/simplex-smp/ &&\
chown debian-tor:debian-tor /var/lib/tor/simplex-smp/ &&\
chmod 700 /var/lib/tor/simplex-smp/
```
```sh
vim /etc/tor/torrc
```
Paste the following:
```sh
# Enable log (otherwise, tor doesn't seem to deploy onion address)
Log notice file /var/log/tor/notices.log
# Enable single hop routing (2 options below are dependencies of the third) - It will reduce the latency at the cost of lower anonimity of the server - as SMP-server onion address is used in the clients together with public address, this is ok. If you deploy SMP-server with onion-only address, keep standard configuration.
SOCKSPort 0
HiddenServiceNonAnonymousMode 1
HiddenServiceSingleHopMode 1
# smp-server hidden service host directory and port mappings
HiddenServiceDir /var/lib/tor/simplex-smp/
HiddenServicePort 5223 localhost:5223
HiddenServicePort 443 localhost:443
```
```sh
vim /etc/tor/instances/tor2/torrc
```
Paste the following:
```sh
# Log tor to systemd daemon
Log notice syslog
# Listen to local 9050 port for socks proxy
SocksPort 9050
```
6. Start tor:
```sh
systemctl enable tor &&\
systemctl start tor &&\
systemctl restart tor &&\
systemctl enable --now tor@tor2
```
7. Install Caddy:
```sh
sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https curl &&\
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg &&\
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list &&\
sudo apt update && sudo apt install caddy
```
8. Configure Caddy:
```sh
vim /etc/caddy/Caddyfile
```
Replace `smp1.example.com` with your actual server domain. Paste the following:
```
http://smp1.example.com {
redir https://smp1.example.com{uri} permanent
}
smp1.example.com:8443 {
tls {
key_type rsa4096
}
}
```
```sh
vim /usr/local/bin/simplex-servers-certs
```
Replace `smp1.example.com` with your actual server domain. Paste the following:
```sh
#!/usr/bin/env sh
set -eu
user='smp'
group="$user"
domain='smp1.example.com'
folder_in="/var/lib/caddy/.local/share/caddy/certificates/acme-v02.api.letsencrypt.org-directory/${domain}"
folder_out='/etc/opt/simplex'
key_name='web.key'
cert_name='web.crt'
# Copy certifiacte from Caddy directory to smp-server directory
cp "${folder_in}/${domain}.crt" "${folder_out}/${cert_name}"
# Assign correct permissions
chown "$user":"$group" "${folder_out}/${cert_name}"
# Copy certifiacte key from Caddy directory to smp-server directory
cp "${folder_in}/${domain}.key" "${folder_out}/${key_name}"
# Assign correct permissions
chown "$user":"$group" "${folder_out}/${key_name}"
```
```sh
chmod +x /usr/local/bin/simplex-servers-certs
```
```sh
sudo crontab -e
```
Paste the following:
```sh
# Every week on 00:20 sunday
20 0 * * 0 /usr/local/bin/simplex-servers-certs
```
9. Enable and start Caddy service:
Wait until "good to go" has been printed.
```sh
systemctl enable --now caddy &&\
sleep 10 &&\
/usr/local/bin/simplex-servers-certs &&\
echo 'good to go'
```
10. Enable and start smp-server:
```sh
systemctl enable --now smp-server.service
```
11. Print your address:
```sh
smp="$(journalctl --output cat -q _SYSTEMD_INVOCATION_ID="$(systemctl show -p InvocationID --value smp-server)" | grep -m1 'Server address:' | awk '{print $NF}' | sed 's/:443.*//')"
tor="$(cat /var/lib/tor/simplex-smp/hostname)"
echo "$smp,$tor"
```
## Detailed guide
### Overview
## Overview
SMP server is the relay server used to pass messages in SimpleX network. SimpleX Chat apps have preset servers (for mobile apps these are smp11, smp12 and smp14.simplex.im), but you can easily change app configuration to use other servers.
SimpleX clients only determine which server is used to receive the messages, separately for each contact (or group connection with a group member), and these servers are only temporary, as the delivery address can change.
To create SMP server, you'll need:
1. VPS or any other server.
2. Your own domain, pointed at the server (`smp.example.com`)
3. A basic Linux knowledge.
_Please note_: when you change the servers in the app configuration, it only affects which servers will be used for the new contacts, the existing contacts will not automatically move to the new servers, but you can move them manually using ["Change receiving address"](../blog/20221108-simplex-chat-v4.2-security-audit-new-website.md#change-your-delivery-address-beta) button in contact/member information pages it will be automated in the future.
### Installation
## Installation
1. First, install `smp-server`:
@@ -286,10 +82,8 @@ Manual installation requires some preliminary actions:
```sh
# For Ubuntu
sudo ufw allow 5223/tcp
sudo ufw allow 443/tcp
sudo ufw allow 80/tcp
# For Fedora
sudo firewall-cmd --permanent --add-port=5223/tcp --add-port=443/tcp --add-port=80/tcp && \
sudo firewall-cmd --permanent --add-port=5223/tcp && \
sudo firewall-cmd --reload
```
@@ -308,7 +102,6 @@ Manual installation requires some preliminary actions:
LimitNOFILE=65535
KillSignal=SIGINT
TimeoutStopSec=infinity
AmbientCapabilities=CAP_NET_BIND_SERVICE
[Install]
WantedBy=multi-user.target
@@ -316,7 +109,7 @@ Manual installation requires some preliminary actions:
And execute `sudo systemctl daemon-reload`.
### Configuration
## Configuration
To see which options are available, execute `smp-server` without flags:
@@ -336,7 +129,7 @@ You can get further help by executing `sudo su smp -c "smp-server <command> -h"`
After that, we need to configure `smp-server`:
#### Interactively
### Interactively
Execute the following command:
@@ -366,7 +159,7 @@ These statistics include daily counts of created, secured and deleted queues, se
Enter your domain or ip address that your smp-server is running on - it will be included in server certificates and also printed as part of server address.
#### Via command line options
### Via command line options
Execute the following command:
@@ -430,7 +223,7 @@ Server address: smp://d5fcsc7hhtPpexYUbI2XPxDbyU2d3WsVmROimcL90ss=:V8ONoJ6ICwnrZ
The server address above should be used in your client configuration, and if you added server password it should only be shared with the other people who you want to allow using your server to receive the messages (all your contacts will be able to send messages - it does not require a password). If you passed IP address or hostnames during the initialisation, they will be printed as part of server address, otherwise replace `<hostnames>` with the actual server hostnames.
### Further configuration
## Further configuration
All generated configuration, along with a description for each parameter, is available inside configuration file in `/etc/opt/simplex/smp-server.ini` for further customization. Depending on the smp-server version, the configuration file looks something like this:
@@ -452,26 +245,26 @@ source_code: https://github.com/simplex-chat/simplexmq
# condition_amendments: link
# Server location and operator.
# server_country: ISO-3166 2-letter code
# operator: entity (organization or person name)
# operator_country: ISO-3166 2-letter code
# website:
server_country: <YOUR_SERVER_LOCATION>
operator: <YOUR_NAME>
operator_country: <YOUR_LOCATION>
website: <WEBSITE_IF_AVAILABLE>
# Administrative contacts.
# admin_simplex: SimpleX address
# admin_email:
#admin_simplex: SimpleX address
admin_email: <EMAIL>
# admin_pgp:
# admin_pgp_fingerprint:
# Contacts for complaints and feedback.
# complaints_simplex: SimpleX address
# complaints_email:
complaints_email: <COMPLAINTS_EMAIL>
# complaints_pgp:
# complaints_pgp_fingerprint:
# Hosting provider.
# hosting: entity (organization or person name)
# hosting_country: ISO-3166 2-letter code
hosting: <HOSTING_PROVIDER_NAME>
hosting_country: <HOSTING_PROVIDER_LOCATION>
[STORE_LOG]
# The server uses STM memory for persistence,
@@ -485,7 +278,6 @@ enable: on
# they are preserved in the .bak file until the next restart.
restore_messages: on
expire_messages_days: 21
expire_ntfs_hours: 24
# Log daily server statistics to CSV file
log_stats: on
@@ -502,17 +294,11 @@ new_queues: on
# with the users who you want to allow creating messaging queues on your server.
# create_password: password to create new queues (any printable ASCII characters without whitespace, '@', ':' and '/')
# control_port_admin_password:
# control_port_user_password:
[TRANSPORT]
# Host is only used to print server address on start.
# You can specify multiple server ports.
host: <domain/ip>
port: 5223,443
# host is only used to print server address on start
host: <your server domain/ip>
port: 5223
log_tls_errors: off
# Use `websockets: 443` to run websockets server in addition to plain TLS.
websockets: off
# control_port: 5224
@@ -524,7 +310,7 @@ websockets: off
# required_host_mode: off
# The domain suffixes of the relays you operate (space-separated) to count as separate proxy statistics.
# own_server_domains:
# own_server_domains: <your domain suffixes>
# SOCKS proxy port for forwarding messages to destination servers.
# You may need a separate instance of SOCKS proxy for incoming single-hop requests.
@@ -540,7 +326,7 @@ websockets: off
[INACTIVE_CLIENTS]
# TTL and interval to check inactive clients
disconnect: off
# ttl: 21600
# ttl: 43200
# check_interval: 3600
[WEB]
@@ -550,18 +336,18 @@ static_path: /var/opt/simplex/www
# Run an embedded server on this port
# Onion sites can use any port and register it in the hidden service config.
# Running on a port 80 may require setting process capabilities.
#http: 8000
# http: 8000
# You can run an embedded TLS web server too if you provide port and cert and key files.
# Not required for running relay on onion address.
https: 443
cert: /etc/opt/simplex/web.crt
key: /etc/opt/simplex/web.key
# https: 443
# cert: /etc/opt/simplex/web.cert
# key: /etc/opt/simplex/web.key
```
### Server security
## Server security
#### Initialization
### Initialization
Although it's convenient to initialize smp-server configuration directly on the server, operators **ARE ADVISED** to initialize smp-server fully offline to protect your SMP server CA private key.
@@ -581,7 +367,7 @@ Follow the steps to quickly initialize the server offline:
rsync -hzasP $HOME/simplex/smp/config/ <server_user>@<server_address>:/etc/opt/simplex/
```
#### Private keys
### Private keys
Connection to the smp server occurs via a TLS connection. During the TLS handshake, the client verifies smp-server CA and server certificates by comparing its fingerprint with the one included in server address. If server TLS credential is compromised, this key can be used to sign a new one, keeping the same server identity and established connections. In order to protect your smp-server from bad actors, operators **ARE ADVISED** to move CA private key to a safe place. That could be:
@@ -606,7 +392,7 @@ Follow the steps to secure your CA keys:
rm /etc/opt/simplex/ca.key
```
#### Online certificate rotation
### Online certificate rotation
Operators of smp servers **ARE ADVISED** to rotate online certificate regularly (e.g., every 3 months). In order to do this, follow the steps:
@@ -682,9 +468,9 @@ Operators of smp servers **ARE ADVISED** to rotate online certificate regularly
10. Done!
### Tor: installation and configuration
## Tor: installation and configuration
#### Installation for onion address
### Installation for onion address
SMP-server can also be deployed to be available via [Tor](https://www.torproject.org) network. Run the following commands as `root` user.
@@ -740,7 +526,6 @@ SMP-server can also be deployed to be available via [Tor](https://www.torproject
# smp-server hidden service host directory and port mappings
HiddenServiceDir /var/lib/tor/simplex-smp/
HiddenServicePort 5223 localhost:5223
HiddenServicePort 443 localhost:443
```
- Create directories:
@@ -765,7 +550,7 @@ SMP-server can also be deployed to be available via [Tor](https://www.torproject
cat /var/lib/tor/simplex-smp/hostname
```
#### SOCKS port for SMP PROXY
### SOCKS port for SMP PROXY
SMP-server versions starting from `v5.8.0-beta.0` can be configured to PROXY smp servers available exclusively through [Tor](https://www.torproject.org) network to be accessible to the clients that do not use Tor. Run the following commands as `root` user.
@@ -812,11 +597,9 @@ SMP-server versions starting from `v5.8.0-beta.0` can be configured to PROXY smp
...
```
### Server information page
## Server information page
SMP server **SHOULD** be configured to serve Web page with server information that can include admin info, server info, provider info, etc. It will also serve connection links, generated using the mobile/desktop apps. Run the following commands as `root` user.
_Please note:_ this configuration is supported since `v6.1.0-beta.2`.
SMP-server versions starting from `v5.8.0` can be configured to serve Web page with server information that can include admin info, server info, provider info, etc. Run the following commands as `root` user.
1. Add the following to your smp-server configuration (please modify fields in [INFORMATION] section to include relevant information):
@@ -825,19 +608,8 @@ _Please note:_ this configuration is supported since `v6.1.0-beta.2`.
```
```ini
[TRANSPORT]
# host is only used to print server address on start
host: <domain/ip>
port: 443,5223
websockets: off
log_tls_errors: off
control_port: 5224
[WEB]
https: 443
static_path: /var/opt/simplex/www
cert: /etc/opt/simplex/web.crt
key: /etc/opt/simplex/web.key
[INFORMATION]
# AGPLv3 license requires that you make any source code modifications
@@ -906,23 +678,16 @@ _Please note:_ this configuration is supported since `v6.1.0-beta.2`.
[Full Caddy instllation instructions](https://caddyserver.com/docs/install)
3. Replace Caddy configuration with the following:
Please replace `YOUR_DOMAIN` with your actual domain (smp.example.com).
3. Replace Caddy configuration with the following (don't forget to replace `<YOUR_DOMAIN>`):
```sh
vim /etc/caddy/Caddyfile
```
```
http://YOUR_DOMAIN {
redir https://YOUR_DOMAIN{uri} permanent
}
YOUR_DOMAIN:8443 {
tls {
key_type rsa4096
}
```caddy
<YOUR_DOMAIN> {
root * /var/opt/simplex/www
file_server
}
```
@@ -932,75 +697,17 @@ _Please note:_ this configuration is supported since `v6.1.0-beta.2`.
systemctl enable --now caddy
```
5. Create script to copy certificates to your smp directory:
5. Upgrade your smp-server to latest version - [Updating your smp server](#updating-your-smp-server)
Please replace `YOUR_DOMAIN` with your actual domain (smp.example.com).
6. Access the webpage you've deployed from your browser. You should see the smp-server information that you've provided in your ini file.
```sh
vim /usr/local/bin/simplex-servers-certs
```
```sh
#!/usr/bin/env sh
set -eu
user='smp'
group="$user"
domain='HOST'
folder_in="/var/lib/caddy/.local/share/caddy/certificates/acme-v02.api.letsencrypt.org-directory/${domain}"
folder_out='/etc/opt/simplex'
key_name='web.key'
cert_name='web.crt'
# Copy certifiacte from Caddy directory to smp-server directory
cp "${folder_in}/${domain}.crt" "${folder_out}/${cert_name}"
# Assign correct permissions
chown "$user":"$group" "${folder_out}/${cert_name}"
# Copy certifiacte key from Caddy directory to smp-server directory
cp "${folder_in}/${domain}.key" "${folder_out}/${key_name}"
# Assign correct permissions
chown "$user":"$group" "${folder_out}/${key_name}"
```
6. Make the script executable and execute it:
```sh
chmod +x /usr/local/bin/simplex-servers-certs && /usr/local/bin/simplex-servers-certs
```
7. Check if certificates were copied:
```sh
ls -haltr /etc/opt/simplex/web*
```
8. Create cronjob to copy certificates to smp directory in timely manner:
```sh
sudo crontab -e
```
```sh
# Every week on 00:20 sunday
20 0 * * 0 /usr/local/bin/simplex-servers-certs
```
9. Then:
- If you're running at least `v6.1.0-beta.2`, [restart the server](#systemd-commands).
- If you're running below `v6.1.0-beta.2`, [upgrade the server](#updating-your-smp-server).
10. Access the webpage you've deployed from your browser (`https://smp.example.org`). You should see the smp-server information that you've provided in your ini file.
### Documentation
## Documentation
All necessary files for `smp-server` are located in `/etc/opt/simplex/` folder.
Stored messages, connections, statistics and server log are located in `/var/opt/simplex/` folder.
#### SMP server address
### SMP server address
SMP server address has the following format:
@@ -1020,7 +727,7 @@ smp://<fingerprint>[:<password>]@<public_hostname>[,<onion_hostname>]
Your configured hostname(s) of `smp-server`. You can check your configured hosts in `/etc/opt/simplex/smp-server.ini`, under `[TRANSPORT]` section in `host:` field.
#### Systemd commands
### Systemd commands
To start `smp-server` on host boot, run:
@@ -1079,18 +786,16 @@ Nov 23 19:23:21 5588ab759e80 smp-server[30878]: not expiring inactive clients
Nov 23 19:23:21 5588ab759e80 smp-server[30878]: creating new queues requires password
```
#### Monitoring
### Monitoring
You can enable `smp-server` statistics for `Grafana` dashboard by setting value `on` in `/etc/opt/simplex/smp-server.ini`, under `[STORE_LOG]` section in `log_stats:` field.
Logs will be stored as `csv` file in `/var/opt/simplex/smp-server-stats.daily.log`. Fields for the `csv` file are:
```sh
fromTime,qCreated,qSecured,qDeleted,msgSent,msgRecv,dayMsgQueues,weekMsgQueues,monthMsgQueues,msgSentNtf,msgRecvNtf,dayCountNtf,weekCountNtf,monthCountNtf,qCount,msgCount,msgExpired,qDeletedNew,qDeletedSecured,pRelays_pRequests,pRelays_pSuccesses,pRelays_pErrorsConnect,pRelays_pErrorsCompat,pRelays_pErrorsOther,pRelaysOwn_pRequests,pRelaysOwn_pSuccesses,pRelaysOwn_pErrorsConnect,pRelaysOwn_pErrorsCompat,pRelaysOwn_pErrorsOther,pMsgFwds_pRequests,pMsgFwds_pSuccesses,pMsgFwds_pErrorsConnect,pMsgFwds_pErrorsCompat,pMsgFwds_pErrorsOther,pMsgFwdsOwn_pRequests,pMsgFwdsOwn_pSuccesses,pMsgFwdsOwn_pErrorsConnect,pMsgFwdsOwn_pErrorsCompat,pMsgFwdsOwn_pErrorsOther,pMsgFwdsRecv,qSub,qSubAuth,qSubDuplicate,qSubProhibited,msgSentAuth,msgSentQuota,msgSentLarge,msgNtfs,msgNtfNoSub,msgNtfLost,qSubNoMsg,msgRecvGet,msgGet,msgGetNoMsg,msgGetAuth,msgGetDuplicate,msgGetProhibited,psSubDaily,psSubWeekly,psSubMonthly,qCount2,ntfCreated,ntfDeleted,ntfSub,ntfSubAuth,ntfSubDuplicate,ntfCount,qDeletedAllB,qSubAllB,qSubEnd,qSubEndB,ntfDeletedB,ntfSubB,msgNtfsB,msgNtfExpired
fromTime,qCreated,qSecured,qDeleted,msgSent,msgRecv,dayMsgQueues,weekMsgQueues,monthMsgQueues,msgSentNtf,msgRecvNtf,dayCountNtf,weekCountNtf,monthCountNtf,qCount,msgCount,msgExpired,qDeletedNew,qDeletedSecured,pRelays_pRequests,pRelays_pSuccesses,pRelays_pErrorsConnect,pRelays_pErrorsCompat,pRelays_pErrorsOther,pRelaysOwn_pRequests,pRelaysOwn_pSuccesses,pRelaysOwn_pErrorsConnect,pRelaysOwn_pErrorsCompat,pRelaysOwn_pErrorsOther,pMsgFwds_pRequests,pMsgFwds_pSuccesses,pMsgFwds_pErrorsConnect,pMsgFwds_pErrorsCompat,pMsgFwds_pErrorsOther,pMsgFwdsOwn_pRequests,pMsgFwdsOwn_pSuccesses,pMsgFwdsOwn_pErrorsConnect,pMsgFwdsOwn_pErrorsCompat,pMsgFwdsOwn_pErrorsOther,pMsgFwdsRecv,qSub,qSubAuth,qSubDuplicate,qSubProhibited,msgSentAuth,msgSentQuota,msgSentLarge
```
#### Fields description
| Field number | Field name | Field Description |
| ------------- | ---------------------------- | -------------------------- |
| 1 | `fromTime` | Date of statistics |
@@ -1151,34 +856,6 @@ fromTime,qCreated,qSecured,qDeleted,msgSent,msgRecv,dayMsgQueues,weekMsgQueues,m
| 45 | `msgSentAuth` | Authentication errors |
| 46 | `msgSentQuota` | Quota errors |
| 47 | `msgSentLarge` | Large message errors |
| 48 | `msgNtfs` | XXXXXXXXXXXXXXXXXXXX |
| 49 | `msgNtfNoSub` | XXXXXXXXXXXXXXXXXXXX |
| 50 | `msgNtfLost` | XXXXXXXXXXXXXXXXXXXX |
| 51 | `qSubNoMsg` | Removed, always 0 |
| 52 | `msgRecvGet` | XXXXXXXXXXXXXXXXX |
| 53 | `msgGet` | XXXXXXXXXXXXXXXXX |
| 54 | `msgGetNoMsg` | XXXXXXXXXXXXXXXXX |
| 55 | `msgGetAuth` | XXXXXXXXXXXXXXXXX |
| 56 | `msgGetDuplicate` | XXXXXXXXXXXXXXXXX |
| 57 | `msgGetProhibited` | XXXXXXXXXXXXXXXXX |
| 58 | `psSub_dayCount` | Removed, always 0 |
| 59 | `psSub_weekCount` | Removed, always 0 |
| 60 | `psSub_monthCount` | Removed, always 0 |
| 61 | `qCount` | XXXXXXXXXXXXXXXXX |
| 62 | `ntfCreated` | XXXXXXXXXXXXXXXXX |
| 63 | `ntfDeleted` | XXXXXXXXXXXXXXXXX |
| 64 | `ntfSub` | XXXXXXXXXXXXXXXXX |
| 65 | `ntfSubAuth` | XXXXXXXXXXXXXXXXX |
| 66 | `ntfSubDuplicate` | XXXXXXXXXXXXXXXXX |
| 67 | `ntfCount` | XXXXXXXXXXXXXXXXX |
| 68 | `qDeletedAllB` | XXXXXXXXXXXXXXXXX |
| 69 | `qSubAllB` | XXXXXXXXXXXXXXXXX |
| 70 | `qSubEnd` | XXXXXXXXXXXXXXXXX |
| 71 | `qSubEndB` | XXXXXXXXXXXXXXXXX |
| 72 | `ntfDeletedB` | XXXXXXXXXXXXXXXXX |
| 73 | `ntfSubB` | XXXXXXXXXXXXXXXXX |
| 74 | `msgNtfsB` | XXXXXXXXXXXXXXXXX |
| 75 | `msgNtfExpired` | XXXXXXXXXXXXXXXXX |
To import `csv` to `Grafana` one should:
@@ -1186,112 +863,83 @@ To import `csv` to `Grafana` one should:
2. Allow local mode by appending following:
```sh
[plugin.marcusolsson-csv-datasource]
allow_local_mode = true
```
```sh
[plugin.marcusolsson-csv-datasource]
allow_local_mode = true
```
... to `/etc/grafana/grafana.ini`
... to `/etc/grafana/grafana.ini`
3. Add a CSV data source:
- In the side menu, click the Configuration tab (cog icon)
- Click Add data source in the top-right corner of the Data Sources tab
- Enter "CSV" in the search box to find the CSV data source
- Click the search result that says "CSV"
- In URL, enter a file that points to CSV content
- In the side menu, click the Configuration tab (cog icon)
- Click Add data source in the top-right corner of the Data Sources tab
- Enter "CSV" in the search box to find the CSV data source
- Click the search result that says "CSV"
- In URL, enter a file that points to CSV content
4. You're done! You should be able to create your own dashboard with statistics.
For further documentation, see: [CSV Data Source for Grafana - Documentation](https://grafana.github.io/grafana-csv-datasource/)
### Updating your SMP server
## Updating your SMP server
To update your smp-server to latest version, choose your installation method and follow the steps:
- Manual deployment
1. Stop the server:
```sh
sudo systemctl stop smp-server
```
2. Update the binary:
```sh
curl -L https://github.com/simplex-chat/simplexmq/releases/latest/download/smp-server-ubuntu-20_04-x86-64 -o /usr/local/bin/smp-server && chmod +x /usr/local/bin/smp-server
```
3. Start the server:
```sh
sudo systemctl start smp-server
```
- [Offical installation script](https://github.com/simplex-chat/simplexmq#using-installation-script)
1. Execute the followin command:
```sh
sudo simplex-servers-update
```
To install specific version, run:
```sh
export VER=<version_from_github_releases> &&\
sudo -E simplex-servers-update
```
2. Done!
- [Docker container](https://github.com/simplex-chat/simplexmq#using-docker)
1. Stop and remove the container:
```sh
docker rm $(docker stop $(docker ps -a -q --filter ancestor=simplexchat/smp-server --format="\{\{.ID\}\}"))
```
2. Pull latest image:
```sh
docker pull simplexchat/smp-server:latest
```
3. Start new container:
```sh
docker run -d \
-p 5223:5223 \
-p 443:443 \
-v $HOME/simplex/smp/config:/etc/opt/simplex:z \
-v $HOME/simplex/smp/logs:/var/opt/simplex:z \
simplexchat/smp-server:latest
```
- [Linode Marketplace](https://www.linode.com/marketplace/apps/simplex-chat/simplex-chat/)
1. Pull latest images:
```sh
docker-compose --project-directory /etc/docker/compose/simplex pull
```
2. Restart the containers:
```sh
docker-compose --project-directory /etc/docker/compose/simplex up -d --remove-orphans
```
3. Remove obsolete images:
```sh
docker image prune
```
### Configuring the app to use the server
## Configuring the app to use the server
To configure the app to use your messaging server copy it's full address, including password, and add it to the app. You have an option to use your server together with preset servers or without them - you can remove or disable them.
+1 -1
View File
@@ -226,7 +226,7 @@ While introduced members establish connection inside group, inviting member forw
### Member roles
Currently members can have one of four roles - `owner`, `admin`, `member` and `observer`. The user that created the group is self-assigned owner role, the new members are assigned role by the member who adds them - only `owner` and `admin` members can add new members; only `owner` members can add members with `owner` role. `Observer` members only receive messages and aren't allowed to send messages.
Currently members can have one of three roles - `owner`, `admin`, `member` and `observer`. The user that created the group is self-assigned owner role, the new members are assigned role by the member who adds them - only `owner` and `admin` members can add new members; only `owner` members can add members with `owner` role. `Observer` members only receive messages and aren't allowed to send messages.
### Messages to manage groups and add members
+1 -1
View File
@@ -1,5 +1,5 @@
name: simplex-chat
version: 6.1.0.9
version: 6.1.0.7
#synopsis:
#description:
homepage: https://github.com/simplex-chat/simplex-chat#readme
+4 -9
View File
@@ -246,7 +246,7 @@ const callCrypto = callCryptoFunction()
declare var RTCRtpScriptTransform: {
prototype: RTCRtpScriptTransform
new (worker: Worker, options?: any, transfer?: any[] | undefined): RTCRtpScriptTransform
new (worker: Worker, options?: any): RTCRtpScriptTransform
}
enum TransformOperation {
@@ -316,8 +316,6 @@ const allowSendScreenAudio = false
// will be stored here and then set when the call will be ready to process them
let afterCallInitializedCandidates: RTCIceCandidateInit[] = []
const stopTrackOnAndroid = false
const processCommand = (function () {
type RTCRtpSenderWithEncryption = RTCRtpSender & {
createEncodedStreams: () => TransformStream
@@ -1143,8 +1141,7 @@ const processCommand = (function () {
// doing it vice versa gives an error like "too many cameras were open" on some Android devices or webViews
// which means the second camera will never be opened
for (const t of source == CallMediaSource.Mic ? call.localStream.getAudioTracks() : call.localStream.getVideoTracks()) {
if (isDesktop || source != CallMediaSource.Mic || stopTrackOnAndroid) t.stop()
else t.enabled = false
t.stop()
call.localStream.removeTrack(t)
}
let localStream: MediaStream
@@ -1203,7 +1200,7 @@ const processCommand = (function () {
if (!localStream || !oldCamera || !videos) return
if (!inactiveCallMediaSources.mic) {
localStream.getAudioTracks().forEach((elem) => (isDesktop || stopTrackOnAndroid ? elem.stop() : (elem.enabled = false)))
localStream.getAudioTracks().forEach((elem) => elem.stop())
localStream.getAudioTracks().forEach((elem) => localStream.removeTrack(elem))
}
if (!inactiveCallMediaSources.camera || oldCamera != newCamera) {
@@ -1477,9 +1474,7 @@ const processCommand = (function () {
if (enable) {
transceiver.sender.replaceTrack(t)
} else {
if (isDesktop || t.kind == CallMediaType.Video || stopTrackOnAndroid) t.stop()
else t.enabled = false
t.stop()
s.removeTrack(t)
transceiver.sender.replaceTrack(null)
}
+1 -1
View File
@@ -1,5 +1,5 @@
{
"https://github.com/simplex-chat/simplexmq.git"."c41bfe831d6d3fdf068f7419cbfed6afa46cb5b5" = "1awqy4srdgcwmjf7q3s9w75w6wp38qk65fza2k3q1a1s2lj6h8w1";
"https://github.com/simplex-chat/simplexmq.git"."b8971a31bcb82fffabcb792c9afd6bc4a96ec649" = "1p6m390ngcsp7i7vy0m0zxh167gkbciavva9a00l6pxwzaz9qmpi";
"https://github.com/simplex-chat/hs-socks.git"."a30cc7a79a08d8108316094f8f2f82a0c5e1ac51" = "0yasvnr7g91k76mjkamvzab2kvlb1g5pspjyjn2fr6v83swjhj38";
"https://github.com/simplex-chat/direct-sqlcipher.git"."f814ee68b16a9447fbb467ccc8f29bdd3546bfd9" = "1ql13f4kfwkbaq7nygkxgw84213i0zm7c1a8hwvramayxl38dq5d";
"https://github.com/simplex-chat/sqlcipher-simple.git"."a46bd361a19376c5211f1058908fc0ae6bf42446" = "1z0r78d8f0812kxbgsm735qf6xx8lvaz27k1a0b4a2m0sshpd5gl";
+1 -2
View File
@@ -5,7 +5,7 @@ cabal-version: 1.12
-- see: https://github.com/sol/hpack
name: simplex-chat
version: 6.1.0.9
version: 6.1.0.7
category: Web, System, Services, Cryptography
homepage: https://github.com/simplex-chat/simplex-chat#readme
author: simplex.chat
@@ -149,7 +149,6 @@ library
Simplex.Chat.Migrations.M20240827_calls_uuid
Simplex.Chat.Migrations.M20240920_user_order
Simplex.Chat.Migrations.M20241008_indexes
Simplex.Chat.Migrations.M20241010_contact_requests_contact_id
Simplex.Chat.Mobile
Simplex.Chat.Mobile.File
Simplex.Chat.Mobile.Shared
+28 -67
View File
@@ -1299,18 +1299,12 @@ processChatCommand' vr = \case
APIAcceptContact incognito connReqId -> withUser $ \_ -> do
(user@User {userId}, cReq@UserContactRequest {userContactLinkId}) <- withFastStore $ \db -> getContactRequest' db connReqId
withUserContactLock "acceptContact" userContactLinkId $ do
(ct, conn@Connection {connId}, sqSecured) <- acceptContactRequest user cReq incognito
ucl <- withFastStore $ \db -> getUserContactLinkById db userId userContactLinkId
let contactUsed = (\(_, groupId_, _) -> isNothing groupId_) ucl
ct' <- withStore' $ \db -> do
deleteContactRequestRec db user cReq
updateContactAccepted db user ct contactUsed
conn' <-
if sqSecured
then conn {connStatus = ConnSndReady} <$ updateConnectionStatusFromTo db connId ConnNew ConnSndReady
else pure conn
pure ct {contactUsed, activeConn = Just conn'}
pure $ CRAcceptingContactRequest user ct'
-- [incognito] generate profile to send, create connection with incognito profile
incognitoProfile <- if incognito then Just . NewIncognito <$> liftIO generateRandomProfile else pure Nothing
ct <- acceptContactRequest user cReq incognitoProfile contactUsed
pure $ CRAcceptingContactRequest user ct
APIRejectContact connReqId -> withUser $ \user -> do
cReq@UserContactRequest {userContactLinkId, agentContactConnId = AgentConnId connId, agentInvitationId = AgentInvId invId} <-
withFastStore $ \db ->
@@ -1769,7 +1763,7 @@ processChatCommand' vr = \case
pure conn'
APIConnectPlan userId cReqUri -> withUserId userId $ \user ->
CRConnectionPlan user <$> connectPlan user cReqUri
APIConnect userId incognito (Just (ACR SCMInvitation cReq@(CRInvitationUri crData e2e))) -> withUserId userId $ \user -> withInvitationLock "connect" (strEncode cReq) . procCmd $ do
APIConnect userId incognito (Just (ACR SCMInvitation cReq)) -> withUserId userId $ \user -> withInvitationLock "connect" (strEncode cReq) . procCmd $ do
subMode <- chatReadVar subscriptionMode
-- [incognito] generate profile to send
incognitoProfile <- if incognito then Just <$> liftIO generateRandomProfile else pure Nothing
@@ -1780,27 +1774,10 @@ processChatCommand' vr = \case
Just (agentV, pqSup') -> do
let chatV = agentToChatVersion agentV
dm <- encodeConnInfoPQ pqSup' chatV $ XInfo profileToSend
withFastStore' (\db -> getConnectionEntityByConnReq db vr user cReqs) >>= \case
Nothing -> joinNewConn chatV dm
Just (RcvDirectMsgConnection conn@Connection {connId, connStatus, contactConnInitiated} Nothing)
| connStatus == ConnNew && contactConnInitiated -> joinNewConn chatV dm -- own connection link
| connStatus == ConnPrepared -> do -- retrying join after error
pcc <- withFastStore $ \db -> getPendingContactConnection db userId connId
joinPreparedConn (aConnId conn) pcc dm
Just ent -> throwChatError $ CECommandError $ "connection exists: " <> show (connEntityInfo ent)
where
joinNewConn chatV dm = do
connId <- withAgent $ \a -> prepareConnectionToJoin a (aUserId user) True cReq pqSup'
pcc <- withFastStore' $ \db -> createDirectConnection db user connId cReq ConnPrepared (incognitoProfile $> profileToSend) subMode chatV pqSup'
joinPreparedConn connId pcc dm
joinPreparedConn connId pcc@PendingContactConnection {pccConnId} dm = do
void $ withAgent $ \a -> joinConnection a (aUserId user) connId True cReq dm pqSup' subMode
withFastStore' $ \db -> updateConnectionStatusFromTo db pccConnId ConnPrepared ConnJoined
pure $ CRSentConfirmation user pcc {pccConnStatus = ConnJoined}
cReqs =
( CRInvitationUri crData {crScheme = SSSimplex} e2e,
CRInvitationUri crData {crScheme = simplexChat} e2e
)
connId <- withAgent $ \a -> prepareConnectionToJoin a (aUserId user) True cReq pqSup'
conn@PendingContactConnection {pccConnId} <- withFastStore' $ \db -> createDirectConnection db user connId cReq ConnJoined (incognitoProfile $> profileToSend) subMode chatV pqSup'
joinPreparedAgentConnection user pccConnId connId cReq dm pqSup' subMode
pure $ CRSentConfirmation user conn
APIConnect userId incognito (Just (ACR SCMContact cReq)) -> withUserId userId $ \user -> connectViaContact user incognito cReq
APIConnect _ _ Nothing -> throwChatError CEInvalidConnReq
Connect incognito aCReqUri@(Just cReqUri) -> withUser $ \user@User {userId} -> do
@@ -2052,21 +2029,20 @@ processChatCommand' vr = \case
Just Connection {peerChatVRange} -> do
subMode <- chatReadVar subscriptionMode
dm <- encodeConnInfo $ XGrpAcpt membershipMemId
agentConnId <- case memberConn fromMember of
Nothing -> do
agentConnId <- withAgent $ \a -> prepareConnectionToJoin a (aUserId user) True connRequest PQSupportOff
let chatV = vr `peerConnChatVersion` peerChatVRange
void $ withFastStore' $ \db -> createMemberConnection db userId fromMember agentConnId chatV peerChatVRange subMode
pure agentConnId
Just conn -> pure $ aConnId conn
withFastStore' $ \db -> do
agentConnId <- withAgent $ \a -> prepareConnectionToJoin a (aUserId user) True connRequest PQSupportOff
let chatV = vr `peerConnChatVersion` peerChatVRange
cId <- withFastStore' $ \db -> do
Connection {connId = cId} <- createMemberConnection db userId fromMember agentConnId chatV peerChatVRange subMode
updateGroupMemberStatus db userId fromMember GSMemAccepted
updateGroupMemberStatus db userId membership GSMemAccepted
void (withAgent $ \a -> joinConnection a (aUserId user) agentConnId True connRequest dm PQSupportOff subMode)
pure cId
void (withAgent $ \a -> joinConnection a (aUserId user) (Just agentConnId) True connRequest dm PQSupportOff subMode)
`catchChatError` \e -> do
withFastStore' $ \db -> do
deleteConnectionRecord db user cId
updateGroupMemberStatus db userId fromMember GSMemInvited
updateGroupMemberStatus db userId membership GSMemInvited
withAgent $ \a -> deleteConnectionAsync a False agentConnId
throwError e
updateCIGroupInvitationStatus user g CIGISAccepted `catchChatError` (toView . CRChatError (Just user))
pure $ CRUserAcceptedGroupSent user g {membership = membership {memberStatus = GSMemAccepted}} Nothing
@@ -2639,7 +2615,7 @@ processChatCommand' vr = \case
joinPreparedAgentConnection user pccConnId connId cReq dm pqSup subMode
joinPreparedAgentConnection :: User -> Int64 -> ConnId -> ConnectionRequestUri m -> ByteString -> PQSupport -> SubscriptionMode -> CM ()
joinPreparedAgentConnection user pccConnId connId cReq connInfo pqSup subMode = do
void (withAgent $ \a -> joinConnection a (aUserId user) connId True cReq connInfo pqSup subMode)
void (withAgent $ \a -> joinConnection a (aUserId user) (Just connId) True cReq connInfo pqSup subMode)
`catchChatError` \e -> do
withFastStore' $ \db -> deleteConnectionRecord db user pccConnId
withAgent $ \a -> deleteConnectionAsync a False connId
@@ -2881,8 +2857,6 @@ processChatCommand' vr = \case
connectPlan user (ACR SCMInvitation (CRInvitationUri crData e2e)) = do
withFastStore' (\db -> getConnectionEntityByConnReq db vr user cReqSchemas) >>= \case
Nothing -> pure $ CPInvitationLink ILPOk
Just (RcvDirectMsgConnection Connection {connStatus = ConnPrepared} Nothing) ->
pure $ CPInvitationLink ILPOk
Just (RcvDirectMsgConnection conn ct_) -> do
let Connection {connStatus, contactConnInitiated} = conn
if
@@ -3690,41 +3664,29 @@ getRcvFilePath fileId fPath_ fn keepHandle = case fPath_ of
liftIO $ B.hPut h "" >> hFlush h
| otherwise = liftIO $ B.writeFile fPath ""
acceptContactRequest :: User -> UserContactRequest -> IncognitoEnabled -> CM (Contact, Connection, SndQueueSecured)
acceptContactRequest user@User {userId} UserContactRequest {agentInvitationId = AgentInvId invId, contactId_, cReqChatVRange, localDisplayName = cName, profileId, profile = cp, userContactLinkId, xContactId, pqSupport} incognito = do
acceptContactRequest :: User -> UserContactRequest -> Maybe IncognitoProfile -> Bool -> CM Contact
acceptContactRequest user UserContactRequest {agentInvitationId = AgentInvId invId, cReqChatVRange, localDisplayName = cName, profileId, profile = cp, userContactLinkId, xContactId, pqSupport} incognitoProfile contactUsed = do
subMode <- chatReadVar subscriptionMode
let pqSup = PQSupportOn
pqSup' = pqSup `CR.pqSupportAnd` pqSupport
vr <- chatVersionRange
let chatV = vr `peerConnChatVersion` cReqChatVRange
(ct, conn, incognitoProfile) <- case contactId_ of
Nothing -> do
incognitoProfile <- if incognito then Just . NewIncognito <$> liftIO generateRandomProfile else pure Nothing
connId <- withAgent $ \a -> prepareConnectionToAccept a True invId pqSup'
(ct, conn) <- withStore' $ \db -> createAcceptedContact db user connId chatV cReqChatVRange cName profileId cp userContactLinkId xContactId incognitoProfile subMode pqSup' False
pure (ct, conn, incognitoProfile)
Just contactId -> do
ct <- withFastStore $ \db -> getContact db vr user contactId
case contactConn ct of
Nothing -> throwChatError $ CECommandError "contact has no connection"
Just conn@Connection {customUserProfileId} -> do
incognitoProfile <- forM customUserProfileId $ \pId -> withFastStore $ \db -> getProfileById db userId pId
pure (ct, conn, ExistingIncognito <$> incognitoProfile)
let profileToSend = profileToSendOnAccept user incognitoProfile False
chatV = vr `peerConnChatVersion` cReqChatVRange
pqSup' = pqSup `CR.pqSupportAnd` pqSupport
dm <- encodeConnInfoPQ pqSup' chatV $ XInfo profileToSend
(ct,conn,) <$> withAgent (\a -> acceptContact a (aConnId conn) True invId dm pqSup' subMode)
(acId, sqSecured) <- withAgent $ \a -> acceptContact a True invId dm pqSup' subMode
let connStatus = if sqSecured then ConnSndReady else ConnNew
withStore' $ \db -> createAcceptedContact db user acId connStatus chatV cReqChatVRange cName profileId cp userContactLinkId xContactId incognitoProfile subMode pqSup' contactUsed
acceptContactRequestAsync :: User -> UserContactRequest -> Maybe IncognitoProfile -> Bool -> PQSupport -> CM Contact
acceptContactRequestAsync user cReq@UserContactRequest {agentInvitationId = AgentInvId invId, cReqChatVRange, localDisplayName = cName, profileId, profile = p, userContactLinkId, xContactId} incognitoProfile contactUsed pqSup = do
acceptContactRequestAsync user UserContactRequest {agentInvitationId = AgentInvId invId, cReqChatVRange, localDisplayName = cName, profileId, profile = p, userContactLinkId, xContactId} incognitoProfile contactUsed pqSup = do
subMode <- chatReadVar subscriptionMode
let profileToSend = profileToSendOnAccept user incognitoProfile False
vr <- chatVersionRange
let chatV = vr `peerConnChatVersion` cReqChatVRange
(cmdId, acId) <- agentAcceptContactAsync user True invId (XInfo profileToSend) subMode pqSup chatV
withStore' $ \db -> do
(ct, Connection {connId}) <- createAcceptedContact db user acId chatV cReqChatVRange cName profileId p userContactLinkId xContactId incognitoProfile subMode pqSup contactUsed
deleteContactRequestRec db user cReq
setCommandConnId db user cmdId connId
ct@Contact {activeConn} <- createAcceptedContact db user acId ConnNew chatV cReqChatVRange cName profileId p userContactLinkId xContactId incognitoProfile subMode pqSup contactUsed
forM_ activeConn $ \Connection {connId} -> setCommandConnId db user cmdId connId
pure ct
acceptGroupJoinRequestAsync :: User -> GroupInfo -> UserContactRequest -> GroupMemberRole -> Maybe IncognitoProfile -> CM GroupMember
@@ -4589,7 +4551,6 @@ processAgentMessageConn vr user@User {userId} corrId agentConnId agentMessage =
lift $ setContactNetworkStatus ct' NSConnected
toView $ CRContactConnected user ct' (fmap fromLocalProfile incognitoProfile)
when (directOrUsed ct') $ do
unless (contactUsed ct') $ withFastStore' $ \db -> updateContactUsed db user ct'
createInternalChatItem user (CDDirectRcv ct') (CIRcvDirectE2EEInfo $ E2EInfo pqEnc) Nothing
createFeatureEnabledItems ct'
when (contactConnInitiated conn') $ do
-4
View File
@@ -1416,10 +1416,6 @@ catchStoreError :: ExceptT StoreError IO a -> (StoreError -> ExceptT StoreError
catchStoreError = catchAllErrors mkStoreError
{-# INLINE catchStoreError #-}
tryStoreError' :: ExceptT StoreError IO a -> IO (Either StoreError a)
tryStoreError' = tryAllErrors' mkStoreError
{-# INLINE tryStoreError' #-}
mkStoreError :: SomeException -> StoreError
mkStoreError = SEInternalError . show
{-# INLINE mkStoreError #-}
@@ -1,22 +0,0 @@
{-# LANGUAGE QuasiQuotes #-}
module Simplex.Chat.Migrations.M20241010_contact_requests_contact_id where
import Database.SQLite.Simple (Query)
import Database.SQLite.Simple.QQ (sql)
m20241010_contact_requests_contact_id :: Query
m20241010_contact_requests_contact_id =
[sql|
ALTER TABLE contact_requests ADD COLUMN contact_id INTEGER REFERENCES contacts ON DELETE CASCADE;
CREATE INDEX idx_contact_requests_contact_id ON contact_requests(contact_id);
|]
down_m20241010_contact_requests_contact_id :: Query
down_m20241010_contact_requests_contact_id =
[sql|
DROP INDEX idx_contact_requests_contact_id;
ALTER TABLE contact_requests DROP COLUMN contact_id;
|]
@@ -327,7 +327,6 @@ CREATE TABLE contact_requests(
peer_chat_min_version INTEGER NOT NULL DEFAULT 1,
peer_chat_max_version INTEGER NOT NULL DEFAULT 1,
pq_support INTEGER NOT NULL DEFAULT 0,
contact_id INTEGER REFERENCES contacts ON DELETE CASCADE,
FOREIGN KEY(user_id, local_display_name)
REFERENCES display_names(user_id, local_display_name)
ON UPDATE CASCADE
@@ -889,4 +888,3 @@ CREATE INDEX idx_chat_items_fwd_from_chat_item_id ON chat_items(
CREATE INDEX idx_received_probes_group_member_id on received_probes(
group_member_id
);
CREATE INDEX idx_contact_requests_contact_id ON contact_requests(contact_id);
-11
View File
@@ -125,17 +125,6 @@ data ConnectionEntity
$(JQ.deriveJSON (sumTypeJSON fstToLower) ''ConnectionEntity)
connEntityInfo :: ConnectionEntity -> String
connEntityInfo = \case
RcvDirectMsgConnection c ct_ -> ctInfo ct_ <> ", status: " <> show (connStatus c)
RcvGroupMsgConnection c g m -> mInfo g m <> ", status: " <> show (connStatus c)
SndFileConnection c _ft -> "snd file, status: " <> show (connStatus c)
RcvFileConnection c _ft -> "rcv file, status: " <> show (connStatus c)
UserContactConnection c _uc -> "user address, status: " <> show (connStatus c)
where
ctInfo = maybe "connection" $ \Contact {contactId} -> "contact " <> show contactId
mInfo GroupInfo {groupId} GroupMember {groupMemberId} = "group " <> show groupId <> ", member " <> show groupMemberId
updateEntityConnStatus :: ConnectionEntity -> ConnStatus -> ConnectionEntity
updateEntityConnStatus connEntity connStatus = case connEntity of
RcvDirectMsgConnection c ct_ -> RcvDirectMsgConnection (st c) ((\ct -> (ct :: Contact) {activeConn = Just $ st c}) <$> ct_)
+2 -2
View File
@@ -73,11 +73,11 @@ import UnliftIO.Directory (copyFile, createDirectoryIfMissing, doesDirectoryExis
-- when acting as host
minRemoteCtrlVersion :: AppVersion
minRemoteCtrlVersion = AppVersion [6, 1, 0, 8]
minRemoteCtrlVersion = AppVersion [6, 1, 0, 4]
-- when acting as controller
minRemoteHostVersion :: AppVersion
minRemoteHostVersion = AppVersion [6, 1, 0, 8]
minRemoteHostVersion = AppVersion [6, 1, 0, 4]
currentAppVersion :: AppVersion
currentAppVersion = AppVersion SC.version
+28 -53
View File
@@ -62,8 +62,6 @@ module Simplex.Chat.Store.Direct
getContactRequestIdByName,
deleteContactRequest,
createAcceptedContact,
deleteContactRequestRec,
updateContactAccepted,
getUserByContactRequestId,
getPendingContactConnections,
updatePCCUser,
@@ -71,7 +69,6 @@ module Simplex.Chat.Store.Direct
getConnectionById,
getConnectionsContacts,
updateConnectionStatus,
updateConnectionStatusFromTo,
updateContactSettings,
setConnConnReqInv,
resetContactConnInitiated,
@@ -658,7 +655,7 @@ createOrUpdateContactRequest db vr user@User {userId} userContactLinkId invId (V
db
[sql|
SELECT
cr.contact_request_id, cr.local_display_name, cr.agent_invitation_id, cr.contact_id, cr.user_contact_link_id,
cr.contact_request_id, cr.local_display_name, cr.agent_invitation_id, cr.user_contact_link_id,
c.agent_conn_id, cr.contact_profile_id, p.display_name, p.full_name, p.image, p.contact_link, cr.xcontact_id, cr.pq_support, p.preferences, cr.created_at, cr.updated_at,
cr.peer_chat_min_version, cr.peer_chat_max_version
FROM contact_requests cr
@@ -727,7 +724,7 @@ getContactRequest db User {userId} contactRequestId =
db
[sql|
SELECT
cr.contact_request_id, cr.local_display_name, cr.agent_invitation_id, cr.contact_id, cr.user_contact_link_id,
cr.contact_request_id, cr.local_display_name, cr.agent_invitation_id, cr.user_contact_link_id,
c.agent_conn_id, cr.contact_profile_id, p.display_name, p.full_name, p.image, p.contact_link, cr.xcontact_id, cr.pq_support, p.preferences, cr.created_at, cr.updated_at,
cr.peer_chat_min_version, cr.peer_chat_max_version
FROM contact_requests cr
@@ -769,8 +766,9 @@ deleteContactRequest db User {userId} contactRequestId = do
(userId, userId, contactRequestId, userId)
DB.execute db "DELETE FROM contact_requests WHERE user_id = ? AND contact_request_id = ?" (userId, contactRequestId)
createAcceptedContact :: DB.Connection -> User -> ConnId -> VersionChat -> VersionRangeChat -> ContactName -> ProfileId -> Profile -> Int64 -> Maybe XContactId -> Maybe IncognitoProfile -> SubscriptionMode -> PQSupport -> Bool -> IO (Contact, Connection)
createAcceptedContact db user@User {userId, profile = LocalProfile {preferences}} agentConnId connChatVersion cReqChatVRange localDisplayName profileId profile userContactLinkId xContactId incognitoProfile subMode pqSup contactUsed = do
createAcceptedContact :: DB.Connection -> User -> ConnId -> ConnStatus -> VersionChat -> VersionRangeChat -> ContactName -> ProfileId -> Profile -> Int64 -> Maybe XContactId -> Maybe IncognitoProfile -> SubscriptionMode -> PQSupport -> Bool -> IO Contact
createAcceptedContact db user@User {userId, profile = LocalProfile {preferences}} agentConnId connStatus connChatVersion cReqChatVRange localDisplayName profileId profile userContactLinkId xContactId incognitoProfile subMode pqSup contactUsed = do
DB.execute db "DELETE FROM contact_requests WHERE user_id = ? AND local_display_name = ?" (userId, localDisplayName)
createdAt <- getCurrentTime
customUserProfileId <- forM incognitoProfile $ \case
NewIncognito p -> createIncognitoProfile_ db userId createdAt p
@@ -781,42 +779,29 @@ createAcceptedContact db user@User {userId, profile = LocalProfile {preferences}
"INSERT INTO contacts (user_id, local_display_name, contact_profile_id, enable_ntfs, user_preferences, created_at, updated_at, chat_ts, xcontact_id, contact_used) VALUES (?,?,?,?,?,?,?,?,?,?)"
(userId, localDisplayName, profileId, True, userPreferences, createdAt, createdAt, createdAt, xContactId, contactUsed)
contactId <- insertedRowId db
DB.execute db "UPDATE contact_requests SET contact_id = ? WHERE user_id = ? AND local_display_name = ?" (contactId, userId, localDisplayName)
conn <- createConnection_ db userId ConnContact (Just contactId) agentConnId ConnNew connChatVersion cReqChatVRange Nothing (Just userContactLinkId) customUserProfileId 0 createdAt subMode pqSup
conn <- createConnection_ db userId ConnContact (Just contactId) agentConnId connStatus connChatVersion cReqChatVRange Nothing (Just userContactLinkId) customUserProfileId 0 createdAt subMode pqSup
let mergedPreferences = contactUserPreferences user userPreferences preferences $ connIncognito conn
ct =
Contact
{ contactId,
localDisplayName,
profile = toLocalProfile profileId profile "",
activeConn = Just conn,
viaGroup = Nothing,
contactUsed,
contactStatus = CSActive,
chatSettings = defaultChatSettings,
userPreferences,
mergedPreferences,
createdAt,
updatedAt = createdAt,
chatTs = Just createdAt,
contactGroupMemberId = Nothing,
contactGrpInvSent = False,
uiThemes = Nothing,
chatDeleted = False,
customData = Nothing
}
pure (ct, conn)
deleteContactRequestRec :: DB.Connection -> User -> UserContactRequest -> IO ()
deleteContactRequestRec db User {userId} UserContactRequest {contactRequestId} =
DB.execute db "DELETE FROM contact_requests WHERE user_id = ? AND contact_request_id = ?" (userId, contactRequestId)
updateContactAccepted :: DB.Connection -> User -> Contact -> Bool -> IO ()
updateContactAccepted db User {userId} Contact {contactId} contactUsed =
DB.execute
db
"UPDATE contacts SET contact_used = ? WHERE user_id = ? AND contact_id = ?"
(contactUsed, userId, contactId)
pure $
Contact
{ contactId,
localDisplayName,
profile = toLocalProfile profileId profile "",
activeConn = Just conn,
viaGroup = Nothing,
contactUsed,
contactStatus = CSActive,
chatSettings = defaultChatSettings,
userPreferences,
mergedPreferences,
createdAt,
updatedAt = createdAt,
chatTs = Just createdAt,
contactGroupMemberId = Nothing,
contactGrpInvSent = False,
uiThemes = Nothing,
chatDeleted = False,
customData = Nothing
}
getContactIdByName :: DB.Connection -> User -> ContactName -> ExceptT StoreError IO Int64
getContactIdByName db User {userId} cName =
@@ -942,17 +927,7 @@ getConnectionsContacts db agentConnIds = do
toContactRef (contactId, connId, acId, localDisplayName) = ContactRef {contactId, connId, agentConnId = AgentConnId acId, localDisplayName}
updateConnectionStatus :: DB.Connection -> Connection -> ConnStatus -> IO ()
updateConnectionStatus db Connection {connId} = updateConnectionStatus_ db connId
{-# INLINE updateConnectionStatus #-}
updateConnectionStatusFromTo :: DB.Connection -> Int64 -> ConnStatus -> ConnStatus -> IO ()
updateConnectionStatusFromTo db connId fromStatus toStatus = do
maybeFirstRow fromOnly (DB.query db "SELECT conn_status FROM connections WHERE connection_id = ?" (Only connId)) >>= \case
Just status | status == fromStatus -> updateConnectionStatus_ db connId toStatus
_ -> pure ()
updateConnectionStatus_ :: DB.Connection -> Int64 -> ConnStatus -> IO ()
updateConnectionStatus_ db connId connStatus = do
updateConnectionStatus db Connection {connId} connStatus = do
currentTs <- getCurrentTime
if connStatus == ConnReady
then DB.execute db "UPDATE connections SET conn_status = ?, updated_at = ?, conn_req_inv = NULL WHERE connection_id = ?" (connStatus, currentTs, connId)
+5 -5
View File
@@ -1933,8 +1933,8 @@ createMemberContact
contactId <- insertedRowId db
DB.execute
db
"UPDATE group_members SET contact_id = ?, updated_at = ? WHERE contact_profile_id = ?"
(contactId, currentTs, memberContactProfileId)
"UPDATE group_members SET contact_id = ?, updated_at = ? WHERE group_member_id = ?"
(contactId, currentTs, groupMemberId)
DB.execute
db
[sql|
@@ -2003,7 +2003,7 @@ createMemberContactInvited
user@User {userId, profile = LocalProfile {preferences}}
connIds
gInfo
m@GroupMember {localDisplayName = memberLDN, memberProfile, memberContactProfileId}
m@GroupMember {groupMemberId, localDisplayName = memberLDN, memberProfile, memberContactProfileId}
mConn
subMode = do
currentTs <- liftIO getCurrentTime
@@ -2031,8 +2031,8 @@ createMemberContactInvited
contactId <- insertedRowId db
DB.execute
db
"UPDATE group_members SET contact_id = ?, updated_at = ? WHERE contact_profile_id = ?"
(contactId, currentTs, memberContactProfileId)
"UPDATE group_members SET contact_id = ?, updated_at = ? WHERE group_member_id = ?"
(contactId, currentTs, groupMemberId)
pure contactId
updateMemberContactInvited :: DB.Connection -> User -> (CommandId, ConnId) -> GroupInfo -> Connection -> Contact -> SubscriptionMode -> ExceptT StoreError IO Contact
+2 -3
View File
@@ -882,7 +882,7 @@ getContactRequestChatPreviews_ db User {userId} pagination clq = case clq of
db
( [sql|
SELECT
cr.contact_request_id, cr.local_display_name, cr.agent_invitation_id, cr.contact_id, cr.user_contact_link_id,
cr.contact_request_id, cr.local_display_name, cr.agent_invitation_id, cr.user_contact_link_id,
c.agent_conn_id, cr.contact_profile_id, p.display_name, p.full_name, p.image, p.contact_link, cr.xcontact_id, cr.pq_support, p.preferences,
cr.created_at, cr.updated_at as ts,
cr.peer_chat_min_version, cr.peer_chat_max_version
@@ -930,7 +930,6 @@ getContactConnectionChatPreviews_ db User {userId} pagination clq = case clq of
FROM connections
WHERE user_id = :user_id
AND conn_type = :conn_contact
AND conn_status != :conn_status
AND contact_id IS NULL
AND conn_level = 0
AND via_contact IS NULL
@@ -939,7 +938,7 @@ getContactConnectionChatPreviews_ db User {userId} pagination clq = case clq of
|]
<> pagQuery
)
([":user_id" := userId, ":conn_contact" := ConnContact, ":conn_status" := ConnPrepared, ":search" := search] <> pagParams)
([":user_id" := userId, ":conn_contact" := ConnContact, ":search" := search] <> pagParams)
toPreview :: (Int64, ConnId, ConnStatus, Maybe ByteString, Maybe Int64, Maybe GroupLinkId, Maybe Int64, Maybe ConnReqInvitation, LocalAlias, UTCTime, UTCTime) -> AChatPreviewData
toPreview connRow =
let conn@PendingContactConnection {updatedAt} = toPendingContactConnection connRow
+1 -3
View File
@@ -113,7 +113,6 @@ import Simplex.Chat.Migrations.M20240528_quota_err_counter
import Simplex.Chat.Migrations.M20240827_calls_uuid
import Simplex.Chat.Migrations.M20240920_user_order
import Simplex.Chat.Migrations.M20241008_indexes
import Simplex.Chat.Migrations.M20241010_contact_requests_contact_id
import Simplex.Messaging.Agent.Store.SQLite.Migrations (Migration (..))
schemaMigrations :: [(String, Query, Maybe Query)]
@@ -226,8 +225,7 @@ schemaMigrations =
("20240528_quota_err_counter", m20240528_quota_err_counter, Just down_m20240528_quota_err_counter),
("20240827_calls_uuid", m20240827_calls_uuid, Just down_m20240827_calls_uuid),
("20240920_user_order", m20240920_user_order, Just down_m20240920_user_order),
("20241008_indexes", m20241008_indexes, Just down_m20241008_indexes),
("20241010_contact_requests_contact_id", m20241010_contact_requests_contact_id, Just down_m20241010_contact_requests_contact_id)
("20241008_indexes", m20241008_indexes, Just down_m20241008_indexes)
]
-- | The list of migrations in ascending order by date
+3 -3
View File
@@ -411,13 +411,13 @@ getProfileById db userId profileId =
toProfile :: (ContactName, Text, Maybe ImageData, Maybe ConnReqContact, LocalAlias, Maybe Preferences) -> LocalProfile
toProfile (displayName, fullName, image, contactLink, localAlias, preferences) = LocalProfile {profileId, displayName, fullName, image, contactLink, preferences, localAlias}
type ContactRequestRow = (Int64, ContactName, AgentInvId, Maybe ContactId, Int64, AgentConnId, Int64, ContactName, Text, Maybe ImageData, Maybe ConnReqContact) :. (Maybe XContactId, PQSupport, Maybe Preferences, UTCTime, UTCTime, VersionChat, VersionChat)
type ContactRequestRow = (Int64, ContactName, AgentInvId, Int64, AgentConnId, Int64, ContactName, Text, Maybe ImageData, Maybe ConnReqContact) :. (Maybe XContactId, PQSupport, Maybe Preferences, UTCTime, UTCTime, VersionChat, VersionChat)
toContactRequest :: ContactRequestRow -> UserContactRequest
toContactRequest ((contactRequestId, localDisplayName, agentInvitationId, contactId_, userContactLinkId, agentContactConnId, profileId, displayName, fullName, image, contactLink) :. (xContactId, pqSupport, preferences, createdAt, updatedAt, minVer, maxVer)) = do
toContactRequest ((contactRequestId, localDisplayName, agentInvitationId, userContactLinkId, agentContactConnId, profileId, displayName, fullName, image, contactLink) :. (xContactId, pqSupport, preferences, createdAt, updatedAt, minVer, maxVer)) = do
let profile = Profile {displayName, fullName, image, contactLink, preferences}
cReqChatVRange = fromMaybe (versionToRange maxVer) $ safeVersionRange minVer maxVer
in UserContactRequest {contactRequestId, agentInvitationId, contactId_, userContactLinkId, agentContactConnId, cReqChatVRange, localDisplayName, profileId, profile, xContactId, pqSupport, createdAt, updatedAt}
in UserContactRequest {contactRequestId, agentInvitationId, userContactLinkId, agentContactConnId, cReqChatVRange, localDisplayName, profileId, profile, xContactId, pqSupport, createdAt, updatedAt}
userQuery :: Query
userQuery =
-5
View File
@@ -297,7 +297,6 @@ userContactGroupId UserContact {groupId} = groupId
data UserContactRequest = UserContactRequest
{ contactRequestId :: Int64,
agentInvitationId :: AgentInvId,
contactId_ :: Maybe ContactId,
userContactLinkId :: Int64,
agentContactConnId :: AgentConnId, -- connection id of user contact
cReqChatVRange :: VersionRangeChat,
@@ -1372,8 +1371,6 @@ aConnId' PendingContactConnection {pccAgentConnId = AgentConnId cId} = cId
data ConnStatus
= -- | connection is created by initiating party with agent NEW command (createConnection)
ConnNew
| -- | connection is prepared, to avoid changing keys on invitation links when retrying.
ConnPrepared
| -- | connection is joined by joining party with agent JOIN command (joinConnection)
ConnJoined
| -- | initiating party received CONF notification (to be renamed to REQ)
@@ -1402,7 +1399,6 @@ instance ToJSON ConnStatus where
instance TextEncoding ConnStatus where
textDecode = \case
"new" -> Just ConnNew
"prepared" -> Just ConnPrepared
"joined" -> Just ConnJoined
"requested" -> Just ConnRequested
"accepted" -> Just ConnAccepted
@@ -1412,7 +1408,6 @@ instance TextEncoding ConnStatus where
_ -> Nothing
textEncode = \case
ConnNew -> "new"
ConnPrepared -> "prepared"
ConnJoined -> "joined"
ConnRequested -> "requested"
ConnAccepted -> "accepted"
-52
View File
@@ -28,8 +28,6 @@ directoryServiceTests :: SpecWith FilePath
directoryServiceTests = do
it "should register group" testDirectoryService
it "should suspend and resume group" testSuspendResume
it "should delete group registration" testDeleteGroup
it "should change initial member role" testSetRole
it "should join found group via link" testJoinGroup
it "should support group names with spaces" testGroupNameWithSpaces
it "should return more groups in search, all and recent groups" testSearchGroups
@@ -141,15 +139,6 @@ testDirectoryService tmp =
bob <# "SimpleX-Directory> Thank you! The group link for ID 1 (PSA) is added to the welcome message."
bob <## "You will be notified once the group is added to the directory - it may take up to 24 hours."
approvalRequested superUser welcomeWithLink' (1 :: Int)
superUser #> "@SimpleX-Directory /pending"
superUser <# "SimpleX-Directory> > /pending"
superUser <## " 1 registered group(s)"
superUser <# "SimpleX-Directory> 1. PSA (Privacy, Security & Anonymity)"
superUser <## "Welcome message:"
superUser <##. "Welcome! Link to join the group PSA: "
superUser <## "Owner: bob"
superUser <## "2 members"
superUser <## "Status: pending admin approval"
superUser #> "@SimpleX-Directory /approve 1:PSA 1"
superUser <# "SimpleX-Directory> > /approve 1:PSA 1"
superUser <## " Group approved!"
@@ -208,47 +197,6 @@ testSuspendResume tmp =
bob <# "SimpleX-Directory> The group ID 1 (privacy) is listed in the directory again!"
groupFound bob "privacy"
testDeleteGroup :: HasCallStack => FilePath -> IO ()
testDeleteGroup tmp =
withDirectoryService tmp $ \superUser dsLink ->
withNewTestChat tmp "bob" bobProfile $ \bob -> do
bob `connectVia` dsLink
registerGroup superUser bob "privacy" "Privacy"
groupFound bob "privacy"
bob #> "@SimpleX-Directory /delete 1:privacy"
bob <# "SimpleX-Directory> > /delete 1:privacy"
bob <## " Your group privacy is deleted from the directory"
groupNotFound bob "privacy"
testSetRole :: HasCallStack => FilePath -> IO ()
testSetRole tmp =
withDirectoryService tmp $ \superUser dsLink ->
withNewTestChat tmp "bob" bobProfile $ \bob ->
withNewTestChat tmp "cath" cathProfile $ \cath -> do
bob `connectVia` dsLink
registerGroup superUser bob "privacy" "Privacy"
groupFound bob "privacy"
bob #> "@SimpleX-Directory /role 1:privacy observer"
bob <# "SimpleX-Directory> > /role 1:privacy observer"
bob <## " The initial member role for the group privacy is set to observer"
bob <## ""
note <- getTermLine bob
let groupLink = dropStrPrefix "Please note: it applies only to members joining via this link: " note
cath ##> ("/c " <> groupLink)
cath <## "connection request sent!"
cath <## "#privacy: joining the group..."
cath <## "#privacy: you joined the group"
cath <#. "#privacy SimpleX-Directory> Link to join the group privacy: https://simplex.chat/"
cath <## "#privacy: member bob (Bob) is connected"
bob <## "#privacy: SimpleX-Directory added cath (Catherine) to the group (connecting...)"
bob <## "#privacy: new member cath is connected"
bob ##> "/ms #privacy"
bob <## "bob (Bob): owner, you, created group"
bob <## "SimpleX-Directory: admin, invited, connected"
bob <## "cath (Catherine): observer, connected"
cath ##> "#privacy hello"
cath <## "#privacy: you don't have permission to send messages"
testJoinGroup :: HasCallStack => FilePath -> IO ()
testJoinGroup tmp =
withDirectoryServiceCfg tmp testCfgGroupLinkViaContact $ \superUser dsLink ->
+2 -2
View File
@@ -463,7 +463,7 @@ smpServerCfg =
withSmpServer :: IO () -> IO ()
withSmpServer = withSmpServer' smpServerCfg
withSmpServer' :: ServerConfig -> IO a -> IO a
withSmpServer' :: ServerConfig -> IO () -> IO ()
withSmpServer' cfg = serverBracket (\started -> runSMPServerBlocking started cfg Nothing)
xftpTestPort :: ServiceName
@@ -515,7 +515,7 @@ withXFTPServer' cfg =
runXFTPServerBlocking started cfg Nothing
)
serverBracket :: (TMVar Bool -> IO ()) -> IO a -> IO a
serverBracket :: (TMVar Bool -> IO ()) -> IO () -> IO ()
serverBracket server f = do
started <- newEmptyTMVarIO
bracket
+2 -131
View File
@@ -1,12 +1,9 @@
{-# LANGUAGE DuplicateRecordFields #-}
{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE PatternSynonyms #-}
{-# LANGUAGE PostfixOperators #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
{-# OPTIONS_GHC -Wno-ambiguous-fields #-}
module ChatTests.Direct where
@@ -25,18 +22,14 @@ import Database.SQLite.Simple (Only (..))
import Simplex.Chat.AppSettings (defaultAppSettings)
import qualified Simplex.Chat.AppSettings as AS
import Simplex.Chat.Call
import Simplex.Chat.Controller (ChatConfig (..), DefaultAgentServers (..))
import Simplex.Chat.Controller (ChatConfig (..))
import Simplex.Chat.Messages (ChatItemId)
import Simplex.Chat.Options
import Simplex.Chat.Options (ChatOpts (..))
import Simplex.Chat.Protocol (supportedChatVRange)
import Simplex.Chat.Store (agentStoreFile, chatStoreFile)
import Simplex.Chat.Types (VersionRangeChat, authErrDisableCount, sameVerificationCode, verificationCode, pattern VersionChat)
import Simplex.Messaging.Agent.Env.SQLite
import Simplex.Messaging.Agent.RetryInterval
import qualified Simplex.Messaging.Agent.Store.SQLite.DB as DB
import qualified Simplex.Messaging.Crypto as C
import Simplex.Messaging.Server.Env.STM hiding (subscriptions)
import Simplex.Messaging.Transport
import Simplex.Messaging.Util (safeDecodeUtf8)
import Simplex.Messaging.Version
import System.Directory (copyFile, doesDirectoryExist, doesFileExist)
@@ -47,8 +40,6 @@ chatDirectTests :: SpecWith FilePath
chatDirectTests = do
describe "direct messages" $ do
describe "add contact and send/receive messages" testAddContact
it "retry connecting via the same link" testRetryConnecting
xit'' "retry connecting via the same link with client timeout" testRetryConnectingClientTimeout
it "mark multiple messages as read" testMarkReadDirect
it "clear chat with contact" testContactClear
it "deleting contact deletes profile" testDeleteContactDeletesProfile
@@ -224,126 +215,6 @@ testAddContact = versionTestMatrix2 runTestAddContact
then chatFeatures
else (0, e2eeInfoNoPQStr) : tail chatFeatures
testRetryConnecting :: HasCallStack => FilePath -> IO ()
testRetryConnecting tmp = testChatCfgOpts2 cfg' opts' aliceProfile bobProfile test tmp
where
test alice bob = do
inv <- withSmpServer' serverCfg' $ do
alice ##> "/_connect 1"
getInvitation alice
alice <## "server disconnected localhost ()"
bob ##> ("/_connect plan 1 " <> inv)
bob <## "invitation link: ok to connect"
bob ##> ("/_connect 1 " <> inv)
bob <##. "smp agent error: BROKER"
withSmpServer' serverCfg' $ do
alice <## "server connected localhost ()"
bob ##> ("/_connect plan 1 " <> inv)
bob <## "invitation link: ok to connect"
bob ##> ("/_connect 1 " <> inv)
bob <## "confirmation sent!"
concurrently_
(bob <## "alice (Alice): contact is connected")
(alice <## "bob (Bob): contact is connected")
alice #> "@bob message 1"
bob <# "alice> message 1"
bob #> "@alice message 2"
alice <# "bob> message 2"
bob <## "server disconnected localhost (@alice)"
alice <## "server disconnected localhost (@bob)"
serverCfg' =
smpServerCfg
{ transports = [("7003", transport @TLS, False)],
msgQueueQuota = 2,
storeLogFile = Just $ tmp <> "/smp-server-store.log",
storeMsgsFile = Just $ tmp <> "/smp-server-messages.log"
}
fastRetryInterval = defaultReconnectInterval {initialInterval = 50000} -- same as in agent tests
cfg' =
testCfg
{ agentConfig =
testAgentCfg
{ quotaExceededTimeout = 1,
messageRetryInterval = RetryInterval2 {riFast = fastRetryInterval, riSlow = fastRetryInterval}
}
}
opts' =
testOpts
{ coreOptions =
testCoreOpts
{ smpServers = ["smp://LcJUMfVhwD8yxjAiSaDzzGF3-kLG4Uh0Fl_ZIjrRwjI=:server_password@localhost:7003"]
}
}
testRetryConnectingClientTimeout :: HasCallStack => FilePath -> IO ()
testRetryConnectingClientTimeout tmp = do
inv <- withSmpServer' serverCfg' $ do
withNewTestChatCfgOpts tmp cfg' opts' "alice" aliceProfile $ \alice -> do
alice ##> "/_connect 1"
inv <- getInvitation alice
withNewTestChatCfgOpts tmp cfgZeroTimeout opts' "bob" bobProfile $ \bob -> do
bob ##> ("/_connect plan 1 " <> inv)
bob <## "invitation link: ok to connect"
bob ##> ("/_connect 1 " <> inv)
bob <## "smp agent error: BROKER {brokerAddress = \"smp://LcJUMfVhwD8yxjAiSaDzzGF3-kLG4Uh0Fl_ZIjrRwjI=@localhost:7003\", brokerErr = TIMEOUT}"
pure inv
logFile <- readFile $ tmp <> "/smp-server-store.log"
logFile `shouldContain` "SECURE"
withSmpServer' serverCfg' $ do
withTestChatCfgOpts tmp cfg' opts' "alice" $ \alice -> do
withTestChatCfgOpts tmp cfg' opts' "bob" $ \bob -> do
bob ##> ("/_connect plan 1 " <> inv)
bob <## "invitation link: ok to connect"
bob ##> ("/_connect 1 " <> inv)
bob <## "confirmation sent!"
concurrently_
(bob <## "alice (Alice): contact is connected")
(alice <## "bob (Bob): contact is connected")
alice #> "@bob message 1"
bob <# "alice> message 1"
bob #> "@alice message 2"
alice <# "bob> message 2"
where
serverCfg' =
smpServerCfg
{ transports = [("7003", transport @TLS, False)],
msgQueueQuota = 2,
storeLogFile = Just $ tmp <> "/smp-server-store.log",
storeMsgsFile = Just $ tmp <> "/smp-server-messages.log"
}
fastRetryInterval = defaultReconnectInterval {initialInterval = 50000} -- same as in agent tests
cfg' =
testCfg
{ agentConfig =
testAgentCfg
{ quotaExceededTimeout = 1,
messageRetryInterval = RetryInterval2 {riFast = fastRetryInterval, riSlow = fastRetryInterval}
}
}
cfgZeroTimeout =
(testCfg :: ChatConfig)
{ agentConfig =
testAgentCfg
{ quotaExceededTimeout = 1,
messageRetryInterval = RetryInterval2 {riFast = fastRetryInterval, riSlow = fastRetryInterval}
},
defaultServers =
let def@DefaultAgentServers {netCfg} = defaultServers testCfg
in def {netCfg = (netCfg :: NetworkConfig) {tcpTimeout = 10}}
}
opts' =
testOpts
{ coreOptions =
testCoreOpts
{ smpServers = ["smp://LcJUMfVhwD8yxjAiSaDzzGF3-kLG4Uh0Fl_ZIjrRwjI=:server_password@localhost:7003"]
}
}
testMarkReadDirect :: HasCallStack => FilePath -> IO ()
testMarkReadDirect = testChat2 aliceProfile bobProfile $ \alice bob -> do
connectUsers alice bob
-68
View File
@@ -130,7 +130,6 @@ chatGroupTests = do
it "invited member replaces member contact reference if it already exists" testMemberContactInvitedConnectionReplaced
it "share incognito profile" testMemberContactIncognito
it "sends and updates profile when creating contact" testMemberContactProfileUpdate
it "re-create member contact after deletion, many groups" testRecreateMemberContactManyGroups
describe "group message forwarding" $ do
it "forward messages between invitee and introduced (x.msg.new)" testGroupMsgForward
it "deduplicate forwarded messages" testGroupMsgForwardDeduplicate
@@ -4538,73 +4537,6 @@ testMemberContactProfileUpdate =
alice <# "#team kate> hello there"
bob <# "#team kate> hello there" -- updated profile
testRecreateMemberContactManyGroups :: HasCallStack => FilePath -> IO ()
testRecreateMemberContactManyGroups =
testChat2 aliceProfile bobProfile $
\alice bob -> do
connectUsers alice bob
createGroup2' "team" alice bob False
createGroup2' "club" alice bob False
-- alice can message bob via team and via club
alice ##> "@#team bob 1"
alice <# "@bob 1"
bob <# "alice> 1"
bob ##> "@#team alice 2"
bob <# "@alice 2"
alice <# "bob> 2"
alice ##> "@#club bob 3"
alice <# "@bob 3"
bob <# "alice> 3"
bob ##> "@#club alice 4"
bob <# "@alice 4"
alice <# "bob> 4"
-- alice deletes contact with bob
alice ##> "/d bob"
alice <## "bob: contact is deleted"
bob <## "alice (Alice) deleted contact with you"
bob ##> "/d alice"
bob <## "alice: contact is deleted"
-- alice creates member contact with bob
alice ##> "@#team bob hi"
alice
<### [ "member #team bob does not have direct connection, creating",
"contact for member #team bob is created",
"sent invitation to connect directly to member #team bob",
WithTime "@bob hi"
]
bob
<### [ "#team alice is creating direct contact alice with you",
WithTime "alice> hi"
]
bob <## "alice (Alice): you can send messages to contact"
concurrently_
(alice <## "bob (Bob): contact is connected")
(bob <## "alice (Alice): contact is connected")
-- alice can message bob via team and via club
alice ##> "@#team bob 1"
alice <# "@bob 1"
bob <# "alice> 1"
bob ##> "@#team alice 2"
bob <# "@alice 2"
alice <# "bob> 2"
alice ##> "@#club bob 3"
alice <# "@bob 3"
bob <# "alice> 3"
bob ##> "@#club alice 4"
bob <# "@alice 4"
alice <# "bob> 4"
testGroupMsgForward :: HasCallStack => FilePath -> IO ()
testGroupMsgForward =
testChat3 aliceProfile bobProfile cathProfile $
-65
View File
@@ -14,14 +14,10 @@ import Control.Monad.Except
import qualified Data.Attoparsec.ByteString.Char8 as A
import qualified Data.ByteString.Char8 as B
import qualified Data.Text as T
import Simplex.Chat.Controller (ChatConfig (..))
import Simplex.Chat.Options
import Simplex.Chat.Store.Shared (createContact)
import Simplex.Chat.Types (ConnStatus (..), Profile (..))
import Simplex.Chat.Types.Shared (GroupMemberRole (..))
import Simplex.Chat.Types.UITheme
import Simplex.Messaging.Agent.Env.SQLite
import Simplex.Messaging.Agent.RetryInterval
import Simplex.Messaging.Encoding.String (StrEncoding (..))
import Simplex.Messaging.Server.Env.STM hiding (subscriptions)
import Simplex.Messaging.Transport
@@ -37,7 +33,6 @@ chatProfileTests = do
it "use multiword profile names" testMultiWordProfileNames
describe "user contact link" $ do
it "create and connect via contact link" testUserContactLink
it "retry accepting connection via contact link" testRetryAcceptingViaContactLink
it "add contact link to profile" testProfileLink
it "auto accept contact requests" testUserContactLinkAutoAccept
it "deduplicate contact requests" testDeduplicateContactRequests
@@ -258,66 +253,6 @@ testUserContactLink =
alice @@@ [("@cath", lastChatFeature), ("@bob", "hey")]
alice <##> cath
testRetryAcceptingViaContactLink :: HasCallStack => FilePath -> IO ()
testRetryAcceptingViaContactLink tmp = testChatCfgOpts2 cfg' opts' aliceProfile bobProfile test tmp
where
test alice bob = do
cLink <- withSmpServer' serverCfg' $ do
alice ##> "/ad"
getContactLink alice True
alice <## "server disconnected localhost ()"
bob ##> ("/_connect plan 1 " <> cLink)
bob <## "contact address: ok to connect"
bob ##> ("/_connect 1 " <> cLink)
bob <##. "smp agent error: BROKER"
withSmpServer' serverCfg' $ do
alice <## "server connected localhost ()"
bob ##> ("/_connect plan 1 " <> cLink)
bob <## "contact address: ok to connect"
bob ##> ("/_connect 1 " <> cLink)
alice <#? bob
alice <## "server disconnected localhost ()"
bob <## "server disconnected localhost ()"
alice ##> "/ac bob"
alice <##. "smp agent error: BROKER"
withSmpServer' serverCfg' $ do
alice <## "server connected localhost ()"
bob <## "server connected localhost ()"
alice ##> "/ac bob"
alice <## "bob (Bob): accepting contact request, you can send messages to contact"
concurrently_
(bob <## "alice (Alice): contact is connected")
(alice <## "bob (Bob): contact is connected")
alice #> "@bob message 1"
bob <# "alice> message 1"
bob #> "@alice message 2"
alice <# "bob> message 2"
alice <## "server disconnected localhost (@bob)"
bob <## "server disconnected localhost (@alice)"
serverCfg' =
smpServerCfg
{ transports = [("7003", transport @TLS, False)],
msgQueueQuota = 2,
storeLogFile = Just $ tmp <> "/smp-server-store.log",
storeMsgsFile = Just $ tmp <> "/smp-server-messages.log"
}
fastRetryInterval = defaultReconnectInterval {initialInterval = 50000} -- same as in agent tests
cfg' =
testCfg
{ agentConfig =
testAgentCfg
{ quotaExceededTimeout = 1,
messageRetryInterval = RetryInterval2 {riFast = fastRetryInterval, riSlow = fastRetryInterval}
}
}
opts' =
testOpts
{ coreOptions =
testCoreOpts
{ smpServers = ["smp://LcJUMfVhwD8yxjAiSaDzzGF3-kLG4Uh0Fl_ZIjrRwjI=:server_password@localhost:7003"]
}
}
testProfileLink :: HasCallStack => FilePath -> IO ()
testProfileLink =
testChat3 aliceProfile bobProfile cathProfile $